PageRenderTime 80ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/league/flysystem/src/Adapter/AbstractFtpAdapter.php

https://gitlab.com/susmitha.plts/photographer_portfolio
PHP | 631 lines | 323 code | 76 blank | 232 comment | 10 complexity | 5acb34cf6e9349782db61fb55d783ad2 MD5 | raw file
  1. <?php
  2. namespace League\Flysystem\Adapter;
  3. use DateTime;
  4. use League\Flysystem\AdapterInterface;
  5. use League\Flysystem\Config;
  6. use League\Flysystem\NotSupportedException;
  7. use RuntimeException;
  8. abstract class AbstractFtpAdapter extends AbstractAdapter
  9. {
  10. /**
  11. * @var mixed
  12. */
  13. protected $connection;
  14. /**
  15. * @var string
  16. */
  17. protected $host;
  18. /**
  19. * @var int
  20. */
  21. protected $port = 21;
  22. /**
  23. * @var string|null
  24. */
  25. protected $username;
  26. /**
  27. * @var string|null
  28. */
  29. protected $password;
  30. /**
  31. * @var bool
  32. */
  33. protected $ssl = false;
  34. /**
  35. * @var int
  36. */
  37. protected $timeout = 90;
  38. /**
  39. * @var bool
  40. */
  41. protected $passive = true;
  42. /**
  43. * @var string
  44. */
  45. protected $separator = '/';
  46. /**
  47. * @var string|null
  48. */
  49. protected $root;
  50. /**
  51. * @var int
  52. */
  53. protected $permPublic = 0744;
  54. /**
  55. * @var int
  56. */
  57. protected $permPrivate = 0700;
  58. /**
  59. * @var array
  60. */
  61. protected $configurable = [];
  62. /**
  63. * @var string
  64. */
  65. protected $systemType;
  66. /**
  67. * @var bool
  68. */
  69. protected $alternativeRecursion = false;
  70. /**
  71. * Constructor.
  72. *
  73. * @param array $config
  74. */
  75. public function __construct(array $config)
  76. {
  77. $this->setConfig($config);
  78. }
  79. /**
  80. * Set the config.
  81. *
  82. * @param array $config
  83. *
  84. * @return $this
  85. */
  86. public function setConfig(array $config)
  87. {
  88. foreach ($this->configurable as $setting) {
  89. if ( ! isset($config[$setting])) {
  90. continue;
  91. }
  92. $method = 'set' . ucfirst($setting);
  93. if (method_exists($this, $method)) {
  94. $this->$method($config[$setting]);
  95. }
  96. }
  97. return $this;
  98. }
  99. /**
  100. * Returns the host.
  101. *
  102. * @return string
  103. */
  104. public function getHost()
  105. {
  106. return $this->host;
  107. }
  108. /**
  109. * Set the host.
  110. *
  111. * @param string $host
  112. *
  113. * @return $this
  114. */
  115. public function setHost($host)
  116. {
  117. $this->host = $host;
  118. return $this;
  119. }
  120. /**
  121. * Set the public permission value.
  122. *
  123. * @param int $permPublic
  124. *
  125. * @return $this
  126. */
  127. public function setPermPublic($permPublic)
  128. {
  129. $this->permPublic = $permPublic;
  130. return $this;
  131. }
  132. /**
  133. * Set the private permission value.
  134. *
  135. * @param int $permPrivate
  136. *
  137. * @return $this
  138. */
  139. public function setPermPrivate($permPrivate)
  140. {
  141. $this->permPrivate = $permPrivate;
  142. return $this;
  143. }
  144. /**
  145. * Returns the ftp port.
  146. *
  147. * @return int
  148. */
  149. public function getPort()
  150. {
  151. return $this->port;
  152. }
  153. /**
  154. * Returns the root folder to work from.
  155. *
  156. * @return string
  157. */
  158. public function getRoot()
  159. {
  160. return $this->root;
  161. }
  162. /**
  163. * Set the ftp port.
  164. *
  165. * @param int|string $port
  166. *
  167. * @return $this
  168. */
  169. public function setPort($port)
  170. {
  171. $this->port = (int) $port;
  172. return $this;
  173. }
  174. /**
  175. * Set the root folder to work from.
  176. *
  177. * @param string $root
  178. *
  179. * @return $this
  180. */
  181. public function setRoot($root)
  182. {
  183. $this->root = rtrim($root, '\\/') . $this->separator;
  184. return $this;
  185. }
  186. /**
  187. * Returns the ftp username.
  188. *
  189. * @return string username
  190. */
  191. public function getUsername()
  192. {
  193. return empty($this->username) ? 'anonymous' : $this->username;
  194. }
  195. /**
  196. * Set ftp username.
  197. *
  198. * @param string $username
  199. *
  200. * @return $this
  201. */
  202. public function setUsername($username)
  203. {
  204. $this->username = $username;
  205. return $this;
  206. }
  207. /**
  208. * Returns the password.
  209. *
  210. * @return string password
  211. */
  212. public function getPassword()
  213. {
  214. return $this->password;
  215. }
  216. /**
  217. * Set the ftp password.
  218. *
  219. * @param string $password
  220. *
  221. * @return $this
  222. */
  223. public function setPassword($password)
  224. {
  225. $this->password = $password;
  226. return $this;
  227. }
  228. /**
  229. * Returns the amount of seconds before the connection will timeout.
  230. *
  231. * @return int
  232. */
  233. public function getTimeout()
  234. {
  235. return $this->timeout;
  236. }
  237. /**
  238. * Set the amount of seconds before the connection should timeout.
  239. *
  240. * @param int $timeout
  241. *
  242. * @return $this
  243. */
  244. public function setTimeout($timeout)
  245. {
  246. $this->timeout = (int) $timeout;
  247. return $this;
  248. }
  249. /**
  250. * Return the FTP system type.
  251. *
  252. * @return string
  253. */
  254. public function getSystemType()
  255. {
  256. return $this->systemType;
  257. }
  258. /**
  259. * Set the FTP system type (windows or unix).
  260. *
  261. * @param string $systemType
  262. *
  263. * @return $this
  264. */
  265. public function setSystemType($systemType)
  266. {
  267. $this->systemType = strtolower($systemType);
  268. return $this;
  269. }
  270. /**
  271. * @inheritdoc
  272. */
  273. public function listContents($directory = '', $recursive = false)
  274. {
  275. return $this->listDirectoryContents($directory, $recursive);
  276. }
  277. abstract protected function listDirectoryContents($directory, $recursive = false);
  278. /**
  279. * Normalize a directory listing.
  280. *
  281. * @param array $listing
  282. * @param string $prefix
  283. *
  284. * @return array directory listing
  285. */
  286. protected function normalizeListing(array $listing, $prefix = '')
  287. {
  288. $base = $prefix;
  289. $result = [];
  290. $listing = $this->removeDotDirectories($listing);
  291. while ($item = array_shift($listing)) {
  292. if (preg_match('#^.*:$#', $item)) {
  293. $base = trim($item, ':');
  294. continue;
  295. }
  296. $result[] = $this->normalizeObject($item, $base);
  297. }
  298. return $this->sortListing($result);
  299. }
  300. /**
  301. * Sort a directory listing.
  302. *
  303. * @param array $result
  304. *
  305. * @return array sorted listing
  306. */
  307. protected function sortListing(array $result)
  308. {
  309. $compare = function ($one, $two) {
  310. return strnatcmp($one['path'], $two['path']);
  311. };
  312. usort($result, $compare);
  313. return $result;
  314. }
  315. /**
  316. * Normalize a file entry.
  317. *
  318. * @param string $item
  319. * @param string $base
  320. *
  321. * @return array normalized file array
  322. *
  323. * @throws NotSupportedException
  324. */
  325. protected function normalizeObject($item, $base)
  326. {
  327. $systemType = $this->systemType ?: $this->detectSystemType($item);
  328. if ($systemType === 'unix') {
  329. return $this->normalizeUnixObject($item, $base);
  330. } elseif ($systemType === 'windows') {
  331. return $this->normalizeWindowsObject($item, $base);
  332. }
  333. throw NotSupportedException::forFtpSystemType($systemType);
  334. }
  335. /**
  336. * Normalize a Unix file entry.
  337. *
  338. * @param string $item
  339. * @param string $base
  340. *
  341. * @return array normalized file array
  342. */
  343. protected function normalizeUnixObject($item, $base)
  344. {
  345. $item = preg_replace('#\s+#', ' ', trim($item), 7);
  346. if (count(explode(' ', $item, 9)) !== 9) {
  347. throw new RuntimeException("Metadata can't be parsed from item '$item' , not enough parts.");
  348. }
  349. list($permissions, /* $number */, /* $owner */, /* $group */, $size, /* $month */, /* $day */, /* $time*/, $name) = explode(' ', $item, 9);
  350. $type = $this->detectType($permissions);
  351. $path = empty($base) ? $name : $base . $this->separator . $name;
  352. if ($type === 'dir') {
  353. return compact('type', 'path');
  354. }
  355. $permissions = $this->normalizePermissions($permissions);
  356. $visibility = $permissions & 0044 ? AdapterInterface::VISIBILITY_PUBLIC : AdapterInterface::VISIBILITY_PRIVATE;
  357. $size = (int) $size;
  358. return compact('type', 'path', 'visibility', 'size');
  359. }
  360. /**
  361. * Normalize a Windows/DOS file entry.
  362. *
  363. * @param string $item
  364. * @param string $base
  365. *
  366. * @return array normalized file array
  367. */
  368. protected function normalizeWindowsObject($item, $base)
  369. {
  370. $item = preg_replace('#\s+#', ' ', trim($item), 3);
  371. if (count(explode(' ', $item, 4)) !== 4) {
  372. throw new RuntimeException("Metadata can't be parsed from item '$item' , not enough parts.");
  373. }
  374. list($date, $time, $size, $name) = explode(' ', $item, 4);
  375. $path = empty($base) ? $name : $base . $this->separator . $name;
  376. // Check for the correct date/time format
  377. $format = strlen($date) === 8 ? 'm-d-yH:iA' : 'Y-m-dH:i';
  378. $timestamp = DateTime::createFromFormat($format, $date . $time)->getTimestamp();
  379. if ($size === '<DIR>') {
  380. $type = 'dir';
  381. return compact('type', 'path', 'timestamp');
  382. }
  383. $type = 'file';
  384. $visibility = AdapterInterface::VISIBILITY_PUBLIC;
  385. $size = (int) $size;
  386. return compact('type', 'path', 'visibility', 'size', 'timestamp');
  387. }
  388. /**
  389. * Get the system type from a listing item.
  390. *
  391. * @param string $item
  392. *
  393. * @return string the system type
  394. */
  395. protected function detectSystemType($item)
  396. {
  397. if (preg_match('/^[0-9]{2,4}-[0-9]{2}-[0-9]{2}/', $item)) {
  398. return $this->systemType = 'windows';
  399. }
  400. return $this->systemType = 'unix';
  401. }
  402. /**
  403. * Get the file type from the permissions.
  404. *
  405. * @param string $permissions
  406. *
  407. * @return string file type
  408. */
  409. protected function detectType($permissions)
  410. {
  411. return substr($permissions, 0, 1) === 'd' ? 'dir' : 'file';
  412. }
  413. /**
  414. * Normalize a permissions string.
  415. *
  416. * @param string $permissions
  417. *
  418. * @return int
  419. */
  420. protected function normalizePermissions($permissions)
  421. {
  422. // remove the type identifier
  423. $permissions = substr($permissions, 1);
  424. // map the string rights to the numeric counterparts
  425. $map = ['-' => '0', 'r' => '4', 'w' => '2', 'x' => '1'];
  426. $permissions = strtr($permissions, $map);
  427. // split up the permission groups
  428. $parts = str_split($permissions, 3);
  429. // convert the groups
  430. $mapper = function ($part) {
  431. return array_sum(str_split($part));
  432. };
  433. // get the sum of the groups
  434. return array_sum(array_map($mapper, $parts));
  435. }
  436. /**
  437. * Filter out dot-directories.
  438. *
  439. * @param array $list
  440. *
  441. * @return array
  442. */
  443. public function removeDotDirectories(array $list)
  444. {
  445. $filter = function ($line) {
  446. if ( ! empty($line) && ! preg_match('#.* \.(\.)?$|^total#', $line)) {
  447. return true;
  448. }
  449. return false;
  450. };
  451. return array_filter($list, $filter);
  452. }
  453. /**
  454. * @inheritdoc
  455. */
  456. public function has($path)
  457. {
  458. return $this->getMetadata($path);
  459. }
  460. /**
  461. * @inheritdoc
  462. */
  463. public function getSize($path)
  464. {
  465. return $this->getMetadata($path);
  466. }
  467. /**
  468. * @inheritdoc
  469. */
  470. public function getVisibility($path)
  471. {
  472. return $this->getMetadata($path);
  473. }
  474. /**
  475. * Ensure a directory exists.
  476. *
  477. * @param string $dirname
  478. */
  479. public function ensureDirectory($dirname)
  480. {
  481. if ( ! empty($dirname) && ! $this->has($dirname)) {
  482. $this->createDir($dirname, new Config());
  483. }
  484. }
  485. /**
  486. * @return mixed
  487. */
  488. public function getConnection()
  489. {
  490. if ( ! $this->isConnected()) {
  491. $this->disconnect();
  492. $this->connect();
  493. }
  494. return $this->connection;
  495. }
  496. /**
  497. * Get the public permission value.
  498. *
  499. * @return int
  500. */
  501. public function getPermPublic()
  502. {
  503. return $this->permPublic;
  504. }
  505. /**
  506. * Get the private permission value.
  507. *
  508. * @return int
  509. */
  510. public function getPermPrivate()
  511. {
  512. return $this->permPrivate;
  513. }
  514. /**
  515. * Disconnect on destruction.
  516. */
  517. public function __destruct()
  518. {
  519. $this->disconnect();
  520. }
  521. /**
  522. * Establish a connection.
  523. */
  524. abstract public function connect();
  525. /**
  526. * Close the connection.
  527. */
  528. abstract public function disconnect();
  529. /**
  530. * Check if a connection is active.
  531. *
  532. * @return bool
  533. */
  534. abstract public function isConnected();
  535. }