This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
|||||||||||
2 | ||||||||||||
3 | /** |
|||||||||||
4 | * elFinder - file manager for web. |
|||||||||||
5 | * Core class. |
|||||||||||
6 | * |
|||||||||||
7 | * @package elfinder |
|||||||||||
8 | * @author Dmitry (dio) Levashov |
|||||||||||
9 | * @author Troex Nevelin |
|||||||||||
10 | * @author Alexey Sukhotin |
|||||||||||
11 | **/ |
|||||||||||
12 | class elFinder { |
|||||||||||
13 | ||||||||||||
14 | /** |
|||||||||||
15 | * API version number |
|||||||||||
16 | * |
|||||||||||
17 | * @var string |
|||||||||||
18 | **/ |
|||||||||||
19 | protected $version = '2.0'; |
|||||||||||
20 | ||||||||||||
21 | /** |
|||||||||||
22 | * Storages (root dirs) |
|||||||||||
23 | * |
|||||||||||
24 | * @var array |
|||||||||||
25 | **/ |
|||||||||||
26 | protected $volumes = array(); |
|||||||||||
27 | ||||||||||||
28 | /** |
|||||||||||
29 | * Network mount drivers |
|||||||||||
30 | * |
|||||||||||
31 | * @var array |
|||||||||||
32 | */ |
|||||||||||
33 | public static $netDrivers = array(); |
|||||||||||
34 | ||||||||||||
35 | /** |
|||||||||||
36 | * elFinder global locale |
|||||||||||
37 | * |
|||||||||||
38 | * @var string |
|||||||||||
39 | */ |
|||||||||||
40 | public static $locale = ''; |
|||||||||||
41 | ||||||||||||
42 | /** |
|||||||||||
43 | * elFinder global sessionCacheKey |
|||||||||||
44 | * |
|||||||||||
45 | * @var string |
|||||||||||
46 | */ |
|||||||||||
47 | public static $sessionCacheKey = ''; |
|||||||||||
48 | ||||||||||||
49 | /** |
|||||||||||
50 | * elFinder base64encodeSessionData |
|||||||||||
51 | * elFinder save session data as `UTF-8` |
|||||||||||
52 | * If the session storage mechanism of the system does not allow `UTF-8` |
|||||||||||
53 | * And it must be `true` option 'base64encodeSessionData' of elFinder |
|||||||||||
54 | * |
|||||||||||
55 | * @var bool |
|||||||||||
56 | */ |
|||||||||||
57 | protected static $base64encodeSessionData = false; |
|||||||||||
58 | ||||||||||||
59 | /** |
|||||||||||
60 | * Session key of net mount volumes |
|||||||||||
61 | * @var string |
|||||||||||
62 | */ |
|||||||||||
63 | protected $netVolumesSessionKey = ''; |
|||||||||||
64 | ||||||||||||
65 | /** |
|||||||||||
66 | * Mounted volumes count |
|||||||||||
67 | * Required to create unique volume id |
|||||||||||
68 | * |
|||||||||||
69 | * @var int |
|||||||||||
70 | **/ |
|||||||||||
71 | public static $volumesCnt = 1; |
|||||||||||
72 | ||||||||||||
73 | /** |
|||||||||||
74 | * Default root (storage) |
|||||||||||
75 | * |
|||||||||||
76 | * @var elFinderStorageDriver |
|||||||||||
77 | **/ |
|||||||||||
78 | protected $default = null; |
|||||||||||
79 | ||||||||||||
80 | /** |
|||||||||||
81 | * Commands and required arguments list |
|||||||||||
82 | * |
|||||||||||
83 | * @var array |
|||||||||||
84 | **/ |
|||||||||||
85 | protected $commands = array( |
|||||||||||
86 | 'open' => array('target' => false, 'tree' => false, 'init' => false, 'mimes' => false, 'compare' => false), |
|||||||||||
87 | 'ls' => array('target' => true, 'mimes' => false), |
|||||||||||
88 | 'tree' => array('target' => true), |
|||||||||||
89 | 'parents' => array('target' => true), |
|||||||||||
90 | 'tmb' => array('targets' => true), |
|||||||||||
91 | 'file' => array('target' => true, 'download' => false), |
|||||||||||
92 | 'size' => array('targets' => true), |
|||||||||||
93 | 'mkdir' => array('target' => true, 'name' => true), |
|||||||||||
94 | 'mkfile' => array('target' => true, 'name' => true, 'mimes' => false), |
|||||||||||
95 | 'rm' => array('targets' => true), |
|||||||||||
96 | 'rename' => array('target' => true, 'name' => true, 'mimes' => false), |
|||||||||||
97 | 'duplicate' => array('targets' => true, 'suffix' => false), |
|||||||||||
98 | 'paste' => array('dst' => true, 'targets' => true, 'cut' => false, 'mimes' => false, 'renames' => false, 'suffix' => false), |
|||||||||||
99 | 'upload' => array('target' => true, 'FILES' => true, 'mimes' => false, 'html' => false, 'upload' => false, 'name' => false, 'upload_path' => false, 'chunk' => false, 'cid' => false, 'node' => false, 'renames' => false, 'suffix' => false), |
|||||||||||
100 | 'get' => array('target' => true, 'conv' => false), |
|||||||||||
101 | 'put' => array('target' => true, 'content' => '', 'mimes' => false), |
|||||||||||
102 | 'archive' => array('targets' => true, 'type' => true, 'mimes' => false, 'name' => false), |
|||||||||||
103 | 'extract' => array('target' => true, 'mimes' => false, 'makedir' => false), |
|||||||||||
104 | 'search' => array('q' => true, 'mimes' => false, 'target' => false), |
|||||||||||
105 | 'info' => array('targets' => true, 'compare' => false), |
|||||||||||
106 | 'dim' => array('target' => true), |
|||||||||||
107 | 'resize' => array('target' => true, 'width' => true, 'height' => true, 'mode' => false, 'x' => false, 'y' => false, 'degree' => false, 'quality' => false), |
|||||||||||
108 | 'netmount' => array('protocol' => true, 'host' => true, 'path' => false, 'port' => false, 'user' => false, 'pass' => false, 'alias' => false, 'options' => false), |
|||||||||||
109 | 'url' => array('target' => true, 'options' => false), |
|||||||||||
110 | 'callback' => array('node' => true, 'json' => false, 'bind' => false, 'done' => false), |
|||||||||||
111 | 'chmod' => array('targets' => true, 'mode' => true) |
|||||||||||
112 | ); |
|||||||||||
113 | ||||||||||||
114 | /** |
|||||||||||
115 | * Plugins instance |
|||||||||||
116 | * |
|||||||||||
117 | * @var array |
|||||||||||
118 | **/ |
|||||||||||
119 | protected $plugins = array(); |
|||||||||||
120 | ||||||||||||
121 | /** |
|||||||||||
122 | * Commands listeners |
|||||||||||
123 | * |
|||||||||||
124 | * @var array |
|||||||||||
125 | **/ |
|||||||||||
126 | protected $listeners = array(); |
|||||||||||
127 | ||||||||||||
128 | /** |
|||||||||||
129 | * script work time for debug |
|||||||||||
130 | * |
|||||||||||
131 | * @var string |
|||||||||||
132 | **/ |
|||||||||||
133 | protected $time = 0; |
|||||||||||
134 | /** |
|||||||||||
135 | * Is elFinder init correctly? |
|||||||||||
136 | * |
|||||||||||
137 | * @var bool |
|||||||||||
138 | **/ |
|||||||||||
139 | protected $loaded = false; |
|||||||||||
140 | /** |
|||||||||||
141 | * Send debug to client? |
|||||||||||
142 | * |
|||||||||||
143 | * @var string |
|||||||||||
144 | **/ |
|||||||||||
145 | protected $debug = false; |
|||||||||||
146 | ||||||||||||
147 | /** |
|||||||||||
148 | * Call `session_write_close()` before exec command? |
|||||||||||
149 | * |
|||||||||||
150 | * @var bool |
|||||||||||
151 | */ |
|||||||||||
152 | protected $sessionCloseEarlier = true; |
|||||||||||
153 | ||||||||||||
154 | /** |
|||||||||||
155 | * SESSION use commands @see __construct() |
|||||||||||
156 | * |
|||||||||||
157 | * @var array |
|||||||||||
158 | */ |
|||||||||||
159 | protected $sessionUseCmds = array(); |
|||||||||||
160 | ||||||||||||
161 | /** |
|||||||||||
162 | * session expires timeout |
|||||||||||
163 | * |
|||||||||||
164 | * @var int |
|||||||||||
165 | **/ |
|||||||||||
166 | protected $timeout = 0; |
|||||||||||
167 | ||||||||||||
168 | /** |
|||||||||||
169 | * Temp dir path for Upload |
|||||||||||
170 | * |
|||||||||||
171 | * @var string |
|||||||||||
172 | */ |
|||||||||||
173 | protected $uploadTempPath = ''; |
|||||||||||
174 | ||||||||||||
175 | /** |
|||||||||||
176 | * undocumented class variable |
|||||||||||
177 | * |
|||||||||||
178 | * @var string |
|||||||||||
179 | **/ |
|||||||||||
180 | protected $uploadDebug = ''; |
|||||||||||
181 | ||||||||||||
182 | /** |
|||||||||||
183 | * Errors from not mounted volumes |
|||||||||||
184 | * |
|||||||||||
185 | * @var array |
|||||||||||
186 | **/ |
|||||||||||
187 | public $mountErrors = array(); |
|||||||||||
188 | ||||||||||||
189 | /** |
|||||||||||
190 | * URL for callback output window for CORS |
|||||||||||
191 | * redirect to this URL when callback output |
|||||||||||
192 | * |
|||||||||||
193 | * @var string URL |
|||||||||||
194 | */ |
|||||||||||
195 | protected $callbackWindowURL = ''; |
|||||||||||
196 | ||||||||||||
197 | // Errors messages |
|||||||||||
198 | const ERROR_UNKNOWN = 'errUnknown'; |
|||||||||||
199 | const ERROR_UNKNOWN_CMD = 'errUnknownCmd'; |
|||||||||||
200 | const ERROR_CONF = 'errConf'; |
|||||||||||
201 | const ERROR_CONF_NO_JSON = 'errJSON'; |
|||||||||||
202 | const ERROR_CONF_NO_VOL = 'errNoVolumes'; |
|||||||||||
203 | const ERROR_INV_PARAMS = 'errCmdParams'; |
|||||||||||
204 | const ERROR_OPEN = 'errOpen'; |
|||||||||||
205 | const ERROR_DIR_NOT_FOUND = 'errFolderNotFound'; |
|||||||||||
206 | const ERROR_FILE_NOT_FOUND = 'errFileNotFound'; // 'File not found.' |
|||||||||||
207 | const ERROR_TRGDIR_NOT_FOUND = 'errTrgFolderNotFound'; // 'Target folder "$1" not found.' |
|||||||||||
208 | const ERROR_NOT_DIR = 'errNotFolder'; |
|||||||||||
209 | const ERROR_NOT_FILE = 'errNotFile'; |
|||||||||||
210 | const ERROR_PERM_DENIED = 'errPerm'; |
|||||||||||
211 | const ERROR_LOCKED = 'errLocked'; // '"$1" is locked and can not be renamed, moved or removed.' |
|||||||||||
212 | const ERROR_EXISTS = 'errExists'; // 'File named "$1" already exists.' |
|||||||||||
213 | const ERROR_INVALID_NAME = 'errInvName'; // 'Invalid file name.' |
|||||||||||
214 | const ERROR_MKDIR = 'errMkdir'; |
|||||||||||
215 | const ERROR_MKFILE = 'errMkfile'; |
|||||||||||
216 | const ERROR_RENAME = 'errRename'; |
|||||||||||
217 | const ERROR_COPY = 'errCopy'; |
|||||||||||
218 | const ERROR_MOVE = 'errMove'; |
|||||||||||
219 | const ERROR_COPY_FROM = 'errCopyFrom'; |
|||||||||||
220 | const ERROR_COPY_TO = 'errCopyTo'; |
|||||||||||
221 | const ERROR_COPY_ITSELF = 'errCopyInItself'; |
|||||||||||
222 | const ERROR_REPLACE = 'errReplace'; // 'Unable to replace "$1".' |
|||||||||||
223 | const ERROR_RM = 'errRm'; // 'Unable to remove "$1".' |
|||||||||||
224 | const ERROR_RM_SRC = 'errRmSrc'; // 'Unable remove source file(s)' |
|||||||||||
225 | const ERROR_MKOUTLINK = 'errMkOutLink'; // 'Unable to create a link to outside the volume root.' |
|||||||||||
226 | const ERROR_UPLOAD = 'errUpload'; // 'Upload error.' |
|||||||||||
227 | const ERROR_UPLOAD_FILE = 'errUploadFile'; // 'Unable to upload "$1".' |
|||||||||||
228 | const ERROR_UPLOAD_NO_FILES = 'errUploadNoFiles'; // 'No files found for upload.' |
|||||||||||
229 | const ERROR_UPLOAD_TOTAL_SIZE = 'errUploadTotalSize'; // 'Data exceeds the maximum allowed size.' |
|||||||||||
230 | const ERROR_UPLOAD_FILE_SIZE = 'errUploadFileSize'; // 'File exceeds maximum allowed size.' |
|||||||||||
231 | const ERROR_UPLOAD_FILE_MIME = 'errUploadMime'; // 'File type not allowed.' |
|||||||||||
232 | const ERROR_UPLOAD_TRANSFER = 'errUploadTransfer'; // '"$1" transfer error.' |
|||||||||||
233 | const ERROR_UPLOAD_TEMP = 'errUploadTemp'; // 'Unable to make temporary file for upload.' |
|||||||||||
234 | // const ERROR_ACCESS_DENIED = 'errAccess'; |
|||||||||||
235 | const ERROR_NOT_REPLACE = 'errNotReplace'; // Object "$1" already exists at this location and can not be replaced with object of another type. |
|||||||||||
236 | const ERROR_SAVE = 'errSave'; |
|||||||||||
237 | const ERROR_EXTRACT = 'errExtract'; |
|||||||||||
238 | const ERROR_ARCHIVE = 'errArchive'; |
|||||||||||
239 | const ERROR_NOT_ARCHIVE = 'errNoArchive'; |
|||||||||||
240 | const ERROR_ARCHIVE_TYPE = 'errArcType'; |
|||||||||||
241 | const ERROR_ARC_SYMLINKS = 'errArcSymlinks'; |
|||||||||||
242 | const ERROR_ARC_MAXSIZE = 'errArcMaxSize'; |
|||||||||||
243 | const ERROR_RESIZE = 'errResize'; |
|||||||||||
244 | const ERROR_UNSUPPORT_TYPE = 'errUsupportType'; |
|||||||||||
245 | const ERROR_CONV_UTF8 = 'errConvUTF8'; |
|||||||||||
246 | const ERROR_NOT_UTF8_CONTENT = 'errNotUTF8Content'; |
|||||||||||
247 | const ERROR_NETMOUNT = 'errNetMount'; |
|||||||||||
248 | const ERROR_NETUNMOUNT = 'errNetUnMount'; |
|||||||||||
249 | const ERROR_NETMOUNT_NO_DRIVER = 'errNetMountNoDriver'; |
|||||||||||
250 | const ERROR_NETMOUNT_FAILED = 'errNetMountFailed'; |
|||||||||||
251 | ||||||||||||
252 | const ERROR_SESSION_EXPIRES = 'errSessionExpires'; |
|||||||||||
253 | ||||||||||||
254 | const ERROR_CREATING_TEMP_DIR = 'errCreatingTempDir'; |
|||||||||||
255 | const ERROR_FTP_DOWNLOAD_FILE = 'errFtpDownloadFile'; |
|||||||||||
256 | const ERROR_FTP_UPLOAD_FILE = 'errFtpUploadFile'; |
|||||||||||
257 | const ERROR_FTP_MKDIR = 'errFtpMkdir'; |
|||||||||||
258 | const ERROR_ARCHIVE_EXEC = 'errArchiveExec'; |
|||||||||||
259 | const ERROR_EXTRACT_EXEC = 'errExtractExec'; |
|||||||||||
260 | const ERROR_SEARCH_TIMEOUT = 'errSearchTimeout'; // 'Timed out while searching "$1". Search result is partial.' |
|||||||||||
261 | ||||||||||||
262 | /** |
|||||||||||
263 | * Constructor |
|||||||||||
264 | * |
|||||||||||
265 | * @param array elFinder and roots configurations |
|||||||||||
266 | * @return void |
|||||||||||
267 | * @author Dmitry (dio) Levashov |
|||||||||||
268 | **/ |
|||||||||||
269 | public function __construct($opts) { |
|||||||||||
270 | // try session start | restart |
|||||||||||
271 | @session_start(); |
|||||||||||
0 ignored issues
–
show
|
||||||||||||
272 | ||||||||||||
273 | $sessionUseCmds = array(); |
|||||||||||
274 | if (isset($opts['sessionUseCmds']) && is_array($opts['sessionUseCmds'])) { |
|||||||||||
275 | $sessionUseCmds = $opts['sessionUseCmds']; |
|||||||||||
276 | } |
|||||||||||
277 | ||||||||||||
278 | // set self::$volumesCnt by HTTP header "X-elFinder-VolumesCntStart" |
|||||||||||
279 | if (isset($_SERVER['HTTP_X_ELFINDER_VOLUMESCNTSTART']) && ($volumesCntStart = intval($_SERVER['HTTP_X_ELFINDER_VOLUMESCNTSTART']))) { |
|||||||||||
280 | self::$volumesCnt = $volumesCntStart; |
|||||||||||
281 | } |
|||||||||||
282 | ||||||||||||
283 | $this->time = $this->utime(); |
|||||||||||
284 | $this->debug = (isset($opts['debug']) && $opts['debug'] ? true : false); |
|||||||||||
285 | $this->sessionCloseEarlier = isset($opts['sessionCloseEarlier'])? (bool)$opts['sessionCloseEarlier'] : true; |
|||||||||||
286 | $this->sessionUseCmds = array_flip($sessionUseCmds); |
|||||||||||
287 | $this->timeout = (isset($opts['timeout']) ? $opts['timeout'] : 0); |
|||||||||||
288 | $this->uploadTempPath = (isset($opts['uploadTempPath']) ? $opts['uploadTempPath'] : ''); |
|||||||||||
289 | $this->netVolumesSessionKey = !empty($opts['netVolumesSessionKey'])? $opts['netVolumesSessionKey'] : 'elFinderNetVolumes'; |
|||||||||||
290 | $this->callbackWindowURL = (isset($opts['callbackWindowURL']) ? $opts['callbackWindowURL'] : ''); |
|||||||||||
291 | self::$sessionCacheKey = !empty($opts['sessionCacheKey']) ? $opts['sessionCacheKey'] : 'elFinderCaches'; |
|||||||||||
292 | ||||||||||||
293 | // check session cache |
|||||||||||
294 | $_optsMD5 = md5(json_encode($opts['roots'])); |
|||||||||||
295 | if (! isset($_SESSION[self::$sessionCacheKey]) || $_SESSION[self::$sessionCacheKey]['_optsMD5'] !== $_optsMD5) { |
|||||||||||
296 | $_SESSION[self::$sessionCacheKey] = array( |
|||||||||||
297 | '_optsMD5' => $_optsMD5 |
|||||||||||
298 | ); |
|||||||||||
299 | } |
|||||||||||
300 | self::$base64encodeSessionData = !empty($opts['base64encodeSessionData']); |
|||||||||||
301 | ||||||||||||
302 | // setlocale and global locale regists to elFinder::locale |
|||||||||||
303 | self::$locale = !empty($opts['locale']) ? $opts['locale'] : 'en_US.UTF-8'; |
|||||||||||
304 | if (false === @setlocale(LC_ALL, self::$locale)) { |
|||||||||||
305 | self::$locale = setlocale(LC_ALL, ''); |
|||||||||||
306 | } |
|||||||||||
307 | ||||||||||||
308 | // bind events listeners |
|||||||||||
309 | if (!empty($opts['bind']) && is_array($opts['bind'])) { |
|||||||||||
310 | $_req = $_SERVER["REQUEST_METHOD"] == 'POST' ? $_POST : $_GET; |
|||||||||||
311 | $_reqCmd = isset($_req['cmd']) ? $_req['cmd'] : ''; |
|||||||||||
312 | foreach ($opts['bind'] as $cmd => $handlers) { |
|||||||||||
313 | $doRegist = (strpos($cmd, '*') !== false); |
|||||||||||
314 | if (! $doRegist) { |
|||||||||||
315 | $_getcmd = create_function('$cmd', 'list($ret) = explode(\'.\', $cmd);return trim($ret);'); |
|||||||||||
0 ignored issues
–
show
The use of
create_function is highly discouraged, better use a closure.
// Instead of
$function = create_function('$a, $b', 'return $a + $b');
// Better use
$function = function($a, $b) { return $a + $b; }
![]() |
||||||||||||
316 | $doRegist = ($_reqCmd && in_array($_reqCmd, array_map($_getcmd, explode(' ', $cmd)))); |
|||||||||||
317 | } |
|||||||||||
318 | if ($doRegist) { |
|||||||||||
319 | if (! is_array($handlers) || is_object($handlers[0])) { |
|||||||||||
320 | $handlers = array($handlers); |
|||||||||||
321 | } |
|||||||||||
322 | foreach($handlers as $handler) { |
|||||||||||
323 | if ($handler) { |
|||||||||||
324 | if (is_string($handler) && strpos($handler, '.')) { |
|||||||||||
325 | list($_domain, $_name, $_method) = array_pad(explode('.', $handler), 3, ''); |
|||||||||||
326 | if (strcasecmp($_domain, 'plugin') === 0) { |
|||||||||||
327 | if ($plugin = $this->getPluginInstance($_name, isset($opts['plugin'][$_name])? $opts['plugin'][$_name] : array()) |
|||||||||||
328 | and method_exists($plugin, $_method)) { |
|||||||||||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
Using logical operators such as
and instead of && is generally not recommended.
PHP has two types of connecting operators (logical operators, and boolean operators):
The difference between these is the order in which they are executed. In most cases,
you would want to use a boolean operator like Let’s take a look at a few examples: // Logical operators have lower precedence:
$f = false or true;
// is executed like this:
($f = false) or true;
// Boolean operators have higher precedence:
$f = false || true;
// is executed like this:
$f = (false || true);
Logical Operators are used for Control-FlowOne case where you explicitly want to use logical operators is for control-flow such as this: $x === 5
or die('$x must be 5.');
// Instead of
if ($x !== 5) {
die('$x must be 5.');
}
Since // The following is currently a parse error.
$x === 5
or throw new RuntimeException('$x must be 5.');
These limitations lead to logical operators rarely being of use in current PHP code. ![]() |
||||||||||||
329 | $this->bind($cmd, array($plugin, $_method)); |
|||||||||||
330 | } |
|||||||||||
331 | } |
|||||||||||
332 | } else { |
|||||||||||
333 | $this->bind($cmd, $handler); |
|||||||||||
334 | } |
|||||||||||
335 | } |
|||||||||||
336 | } |
|||||||||||
337 | } |
|||||||||||
338 | } |
|||||||||||
339 | } |
|||||||||||
340 | ||||||||||||
341 | if (!isset($opts['roots']) || !is_array($opts['roots'])) { |
|||||||||||
342 | $opts['roots'] = array(); |
|||||||||||
343 | } |
|||||||||||
344 | ||||||||||||
345 | // check for net volumes stored in session |
|||||||||||
346 | foreach ($this->getNetVolumes() as $key => $root) { |
|||||||||||
347 | $opts['roots'][$key] = $root; |
|||||||||||
348 | } |
|||||||||||
349 | ||||||||||||
350 | // "mount" volumes |
|||||||||||
351 | foreach ($opts['roots'] as $i => $o) { |
|||||||||||
352 | $class = 'elFinderVolume'.(isset($o['driver']) ? $o['driver'] : ''); |
|||||||||||
353 | ||||||||||||
354 | if (class_exists($class)) { |
|||||||||||
355 | $volume = new $class(); |
|||||||||||
356 | ||||||||||||
357 | try { |
|||||||||||
358 | if ($volume->mount($o)) { |
|||||||||||
359 | // unique volume id (ends on "_") - used as prefix to files hash |
|||||||||||
360 | $id = $volume->id(); |
|||||||||||
361 | ||||||||||||
362 | $this->volumes[$id] = $volume; |
|||||||||||
363 | if ((!$this->default || $volume->root() !== $volume->defaultPath()) && $volume->isReadable()) { |
|||||||||||
364 | $this->default = $this->volumes[$id]; |
|||||||||||
365 | } |
|||||||||||
366 | } else { |
|||||||||||
367 | $this->removeNetVolume($i); |
|||||||||||
368 | $this->mountErrors[] = 'Driver "'.$class.'" : '.implode(' ', $volume->error()); |
|||||||||||
369 | } |
|||||||||||
370 | } catch (Exception $e) { |
|||||||||||
371 | $this->removeNetVolume($i); |
|||||||||||
372 | $this->mountErrors[] = 'Driver "'.$class.'" : '.$e->getMessage(); |
|||||||||||
373 | } |
|||||||||||
374 | } else { |
|||||||||||
375 | $this->mountErrors[] = 'Driver "'.$class.'" does not exists'; |
|||||||||||
376 | } |
|||||||||||
377 | } |
|||||||||||
378 | ||||||||||||
379 | // if at least one readable volume - ii desu >_< |
|||||||||||
380 | $this->loaded = !empty($this->default); |
|||||||||||
381 | } |
|||||||||||
382 | ||||||||||||
383 | /** |
|||||||||||
384 | * Return true if fm init correctly |
|||||||||||
385 | * |
|||||||||||
386 | * @return bool |
|||||||||||
387 | * @author Dmitry (dio) Levashov |
|||||||||||
388 | **/ |
|||||||||||
389 | public function loaded() { |
|||||||||||
390 | return $this->loaded; |
|||||||||||
391 | } |
|||||||||||
392 | ||||||||||||
393 | /** |
|||||||||||
394 | * Return version (api) number |
|||||||||||
395 | * |
|||||||||||
396 | * @return string |
|||||||||||
397 | * @author Dmitry (dio) Levashov |
|||||||||||
398 | **/ |
|||||||||||
399 | public function version() { |
|||||||||||
400 | return $this->version; |
|||||||||||
401 | } |
|||||||||||
402 | ||||||||||||
403 | /** |
|||||||||||
404 | * Add handler to elFinder command |
|||||||||||
405 | * |
|||||||||||
406 | * @param string command name |
|||||||||||
407 | * @param string|array callback name or array(object, method) |
|||||||||||
408 | * @return elFinder |
|||||||||||
409 | * @author Dmitry (dio) Levashov |
|||||||||||
410 | **/ |
|||||||||||
411 | public function bind($cmd, $handler) { |
|||||||||||
412 | $allCmds = array_keys($this->commands); |
|||||||||||
413 | $cmds = array(); |
|||||||||||
414 | foreach(explode(' ', $cmd) as $_cmd) { |
|||||||||||
415 | if ($_cmd !== '') { |
|||||||||||
416 | if ($all = strpos($_cmd, '*') !== false) { |
|||||||||||
0 ignored issues
–
show
$all is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
||||||||||||
417 | list(, $sub) = array_pad(explode('.', $_cmd), 2, ''); |
|||||||||||
418 | if ($sub) { |
|||||||||||
419 | $sub = str_replace('\'', '\\\'', $sub); |
|||||||||||
420 | $addSub = create_function('$cmd', 'return $cmd . \'.\' . trim(\'' . $sub . '\');'); |
|||||||||||
0 ignored issues
–
show
The use of
create_function is highly discouraged, better use a closure.
// Instead of
$function = create_function('$a, $b', 'return $a + $b');
// Better use
$function = function($a, $b) { return $a + $b; }
![]() |
||||||||||||
421 | $cmds = array_merge($cmds, array_map($addSub, $allCmds)); |
|||||||||||
422 | } else { |
|||||||||||
423 | $cmds = array_merge($cmds, $allCmds); |
|||||||||||
424 | } |
|||||||||||
425 | } else { |
|||||||||||
426 | $cmds[] = $_cmd; |
|||||||||||
427 | } |
|||||||||||
428 | } |
|||||||||||
429 | } |
|||||||||||
430 | $cmds = array_unique($cmds); |
|||||||||||
431 | ||||||||||||
432 | foreach ($cmds as $cmd) { |
|||||||||||
433 | if (!isset($this->listeners[$cmd])) { |
|||||||||||
434 | $this->listeners[$cmd] = array(); |
|||||||||||
435 | } |
|||||||||||
436 | ||||||||||||
437 | if (is_callable($handler)) { |
|||||||||||
438 | $this->listeners[$cmd][] = $handler; |
|||||||||||
439 | } |
|||||||||||
440 | } |
|||||||||||
441 | ||||||||||||
442 | return $this; |
|||||||||||
443 | } |
|||||||||||
444 | ||||||||||||
445 | /** |
|||||||||||
446 | * Remove event (command exec) handler |
|||||||||||
447 | * |
|||||||||||
448 | * @param string command name |
|||||||||||
449 | * @param string|array callback name or array(object, method) |
|||||||||||
450 | * @return elFinder |
|||||||||||
451 | * @author Dmitry (dio) Levashov |
|||||||||||
452 | **/ |
|||||||||||
453 | public function unbind($cmd, $handler) { |
|||||||||||
454 | if (!empty($this->listeners[$cmd])) { |
|||||||||||
455 | foreach ($this->listeners[$cmd] as $i => $h) { |
|||||||||||
456 | if ($h === $handler) { |
|||||||||||
457 | unset($this->listeners[$cmd][$i]); |
|||||||||||
458 | return $this; |
|||||||||||
459 | } |
|||||||||||
460 | } |
|||||||||||
461 | } |
|||||||||||
462 | return $this; |
|||||||||||
463 | } |
|||||||||||
464 | ||||||||||||
465 | /** |
|||||||||||
466 | * Return true if command exists |
|||||||||||
467 | * |
|||||||||||
468 | * @param string command name |
|||||||||||
469 | * @return bool |
|||||||||||
470 | * @author Dmitry (dio) Levashov |
|||||||||||
471 | **/ |
|||||||||||
472 | public function commandExists($cmd) { |
|||||||||||
473 | return $this->loaded && isset($this->commands[$cmd]) && method_exists($this, $cmd); |
|||||||||||
474 | } |
|||||||||||
475 | ||||||||||||
476 | /** |
|||||||||||
477 | * Return root - file's owner (public func of volume()) |
|||||||||||
478 | * |
|||||||||||
479 | * @param string file hash |
|||||||||||
480 | * @return elFinderStorageDriver |
|||||||||||
481 | * @author Naoki Sawada |
|||||||||||
482 | */ |
|||||||||||
483 | public function getVolume($hash) { |
|||||||||||
484 | return $this->volume($hash); |
|||||||||||
485 | } |
|||||||||||
486 | ||||||||||||
487 | /** |
|||||||||||
488 | * Return command required arguments info |
|||||||||||
489 | * |
|||||||||||
490 | * @param string command name |
|||||||||||
491 | * @return array |
|||||||||||
492 | * @author Dmitry (dio) Levashov |
|||||||||||
493 | **/ |
|||||||||||
494 | public function commandArgsList($cmd) { |
|||||||||||
495 | return $this->commandExists($cmd) ? $this->commands[$cmd] : array(); |
|||||||||||
496 | } |
|||||||||||
497 | ||||||||||||
498 | private function session_expires() { |
|||||||||||
499 | ||||||||||||
500 | if (!isset($_SESSION[self::$sessionCacheKey . ':LAST_ACTIVITY'])) { |
|||||||||||
501 | $_SESSION[self::$sessionCacheKey . ':LAST_ACTIVITY'] = time(); |
|||||||||||
502 | return false; |
|||||||||||
503 | } |
|||||||||||
504 | ||||||||||||
505 | if ( ($this->timeout > 0) && (time() - $_SESSION[self::$sessionCacheKey . ':LAST_ACTIVITY'] > $this->timeout) ) { |
|||||||||||
506 | return true; |
|||||||||||
507 | } |
|||||||||||
508 | ||||||||||||
509 | $_SESSION[self::$sessionCacheKey . ':LAST_ACTIVITY'] = time(); |
|||||||||||
510 | return false; |
|||||||||||
511 | } |
|||||||||||
512 | ||||||||||||
513 | /** |
|||||||||||
514 | * Exec command and return result |
|||||||||||
515 | * |
|||||||||||
516 | * @param string $cmd command name |
|||||||||||
517 | * @param array $args command arguments |
|||||||||||
518 | * @return array |
|||||||||||
519 | * @author Dmitry (dio) Levashov |
|||||||||||
520 | **/ |
|||||||||||
521 | public function exec($cmd, $args) { |
|||||||||||
522 | ||||||||||||
523 | if (!$this->loaded) { |
|||||||||||
524 | return array('error' => $this->error(self::ERROR_CONF, self::ERROR_CONF_NO_VOL)); |
|||||||||||
525 | } |
|||||||||||
526 | ||||||||||||
527 | if ($this->session_expires()) { |
|||||||||||
528 | return array('error' => $this->error(self::ERROR_SESSION_EXPIRES)); |
|||||||||||
529 | } |
|||||||||||
530 | ||||||||||||
531 | if (!$this->commandExists($cmd)) { |
|||||||||||
532 | return array('error' => $this->error(self::ERROR_UNKNOWN_CMD)); |
|||||||||||
533 | } |
|||||||||||
534 | ||||||||||||
535 | if (!empty($args['mimes']) && is_array($args['mimes'])) { |
|||||||||||
536 | foreach ($this->volumes as $id => $v) { |
|||||||||||
537 | $this->volumes[$id]->setMimesFilter($args['mimes']); |
|||||||||||
538 | } |
|||||||||||
539 | } |
|||||||||||
540 | ||||||||||||
541 | // call pre handlers for this command |
|||||||||||
542 | $args['sessionCloseEarlier'] = isset($this->sessionUseCmds[$cmd])? false : $this->sessionCloseEarlier; |
|||||||||||
543 | if (!empty($this->listeners[$cmd.'.pre'])) { |
|||||||||||
544 | $volume = isset($args['target'])? $this->volume($args['target']) : false; |
|||||||||||
545 | View Code Duplication | foreach ($this->listeners[$cmd.'.pre'] as $handler) { |
||||||||||
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
||||||||||||
546 | call_user_func_array($handler, array($cmd, &$args, $this, $volume)); |
|||||||||||
547 | } |
|||||||||||
548 | } |
|||||||||||
549 | ||||||||||||
550 | // unlock session data for multiple access |
|||||||||||
551 | $this->sessionCloseEarlier && $args['sessionCloseEarlier'] && session_id() && session_write_close(); |
|||||||||||
552 | ||||||||||||
553 | if (substr(PHP_OS,0,3) === 'WIN') { |
|||||||||||
554 | // set time out |
|||||||||||
555 | if (($_max_execution_time = ini_get('max_execution_time')) && $_max_execution_time < 300) { |
|||||||||||
556 | @set_time_limit(300); |
|||||||||||
0 ignored issues
–
show
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
![]() |
||||||||||||
557 | } |
|||||||||||
558 | } |
|||||||||||
559 | ||||||||||||
560 | $result = $this->$cmd($args); |
|||||||||||
561 | ||||||||||||
562 | if (isset($result['removed'])) { |
|||||||||||
563 | foreach ($this->volumes as $volume) { |
|||||||||||
564 | $result['removed'] = array_merge($result['removed'], $volume->removed()); |
|||||||||||
565 | $volume->resetRemoved(); |
|||||||||||
566 | } |
|||||||||||
567 | } |
|||||||||||
568 | ||||||||||||
569 | // call handlers for this command |
|||||||||||
570 | if (!empty($this->listeners[$cmd])) { |
|||||||||||
571 | foreach ($this->listeners[$cmd] as $handler) { |
|||||||||||
572 | if (call_user_func_array($handler,array($cmd,&$result,$args,$this))) { |
|||||||||||
573 | // handler return true to force sync client after command completed |
|||||||||||
574 | $result['sync'] = true; |
|||||||||||
575 | } |
|||||||||||
576 | } |
|||||||||||
577 | } |
|||||||||||
578 | ||||||||||||
579 | // replace removed files info with removed files hashes |
|||||||||||
580 | if (!empty($result['removed'])) { |
|||||||||||
581 | $removed = array(); |
|||||||||||
582 | foreach ($result['removed'] as $file) { |
|||||||||||
583 | $removed[] = $file['hash']; |
|||||||||||
584 | } |
|||||||||||
585 | $result['removed'] = array_unique($removed); |
|||||||||||
586 | } |
|||||||||||
587 | // remove hidden files and filter files by mimetypes |
|||||||||||
588 | if (!empty($result['added'])) { |
|||||||||||
589 | $result['added'] = $this->filter($result['added']); |
|||||||||||
590 | } |
|||||||||||
591 | // remove hidden files and filter files by mimetypes |
|||||||||||
592 | if (!empty($result['changed'])) { |
|||||||||||
593 | $result['changed'] = $this->filter($result['changed']); |
|||||||||||
594 | } |
|||||||||||
595 | ||||||||||||
596 | if ($this->debug || !empty($args['debug'])) { |
|||||||||||
597 | $result['debug'] = array( |
|||||||||||
598 | 'connector' => 'php', |
|||||||||||
599 | 'phpver' => PHP_VERSION, |
|||||||||||
600 | 'time' => $this->utime() - $this->time, |
|||||||||||
601 | 'memory' => (function_exists('memory_get_peak_usage') ? ceil(memory_get_peak_usage()/1024).'Kb / ' : '').ceil(memory_get_usage()/1024).'Kb / '.ini_get('memory_limit'), |
|||||||||||
602 | 'upload' => $this->uploadDebug, |
|||||||||||
603 | 'volumes' => array(), |
|||||||||||
604 | 'mountErrors' => $this->mountErrors |
|||||||||||
605 | ); |
|||||||||||
606 | ||||||||||||
607 | foreach ($this->volumes as $id => $volume) { |
|||||||||||
608 | $result['debug']['volumes'][] = $volume->debug(); |
|||||||||||
609 | } |
|||||||||||
610 | } |
|||||||||||
611 | ||||||||||||
612 | foreach ($this->volumes as $volume) { |
|||||||||||
613 | $volume->umount(); |
|||||||||||
614 | } |
|||||||||||
615 | ||||||||||||
616 | if (!empty($result['callback'])) { |
|||||||||||
617 | $result['callback']['json'] = json_encode($result); |
|||||||||||
618 | $this->callback($result['callback']); |
|||||||||||
619 | } else { |
|||||||||||
620 | return $result; |
|||||||||||
621 | } |
|||||||||||
622 | } |
|||||||||||
623 | ||||||||||||
624 | /** |
|||||||||||
625 | * Return file real path |
|||||||||||
626 | * |
|||||||||||
627 | * @param string $hash file hash |
|||||||||||
628 | * @return string |
|||||||||||
629 | * @author Dmitry (dio) Levashov |
|||||||||||
630 | **/ |
|||||||||||
631 | public function realpath($hash) { |
|||||||||||
632 | if (($volume = $this->volume($hash)) == false) { |
|||||||||||
633 | return false; |
|||||||||||
634 | } |
|||||||||||
635 | return $volume->realpath($hash); |
|||||||||||
636 | } |
|||||||||||
637 | ||||||||||||
638 | /** |
|||||||||||
639 | * Return network volumes config. |
|||||||||||
640 | * |
|||||||||||
641 | * @return array |
|||||||||||
642 | * @author Dmitry (dio) Levashov |
|||||||||||
643 | */ |
|||||||||||
644 | protected function getNetVolumes() { |
|||||||||||
645 | if (isset($_SESSION[$this->netVolumesSessionKey])) { |
|||||||||||
646 | if ($data = elFinder::sessionDataDecode($_SESSION[$this->netVolumesSessionKey], 'array')) { |
|||||||||||
0 ignored issues
–
show
'array' is of type string , but the function expects a boolean|null .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
||||||||||||
647 | return $data; |
|||||||||||
648 | } |
|||||||||||
649 | } |
|||||||||||
650 | return array(); |
|||||||||||
651 | } |
|||||||||||
652 | ||||||||||||
653 | /** |
|||||||||||
654 | * Save network volumes config. |
|||||||||||
655 | * |
|||||||||||
656 | * @param array $volumes volumes config |
|||||||||||
657 | * @return void |
|||||||||||
658 | * @author Dmitry (dio) Levashov |
|||||||||||
659 | */ |
|||||||||||
660 | protected function saveNetVolumes($volumes) { |
|||||||||||
661 | $_SESSION[$this->netVolumesSessionKey] = elFinder::sessionDataEncode($volumes); |
|||||||||||
662 | } |
|||||||||||
663 | ||||||||||||
664 | /** |
|||||||||||
665 | * Remove netmount volume |
|||||||||||
666 | * |
|||||||||||
667 | * @param string $key netvolume key |
|||||||||||
668 | */ |
|||||||||||
669 | protected function removeNetVolume($key) { |
|||||||||||
670 | $netVolumes = $this->getNetVolumes(); |
|||||||||||
671 | if (is_string($key) && isset($netVolumes[$key])) { |
|||||||||||
672 | unset($netVolumes[$key]); |
|||||||||||
673 | $this->saveNetVolumes($netVolumes); |
|||||||||||
674 | } |
|||||||||||
675 | } |
|||||||||||
676 | ||||||||||||
677 | /** |
|||||||||||
678 | * Get plugin instance & set to $this->plugins |
|||||||||||
679 | * |
|||||||||||
680 | * @param string $name Plugin name (dirctory name) |
|||||||||||
681 | * @param array $opts Plugin options (optional) |
|||||||||||
682 | * @return object | bool Plugin object instance Or false |
|||||||||||
683 | * @author Naoki Sawada |
|||||||||||
684 | */ |
|||||||||||
685 | protected function getPluginInstance($name, $opts = array()) { |
|||||||||||
686 | $key = strtolower($name); |
|||||||||||
687 | if (! isset($this->plugins[$key])) { |
|||||||||||
688 | $p_file = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . $name . DIRECTORY_SEPARATOR . 'plugin.php'; |
|||||||||||
689 | if (is_file($p_file)) { |
|||||||||||
690 | require_once $p_file; |
|||||||||||
691 | $class = 'elFinderPlugin' . $name; |
|||||||||||
692 | $this->plugins[$key] = new $class($opts); |
|||||||||||
693 | } else { |
|||||||||||
694 | $this->plugins[$key] = false; |
|||||||||||
695 | } |
|||||||||||
696 | } |
|||||||||||
697 | return $this->plugins[$key]; |
|||||||||||
698 | } |
|||||||||||
699 | ||||||||||||
700 | /***************************************************************************/ |
|||||||||||
701 | /* commands */ |
|||||||||||
702 | /***************************************************************************/ |
|||||||||||
703 | ||||||||||||
704 | /** |
|||||||||||
705 | * Normalize error messages |
|||||||||||
706 | * |
|||||||||||
707 | * @return array |
|||||||||||
708 | * @author Dmitry (dio) Levashov |
|||||||||||
709 | **/ |
|||||||||||
710 | public function error() { |
|||||||||||
711 | $errors = array(); |
|||||||||||
712 | ||||||||||||
713 | foreach (func_get_args() as $msg) { |
|||||||||||
714 | if (is_array($msg)) { |
|||||||||||
715 | $errors = array_merge($errors, $msg); |
|||||||||||
716 | } else { |
|||||||||||
717 | $errors[] = $msg; |
|||||||||||
718 | } |
|||||||||||
719 | } |
|||||||||||
720 | ||||||||||||
721 | return count($errors) ? $errors : array(self::ERROR_UNKNOWN); |
|||||||||||
722 | } |
|||||||||||
723 | ||||||||||||
724 | protected function netmount($args) { |
|||||||||||
725 | // try session restart |
|||||||||||
726 | @session_start(); |
|||||||||||
0 ignored issues
–
show
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
![]() |
||||||||||||
727 | ||||||||||||
728 | $options = array(); |
|||||||||||
729 | $protocol = $args['protocol']; |
|||||||||||
730 | ||||||||||||
731 | if ($protocol === 'netunmount') { |
|||||||||||
732 | $key = $args['host']; |
|||||||||||
733 | $netVolumes = $this->getNetVolumes(); |
|||||||||||
734 | if ($netVolumes[$key]) { |
|||||||||||
735 | $res = true; |
|||||||||||
736 | $volume = $this->volume($args['user']); |
|||||||||||
737 | if (method_exists($volume, 'netunmount')) { |
|||||||||||
738 | $res = $volume->netunmount($netVolumes, $key); |
|||||||||||
739 | } |
|||||||||||
740 | if ($res) { |
|||||||||||
741 | unset($netVolumes[$key]); |
|||||||||||
742 | $this->saveNetVolumes($netVolumes); |
|||||||||||
743 | return array('sync' => true); |
|||||||||||
744 | } |
|||||||||||
745 | } |
|||||||||||
746 | return array('error' => $this->error(self::ERROR_NETUNMOUNT)); |
|||||||||||
747 | } |
|||||||||||
748 | ||||||||||||
749 | $driver = isset(self::$netDrivers[$protocol]) ? self::$netDrivers[$protocol] : ''; |
|||||||||||
750 | $class = 'elfindervolume'.$driver; |
|||||||||||
751 | ||||||||||||
752 | if (!class_exists($class)) { |
|||||||||||
753 | return array('error' => $this->error(self::ERROR_NETMOUNT, $args['host'], self::ERROR_NETMOUNT_NO_DRIVER)); |
|||||||||||
754 | } |
|||||||||||
755 | ||||||||||||
756 | if (!$args['path']) { |
|||||||||||
757 | $args['path'] = '/'; |
|||||||||||
758 | } |
|||||||||||
759 | ||||||||||||
760 | foreach ($args as $k => $v) { |
|||||||||||
761 | if ($k != 'options' && $k != 'protocol' && $v) { |
|||||||||||
762 | $options[$k] = $v; |
|||||||||||
763 | } |
|||||||||||
764 | } |
|||||||||||
765 | ||||||||||||
766 | if (is_array($args['options'])) { |
|||||||||||
767 | foreach ($args['options'] as $key => $value) { |
|||||||||||
768 | $options[$key] = $value; |
|||||||||||
769 | } |
|||||||||||
770 | } |
|||||||||||
771 | ||||||||||||
772 | $volume = new $class(); |
|||||||||||
773 | ||||||||||||
774 | if (method_exists($volume, 'netmountPrepare')) { |
|||||||||||
775 | $options = $volume->netmountPrepare($options); |
|||||||||||
776 | if (isset($options['exit'])) { |
|||||||||||
777 | if ($options['exit'] === 'callback') { |
|||||||||||
778 | $this->callback($options['out']); |
|||||||||||
779 | } |
|||||||||||
780 | return $options; |
|||||||||||
781 | } |
|||||||||||
782 | } |
|||||||||||
783 | ||||||||||||
784 | $netVolumes = $this->getNetVolumes(); |
|||||||||||
785 | if ($volume->mount($options)) { |
|||||||||||
786 | if (! $key = @ $volume->netMountKey) { |
|||||||||||
787 | $key = md5($protocol . '-' . join('-', $options)); |
|||||||||||
788 | } |
|||||||||||
789 | $options['driver'] = $driver; |
|||||||||||
790 | $options['netkey'] = $key; |
|||||||||||
791 | $netVolumes[$key] = $options; |
|||||||||||
792 | $this->saveNetVolumes($netVolumes); |
|||||||||||
793 | $rootstat = $volume->file($volume->root()); |
|||||||||||
794 | $rootstat['netkey'] = $key; |
|||||||||||
795 | return array('added' => array($rootstat)); |
|||||||||||
796 | } else { |
|||||||||||
797 | $this->removeNetVolume($volume); |
|||||||||||
0 ignored issues
–
show
$volume is of type object , but the function expects a string .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
||||||||||||
798 | return array('error' => $this->error(self::ERROR_NETMOUNT, $args['host'], implode(' ', $volume->error()))); |
|||||||||||
799 | } |
|||||||||||
800 | ||||||||||||
801 | } |
|||||||||||
802 | ||||||||||||
803 | /** |
|||||||||||
804 | * "Open" directory |
|||||||||||
805 | * Return array with following elements |
|||||||||||
806 | * - cwd - opened dir info |
|||||||||||
807 | * - files - opened dir content [and dirs tree if $args[tree]] |
|||||||||||
808 | * - api - api version (if $args[init]) |
|||||||||||
809 | * - uplMaxSize - if $args[init] |
|||||||||||
810 | * - error - on failed |
|||||||||||
811 | * |
|||||||||||
812 | * @param array command arguments |
|||||||||||
813 | * @return array |
|||||||||||
814 | * @author Dmitry (dio) Levashov |
|||||||||||
815 | **/ |
|||||||||||
816 | protected function open($args) { |
|||||||||||
817 | $target = $args['target']; |
|||||||||||
818 | $init = !empty($args['init']); |
|||||||||||
819 | $tree = !empty($args['tree']); |
|||||||||||
820 | $volume = $this->volume($target); |
|||||||||||
821 | $cwd = $volume ? $volume->dir($target) : false; |
|||||||||||
822 | $hash = $init ? 'default folder' : '#'.$target; |
|||||||||||
823 | $sleep = 0; |
|||||||||||
0 ignored issues
–
show
$sleep is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
||||||||||||
824 | $compare = ''; |
|||||||||||
825 | ||||||||||||
826 | // on init request we can get invalid dir hash - |
|||||||||||
827 | // dir which can not be opened now, but remembered by client, |
|||||||||||
828 | // so open default dir |
|||||||||||
829 | if ((!$cwd || !$cwd['read']) && $init) { |
|||||||||||
830 | $volume = $this->default; |
|||||||||||
831 | $cwd = $volume->dir($volume->defaultPath()); |
|||||||||||
832 | } |
|||||||||||
833 | ||||||||||||
834 | if (!$cwd) { |
|||||||||||
835 | return array('error' => $this->error(self::ERROR_OPEN, $hash, self::ERROR_DIR_NOT_FOUND)); |
|||||||||||
836 | } |
|||||||||||
837 | if (!$cwd['read']) { |
|||||||||||
838 | return array('error' => $this->error(self::ERROR_OPEN, $hash, self::ERROR_PERM_DENIED)); |
|||||||||||
839 | } |
|||||||||||
840 | ||||||||||||
841 | $files = array(); |
|||||||||||
842 | ||||||||||||
843 | // get other volume root |
|||||||||||
844 | if ($tree) { |
|||||||||||
845 | foreach ($this->volumes as $id => $v) { |
|||||||||||
846 | $files[] = $v->file($v->root()); |
|||||||||||
847 | } |
|||||||||||
848 | } |
|||||||||||
849 | ||||||||||||
850 | // get current working directory files list and add to $files if not exists in it |
|||||||||||
851 | View Code Duplication | if (($ls = $volume->scandir($cwd['hash'])) === false) { |
||||||||||
852 | return array('error' => $this->error(self::ERROR_OPEN, $cwd['name'], $volume->error())); |
|||||||||||
853 | } |
|||||||||||
854 | // long polling mode |
|||||||||||
855 | if ($args['compare']) { |
|||||||||||
856 | $sleep = max(1, (int)$volume->getOption('lsPlSleep')); |
|||||||||||
857 | $limit = max(1, (int)$volume->getOption('plStandby') / $sleep) + 1; |
|||||||||||
858 | $timelimit = ini_get('max_execution_time'); |
|||||||||||
859 | $compare = $args['compare']; |
|||||||||||
0 ignored issues
–
show
$compare is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
||||||||||||
860 | do { |
|||||||||||
861 | $timelimit && @ set_time_limit($timelimit + $sleep); |
|||||||||||
862 | $_mtime = 0; |
|||||||||||
863 | foreach($ls as $_f) { |
|||||||||||
864 | $_mtime = max($_mtime, $_f['ts']); |
|||||||||||
865 | } |
|||||||||||
866 | $compare = strval(count($ls)).':'.strval($_mtime); |
|||||||||||
867 | if ($compare !== $args['compare']) { |
|||||||||||
868 | break; |
|||||||||||
869 | } |
|||||||||||
870 | if (--$limit) { |
|||||||||||
871 | sleep($sleep); |
|||||||||||
872 | $volume->clearstatcache(); |
|||||||||||
873 | if (($ls = $volume->scandir($cwd['hash'])) === false) { |
|||||||||||
874 | break; |
|||||||||||
875 | } |
|||||||||||
876 | } |
|||||||||||
877 | } while($limit); |
|||||||||||
878 | View Code Duplication | if ($ls === false) { |
||||||||||
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
||||||||||||
879 | return array('error' => $this->error(self::ERROR_OPEN, $cwd['name'], $volume->error())); |
|||||||||||
880 | } |
|||||||||||
881 | } |
|||||||||||
882 | ||||||||||||
883 | if ($ls) { |
|||||||||||
884 | if ($files) { |
|||||||||||
0 ignored issues
–
show
The expression
$files of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using ![]() |
||||||||||||
885 | $files = array_merge($files, $ls); |
|||||||||||
886 | $files = array_unique($files, SORT_REGULAR); |
|||||||||||
887 | } else { |
|||||||||||
888 | $files = $ls; |
|||||||||||
889 | } |
|||||||||||
890 | } |
|||||||||||
891 | ||||||||||||
892 | $result = array( |
|||||||||||
893 | 'cwd' => $cwd, |
|||||||||||
894 | 'options' => $volume->options($cwd['hash']), |
|||||||||||
895 | 'files' => $files |
|||||||||||
896 | ); |
|||||||||||
897 | ||||||||||||
898 | if ($compare) { |
|||||||||||
899 | $result['cwd']['compare'] = $compare; |
|||||||||||
900 | } |
|||||||||||
901 | ||||||||||||
902 | if (!empty($args['init'])) { |
|||||||||||
903 | $result['api'] = $this->version; |
|||||||||||
904 | $result['uplMaxSize'] = ini_get('upload_max_filesize'); |
|||||||||||
905 | $result['uplMaxFile'] = ini_get('max_file_uploads'); |
|||||||||||
906 | $result['netDrivers'] = array_keys(self::$netDrivers); |
|||||||||||
907 | if ($volume) { |
|||||||||||
908 | $result['cwd']['root'] = $volume->root(); |
|||||||||||
909 | } |
|||||||||||
910 | } |
|||||||||||
911 | ||||||||||||
912 | return $result; |
|||||||||||
913 | } |
|||||||||||
914 | ||||||||||||
915 | /** |
|||||||||||
916 | * Return dir files names list |
|||||||||||
917 | * |
|||||||||||
918 | * @param array command arguments |
|||||||||||
919 | * @return array |
|||||||||||
920 | * @author Dmitry (dio) Levashov |
|||||||||||
921 | **/ |
|||||||||||
922 | View Code Duplication | protected function ls($args) { |
||||||||||
923 | $target = $args['target']; |
|||||||||||
924 | ||||||||||||
925 | if (($volume = $this->volume($target)) == false |
|||||||||||
926 | || ($list = $volume->ls($target)) === false) { |
|||||||||||
927 | return array('error' => $this->error(self::ERROR_OPEN, '#'.$target)); |
|||||||||||
928 | } |
|||||||||||
929 | return array('list' => $list); |
|||||||||||
930 | } |
|||||||||||
931 | ||||||||||||
932 | /** |
|||||||||||
933 | * Return subdirs for required directory |
|||||||||||
934 | * |
|||||||||||
935 | * @param array command arguments |
|||||||||||
936 | * @return array |
|||||||||||
937 | * @author Dmitry (dio) Levashov |
|||||||||||
938 | **/ |
|||||||||||
939 | View Code Duplication | protected function tree($args) { |
||||||||||
940 | $target = $args['target']; |
|||||||||||
941 | ||||||||||||
942 | if (($volume = $this->volume($target)) == false |
|||||||||||
943 | || ($tree = $volume->tree($target)) == false) { |
|||||||||||
944 | return array('error' => $this->error(self::ERROR_OPEN, '#'.$target)); |
|||||||||||
945 | } |
|||||||||||
946 | ||||||||||||
947 | return array('tree' => $tree); |
|||||||||||
948 | } |
|||||||||||
949 | ||||||||||||
950 | /** |
|||||||||||
951 | * Return parents dir for required directory |
|||||||||||
952 | * |
|||||||||||
953 | * @param array command arguments |
|||||||||||
954 | * @return array |
|||||||||||
955 | * @author Dmitry (dio) Levashov |
|||||||||||
956 | **/ |
|||||||||||
957 | View Code Duplication | protected function parents($args) { |
||||||||||
958 | $target = $args['target']; |
|||||||||||
959 | ||||||||||||
960 | if (($volume = $this->volume($target)) == false |
|||||||||||
961 | || ($tree = $volume->parents($target)) == false) { |
|||||||||||
962 | return array('error' => $this->error(self::ERROR_OPEN, '#'.$target)); |
|||||||||||
963 | } |
|||||||||||
964 | ||||||||||||
965 | return array('tree' => $tree); |
|||||||||||
966 | } |
|||||||||||
967 | ||||||||||||
968 | /** |
|||||||||||
969 | * Return new created thumbnails list |
|||||||||||
970 | * |
|||||||||||
971 | * @param array command arguments |
|||||||||||
972 | * @return array |
|||||||||||
973 | * @author Dmitry (dio) Levashov |
|||||||||||
974 | **/ |
|||||||||||
975 | protected function tmb($args) { |
|||||||||||
976 | ||||||||||||
977 | $result = array('images' => array()); |
|||||||||||
978 | $targets = $args['targets']; |
|||||||||||
979 | ||||||||||||
980 | foreach ($targets as $target) { |
|||||||||||
981 | if (($volume = $this->volume($target)) != false |
|||||||||||
982 | && (($tmb = $volume->tmb($target)) != false)) { |
|||||||||||
983 | $result['images'][$target] = $tmb; |
|||||||||||
984 | } |
|||||||||||
985 | } |
|||||||||||
986 | return $result; |
|||||||||||
987 | } |
|||||||||||
988 | ||||||||||||
989 | /** |
|||||||||||
990 | * Required to output file in browser when volume URL is not set |
|||||||||||
991 | * Return array contains opened file pointer, root itself and required headers |
|||||||||||
992 | * |
|||||||||||
993 | * @param array command arguments |
|||||||||||
994 | * @return array |
|||||||||||
995 | * @author Dmitry (dio) Levashov |
|||||||||||
996 | **/ |
|||||||||||
997 | protected function file($args) { |
|||||||||||
998 | $target = $args['target']; |
|||||||||||
999 | $download = !empty($args['download']); |
|||||||||||
1000 | $h403 = 'HTTP/1.x 403 Access Denied'; |
|||||||||||
1001 | $h404 = 'HTTP/1.x 404 Not Found'; |
|||||||||||
1002 | ||||||||||||
1003 | View Code Duplication | if (($volume = $this->volume($target)) == false) { |
||||||||||
1004 | return array('error' => 'File not found', 'header' => $h404, 'raw' => true); |
|||||||||||
1005 | } |
|||||||||||
1006 | ||||||||||||
1007 | View Code Duplication | if (($file = $volume->file($target)) == false) { |
||||||||||
1008 | return array('error' => 'File not found', 'header' => $h404, 'raw' => true); |
|||||||||||
1009 | } |
|||||||||||
1010 | ||||||||||||
1011 | if (!$file['read']) { |
|||||||||||
1012 | return array('error' => 'Access denied', 'header' => $h403, 'raw' => true); |
|||||||||||
1013 | } |
|||||||||||
1014 | ||||||||||||
1015 | View Code Duplication | if (($fp = $volume->open($target)) == false) { |
||||||||||
1016 | return array('error' => 'File not found', 'header' => $h404, 'raw' => true); |
|||||||||||
1017 | } |
|||||||||||
1018 | ||||||||||||
1019 | // allow change MIME type by 'file.pre' callback functions |
|||||||||||
1020 | $mime = isset($args['mime'])? $args['mime'] : $file['mime']; |
|||||||||||
1021 | if ($download) { |
|||||||||||
1022 | $disp = 'attachment'; |
|||||||||||
1023 | } else { |
|||||||||||
1024 | $dispInlineRegex = $volume->getOption('dispInlineRegex'); |
|||||||||||
1025 | $inlineRegex = false; |
|||||||||||
1026 | if ($dispInlineRegex) { |
|||||||||||
1027 | $inlineRegex = '#' . str_replace('#', '\\#', $dispInlineRegex) . '#'; |
|||||||||||
1028 | try { |
|||||||||||
1029 | preg_match($inlineRegex, ''); |
|||||||||||
1030 | } catch(Exception $e) { |
|||||||||||
1031 | $inlineRegex = false; |
|||||||||||
1032 | } |
|||||||||||
1033 | } |
|||||||||||
1034 | if (!$inlineRegex) { |
|||||||||||
0 ignored issues
–
show
The expression
$inlineRegex of type string|false is loosely compared to false ; this is ambiguous if the string can be empty. You might want to explicitly use === false instead.
In PHP, under loose comparison (like For '' == false // true
'' == null // true
'ab' == false // false
'ab' == null // false
// It is often better to use strict comparison
'' === false // false
'' === null // false
![]() |
||||||||||||
1035 | $inlineRegex = '#^(?:(?:image|text)|application/x-shockwave-flash$)#'; |
|||||||||||
1036 | } |
|||||||||||
1037 | $disp = preg_match($inlineRegex, $mime)? 'inline' : 'attachment'; |
|||||||||||
1038 | } |
|||||||||||
1039 | ||||||||||||
1040 | $filenameEncoded = rawurlencode($file['name']); |
|||||||||||
1041 | if (strpos($filenameEncoded, '%') === false) { // ASCII only |
|||||||||||
1042 | $filename = 'filename="'.$file['name'].'"'; |
|||||||||||
1043 | } else { |
|||||||||||
1044 | $ua = $_SERVER['HTTP_USER_AGENT']; |
|||||||||||
1045 | if (preg_match('/MSIE [4-8]/', $ua)) { // IE < 9 do not support RFC 6266 (RFC 2231/RFC 5987) |
|||||||||||
1046 | $filename = 'filename="'.$filenameEncoded.'"'; |
|||||||||||
1047 | } elseif (strpos($ua, 'Chrome') === false && strpos($ua, 'Safari') !== false && preg_match('#Version/[3-5]#', $ua)) { // Safari < 6 |
|||||||||||
1048 | $filename = 'filename="'.str_replace('"', '', $file['name']).'"'; |
|||||||||||
1049 | } else { // RFC 6266 (RFC 2231/RFC 5987) |
|||||||||||
1050 | $filename = 'filename*=UTF-8\'\''.$filenameEncoded; |
|||||||||||
1051 | } |
|||||||||||
1052 | } |
|||||||||||
1053 | ||||||||||||
1054 | $result = array( |
|||||||||||
1055 | 'volume' => $volume, |
|||||||||||
1056 | 'pointer' => $fp, |
|||||||||||
1057 | 'info' => $file, |
|||||||||||
1058 | 'header' => array( |
|||||||||||
1059 | 'Content-Type: '.$mime, |
|||||||||||
1060 | 'Content-Disposition: '.$disp.'; '.$filename, |
|||||||||||
1061 | 'Content-Transfer-Encoding: binary', |
|||||||||||
1062 | 'Content-Length: '.$file['size'], |
|||||||||||
1063 | 'Connection: close' |
|||||||||||
1064 | ) |
|||||||||||
1065 | ); |
|||||||||||
1066 | if (isset($file['url']) && $file['url'] && $file['url'] != 1) { |
|||||||||||
1067 | $result['header'][] = 'Content-Location: '.$file['url']; |
|||||||||||
1068 | } |
|||||||||||
1069 | return $result; |
|||||||||||
1070 | } |
|||||||||||
1071 | ||||||||||||
1072 | /** |
|||||||||||
1073 | * Count total files size |
|||||||||||
1074 | * |
|||||||||||
1075 | * @param array command arguments |
|||||||||||
1076 | * @return array |
|||||||||||
1077 | * @author Dmitry (dio) Levashov |
|||||||||||
1078 | **/ |
|||||||||||
1079 | protected function size($args) { |
|||||||||||
1080 | $size = 0; |
|||||||||||
1081 | ||||||||||||
1082 | foreach ($args['targets'] as $target) { |
|||||||||||
1083 | if (($volume = $this->volume($target)) == false |
|||||||||||
1084 | || ($file = $volume->file($target)) == false |
|||||||||||
1085 | || !$file['read']) { |
|||||||||||
1086 | return array('error' => $this->error(self::ERROR_OPEN, '#'.$target)); |
|||||||||||
1087 | } |
|||||||||||
1088 | ||||||||||||
1089 | $size += $volume->size($target); |
|||||||||||
1090 | } |
|||||||||||
1091 | return array('size' => $size); |
|||||||||||
1092 | } |
|||||||||||
1093 | ||||||||||||
1094 | /** |
|||||||||||
1095 | * Create directory |
|||||||||||
1096 | * |
|||||||||||
1097 | * @param array command arguments |
|||||||||||
1098 | * @return array |
|||||||||||
1099 | * @author Dmitry (dio) Levashov |
|||||||||||
1100 | **/ |
|||||||||||
1101 | View Code Duplication | protected function mkdir($args) { |
||||||||||
1102 | $target = $args['target']; |
|||||||||||
1103 | $name = $args['name']; |
|||||||||||
1104 | ||||||||||||
1105 | if (($volume = $this->volume($target)) == false) { |
|||||||||||
1106 | return array('error' => $this->error(self::ERROR_MKDIR, $name, self::ERROR_TRGDIR_NOT_FOUND, '#'.$target)); |
|||||||||||
1107 | } |
|||||||||||
1108 | ||||||||||||
1109 | return ($dir = $volume->mkdir($target, $name)) == false |
|||||||||||
1110 | ? array('error' => $this->error(self::ERROR_MKDIR, $name, $volume->error())) |
|||||||||||
1111 | : array('added' => array($dir)); |
|||||||||||
1112 | } |
|||||||||||
1113 | ||||||||||||
1114 | /** |
|||||||||||
1115 | * Create empty file |
|||||||||||
1116 | * |
|||||||||||
1117 | * @param array command arguments |
|||||||||||
1118 | * @return array |
|||||||||||
1119 | * @author Dmitry (dio) Levashov |
|||||||||||
1120 | **/ |
|||||||||||
1121 | View Code Duplication | protected function mkfile($args) { |
||||||||||
1122 | $target = $args['target']; |
|||||||||||
1123 | $name = $args['name']; |
|||||||||||
1124 | ||||||||||||
1125 | if (($volume = $this->volume($target)) == false) { |
|||||||||||
1126 | return array('error' => $this->error(self::ERROR_MKFILE, $name, self::ERROR_TRGDIR_NOT_FOUND, '#'.$target)); |
|||||||||||
1127 | } |
|||||||||||
1128 | ||||||||||||
1129 | return ($file = $volume->mkfile($target, $args['name'])) == false |
|||||||||||
1130 | ? array('error' => $this->error(self::ERROR_MKFILE, $name, $volume->error())) |
|||||||||||
1131 | : array('added' => array($file)); |
|||||||||||
1132 | } |
|||||||||||
1133 | ||||||||||||
1134 | /** |
|||||||||||
1135 | * Rename file |
|||||||||||
1136 | * |
|||||||||||
1137 | * @param array $args |
|||||||||||
1138 | * @return array |
|||||||||||
1139 | * @author Dmitry (dio) Levashov |
|||||||||||
1140 | **/ |
|||||||||||
1141 | protected function rename($args) { |
|||||||||||
1142 | $target = $args['target']; |
|||||||||||
1143 | $name = $args['name']; |
|||||||||||
1144 | ||||||||||||
1145 | View Code Duplication | if (($volume = $this->volume($target)) == false |
||||||||||
1146 | || ($rm = $volume->file($target)) == false) { |
|||||||||||
1147 | return array('error' => $this->error(self::ERROR_RENAME, '#'.$target, self::ERROR_FILE_NOT_FOUND)); |
|||||||||||
1148 | } |
|||||||||||
1149 | $rm['realpath'] = $volume->realpath($target); |
|||||||||||
1150 | ||||||||||||
1151 | return ($file = $volume->rename($target, $name)) == false |
|||||||||||
1152 | ? array('error' => $this->error(self::ERROR_RENAME, $rm['name'], $volume->error())) |
|||||||||||
1153 | : array('added' => array($file), 'removed' => array($rm)); |
|||||||||||
1154 | } |
|||||||||||
1155 | ||||||||||||
1156 | /** |
|||||||||||
1157 | * Duplicate file - create copy with "copy %d" suffix |
|||||||||||
1158 | * |
|||||||||||
1159 | * @param array $args command arguments |
|||||||||||
1160 | * @return array |
|||||||||||
1161 | * @author Dmitry (dio) Levashov |
|||||||||||
1162 | **/ |
|||||||||||
1163 | protected function duplicate($args) { |
|||||||||||
1164 | $targets = is_array($args['targets']) ? $args['targets'] : array(); |
|||||||||||
1165 | $result = array('added' => array()); |
|||||||||||
1166 | $suffix = empty($args['suffix']) ? 'copy' : $args['suffix']; |
|||||||||||
1167 | ||||||||||||
1168 | foreach ($targets as $target) { |
|||||||||||
1169 | View Code Duplication | if (($volume = $this->volume($target)) == false |
||||||||||
1170 | || ($src = $volume->file($target)) == false) { |
|||||||||||
1171 | $result['warning'] = $this->error(self::ERROR_COPY, '#'.$target, self::ERROR_FILE_NOT_FOUND); |
|||||||||||
1172 | break; |
|||||||||||
1173 | } |
|||||||||||
1174 | ||||||||||||
1175 | if (($file = $volume->duplicate($target, $suffix)) == false) { |
|||||||||||
1176 | $result['warning'] = $this->error($volume->error()); |
|||||||||||
1177 | break; |
|||||||||||
1178 | } |
|||||||||||
1179 | ||||||||||||
1180 | $result['added'][] = $file; |
|||||||||||
1181 | } |
|||||||||||
1182 | ||||||||||||
1183 | return $result; |
|||||||||||
1184 | } |
|||||||||||
1185 | ||||||||||||
1186 | /** |
|||||||||||
1187 | * Remove dirs/files |
|||||||||||
1188 | * |
|||||||||||
1189 | * @param array command arguments |
|||||||||||
1190 | * @return array |
|||||||||||
1191 | * @author Dmitry (dio) Levashov |
|||||||||||
1192 | **/ |
|||||||||||
1193 | protected function rm($args) { |
|||||||||||
1194 | $targets = is_array($args['targets']) ? $args['targets'] : array(); |
|||||||||||
1195 | $result = array('removed' => array()); |
|||||||||||
1196 | ||||||||||||
1197 | foreach ($targets as $target) { |
|||||||||||
1198 | View Code Duplication | if (($volume = $this->volume($target)) == false) { |
||||||||||
1199 | $result['warning'] = $this->error(self::ERROR_RM, '#'.$target, self::ERROR_FILE_NOT_FOUND); |
|||||||||||
1200 | return $result; |
|||||||||||
1201 | } |
|||||||||||
1202 | if (!$volume->rm($target)) { |
|||||||||||
1203 | $result['warning'] = $this->error($volume->error()); |
|||||||||||
1204 | return $result; |
|||||||||||
1205 | } |
|||||||||||
1206 | } |
|||||||||||
1207 | ||||||||||||
1208 | return $result; |
|||||||||||
1209 | } |
|||||||||||
1210 | ||||||||||||
1211 | /** |
|||||||||||
1212 | * Get remote contents |
|||||||||||
1213 | * |
|||||||||||
1214 | * @param string $url target url |
|||||||||||
1215 | * @param int $timeout timeout (sec) |
|||||||||||
1216 | * @param int $redirect_max redirect max count |
|||||||||||
1217 | * @param string $ua |
|||||||||||
1218 | * @param resource $fp |
|||||||||||
1219 | * @return string or bool(false) |
|||||||||||
1220 | * @retval string contents |
|||||||||||
1221 | * @retval false error |
|||||||||||
1222 | * @author Naoki Sawada |
|||||||||||
1223 | **/ |
|||||||||||
1224 | protected function get_remote_contents( &$url, $timeout = 30, $redirect_max = 5, $ua = 'Mozilla/5.0', $fp = null ) { |
|||||||||||
1225 | $method = (function_exists('curl_exec') && !ini_get('safe_mode'))? 'curl_get_contents' : 'fsock_get_contents'; |
|||||||||||
1226 | return $this->$method( $url, $timeout, $redirect_max, $ua, $fp ); |
|||||||||||
1227 | } |
|||||||||||
1228 | ||||||||||||
1229 | /** |
|||||||||||
1230 | * Get remote contents with cURL |
|||||||||||
1231 | * |
|||||||||||
1232 | * @param string $url target url |
|||||||||||
1233 | * @param int $timeout timeout (sec) |
|||||||||||
1234 | * @param int $redirect_max redirect max count |
|||||||||||
1235 | * @param string $ua |
|||||||||||
1236 | * @param resource $outfp |
|||||||||||
1237 | * @return string or bool(false) |
|||||||||||
1238 | * @retval string contents |
|||||||||||
1239 | * @retval false error |
|||||||||||
1240 | * @author Naoki Sawada |
|||||||||||
1241 | **/ |
|||||||||||
1242 | protected function curl_get_contents( &$url, $timeout, $redirect_max, $ua, $outfp ){ |
|||||||||||
1243 | $ch = curl_init(); |
|||||||||||
1244 | curl_setopt( $ch, CURLOPT_URL, $url ); |
|||||||||||
1245 | curl_setopt( $ch, CURLOPT_HEADER, false ); |
|||||||||||
1246 | if ($outfp) { |
|||||||||||
1247 | curl_setopt( $ch, CURLOPT_FILE, $outfp ); |
|||||||||||
1248 | } else { |
|||||||||||
1249 | curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true ); |
|||||||||||
1250 | curl_setopt( $ch, CURLOPT_BINARYTRANSFER, true ); |
|||||||||||
1251 | } |
|||||||||||
1252 | curl_setopt( $ch, CURLOPT_LOW_SPEED_LIMIT, 1 ); |
|||||||||||
1253 | curl_setopt( $ch, CURLOPT_LOW_SPEED_TIME, $timeout ); |
|||||||||||
1254 | curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false ); |
|||||||||||
1255 | curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, 1); |
|||||||||||
1256 | curl_setopt( $ch, CURLOPT_MAXREDIRS, $redirect_max); |
|||||||||||
1257 | curl_setopt( $ch, CURLOPT_USERAGENT, $ua); |
|||||||||||
1258 | $result = curl_exec( $ch ); |
|||||||||||
1259 | $url = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL); |
|||||||||||
1260 | curl_close( $ch ); |
|||||||||||
1261 | return $outfp? $outfp : $result; |
|||||||||||
1262 | } |
|||||||||||
1263 | ||||||||||||
1264 | /** |
|||||||||||
1265 | * Get remote contents with fsockopen() |
|||||||||||
1266 | * |
|||||||||||
1267 | * @param string $url url |
|||||||||||
1268 | * @param int $timeout timeout (sec) |
|||||||||||
1269 | * @param int $redirect_max redirect max count |
|||||||||||
1270 | * @param string $ua |
|||||||||||
1271 | * @param resource $outfp |
|||||||||||
1272 | * @return string or bool(false) |
|||||||||||
1273 | * @retval string contents |
|||||||||||
1274 | * @retval false error |
|||||||||||
1275 | * @author Naoki Sawada |
|||||||||||
1276 | */ |
|||||||||||
1277 | protected function fsock_get_contents( &$url, $timeout, $redirect_max, $ua, $outfp ) { |
|||||||||||
1278 | ||||||||||||
1279 | $connect_timeout = 3; |
|||||||||||
1280 | $connect_try = 3; |
|||||||||||
1281 | $method = 'GET'; |
|||||||||||
1282 | $readsize = 4096; |
|||||||||||
1283 | ||||||||||||
1284 | $getSize = null; |
|||||||||||
1285 | $headers = ''; |
|||||||||||
1286 | ||||||||||||
1287 | $arr = parse_url($url); |
|||||||||||
1288 | if (!$arr){ |
|||||||||||
1289 | // Bad request |
|||||||||||
1290 | return false; |
|||||||||||
0 ignored issues
–
show
The return type of
return false; (false ) is incompatible with the return type documented by elFinder::fsock_get_contents of type string .
If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design. Let’s take a look at an example: class Author {
private $name;
public function __construct($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
}
abstract class Post {
public function getAuthor() {
return 'Johannes';
}
}
class BlogPost extends Post {
public function getAuthor() {
return new Author('Johannes');
}
}
class ForumPost extends Post { /* ... */ }
function my_function(Post $post) {
echo strtoupper($post->getAuthor());
}
Our function ![]() |
||||||||||||
1291 | } |
|||||||||||
1292 | ||||||||||||
1293 | // query |
|||||||||||
1294 | $arr['query'] = isset($arr['query']) ? '?'.$arr['query'] : ''; |
|||||||||||
1295 | // port |
|||||||||||
1296 | $arr['port'] = isset($arr['port']) ? $arr['port'] : (!empty($arr['https'])? 443 : 80); |
|||||||||||
1297 | ||||||||||||
1298 | $url_base = $arr['scheme'].'://'.$arr['host'].':'.$arr['port']; |
|||||||||||
1299 | $url_path = isset($arr['path']) ? $arr['path'] : '/'; |
|||||||||||
1300 | $uri = $url_path.$arr['query']; |
|||||||||||
1301 | ||||||||||||
1302 | $query = $method.' '.$uri." HTTP/1.0\r\n"; |
|||||||||||
1303 | $query .= "Host: ".$arr['host']."\r\n"; |
|||||||||||
1304 | if (!empty($ua)) $query .= "User-Agent: ".$ua."\r\n"; |
|||||||||||
1305 | if (!is_null($getSize)) $query .= 'Range: bytes=0-' . ($getSize - 1) . "\r\n"; |
|||||||||||
1306 | ||||||||||||
1307 | $query .= $headers; |
|||||||||||
1308 | ||||||||||||
1309 | $query .= "\r\n"; |
|||||||||||
1310 | ||||||||||||
1311 | $fp = $connect_try_count = 0; |
|||||||||||
1312 | while( !$fp && $connect_try_count < $connect_try ) { |
|||||||||||
1313 | ||||||||||||
1314 | $errno = 0; |
|||||||||||
1315 | $errstr = ""; |
|||||||||||
1316 | $fp = @ fsockopen( |
|||||||||||
1317 | $arr['https'].$arr['host'], |
|||||||||||
1318 | $arr['port'], |
|||||||||||
1319 | $errno,$errstr,$connect_timeout); |
|||||||||||
1320 | if ($fp) break; |
|||||||||||
1321 | $connect_try_count++; |
|||||||||||
1322 | if (connection_aborted()) { |
|||||||||||
1323 | exit(); |
|||||||||||
0 ignored issues
–
show
The method
fsock_get_contents() contains an exit expression.
An exit expression should only be used in rare cases. For example, if you write a short command line script. In most cases however, using an ![]() |
||||||||||||
1324 | } |
|||||||||||
1325 | sleep(1); // wait 1sec |
|||||||||||
1326 | } |
|||||||||||
1327 | ||||||||||||
1328 | $fwrite = 0; |
|||||||||||
0 ignored issues
–
show
$fwrite is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
||||||||||||
1329 | for ($written = 0; $written < strlen($query); $written += $fwrite) { |
|||||||||||
1330 | $fwrite = fwrite($fp, substr($query, $written)); |
|||||||||||
1331 | if (!$fwrite) { |
|||||||||||
1332 | break; |
|||||||||||
1333 | } |
|||||||||||
1334 | } |
|||||||||||
1335 | ||||||||||||
1336 | $response = ''; |
|||||||||||
0 ignored issues
–
show
$response is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
||||||||||||
1337 | ||||||||||||
1338 | if ($timeout) { |
|||||||||||
1339 | socket_set_timeout($fp, $timeout); |
|||||||||||
1340 | } |
|||||||||||
1341 | ||||||||||||
1342 | $_response = ''; |
|||||||||||
1343 | $header = ''; |
|||||||||||
1344 | while($_response !== "\r\n"){ |
|||||||||||
1345 | $_response = fgets($fp, $readsize); |
|||||||||||
1346 | $header .= $_response; |
|||||||||||
1347 | }; |
|||||||||||
1348 | ||||||||||||
1349 | $rccd = array_pad(explode(' ',$header,3), 3, ''); // array('HTTP/1.1','200','OK\r\n...') |
|||||||||||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
89% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them. ![]() |
||||||||||||
1350 | $rc = (int)$rccd[1]; |
|||||||||||
1351 | ||||||||||||
1352 | // Redirect |
|||||||||||
1353 | switch ($rc) { |
|||||||||||
1354 | case 307: // Temporary Redirect |
|||||||||||
1355 | case 303: // See Other |
|||||||||||
1356 | case 302: // Moved Temporarily |
|||||||||||
1357 | case 301: // Moved Permanently |
|||||||||||
1358 | $matches = array(); |
|||||||||||
1359 | if (preg_match('/^Location: (.+?)(#.+)?$/im',$header,$matches) && --$redirect_max > 0) { |
|||||||||||
1360 | $url = trim($matches[1]); |
|||||||||||
1361 | $hash = isset($matches[2])? trim($matches[2]) : ''; |
|||||||||||
0 ignored issues
–
show
$hash is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
||||||||||||
1362 | if (!preg_match('/^https?:\//',$url)) { // no scheme |
|||||||||||
1363 | if ($url{0} != '/') { // Relative path |
|||||||||||
1364 | // to Absolute path |
|||||||||||
1365 | $url = substr($url_path,0,strrpos($url_path,'/')).'/'.$url; |
|||||||||||
1366 | } |
|||||||||||
1367 | // add sheme,host |
|||||||||||
1368 | $url = $url_base.$url; |
|||||||||||
1369 | } |
|||||||||||
1370 | fclose($fp); |
|||||||||||
1371 | return $this->fsock_get_contents( $url, $timeout, $redirect_max, $ua, $outfp ); |
|||||||||||
1372 | } |
|||||||||||
1373 | } |
|||||||||||
1374 | ||||||||||||
1375 | $body = ''; |
|||||||||||
1376 | if (!$outfp) { |
|||||||||||
1377 | $outfp = fopen('php://temp', 'rwb'); |
|||||||||||
1378 | $body = true; |
|||||||||||
1379 | } |
|||||||||||
1380 | while(fwrite($outfp, fread($fp, $readsize))) { |
|||||||||||
1381 | if ($timeout) { |
|||||||||||
1382 | $_status = socket_get_status($fp); |
|||||||||||
1383 | if ($_status['timed_out']) { |
|||||||||||
1384 | fclose($outfp); |
|||||||||||
1385 | fclose($fp); |
|||||||||||
1386 | return false; // Request Time-out |
|||||||||||
0 ignored issues
–
show
The return type of
return false; (false ) is incompatible with the return type documented by elFinder::fsock_get_contents of type string .
If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design. Let’s take a look at an example: class Author {
private $name;
public function __construct($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
}
abstract class Post {
public function getAuthor() {
return 'Johannes';
}
}
class BlogPost extends Post {
public function getAuthor() {
return new Author('Johannes');
}
}
class ForumPost extends Post { /* ... */ }
function my_function(Post $post) {
echo strtoupper($post->getAuthor());
}
Our function ![]() |
||||||||||||
1387 | } |
|||||||||||
1388 | } |
|||||||||||
1389 | } |
|||||||||||
1390 | if ($body) { |
|||||||||||
1391 | rewind($outfp); |
|||||||||||
1392 | $body = stream_get_contents($outfp); |
|||||||||||
1393 | fclose($outfp); |
|||||||||||
1394 | $outfp = null; |
|||||||||||
1395 | } |
|||||||||||
1396 | ||||||||||||
1397 | fclose($fp); |
|||||||||||
1398 | ||||||||||||
1399 | return $outfp? $outfp : $body; // Data |
|||||||||||
0 ignored issues
–
show
|
||||||||||||
1400 | } |
|||||||||||
1401 | ||||||||||||
1402 | /** |
|||||||||||
1403 | * Parse Data URI scheme |
|||||||||||
1404 | * |
|||||||||||
1405 | * @param string $str |
|||||||||||
1406 | * @param array $extTable |
|||||||||||
1407 | * @return array |
|||||||||||
1408 | * @author Naoki Sawada |
|||||||||||
1409 | */ |
|||||||||||
1410 | protected function parse_data_scheme( $str, $extTable ) { |
|||||||||||
1411 | $data = $name = ''; |
|||||||||||
1412 | if ($fp = fopen('data://'.substr($str, 5), 'rb')) { |
|||||||||||
1413 | View Code Duplication | if ($data = stream_get_contents($fp)) { |
||||||||||
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
||||||||||||
1414 | $meta = stream_get_meta_data($fp); |
|||||||||||
1415 | $ext = isset($extTable[$meta['mediatype']])? '.' . $extTable[$meta['mediatype']] : ''; |
|||||||||||
1416 | $name = substr(md5($data), 0, 8) . $ext; |
|||||||||||
1417 | } |
|||||||||||
1418 | fclose($fp); |
|||||||||||
1419 | } |
|||||||||||
1420 | return array($data, $name); |
|||||||||||
1421 | } |
|||||||||||
1422 | ||||||||||||
1423 | /** |
|||||||||||
1424 | * Detect file type extension by local path |
|||||||||||
1425 | * |
|||||||||||
1426 | * @param string $path Local path |
|||||||||||
1427 | * @return string file type extension with dot |
|||||||||||
1428 | * @author Naoki Sawada |
|||||||||||
1429 | */ |
|||||||||||
1430 | protected function detectFileExtension($path) { |
|||||||||||
1431 | static $type, $finfo, $extTable; |
|||||||||||
1432 | if (!$type) { |
|||||||||||
1433 | $keys = array_keys($this->volumes); |
|||||||||||
1434 | $volume = $this->volumes[$keys[0]]; |
|||||||||||
1435 | $extTable = array_flip(array_unique($volume->getMimeTable())); |
|||||||||||
1436 | ||||||||||||
1437 | if (class_exists('finfo', false)) { |
|||||||||||
1438 | $tmpFileInfo = @explode(';', @finfo_file(finfo_open(FILEINFO_MIME), __FILE__)); |
|||||||||||
1439 | } else { |
|||||||||||
1440 | $tmpFileInfo = false; |
|||||||||||
1441 | } |
|||||||||||
1442 | $regexp = '/text\/x\-(php|c\+\+)/'; |
|||||||||||
1443 | if ($tmpFileInfo && preg_match($regexp, array_shift($tmpFileInfo))) { |
|||||||||||
1444 | $type = 'finfo'; |
|||||||||||
1445 | $finfo = finfo_open(FILEINFO_MIME); |
|||||||||||
1446 | } elseif (function_exists('mime_content_type') |
|||||||||||
1447 | && preg_match($regexp, array_shift(explode(';', mime_content_type(__FILE__))))) { |
|||||||||||
0 ignored issues
–
show
|
||||||||||||
1448 | $type = 'mime_content_type'; |
|||||||||||
1449 | } elseif (function_exists('getimagesize')) { |
|||||||||||
1450 | $type = 'getimagesize'; |
|||||||||||
1451 | } else { |
|||||||||||
1452 | $type = 'none'; |
|||||||||||
1453 | } |
|||||||||||
1454 | } |
|||||||||||
1455 | ||||||||||||
1456 | $mime = ''; |
|||||||||||
1457 | if ($type === 'finfo') { |
|||||||||||
1458 | $mime = @finfo_file($finfo, $path); |
|||||||||||
1459 | } elseif ($type === 'mime_content_type') { |
|||||||||||
1460 | $mime = mime_content_type($path); |
|||||||||||
1461 | } elseif ($type === 'getimagesize') { |
|||||||||||
1462 | if ($img = @getimagesize($path)) { |
|||||||||||
1463 | $mime = $img['mime']; |
|||||||||||
1464 | } |
|||||||||||
1465 | } |
|||||||||||
1466 | ||||||||||||
1467 | if ($mime) { |
|||||||||||
1468 | $mime = explode(';', $mime); |
|||||||||||
1469 | $mime = trim($mime[0]); |
|||||||||||
1470 | ||||||||||||
1471 | View Code Duplication | if (in_array($mime, array('application/x-empty', 'inode/x-empty'))) { |
||||||||||
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
||||||||||||
1472 | // finfo return this mime for empty files |
|||||||||||
1473 | $mime = 'text/plain'; |
|||||||||||
1474 | } elseif ($mime == 'application/x-zip') { |
|||||||||||
1475 | // http://elrte.org/redmine/issues/163 |
|||||||||||
1476 | $mime = 'application/zip'; |
|||||||||||
1477 | } |
|||||||||||
1478 | } |
|||||||||||
1479 | ||||||||||||
1480 | return ($mime && isset($extTable[$mime]))? ('.' . $extTable[$mime]) : ''; |
|||||||||||
1481 | } |
|||||||||||
1482 | ||||||||||||
1483 | /** |
|||||||||||
1484 | * Get temporary dirctroy path |
|||||||||||
1485 | * |
|||||||||||
1486 | * @param string $volumeTempPath |
|||||||||||
1487 | * @return string |
|||||||||||
1488 | * @author Naoki Sawada |
|||||||||||
1489 | */ |
|||||||||||
1490 | private function getTempDir($volumeTempPath = null) { |
|||||||||||
1491 | $testDirs = array(); |
|||||||||||
1492 | if ($this->uploadTempPath) { |
|||||||||||
1493 | $testDirs[] = rtrim(realpath($this->uploadTempPath), DIRECTORY_SEPARATOR); |
|||||||||||
1494 | } |
|||||||||||
1495 | if ($volumeTempPath) { |
|||||||||||
0 ignored issues
–
show
The expression
$volumeTempPath of type string|null is loosely compared to true ; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.
In PHP, under loose comparison (like For '' == false // true
'' == null // true
'ab' == false // false
'ab' == null // false
// It is often better to use strict comparison
'' === false // false
'' === null // false
![]() |
||||||||||||
1496 | $testDirs[] = rtrim(realpath($volumeTempPath), DIRECTORY_SEPARATOR); |
|||||||||||
1497 | } |
|||||||||||
1498 | if (function_exists('sys_get_temp_dir')) { |
|||||||||||
1499 | $testDirs[] = sys_get_temp_dir(); |
|||||||||||
1500 | } |
|||||||||||
1501 | $tempDir = ''; |
|||||||||||
1502 | foreach($testDirs as $testDir) { |
|||||||||||
1503 | if (!$testDir || !is_dir($testDir)) continue; |
|||||||||||
1504 | if (is_writable($testDir)) { |
|||||||||||
1505 | $tempDir = $testDir; |
|||||||||||
1506 | $gc = time() - 3600; |
|||||||||||
1507 | foreach(glob($tempDir . DIRECTORY_SEPARATOR .'ELF*') as $cf) { |
|||||||||||
1508 | if (filemtime($cf) < $gc) { |
|||||||||||
1509 | @unlink($cf); |
|||||||||||
0 ignored issues
–
show
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
![]() |
||||||||||||
1510 | } |
|||||||||||
1511 | } |
|||||||||||
1512 | break; |
|||||||||||
1513 | } |
|||||||||||
1514 | } |
|||||||||||
1515 | return $tempDir; |
|||||||||||
1516 | } |
|||||||||||
1517 | ||||||||||||
1518 | /** |
|||||||||||
1519 | * chmod |
|||||||||||
1520 | * |
|||||||||||
1521 | * @param array command arguments |
|||||||||||
1522 | * @return array |
|||||||||||
1523 | * @author David Bartle |
|||||||||||
1524 | **/ |
|||||||||||
1525 | protected function chmod($args) { |
|||||||||||
1526 | $targets = $args['targets']; |
|||||||||||
1527 | $mode = intval((string)$args['mode'], 8); |
|||||||||||
1528 | ||||||||||||
1529 | if (!is_array($targets)) { |
|||||||||||
1530 | $targets = array($targets); |
|||||||||||
1531 | } |
|||||||||||
1532 | ||||||||||||
1533 | $result = array(); |
|||||||||||
1534 | ||||||||||||
1535 | View Code Duplication | if (($volume = $this->volume($targets[0])) == false) { |
||||||||||
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
||||||||||||
1536 | $result['error'] = $this->error(self::ERROR_CONF_NO_VOL); |
|||||||||||
1537 | return $result; |
|||||||||||
1538 | } |
|||||||||||
1539 | ||||||||||||
1540 | $files = array(); |
|||||||||||
1541 | $errors = array(); |
|||||||||||
1542 | foreach($targets as $target) { |
|||||||||||
1543 | $file = $volume->chmod($target, $mode); |
|||||||||||
1544 | if ($file) { |
|||||||||||
1545 | $files = array_merge($files, is_array($file)? $file : array($file)); |
|||||||||||
1546 | } else { |
|||||||||||
1547 | $errors = array_merge($errors, $volume->error()); |
|||||||||||
1548 | } |
|||||||||||
1549 | } |
|||||||||||
1550 | ||||||||||||
1551 | if ($files) { |
|||||||||||
0 ignored issues
–
show
The expression
$files of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using ![]() |
||||||||||||
1552 | $result['changed'] = $files; |
|||||||||||
1553 | if ($errors) { |
|||||||||||
0 ignored issues
–
show
The expression
$errors of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using ![]() |
||||||||||||
1554 | $result['warning'] = $this->error($errors); |
|||||||||||
1555 | } |
|||||||||||
1556 | } else { |
|||||||||||
1557 | $result['error'] = $this->error($errors); |
|||||||||||
1558 | } |
|||||||||||
1559 | ||||||||||||
1560 | return $result; |
|||||||||||
1561 | } |
|||||||||||
1562 | ||||||||||||
1563 | /** |
|||||||||||
1564 | * Check chunked upload files |
|||||||||||
1565 | * |
|||||||||||
1566 | * @param string $tmpname uploaded temporary file path |
|||||||||||
1567 | * @param string $chunk uploaded chunk file name |
|||||||||||
1568 | * @param string $cid uploaded chunked file id |
|||||||||||
1569 | * @param string $tempDir temporary dirctroy path |
|||||||||||
1570 | * @return array (string JoinedTemporaryFilePath, string FileName) or (empty, empty) |
|||||||||||
1571 | * @author Naoki Sawada |
|||||||||||
1572 | */ |
|||||||||||
1573 | private function checkChunkedFile($tmpname, $chunk, $cid, $tempDir, $volume = null) { |
|||||||||||
0 ignored issues
–
show
checkChunkedFile uses the super-global variable $_POST which is generally not recommended.
Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable: // Bad
class Router
{
public function generate($path)
{
return $_SERVER['HOST'].$path;
}
}
// Better
class Router
{
private $host;
public function __construct($host)
{
$this->host = $host;
}
public function generate($path)
{
return $this->host.$path;
}
}
class Controller
{
public function myAction(Request $request)
{
// Instead of
$page = isset($_GET['page']) ? intval($_GET['page']) : 1;
// Better (assuming you use the Symfony2 request)
$page = $request->query->get('page', 1);
}
}
![]() |
||||||||||||
1574 | if (preg_match('/^(.+)(\.\d+_(\d+))\.part$/s', $chunk, $m)) { |
|||||||||||
1575 | $fname = $m[1]; |
|||||||||||
1576 | $encname = md5($cid . '_' . $fname); |
|||||||||||
1577 | $base = $tempDir . DIRECTORY_SEPARATOR . 'ELF' . $encname; |
|||||||||||
1578 | $clast = intval($m[3]); |
|||||||||||
1579 | if (is_null($tmpname)) { |
|||||||||||
1580 | ignore_user_abort(true); |
|||||||||||
1581 | sleep(10); // wait 10 sec |
|||||||||||
1582 | // chunked file upload fail |
|||||||||||
1583 | foreach(glob($base . '*') as $cf) { |
|||||||||||
1584 | @unlink($cf); |
|||||||||||
0 ignored issues
–
show
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
![]() |
||||||||||||
1585 | } |
|||||||||||
1586 | ignore_user_abort(false); |
|||||||||||
1587 | return; |
|||||||||||
1588 | } |
|||||||||||
1589 | ||||||||||||
1590 | $range = isset($_POST['range'])? trim($_POST['range']) : ''; |
|||||||||||
1591 | if ($range && preg_match('/^(\d+),(\d+),(\d+)$/', $range, $ranges)) { |
|||||||||||
1592 | $start = $ranges[1]; |
|||||||||||
1593 | $len = $ranges[2]; |
|||||||||||
1594 | $size = $ranges[3]; |
|||||||||||
1595 | $tmp = $base . '.part'; |
|||||||||||
1596 | $csize = filesize($tmpname); |
|||||||||||
1597 | ||||||||||||
1598 | $tmpExists = is_file($tmp); |
|||||||||||
1599 | if (!$tmpExists) { |
|||||||||||
1600 | // check upload max size |
|||||||||||
1601 | $uploadMaxSize = $volume->getUploadMaxSize(); |
|||||||||||
1602 | if ($uploadMaxSize > 0 && $size > $uploadMaxSize) { |
|||||||||||
1603 | return array(self::ERROR_UPLOAD_FILE_SIZE, false); |
|||||||||||
1604 | } |
|||||||||||
1605 | // make temp file |
|||||||||||
1606 | $ok = false; |
|||||||||||
1607 | if ($fp = fopen($tmp, 'wb')) { |
|||||||||||
1608 | flock($fp, LOCK_EX); |
|||||||||||
1609 | $ok = ftruncate($fp, $size); |
|||||||||||
1610 | flock($fp, LOCK_UN); |
|||||||||||
1611 | fclose($fp); |
|||||||||||
1612 | touch($base); |
|||||||||||
1613 | } |
|||||||||||
1614 | if (!$ok) { |
|||||||||||
1615 | unlink($tmp); |
|||||||||||
1616 | return array(self::ERROR_UPLOAD_TEMP, false); |
|||||||||||
1617 | } |
|||||||||||
1618 | } else { |
|||||||||||
1619 | // wait until makeing temp file (for anothor session) |
|||||||||||
1620 | $cnt = 1200; // Time limit 120 sec |
|||||||||||
1621 | while(!is_file($base) && --$cnt) { |
|||||||||||
1622 | usleep(100000); // wait 100ms |
|||||||||||
1623 | } |
|||||||||||
1624 | if (!$cnt) { |
|||||||||||
1625 | return array(self::ERROR_UPLOAD_TEMP, false); |
|||||||||||
1626 | } |
|||||||||||
1627 | } |
|||||||||||
1628 | ||||||||||||
1629 | // check size info |
|||||||||||
1630 | if ($len != $csize || $start + $len > $size || ($tmpExists && $size != filesize($tmp))) { |
|||||||||||
1631 | return array(self::ERROR_UPLOAD_TEMP, false); |
|||||||||||
1632 | } |
|||||||||||
1633 | ||||||||||||
1634 | // write chunk data |
|||||||||||
1635 | $writelen = 0; |
|||||||||||
0 ignored issues
–
show
$writelen is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
||||||||||||
1636 | $src = fopen($tmpname, 'rb'); |
|||||||||||
1637 | $fp = fopen($tmp, 'cb'); |
|||||||||||
1638 | fseek($fp, $start); |
|||||||||||
1639 | $writelen = stream_copy_to_stream($src, $fp, $len); |
|||||||||||
1640 | fclose($fp); |
|||||||||||
1641 | fclose($src); |
|||||||||||
1642 | if ($writelen != $len) { |
|||||||||||
1643 | return array(self::ERROR_UPLOAD_TEMP, false); |
|||||||||||
1644 | } |
|||||||||||
1645 | ||||||||||||
1646 | // write counts |
|||||||||||
1647 | file_put_contents($base, "\0", FILE_APPEND | LOCK_EX); |
|||||||||||
1648 | ||||||||||||
1649 | if (filesize($base) >= $clast + 1) { |
|||||||||||
1650 | // Completion |
|||||||||||
1651 | unlink($base); |
|||||||||||
1652 | return array($tmp, $fname); |
|||||||||||
1653 | } |
|||||||||||
1654 | } else { |
|||||||||||
1655 | // old way |
|||||||||||
1656 | $part = $base . $m[2]; |
|||||||||||
1657 | if (move_uploaded_file($tmpname, $part)) { |
|||||||||||
1658 | @chmod($part, 0600); |
|||||||||||
0 ignored issues
–
show
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
![]() |
||||||||||||
1659 | if ($clast < count(glob($base . '*'))) { |
|||||||||||
1660 | $parts = array(); |
|||||||||||
1661 | for ($i = 0; $i <= $clast; $i++) { |
|||||||||||
1662 | $name = $base . '.' . $i . '_' . $clast; |
|||||||||||
1663 | if (is_readable($name)) { |
|||||||||||
1664 | $parts[] = $name; |
|||||||||||
1665 | } else { |
|||||||||||
1666 | $parts = null; |
|||||||||||
1667 | break; |
|||||||||||
1668 | } |
|||||||||||
1669 | } |
|||||||||||
1670 | if ($parts) { |
|||||||||||
1671 | if (!is_file($base)) { |
|||||||||||
1672 | touch($base); |
|||||||||||
1673 | if ($resfile = tempnam($tempDir, 'ELF')) { |
|||||||||||
1674 | $target = fopen($resfile, 'wb'); |
|||||||||||
1675 | foreach($parts as $f) { |
|||||||||||
1676 | $fp = fopen($f, 'rb'); |
|||||||||||
1677 | while (!feof($fp)) { |
|||||||||||
1678 | fwrite($target, fread($fp, 8192)); |
|||||||||||
1679 | } |
|||||||||||
1680 | fclose($fp); |
|||||||||||
1681 | unlink($f); |
|||||||||||
1682 | } |
|||||||||||
1683 | fclose($target); |
|||||||||||
1684 | unlink($base); |
|||||||||||
1685 | return array($resfile, $fname); |
|||||||||||
1686 | } |
|||||||||||
1687 | unlink($base); |
|||||||||||
1688 | } |
|||||||||||
1689 | } |
|||||||||||
1690 | } |
|||||||||||
1691 | } |
|||||||||||
1692 | } |
|||||||||||
1693 | } |
|||||||||||
1694 | return array('', ''); |
|||||||||||
1695 | } |
|||||||||||
1696 | ||||||||||||
1697 | /** |
|||||||||||
1698 | * Save uploaded files |
|||||||||||
1699 | * |
|||||||||||
1700 | * @param array |
|||||||||||
1701 | * @return array |
|||||||||||
1702 | * @author Dmitry (dio) Levashov |
|||||||||||
1703 | **/ |
|||||||||||
1704 | protected function upload($args) { |
|||||||||||
1705 | $ngReg = '/[\/\\?*:|"<>]/'; |
|||||||||||
1706 | $target = $args['target']; |
|||||||||||
1707 | $volume = $this->volume($target); |
|||||||||||
1708 | $files = isset($args['FILES']['upload']) && is_array($args['FILES']['upload']) ? $args['FILES']['upload'] : array(); |
|||||||||||
1709 | $header = empty($args['html']) ? array() : array('header' => 'Content-Type: text/html; charset=utf-8'); |
|||||||||||
1710 | $result = array_merge(array('added' => array()), $header); |
|||||||||||
1711 | $paths = $args['upload_path']? $args['upload_path'] : array(); |
|||||||||||
1712 | $chunk = $args['chunk']? $args['chunk'] : ''; |
|||||||||||
1713 | $cid = $args['cid']? (int)$args['cid'] : ''; |
|||||||||||
1714 | ||||||||||||
1715 | $renames= array(); |
|||||||||||
1716 | $suffix = '~'; |
|||||||||||
1717 | if ($args['renames'] && is_array($args['renames'])) { |
|||||||||||
1718 | $renames = array_flip($args['renames']); |
|||||||||||
1719 | View Code Duplication | if (is_string($args['suffix']) && ! preg_match($ngReg, $args['suffix'])) { |
||||||||||
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
||||||||||||
1720 | $suffix = $args['suffix']; |
|||||||||||
1721 | } |
|||||||||||
1722 | } |
|||||||||||
1723 | ||||||||||||
1724 | if (!$volume) { |
|||||||||||
1725 | return array_merge(array('error' => $this->error(self::ERROR_UPLOAD, self::ERROR_TRGDIR_NOT_FOUND, '#'.$target)), $header); |
|||||||||||
1726 | } |
|||||||||||
1727 | ||||||||||||
1728 | // regist Shutdown function |
|||||||||||
1729 | $GLOBALS['elFinderTempFiles'] = array(); |
|||||||||||
1730 | // if (version_compare(PHP_VERSION, '5.3.0', '>=')) { |
|||||||||||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
57% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them. ![]() |
||||||||||||
1731 | // $shutdownfunc = function(){ // <- Parse error on PHP < 5.3 ;-( |
|||||||||||
1732 | // foreach(array_keys($GLOBALS['elFinderTempFiles']) as $f){ |
|||||||||||
1733 | // @unlink($f); |
|||||||||||
1734 | // } |
|||||||||||
1735 | // }; |
|||||||||||
1736 | // } else { |
|||||||||||
1737 | $shutdownfunc = create_function('', ' |
|||||||||||
0 ignored issues
–
show
The use of
create_function is highly discouraged, better use a closure.
// Instead of
$function = create_function('$a, $b', 'return $a + $b');
// Better use
$function = function($a, $b) { return $a + $b; }
![]() |
||||||||||||
1738 | foreach(array_keys($GLOBALS[\'elFinderTempFiles\']) as $f){ |
|||||||||||
1739 | @unlink($f); |
|||||||||||
1740 | } |
|||||||||||
1741 | '); |
|||||||||||
1742 | // } |
|||||||||||
1743 | register_shutdown_function($shutdownfunc); |
|||||||||||
1744 | ||||||||||||
1745 | // file extentions table by MIME |
|||||||||||
1746 | $extTable = array_flip(array_unique($volume->getMimeTable())); |
|||||||||||
1747 | ||||||||||||
1748 | if (empty($files)) { |
|||||||||||
1749 | if (!$args['upload'] && $args['name'] && is_array($args['name'])) { |
|||||||||||
1750 | $error = ''; |
|||||||||||
1751 | $result['name'] = array(); |
|||||||||||
1752 | foreach($args['name'] as $_i => $_name) { |
|||||||||||
1753 | if (!$volume->isUploadableByName($_name)) { |
|||||||||||
1754 | $error = $this->error(self::ERROR_UPLOAD_FILE, $_name, self::ERROR_UPLOAD_FILE_MIME); |
|||||||||||
1755 | break; |
|||||||||||
1756 | } |
|||||||||||
1757 | $result['name'][$_i] = preg_replace($ngReg, '_', $_name); |
|||||||||||
1758 | } |
|||||||||||
1759 | if ($error) { |
|||||||||||
1760 | $result['error'] = $error; |
|||||||||||
1761 | return $result; |
|||||||||||
1762 | } |
|||||||||||
1763 | $result = array_merge_recursive($result, $this->ls($args)); |
|||||||||||
1764 | if (empty($result['list'])) { |
|||||||||||
1765 | $result['name'] = array(); |
|||||||||||
1766 | } else { |
|||||||||||
1767 | $result['name'] = array_merge(array_intersect($result['name'], $result['list'])); |
|||||||||||
1768 | } |
|||||||||||
1769 | return $result; |
|||||||||||
1770 | } |
|||||||||||
1771 | if (isset($args['upload']) && is_array($args['upload']) && ($tempDir = $this->getTempDir($volume->getTempPath()))) { |
|||||||||||
1772 | $names = array(); |
|||||||||||
1773 | foreach($args['upload'] as $i => $url) { |
|||||||||||
1774 | // check chunked file upload commit |
|||||||||||
1775 | if ($args['chunk']) { |
|||||||||||
1776 | if ($url === 'chunkfail' && $args['mimes'] === 'chunkfail') { |
|||||||||||
1777 | $this->checkChunkedFile(null, $chunk, $cid, $tempDir); |
|||||||||||
1778 | if (preg_match('/^(.+)(\.\d+_(\d+))\.part$/s', $chunk, $m)) { |
|||||||||||
1779 | $result['warning'] = $this->error(self::ERROR_UPLOAD_FILE, $m[1], self::ERROR_UPLOAD_TRANSFER); |
|||||||||||
1780 | } |
|||||||||||
1781 | return $result; |
|||||||||||
1782 | } else { |
|||||||||||
1783 | $tmpfname = $tempDir . '/' . $args['chunk']; |
|||||||||||
1784 | $files['tmp_name'][$i] = $tmpfname; |
|||||||||||
1785 | $files['name'][$i] = $url; |
|||||||||||
1786 | $files['error'][$i] = 0; |
|||||||||||
1787 | $GLOBALS['elFinderTempFiles'][$tmpfname] = true; |
|||||||||||
1788 | break; |
|||||||||||
1789 | } |
|||||||||||
1790 | } |
|||||||||||
1791 | ||||||||||||
1792 | $tmpfname = $tempDir . DIRECTORY_SEPARATOR . 'ELF_FATCH_' . md5($url.microtime(true)); |
|||||||||||
1793 | ||||||||||||
1794 | $_name = ''; |
|||||||||||
1795 | // check is data: |
|||||||||||
1796 | if (substr($url, 0, 5) === 'data:') { |
|||||||||||
1797 | list($data, $args['name'][$i]) = $this->parse_data_scheme($url, $extTable); |
|||||||||||
1798 | } else { |
|||||||||||
1799 | $fp = fopen($tmpfname, 'wb'); |
|||||||||||
1800 | $data = $this->get_remote_contents($url, 30, 5, 'Mozilla/5.0', $fp); |
|||||||||||
1801 | $_POST['overwrite'] = false; |
|||||||||||
1802 | $_name = preg_replace('~^.*?([^/#?]+)(?:\?.*)?(?:#.*)?$~', '$1', rawurldecode($url)); |
|||||||||||
1803 | // Check `Content-Disposition` response header |
|||||||||||
1804 | if ($data && ($headers = get_headers($url, true)) && !empty($headers['Content-Disposition'])) { |
|||||||||||
1805 | if (preg_match('/filename\*?=(?:(.+?)\'\')?"?([a-z0-9_.~%-]+)"?/i', $headers['Content-Disposition'], $m)) { |
|||||||||||
1806 | $_name = rawurldecode($m[2]); |
|||||||||||
1807 | if ($m[1] && strtoupper($m[1]) !== 'UTF-8' && function_exists('mb_convert_encoding')) { |
|||||||||||
1808 | $_name = mb_convert_encoding($_name, 'UTF-8', $m[1]); |
|||||||||||
1809 | } |
|||||||||||
1810 | } |
|||||||||||
1811 | } |
|||||||||||
1812 | } |
|||||||||||
1813 | if ($data) { |
|||||||||||
1814 | if (isset($args['name'][$i])) { |
|||||||||||
1815 | $_name = $args['name'][$i]; |
|||||||||||
1816 | } |
|||||||||||
1817 | if ($_name) { |
|||||||||||
1818 | $_ext = ''; |
|||||||||||
1819 | if (preg_match('/(\.[a-z0-9]{1,7})$/', $_name, $_match)) { |
|||||||||||
1820 | $_ext = $_match[1]; |
|||||||||||
1821 | } |
|||||||||||
1822 | if ((is_resource($data) && fclose($data)) || file_put_contents($tmpfname, $data)) { |
|||||||||||
1823 | $GLOBALS['elFinderTempFiles'][$tmpfname] = true; |
|||||||||||
1824 | $_name = preg_replace($ngReg, '_', $_name); |
|||||||||||
1825 | list($_a, $_b) = array_pad(explode('.', $_name, 2), 2, ''); |
|||||||||||
1826 | if ($_b === '') { |
|||||||||||
1827 | if ($_ext) { |
|||||||||||
1828 | rename($tmpfname, $tmpfname . $_ext); |
|||||||||||
1829 | $tmpfname = $tmpfname . $_ext; |
|||||||||||
1830 | } |
|||||||||||
1831 | $_b = $this->detectFileExtension($tmpfname); |
|||||||||||
1832 | $_name = $_a.$_b; |
|||||||||||
1833 | } else { |
|||||||||||
1834 | $_b = '.'.$_b; |
|||||||||||
1835 | } |
|||||||||||
1836 | if (isset($names[$_name])) { |
|||||||||||
1837 | $_name = $_a.'_'.$names[$_name]++.$_b; |
|||||||||||
1838 | } else { |
|||||||||||
1839 | $names[$_name] = 1; |
|||||||||||
1840 | } |
|||||||||||
1841 | $files['tmp_name'][$i] = $tmpfname; |
|||||||||||
1842 | $files['name'][$i] = $_name; |
|||||||||||
1843 | $files['error'][$i] = 0; |
|||||||||||
1844 | } else { |
|||||||||||
1845 | @ unlink($tmpfname); |
|||||||||||
0 ignored issues
–
show
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
![]() |
||||||||||||
1846 | } |
|||||||||||
1847 | } |
|||||||||||
1848 | } |
|||||||||||
1849 | } |
|||||||||||
1850 | } |
|||||||||||
1851 | if (empty($files)) { |
|||||||||||
1852 | return array_merge(array('error' => $this->error(self::ERROR_UPLOAD, self::ERROR_UPLOAD_NO_FILES)), $header); |
|||||||||||
1853 | } |
|||||||||||
1854 | } |
|||||||||||
1855 | ||||||||||||
1856 | foreach ($files['name'] as $i => $name) { |
|||||||||||
1857 | if (($error = $files['error'][$i]) > 0) { |
|||||||||||
1858 | $result['warning'] = $this->error(self::ERROR_UPLOAD_FILE, $name, $error == UPLOAD_ERR_INI_SIZE || $error == UPLOAD_ERR_FORM_SIZE ? self::ERROR_UPLOAD_FILE_SIZE : self::ERROR_UPLOAD_TRANSFER); |
|||||||||||
1859 | $this->uploadDebug = 'Upload error code: '.$error; |
|||||||||||
1860 | break; |
|||||||||||
1861 | } |
|||||||||||
1862 | ||||||||||||
1863 | $tmpname = $files['tmp_name'][$i]; |
|||||||||||
1864 | $path = ($paths && !empty($paths[$i]))? $paths[$i] : ''; |
|||||||||||
1865 | if ($name === 'blob') { |
|||||||||||
1866 | if ($chunk) { |
|||||||||||
1867 | if ($tempDir = $this->getTempDir($volume->getTempPath())) { |
|||||||||||
1868 | list($tmpname, $name) = $this->checkChunkedFile($tmpname, $chunk, $cid, $tempDir, $volume); |
|||||||||||
1869 | if ($tmpname) { |
|||||||||||
1870 | if ($name === false) { |
|||||||||||
1871 | preg_match('/^(.+)(\.\d+_(\d+))\.part$/s', $chunk, $m); |
|||||||||||
1872 | $result['error'] = $this->error(self::ERROR_UPLOAD_FILE, $m[1], $tmpname); |
|||||||||||
1873 | $result['_chunkfailure'] = true; |
|||||||||||
1874 | $this->uploadDebug = 'Upload error: ' . $tmpname; |
|||||||||||
1875 | } else if ($name) { |
|||||||||||
1876 | $result['_chunkmerged'] = basename($tmpname); |
|||||||||||
1877 | $result['_name'] = $name; |
|||||||||||
1878 | } |
|||||||||||
1879 | } |
|||||||||||
1880 | } else { |
|||||||||||
1881 | $result['error'] = $this->error(self::ERROR_UPLOAD_FILE, $chunk, self::ERROR_UPLOAD_TRANSFER); |
|||||||||||
1882 | $this->uploadDebug = 'Upload error: unable open tmp file'; |
|||||||||||
1883 | } |
|||||||||||
1884 | return $result; |
|||||||||||
1885 | View Code Duplication | } else { |
||||||||||
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
||||||||||||
1886 | // for form clipboard with Google Chrome |
|||||||||||
1887 | $type = $files['type'][$i]; |
|||||||||||
1888 | $ext = isset($extTable[$type])? '.' . $extTable[$type] : ''; |
|||||||||||
1889 | $name = substr(md5(basename($tmpname)), 0, 8) . $ext; |
|||||||||||
1890 | } |
|||||||||||
1891 | } |
|||||||||||
1892 | ||||||||||||
1893 | // do hook function 'upload.presave' |
|||||||||||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
38% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them. ![]() |
||||||||||||
1894 | if (! empty($this->listeners['upload.presave'])) { |
|||||||||||
1895 | View Code Duplication | foreach($this->listeners['upload.presave'] as $handler) { |
||||||||||
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
||||||||||||
1896 | call_user_func_array($handler, array(&$path, &$name, $tmpname, $this, $volume)); |
|||||||||||
1897 | } |
|||||||||||
1898 | } |
|||||||||||
1899 | ||||||||||||
1900 | if (($fp = fopen($tmpname, 'rb')) == false) { |
|||||||||||
1901 | $result['warning'] = $this->error(self::ERROR_UPLOAD_FILE, $name, self::ERROR_UPLOAD_TRANSFER); |
|||||||||||
1902 | $this->uploadDebug = 'Upload error: unable open tmp file'; |
|||||||||||
1903 | if (! is_uploaded_file($tmpname)) { |
|||||||||||
1904 | if (@ unlink($tmpname)) unset($GLOBALS['elFinderTempFiles'][$tmpfname]); |
|||||||||||
1905 | continue; |
|||||||||||
1906 | } |
|||||||||||
1907 | break; |
|||||||||||
1908 | } |
|||||||||||
1909 | $rnres = array(); |
|||||||||||
1910 | if ($path) { |
|||||||||||
1911 | $_target = $volume->getUploadTaget($target, $path, $result); |
|||||||||||
1912 | } else { |
|||||||||||
1913 | $_target = $target; |
|||||||||||
1914 | // file rename for backup |
|||||||||||
1915 | if (isset($renames[$name])) { |
|||||||||||
1916 | $dir = $volume->realpath($_target); |
|||||||||||
1917 | $hash = $volume->getHash($dir, $name); |
|||||||||||
1918 | $rnres = $this->rename(array('target' => $hash, 'name' => $volume->uniqueName($dir, $name, $suffix, true, 0))); |
|||||||||||
1919 | if (!empty($rnres['error'])) { |
|||||||||||
1920 | $result['warning'] = $rnres['error']; |
|||||||||||
1921 | break; |
|||||||||||
1922 | } |
|||||||||||
1923 | } |
|||||||||||
1924 | } |
|||||||||||
1925 | if (! $_target || ($file = $volume->upload($fp, $_target, $name, $tmpname)) === false) { |
|||||||||||
1926 | $result['warning'] = $this->error(self::ERROR_UPLOAD_FILE, $name, $volume->error()); |
|||||||||||
1927 | fclose($fp); |
|||||||||||
1928 | View Code Duplication | if (! is_uploaded_file($tmpname)) { |
||||||||||
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
||||||||||||
1929 | if (@ unlink($tmpname)) unset($GLOBALS['elFinderTempFiles'][$tmpname]);; |
|||||||||||
1930 | continue; |
|||||||||||
1931 | } |
|||||||||||
1932 | break; |
|||||||||||
1933 | } |
|||||||||||
1934 | ||||||||||||
1935 | is_resource($fp) && fclose($fp); |
|||||||||||
1936 | if (! is_uploaded_file($tmpname)){ |
|||||||||||
1937 | clearstatcache(); |
|||||||||||
1938 | View Code Duplication | if (!is_file($tmpname) || @ unlink($tmpname)) { |
||||||||||
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
||||||||||||
1939 | unset($GLOBALS['elFinderTempFiles'][$tmpname]); |
|||||||||||
1940 | } |
|||||||||||
1941 | } |
|||||||||||
1942 | $result['added'][] = $file; |
|||||||||||
1943 | if ($rnres) { |
|||||||||||
0 ignored issues
–
show
The expression
$rnres of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using ![]() |
||||||||||||
1944 | $result = array_merge_recursive($result, $rnres); |
|||||||||||
1945 | } |
|||||||||||
1946 | } |
|||||||||||
1947 | if ($GLOBALS['elFinderTempFiles']) { |
|||||||||||
1948 | foreach(array_keys($GLOBALS['elFinderTempFiles']) as $_temp) { |
|||||||||||
1949 | @ unlink($_temp); |
|||||||||||
0 ignored issues
–
show
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
![]() |
||||||||||||
1950 | } |
|||||||||||
1951 | } |
|||||||||||
1952 | $result['removed'] = $volume->removed(); |
|||||||||||
1953 | ||||||||||||
1954 | if (!empty($args['node'])) { |
|||||||||||
1955 | $result['callback'] = array( |
|||||||||||
1956 | 'node' => $args['node'], |
|||||||||||
1957 | 'bind' => 'upload' |
|||||||||||
1958 | ); |
|||||||||||
1959 | } |
|||||||||||
1960 | return $result; |
|||||||||||
1961 | } |
|||||||||||
1962 | ||||||||||||
1963 | /** |
|||||||||||
1964 | * Copy/move files into new destination |
|||||||||||
1965 | * |
|||||||||||
1966 | * @param array command arguments |
|||||||||||
1967 | * @return array |
|||||||||||
1968 | * @author Dmitry (dio) Levashov |
|||||||||||
1969 | **/ |
|||||||||||
1970 | protected function paste($args) { |
|||||||||||
1971 | $dst = $args['dst']; |
|||||||||||
1972 | $targets = is_array($args['targets']) ? $args['targets'] : array(); |
|||||||||||
1973 | $cut = !empty($args['cut']); |
|||||||||||
1974 | $error = $cut ? self::ERROR_MOVE : self::ERROR_COPY; |
|||||||||||
1975 | $result = array('added' => array(), 'removed' => array()); |
|||||||||||
1976 | ||||||||||||
1977 | if (($dstVolume = $this->volume($dst)) == false) { |
|||||||||||
1978 | return array('error' => $this->error($error, '#'.$targets[0], self::ERROR_TRGDIR_NOT_FOUND, '#'.$dst)); |
|||||||||||
1979 | } |
|||||||||||
1980 | ||||||||||||
1981 | $renames = array(); |
|||||||||||
1982 | $suffix = '~'; |
|||||||||||
1983 | if (!empty($args['renames'])) { |
|||||||||||
1984 | $renames = array_flip($args['renames']); |
|||||||||||
1985 | View Code Duplication | if (is_string($args['suffix']) && ! preg_match('/[\/\\?*:|"<>]/', $args['suffix'])) { |
||||||||||
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
||||||||||||
1986 | $suffix = $args['suffix']; |
|||||||||||
1987 | } |
|||||||||||
1988 | } |
|||||||||||
1989 | ||||||||||||
1990 | foreach ($targets as $target) { |
|||||||||||
1991 | View Code Duplication | if (($srcVolume = $this->volume($target)) == false) { |
||||||||||
1992 | $result['warning'] = $this->error($error, '#'.$target, self::ERROR_FILE_NOT_FOUND); |
|||||||||||
1993 | break; |
|||||||||||
1994 | } |
|||||||||||
1995 | ||||||||||||
1996 | $rnres = array(); |
|||||||||||
1997 | if ($renames) { |
|||||||||||
0 ignored issues
–
show
The expression
$renames of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using ![]() |
||||||||||||
1998 | $file = $srcVolume->file($target); |
|||||||||||
1999 | if (isset($renames[$file['name']])) { |
|||||||||||
2000 | $dir = $dstVolume->realpath($dst); |
|||||||||||
2001 | $hash = $dstVolume->getHash($dir, $file['name']); |
|||||||||||
2002 | $rnres = $this->rename(array('target' => $hash, 'name' => $dstVolume->uniqueName($dir, $file['name'], $suffix, true, 0))); |
|||||||||||
2003 | if (!empty($rnres['error'])) { |
|||||||||||
2004 | $result['warning'] = $rnres['error']; |
|||||||||||
2005 | break; |
|||||||||||
2006 | } |
|||||||||||
2007 | } |
|||||||||||
2008 | } |
|||||||||||
2009 | ||||||||||||
2010 | if (($file = $dstVolume->paste($srcVolume, $target, $dst, $cut)) == false) { |
|||||||||||
2011 | $result['warning'] = $this->error($dstVolume->error()); |
|||||||||||
2012 | break; |
|||||||||||
2013 | } |
|||||||||||
2014 | ||||||||||||
2015 | $result['added'][] = $file; |
|||||||||||
2016 | if ($rnres) { |
|||||||||||
0 ignored issues
–
show
The expression
$rnres of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using ![]() |
||||||||||||
2017 | $result = array_merge_recursive($result, $rnres); |
|||||||||||
2018 | } |
|||||||||||
2019 | } |
|||||||||||
2020 | return $result; |
|||||||||||
2021 | } |
|||||||||||
2022 | ||||||||||||
2023 | /** |
|||||||||||
2024 | * Return file content |
|||||||||||
2025 | * |
|||||||||||
2026 | * @param array $args command arguments |
|||||||||||
2027 | * @return array |
|||||||||||
2028 | * @author Dmitry (dio) Levashov |
|||||||||||
2029 | **/ |
|||||||||||
2030 | protected function get($args) { |
|||||||||||
2031 | $target = $args['target']; |
|||||||||||
2032 | $volume = $this->volume($target); |
|||||||||||
2033 | ||||||||||||
2034 | if (!$volume || ($file = $volume->file($target)) == false) { |
|||||||||||
2035 | return array('error' => $this->error(self::ERROR_OPEN, '#'.$target, self::ERROR_FILE_NOT_FOUND)); |
|||||||||||
2036 | } |
|||||||||||
2037 | ||||||||||||
2038 | View Code Duplication | if (($content = $volume->getContents($target)) === false) { |
||||||||||
2039 | return array('error' => $this->error(self::ERROR_OPEN, $volume->path($target), $volume->error())); |
|||||||||||
2040 | } |
|||||||||||
2041 | ||||||||||||
2042 | if ($args['conv'] && function_exists('mb_detect_encoding') && function_exists('mb_convert_encoding')) { |
|||||||||||
2043 | $mime = isset($file['mime'])? $file['mime'] : ''; |
|||||||||||
2044 | if ($mime && strtolower(substr($mime, 0, 4)) === 'text') { |
|||||||||||
2045 | if ($enc = mb_detect_encoding ( $content , mb_detect_order(), true)) { |
|||||||||||
2046 | if (strtolower($enc) !== 'utf-8') { |
|||||||||||
2047 | $content = mb_convert_encoding($content, 'UTF-8', $enc); |
|||||||||||
2048 | } |
|||||||||||
2049 | } |
|||||||||||
2050 | } |
|||||||||||
2051 | } |
|||||||||||
2052 | ||||||||||||
2053 | $json = json_encode($content); |
|||||||||||
2054 | ||||||||||||
2055 | if ($json === false || strlen($json) < strlen($content)) { |
|||||||||||
2056 | if ($args['conv']) { |
|||||||||||
2057 | return array('error' => $this->error(self::ERROR_CONV_UTF8,self::ERROR_NOT_UTF8_CONTENT, $volume->path($target))); |
|||||||||||
2058 | } else { |
|||||||||||
2059 | return array('doconv' => true); |
|||||||||||
2060 | } |
|||||||||||
2061 | } |
|||||||||||
2062 | ||||||||||||
2063 | return array('content' => $content); |
|||||||||||
2064 | } |
|||||||||||
2065 | ||||||||||||
2066 | /** |
|||||||||||
2067 | * Save content into text file |
|||||||||||
2068 | * |
|||||||||||
2069 | * @return array |
|||||||||||
2070 | * @author Dmitry (dio) Levashov |
|||||||||||
2071 | **/ |
|||||||||||
2072 | protected function put($args) { |
|||||||||||
2073 | $target = $args['target']; |
|||||||||||
2074 | ||||||||||||
2075 | View Code Duplication | if (($volume = $this->volume($target)) == false |
||||||||||
2076 | || ($file = $volume->file($target)) == false) { |
|||||||||||
2077 | return array('error' => $this->error(self::ERROR_SAVE, '#'.$target, self::ERROR_FILE_NOT_FOUND)); |
|||||||||||
2078 | } |
|||||||||||
2079 | ||||||||||||
2080 | View Code Duplication | if (($file = $volume->putContents($target, $args['content'])) == false) { |
||||||||||
2081 | return array('error' => $this->error(self::ERROR_SAVE, $volume->path($target), $volume->error())); |
|||||||||||
2082 | } |
|||||||||||
2083 | ||||||||||||
2084 | return array('changed' => array($file)); |
|||||||||||
2085 | } |
|||||||||||
2086 | ||||||||||||
2087 | /** |
|||||||||||
2088 | * Extract files from archive |
|||||||||||
2089 | * |
|||||||||||
2090 | * @param array $args command arguments |
|||||||||||
2091 | * @return array |
|||||||||||
2092 | * @author Dmitry (dio) Levashov, |
|||||||||||
2093 | * @author Alexey Sukhotin |
|||||||||||
2094 | **/ |
|||||||||||
2095 | protected function extract($args) { |
|||||||||||
2096 | $target = $args['target']; |
|||||||||||
2097 | $mimes = !empty($args['mimes']) && is_array($args['mimes']) ? $args['mimes'] : array(); |
|||||||||||
2098 | $error = array(self::ERROR_EXTRACT, '#'.$target); |
|||||||||||
2099 | $makedir = isset($args['makedir'])? (bool)$args['makedir'] : null; |
|||||||||||
2100 | ||||||||||||
2101 | View Code Duplication | if (($volume = $this->volume($target)) == false |
||||||||||
2102 | || ($file = $volume->file($target)) == false) { |
|||||||||||
2103 | return array('error' => $this->error(self::ERROR_EXTRACT, '#'.$target, self::ERROR_FILE_NOT_FOUND)); |
|||||||||||
2104 | } |
|||||||||||
2105 | ||||||||||||
2106 | return ($file = $volume->extract($target, $makedir)) |
|||||||||||
2107 | ? array('added' => isset($file['read'])? array($file) : $file) |
|||||||||||
2108 | : array('error' => $this->error(self::ERROR_EXTRACT, $volume->path($target), $volume->error())); |
|||||||||||
2109 | } |
|||||||||||
2110 | ||||||||||||
2111 | /** |
|||||||||||
2112 | * Create archive |
|||||||||||
2113 | * |
|||||||||||
2114 | * @param array $args command arguments |
|||||||||||
2115 | * @return array |
|||||||||||
2116 | * @author Dmitry (dio) Levashov, |
|||||||||||
2117 | * @author Alexey Sukhotin |
|||||||||||
2118 | **/ |
|||||||||||
2119 | protected function archive($args) { |
|||||||||||
2120 | $type = $args['type']; |
|||||||||||
2121 | $targets = isset($args['targets']) && is_array($args['targets']) ? $args['targets'] : array(); |
|||||||||||
2122 | $name = isset($args['name'])? $args['name'] : ''; |
|||||||||||
2123 | ||||||||||||
2124 | View Code Duplication | if (($volume = $this->volume($targets[0])) == false) { |
||||||||||
2125 | return $this->error(self::ERROR_ARCHIVE, self::ERROR_TRGDIR_NOT_FOUND); |
|||||||||||
2126 | } |
|||||||||||
2127 | ||||||||||||
2128 | return ($file = $volume->archive($targets, $args['type'], $name)) |
|||||||||||
2129 | ? array('added' => array($file)) |
|||||||||||
2130 | : array('error' => $this->error(self::ERROR_ARCHIVE, $volume->error())); |
|||||||||||
2131 | } |
|||||||||||
2132 | ||||||||||||
2133 | /** |
|||||||||||
2134 | * Search files |
|||||||||||
2135 | * |
|||||||||||
2136 | * @param array $args command arguments |
|||||||||||
2137 | * @return array |
|||||||||||
2138 | * @author Dmitry Levashov |
|||||||||||
2139 | **/ |
|||||||||||
2140 | protected function search($args) { |
|||||||||||
2141 | $q = trim($args['q']); |
|||||||||||
2142 | $mimes = !empty($args['mimes']) && is_array($args['mimes']) ? $args['mimes'] : array(); |
|||||||||||
2143 | $target = !empty($args['target'])? $args['target'] : null; |
|||||||||||
2144 | $result = array(); |
|||||||||||
2145 | $errors = array(); |
|||||||||||
2146 | ||||||||||||
2147 | if ($target) { |
|||||||||||
2148 | View Code Duplication | if ($volume = $this->volume($target)) { |
||||||||||
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
||||||||||||
2149 | $result = $volume->search($q, $mimes, $target); |
|||||||||||
2150 | $errors = array_merge($errors, $volume->error()); |
|||||||||||
2151 | } |
|||||||||||
2152 | View Code Duplication | } else { |
||||||||||
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
||||||||||||
2153 | foreach ($this->volumes as $volume) { |
|||||||||||
2154 | $result = array_merge($result, $volume->search($q, $mimes)); |
|||||||||||
2155 | $errors = array_merge($errors, $volume->error()); |
|||||||||||
2156 | } |
|||||||||||
2157 | } |
|||||||||||
2158 | ||||||||||||
2159 | $result = array('files' => $result); |
|||||||||||
2160 | if ($errors) { |
|||||||||||
0 ignored issues
–
show
The expression
$errors of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using ![]() |
||||||||||||
2161 | $result['warning'] = $errors; |
|||||||||||
2162 | } |
|||||||||||
2163 | return $result; |
|||||||||||
2164 | } |
|||||||||||
2165 | ||||||||||||
2166 | /** |
|||||||||||
2167 | * Return file info (used by client "places" ui) |
|||||||||||
2168 | * |
|||||||||||
2169 | * @param array $args command arguments |
|||||||||||
2170 | * @return array |
|||||||||||
2171 | * @author Dmitry Levashov |
|||||||||||
2172 | **/ |
|||||||||||
2173 | protected function info($args) { |
|||||||||||
2174 | $files = array(); |
|||||||||||
2175 | $sleep = 0; |
|||||||||||
0 ignored issues
–
show
$sleep is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
||||||||||||
2176 | $compare = null; |
|||||||||||
2177 | // long polling mode |
|||||||||||
2178 | if ($args['compare'] && count($args['targets']) === 1) { |
|||||||||||
2179 | $compare = intval($args['compare']); |
|||||||||||
2180 | $hash = $args['targets'][0]; |
|||||||||||
2181 | if ($volume = $this->volume($hash)) { |
|||||||||||
2182 | $standby = (int)$volume->getOption('plStandby'); |
|||||||||||
2183 | $_compare = false; |
|||||||||||
2184 | if (($syncCheckFunc = $volume->getOption('syncCheckFunc')) && is_callable($syncCheckFunc)) { |
|||||||||||
2185 | $_compare = call_user_func_array($syncCheckFunc, array($volume->realpath($hash), $standby, $compare, $volume, $this)); |
|||||||||||
2186 | } |
|||||||||||
2187 | if ($_compare !== false) { |
|||||||||||
2188 | $compare = $_compare; |
|||||||||||
2189 | } else { |
|||||||||||
2190 | $sleep = max(1, (int)$volume->getOption('tsPlSleep')); |
|||||||||||
2191 | $limit = max(1, $standby / $sleep) + 1; |
|||||||||||
2192 | $timelimit = ini_get('max_execution_time'); |
|||||||||||
2193 | do { |
|||||||||||
2194 | $timelimit && @ set_time_limit($timelimit + $sleep); |
|||||||||||
2195 | $volume->clearstatcache(); |
|||||||||||
2196 | if (($info = $volume->file($hash)) != false) { |
|||||||||||
2197 | if ($info['ts'] != $compare) { |
|||||||||||
2198 | $compare = $info['ts']; |
|||||||||||
2199 | break; |
|||||||||||
2200 | } |
|||||||||||
2201 | } else { |
|||||||||||
2202 | $compare = 0; |
|||||||||||
2203 | break; |
|||||||||||
2204 | } |
|||||||||||
2205 | if (--$limit) { |
|||||||||||
2206 | sleep($sleep); |
|||||||||||
2207 | } |
|||||||||||
2208 | } while($limit); |
|||||||||||
2209 | } |
|||||||||||
2210 | } |
|||||||||||
2211 | } else { |
|||||||||||
2212 | foreach ($args['targets'] as $hash) { |
|||||||||||
2213 | if (($volume = $this->volume($hash)) != false |
|||||||||||
2214 | && ($info = $volume->file($hash)) != false) { |
|||||||||||
2215 | $files[] = $info; |
|||||||||||
2216 | } |
|||||||||||
2217 | } |
|||||||||||
2218 | } |
|||||||||||
2219 | ||||||||||||
2220 | $result = array('files' => $files); |
|||||||||||
2221 | if (!is_null($compare)) { |
|||||||||||
2222 | $result['compare'] = strval($compare); |
|||||||||||
2223 | } |
|||||||||||
2224 | return $result; |
|||||||||||
2225 | } |
|||||||||||
2226 | ||||||||||||
2227 | /** |
|||||||||||
2228 | * Return image dimmensions |
|||||||||||
2229 | * |
|||||||||||
2230 | * @param array $args command arguments |
|||||||||||
2231 | * @return array |
|||||||||||
2232 | * @author Dmitry (dio) Levashov |
|||||||||||
2233 | **/ |
|||||||||||
2234 | protected function dim($args) { |
|||||||||||
2235 | $target = $args['target']; |
|||||||||||
2236 | ||||||||||||
2237 | if (($volume = $this->volume($target)) != false) { |
|||||||||||
2238 | $dim = $volume->dimensions($target); |
|||||||||||
2239 | return $dim ? array('dim' => $dim) : array(); |
|||||||||||
2240 | } |
|||||||||||
2241 | return array(); |
|||||||||||
2242 | } |
|||||||||||
2243 | ||||||||||||
2244 | /** |
|||||||||||
2245 | * Resize image |
|||||||||||
2246 | * |
|||||||||||
2247 | * @param array command arguments |
|||||||||||
2248 | * @return array |
|||||||||||
2249 | * @author Dmitry (dio) Levashov |
|||||||||||
2250 | * @author Alexey Sukhotin |
|||||||||||
2251 | **/ |
|||||||||||
2252 | protected function resize($args) { |
|||||||||||
2253 | $target = $args['target']; |
|||||||||||
2254 | $width = $args['width']; |
|||||||||||
2255 | $height = $args['height']; |
|||||||||||
2256 | $x = (int)$args['x']; |
|||||||||||
2257 | $y = (int)$args['y']; |
|||||||||||
2258 | $mode = $args['mode']; |
|||||||||||
2259 | $bg = null; |
|||||||||||
2260 | $degree = (int)$args['degree']; |
|||||||||||
2261 | $quality= (int)$args['quality']; |
|||||||||||
2262 | ||||||||||||
2263 | View Code Duplication | if (($volume = $this->volume($target)) == false |
||||||||||
2264 | || ($file = $volume->file($target)) == false) { |
|||||||||||
2265 | return array('error' => $this->error(self::ERROR_RESIZE, '#'.$target, self::ERROR_FILE_NOT_FOUND)); |
|||||||||||
2266 | } |
|||||||||||
2267 | ||||||||||||
2268 | return ($file = $volume->resize($target, $width, $height, $x, $y, $mode, $bg, $degree, $quality)) |
|||||||||||
2269 | ? array('changed' => array($file)) |
|||||||||||
2270 | : array('error' => $this->error(self::ERROR_RESIZE, $volume->path($target), $volume->error())); |
|||||||||||
2271 | } |
|||||||||||
2272 | ||||||||||||
2273 | /** |
|||||||||||
2274 | * Return content URL |
|||||||||||
2275 | * |
|||||||||||
2276 | * @param array $args command arguments |
|||||||||||
2277 | * @return array |
|||||||||||
2278 | * @author Naoki Sawada |
|||||||||||
2279 | **/ |
|||||||||||
2280 | protected function url($args) { |
|||||||||||
2281 | $target = $args['target']; |
|||||||||||
2282 | $options = isset($args['options'])? $args['options'] : array(); |
|||||||||||
2283 | if (($volume = $this->volume($target)) != false) { |
|||||||||||
2284 | $url = $volume->getContentUrl($target, $options); |
|||||||||||
2285 | return $url ? array('url' => $url) : array(); |
|||||||||||
2286 | } |
|||||||||||
2287 | return array(); |
|||||||||||
2288 | } |
|||||||||||
2289 | ||||||||||||
2290 | /** |
|||||||||||
2291 | * Output callback result with JavaScript that control elFinder |
|||||||||||
2292 | * or HTTP redirect to callbackWindowURL |
|||||||||||
2293 | * |
|||||||||||
2294 | * @param array command arguments |
|||||||||||
2295 | * @author Naoki Sawada |
|||||||||||
2296 | */ |
|||||||||||
2297 | protected function callback($args) { |
|||||||||||
2298 | $checkReg = '/[^a-zA-Z0-9;._-]/'; |
|||||||||||
2299 | $node = (isset($args['node']) && !preg_match($checkReg, $args['node']))? $args['node'] : ''; |
|||||||||||
2300 | $json = (isset($args['json']) && @json_decode($args['json']))? $args['json'] : '{}'; |
|||||||||||
2301 | $bind = (isset($args['bind']) && !preg_match($checkReg, $args['bind']))? $args['bind'] : ''; |
|||||||||||
2302 | $done = (!empty($args['done'])); |
|||||||||||
2303 | ||||||||||||
2304 | while( ob_get_level() ) { |
|||||||||||
2305 | if (! ob_end_clean()) { |
|||||||||||
2306 | break; |
|||||||||||
2307 | } |
|||||||||||
2308 | } |
|||||||||||
2309 | ||||||||||||
2310 | if ($done || ! $this->callbackWindowURL) { |
|||||||||||
2311 | $script = ''; |
|||||||||||
2312 | if ($node) { |
|||||||||||
2313 | $script .= ' |
|||||||||||
2314 | var w = window.opener || window.parent || window; |
|||||||||||
2315 | try { |
|||||||||||
2316 | var elf = w.document.getElementById(\''.$node.'\').elfinder; |
|||||||||||
2317 | if (elf) { |
|||||||||||
2318 | var data = '.$json.'; |
|||||||||||
2319 | if (data.error) { |
|||||||||||
2320 | elf.error(data.error); |
|||||||||||
2321 | } else { |
|||||||||||
2322 | data.warning && elf.error(data.warning); |
|||||||||||
2323 | data.removed && data.removed.length && elf.remove(data); |
|||||||||||
2324 | data.added && data.added.length && elf.add(data); |
|||||||||||
2325 | data.changed && data.changed.length && elf.change(data);'; |
|||||||||||
2326 | if ($bind) { |
|||||||||||
2327 | $script .= ' |
|||||||||||
2328 | elf.trigger(\''.$bind.'\', data);'; |
|||||||||||
2329 | } |
|||||||||||
2330 | $script .= ' |
|||||||||||
2331 | data.sync && elf.sync(); |
|||||||||||
2332 | } |
|||||||||||
2333 | } |
|||||||||||
2334 | } catch(e) { |
|||||||||||
2335 | // for CORS |
|||||||||||
2336 | w.postMessage && w.postMessage(JSON.stringify({bind:\''.$bind.'\',data:'.$json.'}), \'*\'); |
|||||||||||
2337 | }'; |
|||||||||||
2338 | } |
|||||||||||
2339 | $script .= 'window.close();'; |
|||||||||||
2340 | ||||||||||||
2341 | $out = '<!DOCTYPE html><html><head><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><script>'.$script.'</script></head><body><a href="#" onlick="window.close();return false;">Close this window</a></body></html>'; |
|||||||||||
2342 | ||||||||||||
2343 | header('Content-Type: text/html; charset=utf-8'); |
|||||||||||
2344 | header('Content-Length: '.strlen($out)); |
|||||||||||
2345 | header('Cache-Control: private'); |
|||||||||||
2346 | header('Pragma: no-cache'); |
|||||||||||
2347 | ||||||||||||
2348 | echo $out; |
|||||||||||
2349 | ||||||||||||
2350 | } else { |
|||||||||||
2351 | $url = $this->callbackWindowURL; |
|||||||||||
2352 | $url .= ((strpos($url, '?') === false)? '?' : '&') |
|||||||||||
2353 | . '&node=' . rawurlencode($node) |
|||||||||||
2354 | . (($json !== '{}')? ('&json=' . rawurlencode($json)) : '') |
|||||||||||
2355 | . ($bind? ('&bind=' . rawurlencode($bind)) : '') |
|||||||||||
2356 | . '&done=1'; |
|||||||||||
2357 | ||||||||||||
2358 | header('Location: ' . $url); |
|||||||||||
2359 | ||||||||||||
2360 | } |
|||||||||||
2361 | exit(); |
|||||||||||
0 ignored issues
–
show
The method
callback() contains an exit expression.
An exit expression should only be used in rare cases. For example, if you write a short command line script. In most cases however, using an ![]() |
||||||||||||
2362 | } |
|||||||||||
2363 | ||||||||||||
2364 | /***************************************************************************/ |
|||||||||||
2365 | /* utils */ |
|||||||||||
2366 | /***************************************************************************/ |
|||||||||||
2367 | ||||||||||||
2368 | /** |
|||||||||||
2369 | * Return root - file's owner |
|||||||||||
2370 | * |
|||||||||||
2371 | * @param string file hash |
|||||||||||
2372 | * @return elFinderStorageDriver |
|||||||||||
2373 | * @author Dmitry (dio) Levashov |
|||||||||||
2374 | **/ |
|||||||||||
2375 | protected function volume($hash) { |
|||||||||||
2376 | foreach ($this->volumes as $id => $v) { |
|||||||||||
2377 | if (strpos(''.$hash, $id) === 0) { |
|||||||||||
2378 | return $this->volumes[$id]; |
|||||||||||
2379 | } |
|||||||||||
2380 | } |
|||||||||||
2381 | return false; |
|||||||||||
2382 | } |
|||||||||||
2383 | ||||||||||||
2384 | /** |
|||||||||||
2385 | * Return files info array |
|||||||||||
2386 | * |
|||||||||||
2387 | * @param array $data one file info or files info |
|||||||||||
2388 | * @return array |
|||||||||||
2389 | * @author Dmitry (dio) Levashov |
|||||||||||
2390 | **/ |
|||||||||||
2391 | protected function toArray($data) { |
|||||||||||
2392 | return isset($data['hash']) || !is_array($data) ? array($data) : $data; |
|||||||||||
2393 | } |
|||||||||||
2394 | ||||||||||||
2395 | /** |
|||||||||||
2396 | * Return fils hashes list |
|||||||||||
2397 | * |
|||||||||||
2398 | * @param array $files files info |
|||||||||||
2399 | * @return array |
|||||||||||
2400 | * @author Dmitry (dio) Levashov |
|||||||||||
2401 | **/ |
|||||||||||
2402 | protected function hashes($files) { |
|||||||||||
2403 | $ret = array(); |
|||||||||||
2404 | foreach ($files as $file) { |
|||||||||||
2405 | $ret[] = $file['hash']; |
|||||||||||
2406 | } |
|||||||||||
2407 | return $ret; |
|||||||||||
2408 | } |
|||||||||||
2409 | ||||||||||||
2410 | /** |
|||||||||||
2411 | * Remove from files list hidden files and files with required mime types |
|||||||||||
2412 | * |
|||||||||||
2413 | * @param array $files files info |
|||||||||||
2414 | * @return array |
|||||||||||
2415 | * @author Dmitry (dio) Levashov |
|||||||||||
2416 | **/ |
|||||||||||
2417 | protected function filter($files) { |
|||||||||||
2418 | foreach ($files as $i => $file) { |
|||||||||||
2419 | if (!empty($file['hidden']) || !$this->default->mimeAccepted($file['mime'])) { |
|||||||||||
2420 | unset($files[$i]); |
|||||||||||
2421 | } |
|||||||||||
2422 | } |
|||||||||||
2423 | return array_merge($files, array()); |
|||||||||||
2424 | } |
|||||||||||
2425 | ||||||||||||
2426 | protected function utime() { |
|||||||||||
2427 | $time = explode(" ", microtime()); |
|||||||||||
2428 | return (double)$time[1] + (double)$time[0]; |
|||||||||||
2429 | } |
|||||||||||
2430 | ||||||||||||
2431 | ||||||||||||
2432 | /***************************************************************************/ |
|||||||||||
2433 | /* static utils */ |
|||||||||||
2434 | /***************************************************************************/ |
|||||||||||
2435 | ||||||||||||
2436 | /** |
|||||||||||
2437 | * Return Is Animation Gif |
|||||||||||
2438 | * |
|||||||||||
2439 | * @param string $path server local path of target image |
|||||||||||
2440 | * @return bool |
|||||||||||
2441 | */ |
|||||||||||
2442 | public static function isAnimationGif($path) { |
|||||||||||
2443 | list($width, $height, $type, $attr) = getimagesize($path); |
|||||||||||
0 ignored issues
–
show
The assignment to
$width is unused. Consider omitting it like so list($first,,$third) .
This checks looks for assignemnts to variables using the Consider the following code example. <?php
function returnThreeValues() {
return array('a', 'b', 'c');
}
list($a, $b, $c) = returnThreeValues();
print $a . " - " . $c;
Only the variables Instead, the list call could have been. list($a,, $c) = returnThreeValues();
![]() The assignment to
$height is unused. Consider omitting it like so list($first,,$third) .
This checks looks for assignemnts to variables using the Consider the following code example. <?php
function returnThreeValues() {
return array('a', 'b', 'c');
}
list($a, $b, $c) = returnThreeValues();
print $a . " - " . $c;
Only the variables Instead, the list call could have been. list($a,, $c) = returnThreeValues();
![]() The assignment to
$attr is unused. Consider omitting it like so list($first,,$third) .
This checks looks for assignemnts to variables using the Consider the following code example. <?php
function returnThreeValues() {
return array('a', 'b', 'c');
}
list($a, $b, $c) = returnThreeValues();
print $a . " - " . $c;
Only the variables Instead, the list call could have been. list($a,, $c) = returnThreeValues();
![]() |
||||||||||||
2444 | switch ($type) { |
|||||||||||
2445 | case IMAGETYPE_GIF: |
|||||||||||
2446 | break; |
|||||||||||
2447 | default: |
|||||||||||
2448 | return false; |
|||||||||||
2449 | } |
|||||||||||
2450 | ||||||||||||
2451 | $imgcnt = 0; |
|||||||||||
2452 | $fp = fopen($path, 'rb'); |
|||||||||||
2453 | @fread($fp, 4); |
|||||||||||
0 ignored issues
–
show
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
![]() |
||||||||||||
2454 | $c = @fread($fp,1); |
|||||||||||
2455 | if (ord($c) != 0x39) { // GIF89a |
|||||||||||
2456 | return false; |
|||||||||||
2457 | } |
|||||||||||
2458 | ||||||||||||
2459 | while (!feof($fp)) { |
|||||||||||
2460 | do { |
|||||||||||
2461 | $c = fread($fp, 1); |
|||||||||||
2462 | } while(ord($c) != 0x21 && !feof($fp)); |
|||||||||||
2463 | ||||||||||||
2464 | if (feof($fp)) { |
|||||||||||
2465 | break; |
|||||||||||
2466 | } |
|||||||||||
2467 | ||||||||||||
2468 | $c2 = fread($fp,2); |
|||||||||||
2469 | if (bin2hex($c2) == "f904") { |
|||||||||||
2470 | $imgcnt++; |
|||||||||||
2471 | } |
|||||||||||
2472 | ||||||||||||
2473 | if (feof($fp)) { |
|||||||||||
2474 | break; |
|||||||||||
2475 | } |
|||||||||||
2476 | } |
|||||||||||
2477 | ||||||||||||
2478 | if ($imgcnt > 1) { |
|||||||||||
2479 | return true; |
|||||||||||
2480 | } else { |
|||||||||||
2481 | return false; |
|||||||||||
2482 | } |
|||||||||||
2483 | } |
|||||||||||
2484 | ||||||||||||
2485 | /** |
|||||||||||
2486 | * Return Is seekable stream resource |
|||||||||||
2487 | * |
|||||||||||
2488 | * @param resource $resource |
|||||||||||
2489 | * @return bool |
|||||||||||
2490 | */ |
|||||||||||
2491 | public static function isSeekableStream($resource) { |
|||||||||||
2492 | $metadata = stream_get_meta_data($resource); |
|||||||||||
2493 | return $metadata['seekable']; |
|||||||||||
2494 | } |
|||||||||||
2495 | ||||||||||||
2496 | /** |
|||||||||||
2497 | * serialize and base64_encode of session data (If needed) |
|||||||||||
2498 | * |
|||||||||||
2499 | * @param mixed $var target variable |
|||||||||||
2500 | * @author Naoki Sawada |
|||||||||||
2501 | */ |
|||||||||||
2502 | public static function sessionDataEncode($var) { |
|||||||||||
2503 | if (self::$base64encodeSessionData) { |
|||||||||||
2504 | $var = base64_encode(serialize($var)); |
|||||||||||
2505 | } |
|||||||||||
2506 | return $var; |
|||||||||||
2507 | } |
|||||||||||
2508 | ||||||||||||
2509 | /** |
|||||||||||
2510 | * base64_decode and unserialize of session data (If needed) |
|||||||||||
2511 | * |
|||||||||||
2512 | * @param mixed $var target variable |
|||||||||||
2513 | * @param bool $checkIs data type for check (array|string|object|int) |
|||||||||||
2514 | * @author Naoki Sawada |
|||||||||||
2515 | */ |
|||||||||||
2516 | public static function sessionDataDecode(&$var, $checkIs = null) { |
|||||||||||
2517 | if (self::$base64encodeSessionData) { |
|||||||||||
2518 | $data = @unserialize(@base64_decode($var)); |
|||||||||||
2519 | } else { |
|||||||||||
2520 | $data = $var; |
|||||||||||
2521 | } |
|||||||||||
2522 | $chk = true; |
|||||||||||
2523 | if ($checkIs) { |
|||||||||||
2524 | switch ($checkIs) { |
|||||||||||
2525 | case 'array': |
|||||||||||
2526 | $chk = is_array($data); |
|||||||||||
2527 | break; |
|||||||||||
2528 | case 'string': |
|||||||||||
2529 | $chk = is_string($data); |
|||||||||||
2530 | break; |
|||||||||||
2531 | case 'object': |
|||||||||||
2532 | $chk = is_object($data); |
|||||||||||
2533 | break; |
|||||||||||
2534 | case 'int': |
|||||||||||
2535 | $chk = is_int($data); |
|||||||||||
2536 | break; |
|||||||||||
2537 | } |
|||||||||||
2538 | } |
|||||||||||
2539 | if (!$chk) { |
|||||||||||
2540 | unset($var); |
|||||||||||
2541 | return false; |
|||||||||||
2542 | } |
|||||||||||
2543 | return $data; |
|||||||||||
2544 | } |
|||||||||||
2545 | } // END class |
|||||||||||
2546 |
If you suppress an error, we recommend checking for the error condition explicitly: