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

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

https://gitlab.com/4gdevs/online-class-record-system
PHP | 448 lines | 258 code | 75 blank | 115 comment | 27 complexity | b747f0c93e3896d483e4b0a922a2c99f MD5 | raw file
  1. <?php
  2. namespace League\Flysystem\Adapter;
  3. use League\Flysystem\Adapter\Polyfill\StreamedCopyTrait;
  4. use League\Flysystem\AdapterInterface;
  5. use League\Flysystem\Config;
  6. use League\Flysystem\Util;
  7. use RuntimeException;
  8. class Ftp extends AbstractFtpAdapter
  9. {
  10. use StreamedCopyTrait;
  11. /**
  12. * @var int
  13. */
  14. protected $transferMode = FTP_BINARY;
  15. /**
  16. * @var null|bool
  17. */
  18. protected $ignorePassiveAddress = null;
  19. /**
  20. * @var array
  21. */
  22. protected $configurable = [
  23. 'host',
  24. 'port',
  25. 'username',
  26. 'password',
  27. 'ssl',
  28. 'timeout',
  29. 'root',
  30. 'permPrivate',
  31. 'permPublic',
  32. 'passive',
  33. 'transferMode',
  34. 'systemType',
  35. 'ignorePassiveAddress',
  36. ];
  37. /**
  38. * Set the transfer mode.
  39. *
  40. * @param int $mode
  41. *
  42. * @return $this
  43. */
  44. public function setTransferMode($mode)
  45. {
  46. $this->transferMode = $mode;
  47. return $this;
  48. }
  49. /**
  50. * Set if Ssl is enabled.
  51. *
  52. * @param bool $ssl
  53. *
  54. * @return $this
  55. */
  56. public function setSsl($ssl)
  57. {
  58. $this->ssl = (bool) $ssl;
  59. return $this;
  60. }
  61. /**
  62. * Set if passive mode should be used.
  63. *
  64. * @param bool $passive
  65. */
  66. public function setPassive($passive = true)
  67. {
  68. $this->passive = $passive;
  69. }
  70. /**
  71. * @param bool $ignorePassiveAddress
  72. */
  73. public function setIgnorePassiveAddress($ignorePassiveAddress)
  74. {
  75. $this->ignorePassiveAddress = $ignorePassiveAddress;
  76. }
  77. /**
  78. * Connect to the FTP server.
  79. */
  80. public function connect()
  81. {
  82. if ($this->ssl) {
  83. $this->connection = ftp_ssl_connect($this->getHost(), $this->getPort(), $this->getTimeout());
  84. } else {
  85. $this->connection = ftp_connect($this->getHost(), $this->getPort(), $this->getTimeout());
  86. }
  87. if ( ! $this->connection) {
  88. throw new RuntimeException('Could not connect to host: ' . $this->getHost() . ', port:' . $this->getPort());
  89. }
  90. $this->login();
  91. $this->setConnectionPassiveMode();
  92. $this->setConnectionRoot();
  93. }
  94. /**
  95. * Set the connections to passive mode.
  96. *
  97. * @throws RuntimeException
  98. */
  99. protected function setConnectionPassiveMode()
  100. {
  101. if (is_bool($this->ignorePassiveAddress) && defined('FTP_USEPASVADDRESS')) {
  102. ftp_set_option($this->connection, FTP_USEPASVADDRESS, ! $this->ignorePassiveAddress);
  103. }
  104. if ( ! ftp_pasv($this->connection, $this->passive)) {
  105. throw new RuntimeException(
  106. 'Could not set passive mode for connection: ' . $this->getHost() . '::' . $this->getPort()
  107. );
  108. }
  109. }
  110. /**
  111. * Set the connection root.
  112. */
  113. protected function setConnectionRoot()
  114. {
  115. $root = $this->getRoot();
  116. $connection = $this->connection;
  117. if (empty($root) === false && ! ftp_chdir($connection, $root)) {
  118. throw new RuntimeException('Root is invalid or does not exist: ' . $this->getRoot());
  119. }
  120. // Store absolute path for further reference.
  121. // This is needed when creating directories and
  122. // initial root was a relative path, else the root
  123. // would be relative to the chdir'd path.
  124. $this->root = ftp_pwd($connection);
  125. }
  126. /**
  127. * Login.
  128. *
  129. * @throws RuntimeException
  130. */
  131. protected function login()
  132. {
  133. set_error_handler(
  134. function () {
  135. }
  136. );
  137. $isLoggedIn = ftp_login($this->connection, $this->getUsername(), $this->getPassword());
  138. restore_error_handler();
  139. if ( ! $isLoggedIn) {
  140. $this->disconnect();
  141. throw new RuntimeException(
  142. 'Could not login with connection: ' . $this->getHost() . '::' . $this->getPort(
  143. ) . ', username: ' . $this->getUsername()
  144. );
  145. }
  146. }
  147. /**
  148. * Disconnect from the FTP server.
  149. */
  150. public function disconnect()
  151. {
  152. if ($this->isConnected()) {
  153. ftp_close($this->connection);
  154. }
  155. $this->connection = null;
  156. }
  157. /**
  158. * @inheritdoc
  159. */
  160. public function write($path, $contents, Config $config)
  161. {
  162. $stream = fopen('php://temp', 'w+b');
  163. fwrite($stream, $contents);
  164. rewind($stream);
  165. $result = $this->writeStream($path, $stream, $config);
  166. fclose($stream);
  167. if ($result === false) {
  168. return false;
  169. }
  170. $result['contents'] = $contents;
  171. $result['mimetype'] = Util::guessMimeType($path, $contents);
  172. return $result;
  173. }
  174. /**
  175. * @inheritdoc
  176. */
  177. public function writeStream($path, $resource, Config $config)
  178. {
  179. $this->ensureDirectory(Util::dirname($path));
  180. if ( ! ftp_fput($this->getConnection(), $path, $resource, $this->transferMode)) {
  181. return false;
  182. }
  183. if ($visibility = $config->get('visibility')) {
  184. $this->setVisibility($path, $visibility);
  185. }
  186. return compact('path', 'visibility');
  187. }
  188. /**
  189. * @inheritdoc
  190. */
  191. public function update($path, $contents, Config $config)
  192. {
  193. return $this->write($path, $contents, $config);
  194. }
  195. /**
  196. * @inheritdoc
  197. */
  198. public function updateStream($path, $resource, Config $config)
  199. {
  200. return $this->writeStream($path, $resource, $config);
  201. }
  202. /**
  203. * @inheritdoc
  204. */
  205. public function rename($path, $newpath)
  206. {
  207. return ftp_rename($this->getConnection(), $path, $newpath);
  208. }
  209. /**
  210. * @inheritdoc
  211. */
  212. public function delete($path)
  213. {
  214. return ftp_delete($this->getConnection(), $path);
  215. }
  216. /**
  217. * @inheritdoc
  218. */
  219. public function deleteDir($dirname)
  220. {
  221. $connection = $this->getConnection();
  222. $contents = array_reverse($this->listDirectoryContents($dirname));
  223. foreach ($contents as $object) {
  224. if ($object['type'] === 'file') {
  225. if ( ! ftp_delete($connection, $object['path'])) {
  226. return false;
  227. }
  228. } elseif ( ! ftp_rmdir($connection, $object['path'])) {
  229. return false;
  230. }
  231. }
  232. return ftp_rmdir($connection, $dirname);
  233. }
  234. /**
  235. * @inheritdoc
  236. */
  237. public function createDir($dirname, Config $config)
  238. {
  239. $connection = $this->getConnection();
  240. $directories = explode('/', $dirname);
  241. foreach ($directories as $directory) {
  242. if (false === $this->createActualDirectory($directory, $connection)) {
  243. $this->setConnectionRoot();
  244. return false;
  245. }
  246. ftp_chdir($connection, $directory);
  247. }
  248. $this->setConnectionRoot();
  249. return ['path' => $dirname];
  250. }
  251. /**
  252. * Create a directory.
  253. *
  254. * @param string $directory
  255. * @param resource $connection
  256. *
  257. * @return bool
  258. */
  259. protected function createActualDirectory($directory, $connection)
  260. {
  261. // List the current directory
  262. $listing = ftp_nlist($connection, '.');
  263. foreach ($listing as $key => $item) {
  264. if (preg_match('~^\./.*~', $item)) {
  265. $listing[$key] = substr($item, 2);
  266. }
  267. }
  268. if (in_array($directory, $listing)) {
  269. return true;
  270. }
  271. return (boolean) ftp_mkdir($connection, $directory);
  272. }
  273. /**
  274. * @inheritdoc
  275. */
  276. public function getMetadata($path)
  277. {
  278. $connection = $this->getConnection();
  279. if ($path === '') {
  280. return ['type' => 'dir', 'path' => ''];
  281. }
  282. if (@ftp_chdir($connection, $path) === true) {
  283. $this->setConnectionRoot();
  284. return ['type' => 'dir', 'path' => $path];
  285. }
  286. $listing = ftp_rawlist($connection, str_replace('*', '\\*', $path));
  287. if (empty($listing)) {
  288. return false;
  289. }
  290. if (preg_match('/.* not found/', $listing[0])) {
  291. return false;
  292. }
  293. return $this->normalizeObject($listing[0], '');
  294. }
  295. /**
  296. * @inheritdoc
  297. */
  298. public function getMimetype($path)
  299. {
  300. if ( ! $metadata = $this->read($path)) {
  301. return false;
  302. }
  303. $metadata['mimetype'] = Util::guessMimeType($path, $metadata['contents']);
  304. return $metadata;
  305. }
  306. /**
  307. * @inheritdoc
  308. */
  309. public function getTimestamp($path)
  310. {
  311. $timestamp = ftp_mdtm($this->getConnection(), $path);
  312. return ($timestamp !== -1) ? ['timestamp' => $timestamp] : false;
  313. }
  314. /**
  315. * @inheritdoc
  316. */
  317. public function read($path)
  318. {
  319. if ( ! $object = $this->readStream($path)) {
  320. return false;
  321. }
  322. $object['contents'] = stream_get_contents($object['stream']);
  323. fclose($object['stream']);
  324. unset($object['stream']);
  325. return $object;
  326. }
  327. /**
  328. * @inheritdoc
  329. */
  330. public function readStream($path)
  331. {
  332. $stream = fopen('php://temp', 'w+');
  333. $result = ftp_fget($this->getConnection(), $stream, $path, $this->transferMode);
  334. rewind($stream);
  335. if ( ! $result) {
  336. fclose($stream);
  337. return false;
  338. }
  339. return compact('stream');
  340. }
  341. /**
  342. * @inheritdoc
  343. */
  344. public function setVisibility($path, $visibility)
  345. {
  346. $mode = $visibility === AdapterInterface::VISIBILITY_PUBLIC ? $this->getPermPublic() : $this->getPermPrivate();
  347. if ( ! ftp_chmod($this->getConnection(), $mode, $path)) {
  348. return false;
  349. }
  350. return compact('visibility');
  351. }
  352. /**
  353. * @inheritdoc
  354. *
  355. * @param string $directory
  356. */
  357. protected function listDirectoryContents($directory, $recursive = true)
  358. {
  359. $directory = str_replace('*', '\\*', $directory);
  360. $options = $recursive ? '-alnR' : '-aln';
  361. $listing = ftp_rawlist($this->getConnection(), $options . ' ' . $directory);
  362. return $listing ? $this->normalizeListing($listing, $directory) : [];
  363. }
  364. /**
  365. * Check if the connection is open.
  366. *
  367. * @return bool
  368. */
  369. public function isConnected()
  370. {
  371. return is_resource($this->connection) && ftp_systype($this->connection) !== false;
  372. }
  373. }