PageRenderTime 63ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

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

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