PageRenderTime 27ms CodeModel.GetById 35ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/internal/Magento/Framework/Filesystem/Io/Ftp.php

https://gitlab.com/crazybutterfly815/magento2
PHP | 335 lines | 166 code | 41 blank | 128 comment | 28 complexity | 753c16d990d619ba269b895a5ccffeb9 MD5 | raw file
  1. <?php
  2. /**
  3. * Copyright © 2016 Magento. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Framework\Filesystem\Io;
  7. use Magento\Framework\Filesystem\DriverInterface;
  8. use Magento\Framework\Phrase;
  9. use Magento\Framework\Exception\LocalizedException;
  10. /**
  11. * FTP client
  12. */
  13. class Ftp extends AbstractIo
  14. {
  15. const ERROR_EMPTY_HOST = 1;
  16. const ERROR_INVALID_CONNECTION = 2;
  17. const ERROR_INVALID_LOGIN = 3;
  18. const ERROR_INVALID_PATH = 4;
  19. const ERROR_INVALID_MODE = 5;
  20. const ERROR_INVALID_DESTINATION = 6;
  21. const ERROR_INVALID_SOURCE = 7;
  22. /**
  23. * Connection config
  24. *
  25. * @var array
  26. */
  27. protected $_config;
  28. /**
  29. * An FTP connection
  30. *
  31. * @var resource
  32. */
  33. protected $_conn;
  34. /**
  35. * Error code
  36. *
  37. * @var int
  38. */
  39. protected $_error;
  40. /**
  41. * @var string
  42. */
  43. protected $_tmpFilename;
  44. /**
  45. * Open a connection
  46. *
  47. * Possible argument keys:
  48. * - host required
  49. * - port default 21
  50. * - timeout default 90
  51. * - user default anonymous
  52. * - password default empty
  53. * - ssl default false
  54. * - passive default false
  55. * - path default empty
  56. * - file_mode default FTP_BINARY
  57. *
  58. * @param array $args
  59. * @return true
  60. * @throws LocalizedException
  61. * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  62. * @SuppressWarnings(PHPMD.NPathComplexity)
  63. */
  64. public function open(array $args = [])
  65. {
  66. if (empty($args['host'])) {
  67. $this->_error = self::ERROR_EMPTY_HOST;
  68. throw new LocalizedException(new Phrase('Empty host specified'));
  69. }
  70. if (empty($args['port'])) {
  71. $args['port'] = 21;
  72. }
  73. if (empty($args['user'])) {
  74. $args['user'] = 'anonymous';
  75. $args['password'] = 'anonymous@noserver.com';
  76. }
  77. if (empty($args['password'])) {
  78. $args['password'] = '';
  79. }
  80. if (empty($args['timeout'])) {
  81. $args['timeout'] = 90;
  82. }
  83. if (empty($args['file_mode'])) {
  84. $args['file_mode'] = FTP_BINARY;
  85. }
  86. $this->_config = $args;
  87. if (empty($this->_config['ssl'])) {
  88. $this->_conn = @ftp_connect($this->_config['host'], $this->_config['port'], $this->_config['timeout']);
  89. } else {
  90. $this->_conn = @ftp_ssl_connect($this->_config['host'], $this->_config['port'], $this->_config['timeout']);
  91. }
  92. if (!$this->_conn) {
  93. $this->_error = self::ERROR_INVALID_CONNECTION;
  94. throw new LocalizedException(new Phrase('Could not establish FTP connection, invalid host or port'));
  95. }
  96. if (!@ftp_login($this->_conn, $this->_config['user'], $this->_config['password'])) {
  97. $this->_error = self::ERROR_INVALID_LOGIN;
  98. $this->close();
  99. throw new LocalizedException(new Phrase('Invalid user name or password'));
  100. }
  101. if (!empty($this->_config['path'])) {
  102. if (!@ftp_chdir($this->_conn, $this->_config['path'])) {
  103. $this->_error = self::ERROR_INVALID_PATH;
  104. $this->close();
  105. throw new LocalizedException(new Phrase('Invalid path'));
  106. }
  107. }
  108. if (!empty($this->_config['passive'])) {
  109. if (!@ftp_pasv($this->_conn, true)) {
  110. $this->_error = self::ERROR_INVALID_MODE;
  111. $this->close();
  112. throw new LocalizedException(new Phrase('Invalid file transfer mode'));
  113. }
  114. }
  115. return true;
  116. }
  117. /**
  118. * Close a connection
  119. *
  120. * @return bool
  121. */
  122. public function close()
  123. {
  124. return @ftp_close($this->_conn);
  125. }
  126. /**
  127. * Create a directory
  128. *
  129. * @todo implement $mode and $recursive
  130. * @param string $dir
  131. * @param int $mode
  132. * @param bool $recursive
  133. * @return bool
  134. * @SuppressWarnings(PHPMD.UnusedFormalParameter)
  135. */
  136. public function mkdir($dir, $mode = 0777, $recursive = true)
  137. {
  138. return @ftp_mkdir($this->_conn, $dir);
  139. }
  140. /**
  141. * Delete a directory
  142. *
  143. * @param string $dir
  144. * @param bool $recursive
  145. * @return bool
  146. * @SuppressWarnings(PHPMD.UnusedFormalParameter)
  147. */
  148. public function rmdir($dir, $recursive = false)
  149. {
  150. return @ftp_rmdir($this->_conn, $dir);
  151. }
  152. /**
  153. * Get current working directory
  154. *
  155. * @return string
  156. */
  157. public function pwd()
  158. {
  159. return @ftp_pwd($this->_conn);
  160. }
  161. /**
  162. * Change current working directory
  163. *
  164. * @param string $dir
  165. * @return bool
  166. * @SuppressWarnings(PHPMD.ShortMethodName)
  167. */
  168. public function cd($dir)
  169. {
  170. return @ftp_chdir($this->_conn, $dir);
  171. }
  172. /**
  173. * Read a file to result, file or stream
  174. *
  175. * @param string $filename
  176. * @param string|resource|null $dest destination file name, stream, or if null will return file contents
  177. * @return false|string
  178. */
  179. public function read($filename, $dest = null)
  180. {
  181. if (is_string($dest)) {
  182. $result = ftp_get($this->_conn, $dest, $filename, $this->_config['file_mode']);
  183. } else {
  184. if (is_resource($dest)) {
  185. $stream = $dest;
  186. } elseif ($dest === null) {
  187. $stream = tmpfile();
  188. } else {
  189. $this->_error = self::ERROR_INVALID_DESTINATION;
  190. return false;
  191. }
  192. $result = ftp_fget($this->_conn, $stream, $filename, $this->_config['file_mode']);
  193. if ($dest === null) {
  194. fseek($stream, 0);
  195. $result = '';
  196. for ($result = ''; $s = fread($stream, 4096); $result .= $s) {
  197. }
  198. fclose($stream);
  199. }
  200. }
  201. return $result;
  202. }
  203. /**
  204. * Write a file from string, file or stream
  205. *
  206. * @param string $filename
  207. * @param string|resource $src filename, string data or source stream
  208. * @param null $mode
  209. * @return bool
  210. * @SuppressWarnings(PHPMD.UnusedFormalParameter)
  211. */
  212. public function write($filename, $src, $mode = null)
  213. {
  214. if (is_string($src) && is_readable($src)) {
  215. return @ftp_put($this->_conn, $filename, $src, $this->_config['file_mode']);
  216. } else {
  217. if (is_string($src)) {
  218. $stream = tmpfile();
  219. fputs($stream, $src);
  220. fseek($stream, 0);
  221. } elseif (is_resource($src)) {
  222. $stream = $src;
  223. } else {
  224. $this->_error = self::ERROR_INVALID_SOURCE;
  225. return false;
  226. }
  227. $result = ftp_fput($this->_conn, $filename, $stream, $this->_config['file_mode']);
  228. if (is_string($src)) {
  229. fclose($stream);
  230. }
  231. return $result;
  232. }
  233. }
  234. /**
  235. * Delete a file
  236. *
  237. * @param string $filename
  238. * @return bool
  239. * @SuppressWarnings(PHPMD.ShortMethodName)
  240. */
  241. public function rm($filename)
  242. {
  243. return @ftp_delete($this->_conn, $filename);
  244. }
  245. /**
  246. * Rename or move a directory or a file
  247. *
  248. * @param string $src
  249. * @param string $dest
  250. * @return bool
  251. * @SuppressWarnings(PHPMD.ShortMethodName)
  252. */
  253. public function mv($src, $dest)
  254. {
  255. return @ftp_rename($this->_conn, $src, $dest);
  256. }
  257. /**
  258. * Change mode of a directory or a file
  259. *
  260. * @param string $filename
  261. * @param int $mode
  262. * @return bool
  263. */
  264. public function chmod($filename, $mode)
  265. {
  266. return @ftp_chmod($this->_conn, $mode, $filename);
  267. }
  268. /**
  269. * @param null $grep ignored parameter
  270. * @return array
  271. * @SuppressWarnings(PHPMD.ShortMethodName)
  272. * @SuppressWarnings(PHPMD.UnusedFormalParameter)
  273. */
  274. public function ls($grep = null)
  275. {
  276. $ls = @ftp_nlist($this->_conn, '.');
  277. $list = [];
  278. foreach ($ls as $file) {
  279. $list[] = ['text' => $file, 'id' => $this->pwd() . '/' . $file];
  280. }
  281. return $list;
  282. }
  283. /**
  284. * @param bool $new
  285. * @return string
  286. */
  287. protected function _tmpFilename($new = false)
  288. {
  289. if ($new || !$this->_tmpFilename) {
  290. $this->_tmpFilename = tempnam(md5(uniqid(rand(), true)), '');
  291. }
  292. return $this->_tmpFilename;
  293. }
  294. }