initial commit
[namibia] / module / Utility / src / Utility / Remote / Ftp.php
1 <?php
2 /**
3  * FTP wrapper class
4  * @author Tjaart Viljoen
5  * @copyright 2013 Nirph Online
6  */
7 namespace Utility\Remote;
8
9 class Ftp
10 {
11         protected $_serverAddress;
12         protected $_connection;
13         protected $_username;
14         protected $_password;
15         protected $_verbose;
16         protected $_timeout = 60;
17
18         /**
19          * Class constructor.
20          * Set default parameters.
21          * @param string $serverAddress
22          * @param string $username
23          * @param string $password
24          */
25         function __construct($serverAddress, $username, $password, $timeout = 60, $verbose = false)
26         {
27                 $this->_serverAddress = $serverAddress;
28                 $this->_username          = $username;
29                 $this->_password          = $password;
30                 $this->_verbose           = $verbose;
31                 $this->_timeout           = $timeout;
32         }
33
34         /**
35          * Change remote FTP directory.
36          * @param unknown $directory
37          * @throws \ErrorException
38          * @return boolean
39          */
40         public function changeDirectory($directory)
41         {
42                 $this->_secureConnection();
43                 $this->_output('Changing directory to "' . $directory . '"');
44                 $result = ftp_chdir($this->_connection, $directory);
45
46                 if(false == $result)
47                 {
48                         error_log('Couldn\'t change to FTP directory "' . $directory . '"');
49                         throw new \Exception('Couldn\'t change to FTP directory "' . $directory . '"');
50                         return false;
51                 }
52                 return $result;
53         }
54
55         /**
56          * Create a new remote directory.
57          * @param string $directory
58          * @throws \Exception
59          * @return boolean
60          */
61         public function createDirectory($directory)
62         {
63                 $this->_secureConnection();
64                 $this->_output('Creating directory "' . $directory . '"');
65                 $result = ftp_mkdir($this->_connection, $directory);
66                 if(false == $result)
67                 {
68                         $error = 'Couldn\'t create remote FTP directory "' . $directory . '"' ;
69                         error_log($error);
70                         throw new \Exception($error);
71                         return false;
72                 }
73                 return true;
74         }
75
76         /**
77          * Connect to the remote server.
78          * @throws \Exception
79          * @return \Utility\Remote\Ftp
80          */
81         public function connect()
82         {
83                 $this->_connection = ftp_connect($this->_serverAddress);
84
85                 if(false == $this->_connection)
86                 {
87                         throw new \Exception("Couldn't connect to FTP server: " . $this->_serverAddress );
88                 }
89                 $this->_output('Connected to "' . $this->_serverAddress . '"');
90                 return $this;
91         }
92
93         /**
94          * Close the remote FTP server connection.
95          */
96         public function closeConnection()
97         {
98                 $this->_output('Closing FTP connection');
99                 ftp_close($this->_connection);
100                 $this->_connection = null;
101         }
102
103         /**
104          * Login to the remote FTP server.
105          * @throws \Exception
106          * @return \Utility\Remote\Ftp
107          */
108         protected function _login()
109         {
110                 $this->_output('Logging in to "' . $this->_serverAddress . '"');
111                 $logingResult = ftp_login($this->_connection, $this->_username, $this->_password);
112
113                 if(false == $logingResult)
114                 {
115                         $this->_output('Login failure');
116                         $this->closeConnection();
117                         throw new \Exception("Couldn't log into remote server, please check your credentials and try again");
118                 }
119                 $this->_output('Logged in to "' . $this->_serverAddress . '"');
120                 return $this;
121         }
122
123         /**
124          * $return the content of a directory.
125          * Returns an empty array on error.
126          * @param string $directory
127          * @return array
128          */
129         public function getDirectoryContents($directory = '.')
130         {
131                 $this->_secureConnection();
132                 $this->_output('Retrieving direcory contents for "' . $directory . '"');
133                 $contents = ftp_nlist($this->_connection, '.');
134
135                 if(false == $contents)
136                 {
137                         error_log('Couldn\'t retrieve directory contents for: ' . $this->_serverAddress . ', directory: "' . $directory . '"');
138                         return array();
139                 }
140                 return $contents;
141         }
142
143         /**
144          * Delete a remote Directory
145          * @example deleteRemoteDirectory('./relative-path-directory');
146          * @example deleteRemoteDirectory('/temp/absolute-path-directory');
147          * @param string $directory
148          * @return boolean
149          */
150         public function deleteRemoteDirectory($directory)
151         {
152                 $this->_secureConnection();
153                 $this->_output('Deleting direcory "' . $directory . '"');
154                 $result = ftp_rmdir($this->_connection, $directory);
155
156                 if(false == $result)
157                 {
158                         error_log('Couldn\'t delete remote FTP directory "' . $directory . '"');
159                         return false;
160                 }
161
162                 return true;
163         }
164
165         /**
166          * Delete a remote file
167          * @param string $filename
168          * @return boolean
169          */
170         public function deleteRemoteFile($filename)
171         {
172                 $this->_secureConnection();
173                 $this->_output('Deleting file "' . $filename . '"');
174                 $result = ftp_delete($this->_connection, $filename);
175
176                 if(false == $result)
177                 {
178                         error_log('Couldn\'t delete remote FTP file "' . $filename . '"');
179                         return false;
180                 }
181
182                 return true;
183         }
184
185         /**
186          * Download a remote file to a specified location.
187          * @param string $localFilename
188          * @param string $remoteFilename
189          * @throws \Exception
190          * @return void|boolean
191          */
192         public function downloadFile($localFilename, $remoteFilename)
193         {
194                 set_time_limit(0);
195                 $this->_secureConnection();
196                 $this->_output('Downloading file"' . $remoteFilename . '" to "' . $localFilename . '"');
197                 ftp_pasv($this->_connection, true);
198                 if(ftp_get($this->_connection, $localFilename, $remoteFilename, FTP_BINARY))
199                 {
200                         ftp_pasv($this->_connection, false);
201                         return true;
202                 }
203                 ftp_pasv($this->_connection, false);
204                 return false;
205         }
206
207         /**
208          * Upload a specified file.
209          * @param string $localFilename
210          * @param string $remoteFilename
211          * @throws \Exception
212          * @return void|boolean
213          */
214         public function uploadFile($localFilename, $remoteFilename, $mode = FTP_BINARY)
215         {
216                 set_time_limit(0);
217                 $this->_secureConnection();
218                 $this->_output('Uploading file"' . $localFilename . '" to "' . $remoteFilename . '"');
219                 ftp_pasv($this->_connection, true);
220                 if(ftp_put($this->_connection, $remoteFilename, $localFilename, $mode))
221                 {
222                         ftp_pasv($this->_connection, false);
223                         return true;
224                 }
225
226                 ftp_pasv($this->_connection, false);
227
228                 $error = 'Couldn\'t upload "' . $localFilename . '" to remote location "' . $remoteFilename . '"';
229                 error_log($error);
230                 throw new \Exception($error);
231                 return false;
232         }
233
234         /**
235          * Checks the connection and reconnects to the remote FTP server if necessary
236          */
237         protected function _secureConnection()
238         {
239                 if(null == $this->_connection)
240                 {
241                         $this->connect();
242                         $this->_login();
243                 }
244         }
245
246         /**
247          * Returns the present working directory
248          * @return string
249          */
250         public function whereAmI()
251         {
252                 $this->_secureConnection();
253                 return (string) ftp_pwd($this->_connection);
254         }
255
256         protected function _output($string)
257         {
258                 if(false == $this->_verbose)
259                 {
260                         return;
261                 }
262                 echo $string . PHP_EOL;
263         }
264 }