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

/system/libraries/Ftp.php

http://github.com/imagecms/ImageCMS
PHP | 660 lines | 319 code | 93 blank | 248 comment | 72 complexity | 046c428f0b414d7156ab98ef47ffc0ce MD5 | raw file
Possible License(s): LGPL-2.1, AGPL-1.0
  1. <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
  2. /**
  3. * CodeIgniter
  4. *
  5. * An open source application development framework for PHP 5.1.6 or newer
  6. *
  7. * @package CodeIgniter
  8. * @author EllisLab Dev Team
  9. * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc.
  10. * @copyright Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/)
  11. * @license http://codeigniter.com/user_guide/license.html
  12. * @link http://codeigniter.com
  13. * @since Version 1.0
  14. * @filesource
  15. */
  16. // ------------------------------------------------------------------------
  17. /**
  18. * FTP Class
  19. *
  20. * @package CodeIgniter
  21. * @subpackage Libraries
  22. * @category Libraries
  23. * @author EllisLab Dev Team
  24. * @link http://codeigniter.com/user_guide/libraries/ftp.html
  25. */
  26. class CI_FTP {
  27. var $hostname = '';
  28. var $username = '';
  29. var $password = '';
  30. var $port = 21;
  31. var $passive = TRUE;
  32. var $debug = FALSE;
  33. var $conn_id = FALSE;
  34. /**
  35. * Constructor - Sets Preferences
  36. *
  37. * The constructor can be passed an array of config values
  38. */
  39. public function __construct($config = array())
  40. {
  41. if (count($config) > 0)
  42. {
  43. $this->initialize($config);
  44. }
  45. log_message('debug', "FTP Class Initialized");
  46. }
  47. // --------------------------------------------------------------------
  48. /**
  49. * Initialize preferences
  50. *
  51. * @access public
  52. * @param array
  53. * @return void
  54. */
  55. function initialize($config = array())
  56. {
  57. foreach ($config as $key => $val)
  58. {
  59. if (isset($this->$key))
  60. {
  61. $this->$key = $val;
  62. }
  63. }
  64. // Prep the hostname
  65. $this->hostname = preg_replace('|.+?://|', '', $this->hostname);
  66. }
  67. // --------------------------------------------------------------------
  68. /**
  69. * FTP Connect
  70. *
  71. * @access public
  72. * @param array the connection values
  73. * @return bool
  74. */
  75. function connect($config = array())
  76. {
  77. if (count($config) > 0)
  78. {
  79. $this->initialize($config);
  80. }
  81. if (FALSE === ($this->conn_id = @ftp_connect($this->hostname, $this->port)))
  82. {
  83. if ($this->debug == TRUE)
  84. {
  85. $this->_error('ftp_unable_to_connect');
  86. }
  87. return FALSE;
  88. }
  89. if ( ! $this->_login())
  90. {
  91. if ($this->debug == TRUE)
  92. {
  93. $this->_error('ftp_unable_to_login');
  94. }
  95. return FALSE;
  96. }
  97. // Set passive mode if needed
  98. if ($this->passive == TRUE)
  99. {
  100. ftp_pasv($this->conn_id, TRUE);
  101. }
  102. return TRUE;
  103. }
  104. // --------------------------------------------------------------------
  105. /**
  106. * FTP Login
  107. *
  108. * @access private
  109. * @return bool
  110. */
  111. function _login()
  112. {
  113. return @ftp_login($this->conn_id, $this->username, $this->password);
  114. }
  115. // --------------------------------------------------------------------
  116. /**
  117. * Validates the connection ID
  118. *
  119. * @access private
  120. * @return bool
  121. */
  122. function _is_conn()
  123. {
  124. if ( ! is_resource($this->conn_id))
  125. {
  126. if ($this->debug == TRUE)
  127. {
  128. $this->_error('ftp_no_connection');
  129. }
  130. return FALSE;
  131. }
  132. return TRUE;
  133. }
  134. // --------------------------------------------------------------------
  135. /**
  136. * Change directory
  137. *
  138. * The second parameter lets us momentarily turn off debugging so that
  139. * this function can be used to test for the existence of a folder
  140. * without throwing an error. There's no FTP equivalent to is_dir()
  141. * so we do it by trying to change to a particular directory.
  142. * Internally, this parameter is only used by the "mirror" function below.
  143. *
  144. * @access public
  145. * @param string
  146. * @param bool
  147. * @return bool
  148. */
  149. function changedir($path = '', $supress_debug = FALSE)
  150. {
  151. if ($path == '' OR ! $this->_is_conn())
  152. {
  153. return FALSE;
  154. }
  155. $result = @ftp_chdir($this->conn_id, $path);
  156. if ($result === FALSE)
  157. {
  158. if ($this->debug == TRUE AND $supress_debug == FALSE)
  159. {
  160. $this->_error('ftp_unable_to_changedir');
  161. }
  162. return FALSE;
  163. }
  164. return TRUE;
  165. }
  166. // --------------------------------------------------------------------
  167. /**
  168. * Create a directory
  169. *
  170. * @access public
  171. * @param string
  172. * @return bool
  173. */
  174. function mkdir($path = '', $permissions = NULL)
  175. {
  176. if ($path == '' OR ! $this->_is_conn())
  177. {
  178. return FALSE;
  179. }
  180. $result = @ftp_mkdir($this->conn_id, $path);
  181. if ($result === FALSE)
  182. {
  183. if ($this->debug == TRUE)
  184. {
  185. $this->_error('ftp_unable_to_makdir');
  186. }
  187. return FALSE;
  188. }
  189. // Set file permissions if needed
  190. if ( ! is_null($permissions))
  191. {
  192. $this->chmod($path, (int)$permissions);
  193. }
  194. return TRUE;
  195. }
  196. // --------------------------------------------------------------------
  197. /**
  198. * Upload a file to the server
  199. *
  200. * @access public
  201. * @param string
  202. * @param string
  203. * @param string
  204. * @return bool
  205. */
  206. function upload($locpath, $rempath, $mode = 'auto', $permissions = NULL)
  207. {
  208. if ( ! $this->_is_conn())
  209. {
  210. return FALSE;
  211. }
  212. if ( ! file_exists($locpath))
  213. {
  214. $this->_error('ftp_no_source_file');
  215. return FALSE;
  216. }
  217. // Set the mode if not specified
  218. if ($mode == 'auto')
  219. {
  220. // Get the file extension so we can set the upload type
  221. $ext = $this->_getext($locpath);
  222. $mode = $this->_settype($ext);
  223. }
  224. $mode = ($mode == 'ascii') ? FTP_ASCII : FTP_BINARY;
  225. $result = @ftp_put($this->conn_id, $rempath, $locpath, $mode);
  226. if ($result === FALSE)
  227. {
  228. if ($this->debug == TRUE)
  229. {
  230. $this->_error('ftp_unable_to_upload');
  231. }
  232. return FALSE;
  233. }
  234. // Set file permissions if needed
  235. if ( ! is_null($permissions))
  236. {
  237. $this->chmod($rempath, (int)$permissions);
  238. }
  239. return TRUE;
  240. }
  241. // --------------------------------------------------------------------
  242. /**
  243. * Download a file from a remote server to the local server
  244. *
  245. * @access public
  246. * @param string
  247. * @param string
  248. * @param string
  249. * @return bool
  250. */
  251. function download($rempath, $locpath, $mode = 'auto')
  252. {
  253. if ( ! $this->_is_conn())
  254. {
  255. return FALSE;
  256. }
  257. // Set the mode if not specified
  258. if ($mode == 'auto')
  259. {
  260. // Get the file extension so we can set the upload type
  261. $ext = $this->_getext($rempath);
  262. $mode = $this->_settype($ext);
  263. }
  264. $mode = ($mode == 'ascii') ? FTP_ASCII : FTP_BINARY;
  265. $result = @ftp_get($this->conn_id, $locpath, $rempath, $mode);
  266. if ($result === FALSE)
  267. {
  268. if ($this->debug == TRUE)
  269. {
  270. $this->_error('ftp_unable_to_download');
  271. }
  272. return FALSE;
  273. }
  274. return TRUE;
  275. }
  276. // --------------------------------------------------------------------
  277. /**
  278. * Rename (or move) a file
  279. *
  280. * @access public
  281. * @param string
  282. * @param string
  283. * @param bool
  284. * @return bool
  285. */
  286. function rename($old_file, $new_file, $move = FALSE)
  287. {
  288. if ( ! $this->_is_conn())
  289. {
  290. return FALSE;
  291. }
  292. $result = @ftp_rename($this->conn_id, $old_file, $new_file);
  293. if ($result === FALSE)
  294. {
  295. if ($this->debug == TRUE)
  296. {
  297. $msg = ($move == FALSE) ? 'ftp_unable_to_rename' : 'ftp_unable_to_move';
  298. $this->_error($msg);
  299. }
  300. return FALSE;
  301. }
  302. return TRUE;
  303. }
  304. // --------------------------------------------------------------------
  305. /**
  306. * Move a file
  307. *
  308. * @access public
  309. * @param string
  310. * @param string
  311. * @return bool
  312. */
  313. function move($old_file, $new_file)
  314. {
  315. return $this->rename($old_file, $new_file, TRUE);
  316. }
  317. // --------------------------------------------------------------------
  318. /**
  319. * Rename (or move) a file
  320. *
  321. * @access public
  322. * @param string
  323. * @return bool
  324. */
  325. function delete_file($filepath)
  326. {
  327. if ( ! $this->_is_conn())
  328. {
  329. return FALSE;
  330. }
  331. $result = @ftp_delete($this->conn_id, $filepath);
  332. if ($result === FALSE)
  333. {
  334. if ($this->debug == TRUE)
  335. {
  336. $this->_error('ftp_unable_to_delete');
  337. }
  338. return FALSE;
  339. }
  340. return TRUE;
  341. }
  342. // --------------------------------------------------------------------
  343. /**
  344. * Delete a folder and recursively delete everything (including sub-folders)
  345. * containted within it.
  346. *
  347. * @access public
  348. * @param string
  349. * @return bool
  350. */
  351. function delete_dir($filepath)
  352. {
  353. if ( ! $this->_is_conn())
  354. {
  355. return FALSE;
  356. }
  357. // Add a trailing slash to the file path if needed
  358. $filepath = preg_replace("/(.+?)\/*$/", "\\1/", $filepath);
  359. $list = $this->list_files($filepath);
  360. if ($list !== FALSE AND count($list) > 0)
  361. {
  362. foreach ($list as $item)
  363. {
  364. // If we can't delete the item it's probaly a folder so
  365. // we'll recursively call delete_dir()
  366. if ( ! @ftp_delete($this->conn_id, $item))
  367. {
  368. $this->delete_dir($item);
  369. }
  370. }
  371. }
  372. $result = @ftp_rmdir($this->conn_id, $filepath);
  373. if ($result === FALSE)
  374. {
  375. if ($this->debug == TRUE)
  376. {
  377. $this->_error('ftp_unable_to_delete');
  378. }
  379. return FALSE;
  380. }
  381. return TRUE;
  382. }
  383. // --------------------------------------------------------------------
  384. /**
  385. * Set file permissions
  386. *
  387. * @access public
  388. * @param string the file path
  389. * @param string the permissions
  390. * @return bool
  391. */
  392. function chmod($path, $perm)
  393. {
  394. if ( ! $this->_is_conn())
  395. {
  396. return FALSE;
  397. }
  398. if ( ! function_exists('ftp_chmod'))
  399. {
  400. if ($this->debug == TRUE)
  401. {
  402. $this->_error('ftp_unable_to_chmod');
  403. }
  404. return FALSE;
  405. }
  406. $result = @ftp_chmod($this->conn_id, $perm, $path);
  407. if ($result === FALSE)
  408. {
  409. if ($this->debug == TRUE)
  410. {
  411. $this->_error('ftp_unable_to_chmod');
  412. }
  413. return FALSE;
  414. }
  415. return TRUE;
  416. }
  417. // --------------------------------------------------------------------
  418. /**
  419. * FTP List files in the specified directory
  420. *
  421. * @access public
  422. * @return array
  423. */
  424. function list_files($path = '.')
  425. {
  426. if ( ! $this->_is_conn())
  427. {
  428. return FALSE;
  429. }
  430. return ftp_nlist($this->conn_id, $path);
  431. }
  432. // ------------------------------------------------------------------------
  433. /**
  434. * Read a directory and recreate it remotely
  435. *
  436. * This function recursively reads a folder and everything it contains (including
  437. * sub-folders) and creates a mirror via FTP based on it. Whatever the directory structure
  438. * of the original file path will be recreated on the server.
  439. *
  440. * @access public
  441. * @param string path to source with trailing slash
  442. * @param string path to destination - include the base folder with trailing slash
  443. * @return bool
  444. */
  445. function mirror($locpath, $rempath)
  446. {
  447. if ( ! $this->_is_conn())
  448. {
  449. return FALSE;
  450. }
  451. // Open the local file path
  452. if ($fp = @opendir($locpath))
  453. {
  454. // Attempt to open the remote file path.
  455. if ( ! $this->changedir($rempath, TRUE))
  456. {
  457. // If it doesn't exist we'll attempt to create the direcotory
  458. if ( ! $this->mkdir($rempath) OR ! $this->changedir($rempath))
  459. {
  460. return FALSE;
  461. }
  462. }
  463. // Recursively read the local directory
  464. while (FALSE !== ($file = readdir($fp)))
  465. {
  466. if (@is_dir($locpath.$file) && substr($file, 0, 1) != '.')
  467. {
  468. $this->mirror($locpath.$file."/", $rempath.$file."/");
  469. }
  470. elseif (substr($file, 0, 1) != ".")
  471. {
  472. // Get the file extension so we can se the upload type
  473. $ext = $this->_getext($file);
  474. $mode = $this->_settype($ext);
  475. $this->upload($locpath.$file, $rempath.$file, $mode);
  476. }
  477. }
  478. return TRUE;
  479. }
  480. return FALSE;
  481. }
  482. // --------------------------------------------------------------------
  483. /**
  484. * Extract the file extension
  485. *
  486. * @access private
  487. * @param string
  488. * @return string
  489. */
  490. function _getext($filename)
  491. {
  492. if (FALSE === strpos($filename, '.'))
  493. {
  494. return 'txt';
  495. }
  496. $x = explode('.', $filename);
  497. return end($x);
  498. }
  499. // --------------------------------------------------------------------
  500. /**
  501. * Set the upload type
  502. *
  503. * @access private
  504. * @param string
  505. * @return string
  506. */
  507. function _settype($ext)
  508. {
  509. $text_types = array(
  510. 'txt',
  511. 'text',
  512. 'php',
  513. 'phps',
  514. 'php4',
  515. 'js',
  516. 'css',
  517. 'htm',
  518. 'html',
  519. 'phtml',
  520. 'shtml',
  521. 'log',
  522. 'xml'
  523. );
  524. return (in_array($ext, $text_types)) ? 'ascii' : 'binary';
  525. }
  526. // ------------------------------------------------------------------------
  527. /**
  528. * Close the connection
  529. *
  530. * @access public
  531. * @param string path to source
  532. * @param string path to destination
  533. * @return bool
  534. */
  535. function close()
  536. {
  537. if ( ! $this->_is_conn())
  538. {
  539. return FALSE;
  540. }
  541. @ftp_close($this->conn_id);
  542. }
  543. // ------------------------------------------------------------------------
  544. /**
  545. * Display error message
  546. *
  547. * @access private
  548. * @param string
  549. * @return bool
  550. */
  551. function _error($line)
  552. {
  553. $CI =& get_instance();
  554. $CI->lang->load('ftp');
  555. show_error($CI->lang->line($line));
  556. }
  557. }
  558. // END FTP Class
  559. /* End of file Ftp.php */
  560. /* Location: ./system/libraries/Ftp.php */