1 | <?php |
||||
2 | /** |
||||
3 | * This file is part of SebastianFeldmann\Ftp. |
||||
4 | * |
||||
5 | * (c) Sebastian Feldmann <[email protected]> |
||||
6 | * |
||||
7 | * For the full copyright and license information, please view the LICENSE |
||||
8 | * file that was distributed with this source code. |
||||
9 | */ |
||||
10 | namespace SebastianFeldmann\Ftp; |
||||
11 | |||||
12 | use RuntimeException; |
||||
13 | |||||
14 | /** |
||||
15 | * Class Client |
||||
16 | * |
||||
17 | * @package SebastianFeldmann\Ftp |
||||
18 | * @author Sebastian Feldmann <[email protected]> |
||||
19 | * @link https://github.com/sebastianfeldmann/ftp |
||||
20 | * @since Class available since Release 1.0.0 |
||||
21 | * |
||||
22 | * @method void cdUp() - Changes to the parent directory |
||||
23 | * @method void chDir(string $directory) - Changes the current directory on a FTP server |
||||
24 | * @method void pwd() - Returns current working directory |
||||
25 | * @method array nlist(string $path) - Returns list of files in given dir |
||||
26 | * @method int size(string $file) - Returns given files sizes in bytes |
||||
27 | * @method string mdtm(string $file) - Returns last modification time from given file |
||||
28 | * @method void pasv(bool $passive) - Sets the ftp passive mode on or off |
||||
29 | */ |
||||
30 | class Client |
||||
31 | { |
||||
32 | /** |
||||
33 | * PHP FTP connection resource. |
||||
34 | * |
||||
35 | * @var resource |
||||
36 | */ |
||||
37 | private $connection; |
||||
38 | |||||
39 | /** |
||||
40 | * Host to connect to. |
||||
41 | * |
||||
42 | * @var string |
||||
43 | */ |
||||
44 | private $host; |
||||
45 | |||||
46 | /** |
||||
47 | * Port to connect to. |
||||
48 | * |
||||
49 | * @var int |
||||
50 | */ |
||||
51 | private $port; |
||||
52 | |||||
53 | /** |
||||
54 | * User to login. |
||||
55 | * |
||||
56 | * @var string |
||||
57 | */ |
||||
58 | private $user; |
||||
59 | |||||
60 | /** |
||||
61 | * Password to login. |
||||
62 | * |
||||
63 | * @var string |
||||
64 | */ |
||||
65 | private $password; |
||||
66 | |||||
67 | /** |
||||
68 | * Use passive ftp mode |
||||
69 | * |
||||
70 | * @var bool |
||||
71 | */ |
||||
72 | private $passive; |
||||
73 | |||||
74 | /** |
||||
75 | * Client constructor. |
||||
76 | * |
||||
77 | * @param string $url |
||||
78 | * @param bool $passive |
||||
79 | */ |
||||
80 | 1 | public function __construct(string $url, bool $passive = false) |
|||
81 | { |
||||
82 | 1 | if (!extension_loaded('ftp')) { |
|||
83 | throw new RuntimeException('FTP extension is not loaded.'); |
||||
84 | } |
||||
85 | 1 | $this->passive = $passive; |
|||
86 | 1 | $this->setup($url); |
|||
87 | 1 | $this->login(); |
|||
88 | 1 | } |
|||
89 | |||||
90 | /** |
||||
91 | * Determine if file is a directory. |
||||
92 | * |
||||
93 | * @param string $name |
||||
94 | * @return bool |
||||
95 | */ |
||||
96 | 1 | public function isDir(string $name) |
|||
97 | { |
||||
98 | 1 | $current = $this->pwd(); |
|||
0 ignored issues
–
show
|
|||||
99 | try { |
||||
100 | 1 | $this->chDir($name); |
|||
101 | 1 | $this->chDir($current); |
|||
0 ignored issues
–
show
$current of type void is incompatible with the type string expected by parameter $directory of SebastianFeldmann\Ftp\Client::chDir() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
102 | 1 | return true; |
|||
103 | 1 | } catch (\Exception $e) { |
|||
104 | // do nothing |
||||
105 | } |
||||
106 | 1 | return false; |
|||
107 | } |
||||
108 | |||||
109 | /** |
||||
110 | * Returns to the home directory. |
||||
111 | * |
||||
112 | * @return void |
||||
113 | */ |
||||
114 | public function chHome() |
||||
115 | { |
||||
116 | $this->chDir(''); |
||||
117 | } |
||||
118 | |||||
119 | /** |
||||
120 | * Return list of all files in directory. |
||||
121 | * |
||||
122 | * @param string $path |
||||
123 | * @return \SebastianFeldmann\Ftp\File[] |
||||
124 | * @throws \Exception |
||||
125 | */ |
||||
126 | 1 | public function ls(string $path = '') : array |
|||
127 | { |
||||
128 | 1 | $list = []; |
|||
129 | 1 | foreach ($this->nlist($path) as $name) { |
|||
130 | 1 | $type = $this->isDir($name) ? 'dir' : 'file'; |
|||
131 | 1 | $mtime = $this->mdtm($name); |
|||
132 | 1 | $size = $this->size($name); |
|||
133 | 1 | $list[] = new File(['name' => $name, 'modify' => $mtime, 'type' => $type, 'size' => $size]); |
|||
134 | } |
||||
135 | 1 | return $list; |
|||
136 | } |
||||
137 | |||||
138 | /** |
||||
139 | * Return list of directories in given path. |
||||
140 | * |
||||
141 | * @param string $path |
||||
142 | * @return array |
||||
143 | * @throws \Exception |
||||
144 | */ |
||||
145 | public function lsDirs(string $path = '') : array |
||||
146 | { |
||||
147 | return array_filter( |
||||
148 | $this->ls($path), |
||||
149 | function(File $file) { |
||||
150 | return $file->isDir(); |
||||
151 | } |
||||
152 | ); |
||||
153 | } |
||||
154 | |||||
155 | /** |
||||
156 | * Return list of files in given path. |
||||
157 | * |
||||
158 | * @param string $path |
||||
159 | * @return array |
||||
160 | * @throws \Exception |
||||
161 | */ |
||||
162 | public function lsFiles(string $path = '') : array |
||||
163 | { |
||||
164 | return array_filter( |
||||
165 | $this->ls($path), |
||||
166 | function(File $file) { |
||||
167 | return $file->isFile(); |
||||
168 | } |
||||
169 | ); |
||||
170 | } |
||||
171 | |||||
172 | /** |
||||
173 | * Upload local file to ftp server. |
||||
174 | * |
||||
175 | * @param string $file Path to local file that should be uploaded. |
||||
176 | * @param string $path Path to store the file under. |
||||
177 | * @param string $name Filename on the ftp server. |
||||
178 | * @return void |
||||
179 | */ |
||||
180 | public function uploadFile(string $file, string $path, string $name) |
||||
181 | { |
||||
182 | // to store the file we have to make sure the directory exists |
||||
183 | foreach ($this->extractDirectories($path) as $dir) { |
||||
184 | // if change to directory fails |
||||
185 | // create the dir and change into it afterwards |
||||
186 | if (!$this->chDir($dir)) { |
||||
0 ignored issues
–
show
Are you sure the usage of
$this->chDir($dir) targeting SebastianFeldmann\Ftp\Client::chDir() seems to always return null.
This check looks for function or method calls that always return null and whose return value is used. class A
{
function getObject()
{
return null;
}
}
$a = new A();
if ($a->getObject()) {
The method The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.
Loading history...
|
|||||
187 | $this->mkDir($dir); |
||||
188 | $this->chDir($dir); |
||||
189 | } |
||||
190 | } |
||||
191 | if (!$this->put($name, $file, FTP_BINARY)) { |
||||
192 | $error = error_get_last(); |
||||
193 | $message = $error['message']; |
||||
194 | throw new RuntimeException(sprintf('error uploading file: %s - %s', $file, $message)); |
||||
195 | } |
||||
196 | } |
||||
197 | |||||
198 | /** |
||||
199 | * Setup local member variables by parsing the ftp url. |
||||
200 | * |
||||
201 | * @param string $url |
||||
202 | */ |
||||
203 | 1 | private function setup(string $url) |
|||
204 | { |
||||
205 | 1 | $parts = \parse_url($url); |
|||
206 | 1 | $this->host = $parts['host'] ?? ''; |
|||
207 | 1 | $this->port = $parts['port'] ?? 21; |
|||
208 | 1 | $this->user = $parts['user'] ?? ''; |
|||
209 | 1 | $this->password = $parts['pass'] ?? ''; |
|||
210 | 1 | } |
|||
211 | |||||
212 | /** |
||||
213 | * Setup ftp connection |
||||
214 | * |
||||
215 | * @throws \RuntimeException |
||||
216 | */ |
||||
217 | 1 | private function login() |
|||
218 | { |
||||
219 | 1 | if (empty($this->host)) { |
|||
220 | throw new RuntimeException('no host to connect to'); |
||||
221 | } |
||||
222 | |||||
223 | 1 | $old = error_reporting(0); |
|||
224 | 1 | if (!$this->connection = ftp_connect($this->host, $this->port)) { |
|||
225 | error_reporting($old); |
||||
226 | throw new RuntimeException(sprintf('unable to connect to ftp server %s', $this->host)); |
||||
227 | } |
||||
228 | |||||
229 | 1 | if (!ftp_login($this->connection, $this->user, $this->password)) { |
|||
230 | error_reporting($old); |
||||
231 | throw new RuntimeException( |
||||
232 | sprintf('authentication failed for %s@%s', $this->user, $this->host) |
||||
233 | ); |
||||
234 | } |
||||
235 | // set passive mode if needed |
||||
236 | 1 | $this->pasv($this->passive); |
|||
237 | 1 | error_reporting($old); |
|||
238 | 1 | } |
|||
239 | |||||
240 | /** |
||||
241 | * Return list of remote directories to travers. |
||||
242 | * |
||||
243 | * @param string $path |
||||
244 | * @return array |
||||
245 | */ |
||||
246 | private function extractDirectories(string $path) : array |
||||
247 | { |
||||
248 | $remoteDirs = []; |
||||
249 | if (!empty($path)) { |
||||
250 | $remoteDirs = explode('/', $path); |
||||
251 | // fix empty first array element for absolute path |
||||
252 | if (substr($path, 0, 1) === '/') { |
||||
253 | $remoteDirs[0] = '/'; |
||||
254 | } |
||||
255 | $remoteDirs = array_filter($remoteDirs); |
||||
256 | } |
||||
257 | return $remoteDirs; |
||||
258 | } |
||||
259 | |||||
260 | /** |
||||
261 | * Handle all ftp_* functions. |
||||
262 | * |
||||
263 | * @param string $name |
||||
264 | * @param array $args |
||||
265 | * @return mixed |
||||
266 | */ |
||||
267 | 1 | public function __call($name, $args) |
|||
268 | { |
||||
269 | 1 | $function = 'ftp_' . strtolower($name); |
|||
270 | 1 | if (!function_exists($function)) { |
|||
271 | throw new RuntimeException(sprintf('invalid method call: %s', $function)); |
||||
272 | } |
||||
273 | 1 | $old = error_reporting(0); |
|||
274 | 1 | array_unshift($args, $this->connection); |
|||
275 | 1 | if (!$result = call_user_func_array($function, $args)) { |
|||
276 | 1 | $error = error_get_last(); |
|||
277 | 1 | error_reporting($old); |
|||
278 | 1 | throw new RuntimeException($error['message']); |
|||
279 | } |
||||
280 | 1 | error_reporting($old); |
|||
281 | 1 | return $result; |
|||
282 | } |
||||
283 | } |
||||
284 |
This check looks for function or method calls that always return null and whose return value is assigned to a variable.
The method
getObject()
can return nothing but null, so it makes no sense to assign that value to a variable.The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.