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 | * Base class for elFinder volume. |
||
4 | * Provide 2 layers: |
||
5 | * 1. Public API (commands) |
||
6 | * 2. abstract fs API. |
||
7 | * |
||
8 | * All abstract methods begin with "_" |
||
9 | * |
||
10 | * @author Dmitry (dio) Levashov |
||
11 | * @author Troex Nevelin |
||
12 | * @author Alexey Sukhotin |
||
13 | **/ |
||
14 | abstract class elFinderVolumeDriver |
||
0 ignored issues
–
show
|
|||
15 | { |
||
16 | /** |
||
17 | * Net mount key. |
||
18 | * |
||
19 | * @var string |
||
20 | **/ |
||
21 | public $netMountKey = ''; |
||
22 | |||
23 | /** |
||
24 | * Request args |
||
25 | * $_POST or $_GET values. |
||
26 | * |
||
27 | * @var array |
||
28 | */ |
||
29 | protected $ARGS = []; |
||
30 | |||
31 | /** |
||
32 | * Driver id |
||
33 | * Must be started from letter and contains [a-z0-9] |
||
34 | * Used as part of volume id. |
||
35 | * |
||
36 | * @var string |
||
37 | **/ |
||
38 | protected $driverId = 'a'; |
||
39 | |||
40 | /** |
||
41 | * Volume id - used as prefix for files hashes. |
||
42 | * |
||
43 | * @var string |
||
44 | **/ |
||
45 | protected $id = ''; |
||
46 | |||
47 | /** |
||
48 | * Flag - volume "mounted" and available. |
||
49 | * |
||
50 | * @var bool |
||
51 | **/ |
||
52 | protected $mounted = false; |
||
53 | |||
54 | /** |
||
55 | * Root directory path. |
||
56 | * |
||
57 | * @var string |
||
58 | **/ |
||
59 | protected $root = ''; |
||
60 | |||
61 | /** |
||
62 | * Root basename | alias. |
||
63 | * |
||
64 | * @var string |
||
65 | **/ |
||
66 | protected $rootName = ''; |
||
67 | |||
68 | /** |
||
69 | * Default directory to open. |
||
70 | * |
||
71 | * @var string |
||
72 | **/ |
||
73 | protected $startPath = ''; |
||
74 | |||
75 | /** |
||
76 | * Base URL. |
||
77 | * |
||
78 | * @var string |
||
79 | **/ |
||
80 | protected $URL = ''; |
||
81 | |||
82 | /** |
||
83 | * A file save destination path when a temporary content URL is required |
||
84 | * on a network volume or the like |
||
85 | * If not specified, it tries to use "Connector Path/../files/.tmb". |
||
86 | * |
||
87 | * @var string |
||
88 | */ |
||
89 | protected $tmpLinkPath = ''; |
||
90 | |||
91 | /** |
||
92 | * A file save destination URL when a temporary content URL is required |
||
93 | * on a network volume or the like |
||
94 | * If not specified, it tries to use "Connector URL/../files/.tmb". |
||
95 | * |
||
96 | * @var string |
||
97 | */ |
||
98 | protected $tmpLinkUrl = ''; |
||
99 | |||
100 | /** |
||
101 | * Thumbnails dir path. |
||
102 | * |
||
103 | * @var string |
||
104 | **/ |
||
105 | protected $tmbPath = ''; |
||
106 | |||
107 | /** |
||
108 | * Is thumbnails dir writable. |
||
109 | * |
||
110 | * @var bool |
||
111 | **/ |
||
112 | protected $tmbPathWritable = false; |
||
113 | |||
114 | /** |
||
115 | * Thumbnails base URL. |
||
116 | * |
||
117 | * @var string |
||
118 | **/ |
||
119 | protected $tmbURL = ''; |
||
120 | |||
121 | /** |
||
122 | * Thumbnails size in px. |
||
123 | * |
||
124 | * @var int |
||
125 | **/ |
||
126 | protected $tmbSize = 48; |
||
127 | |||
128 | /** |
||
129 | * Image manipulation lib name |
||
130 | * auto|imagick|gd|convert. |
||
131 | * |
||
132 | * @var string |
||
133 | **/ |
||
134 | protected $imgLib = 'auto'; |
||
135 | |||
136 | /** |
||
137 | * Video to Image converter. |
||
138 | * |
||
139 | * @var array |
||
140 | */ |
||
141 | protected $imgConverter = []; |
||
142 | |||
143 | /** |
||
144 | * Library to crypt files name. |
||
145 | * |
||
146 | * @var string |
||
147 | **/ |
||
148 | protected $cryptLib = ''; |
||
149 | |||
150 | /** |
||
151 | * Archivers config. |
||
152 | * |
||
153 | * @var array |
||
154 | **/ |
||
155 | protected $archivers = [ |
||
156 | 'create' => [], |
||
157 | 'extract' => [], |
||
158 | ]; |
||
159 | |||
160 | /** |
||
161 | * Server character encoding. |
||
162 | * |
||
163 | * @var string or null |
||
164 | **/ |
||
165 | protected $encoding = null; |
||
166 | |||
167 | /** |
||
168 | * How many subdirs levels return for tree. |
||
169 | * |
||
170 | * @var int |
||
171 | **/ |
||
172 | protected $treeDeep = 1; |
||
173 | |||
174 | /** |
||
175 | * Errors from last failed action. |
||
176 | * |
||
177 | * @var array |
||
178 | **/ |
||
179 | protected $error = []; |
||
180 | |||
181 | /** |
||
182 | * Today 24:00 timestamp. |
||
183 | * |
||
184 | * @var int |
||
185 | **/ |
||
186 | protected $today = 0; |
||
187 | |||
188 | /** |
||
189 | * Yesterday 24:00 timestamp. |
||
190 | * |
||
191 | * @var int |
||
192 | **/ |
||
193 | protected $yesterday = 0; |
||
194 | |||
195 | /** |
||
196 | * Force make dirctory on extract. |
||
197 | * |
||
198 | * @var int |
||
199 | **/ |
||
200 | protected $extractToNewdir = 'auto'; |
||
201 | |||
202 | /** |
||
203 | * Object configuration. |
||
204 | * |
||
205 | * @var array |
||
206 | **/ |
||
207 | protected $options = [ |
||
208 | // Driver ID (Prefix of volume ID), Normally, the value specified for each volume driver is used. |
||
209 | 'driverId' => '', |
||
210 | // Id (Suffix of volume ID), Normally, the number incremented according to the specified number of volumes is used. |
||
211 | 'id' => '', |
||
212 | // revision id of root directory that uses for caching control of root stat |
||
213 | 'rootRev' => '', |
||
214 | // driver type it uses volume root's CSS class name. e.g. 'group' -> Adds 'elfinder-group' to CSS class name. |
||
215 | 'type' => '', |
||
216 | // root directory path |
||
217 | 'path' => '', |
||
218 | // Folder hash value on elFinder to be the parent of this volume |
||
219 | 'phash' => '', |
||
220 | // Folder hash value on elFinder to trash bin of this volume, it require 'copyJoin' to true |
||
221 | 'trashHash' => '', |
||
222 | // open this path on initial request instead of root path |
||
223 | 'startPath' => '', |
||
224 | // how many subdirs levels return per request |
||
225 | 'treeDeep' => 1, |
||
226 | // root url, not set to disable sending URL to client (replacement for old "fileURL" option) |
||
227 | 'URL' => '', |
||
228 | // directory link url to own manager url with folder hash (`true`, `false` or default `'auto'`: URL is empty then `true` else `false`) |
||
229 | 'dirUrlOwn' => 'auto', |
||
230 | // directory separator. required by client to show paths correctly |
||
231 | 'separator' => DIRECTORY_SEPARATOR, |
||
232 | // Server character encoding (default is '': UTF-8) |
||
233 | 'encoding' => '', |
||
234 | // for convert character encoding (default is '': Not change locale) |
||
235 | 'locale' => '', |
||
236 | // URL of volume icon (16x16 pixel image file) |
||
237 | 'icon' => '', |
||
238 | // CSS Class of volume root in tree |
||
239 | 'rootCssClass' => '', |
||
240 | // Items to disable session caching |
||
241 | 'noSessionCache' => [], |
||
242 | // enable i18n folder name that convert name to elFinderInstance.messages['folder_'+name] |
||
243 | 'i18nFolderName' => false, |
||
244 | // Search timeout (sec) |
||
245 | 'searchTimeout' => 30, |
||
246 | // Search exclusion directory regex pattern (require demiliter e.g. '#/path/to/exclude_directory#i') |
||
247 | 'searchExDirReg' => '', |
||
248 | // library to crypt/uncrypt files names (not implemented) |
||
249 | 'cryptLib' => '', |
||
250 | // how to detect files mimetypes. (auto/internal/finfo/mime_content_type) |
||
251 | 'mimeDetect' => 'auto', |
||
252 | // mime.types file path (for mimeDetect==internal) |
||
253 | 'mimefile' => '', |
||
254 | // Static extension/MIME of general server side scripts to security issues |
||
255 | 'staticMineMap' => [ |
||
256 | 'php:*' => 'text/x-php', |
||
257 | 'php3:*' => 'text/x-php', |
||
258 | 'php4:*' => 'text/x-php', |
||
259 | 'php5:*' => 'text/x-php', |
||
260 | 'phtml:*' => 'text/x-php', |
||
261 | 'cgi:*' => 'text/x-httpd-cgi', |
||
262 | 'pl:*' => 'text/x-perl', |
||
263 | 'asp:*' => 'text/x-asap', |
||
264 | 'aspx:*' => 'text/x-asap', |
||
265 | 'py:*' => 'text/x-python', |
||
266 | 'rb:*' => 'text/x-ruby', |
||
267 | 'jsp:*' => 'text/x-jsp', |
||
268 | ], |
||
269 | // mime type normalize map : Array '[ext]:[detected mime type]' => '[normalized mime]' |
||
270 | 'mimeMap' => [ |
||
271 | 'md:application/x-genesis-rom' => 'text/x-markdown', |
||
272 | 'md:text/plain' => 'text/x-markdown', |
||
273 | 'markdown:text/plain' => 'text/x-markdown', |
||
274 | 'css:text/x-asm' => 'text/css', |
||
275 | 'ico:image/vnd.microsoft.icon' => 'image/x-icon', |
||
276 | 'csv:text/plain' => 'text/csv', |
||
277 | 'm4a:video/mp4' => 'audio/mp4', |
||
278 | 'oga:application/ogg' => 'audio/ogg', |
||
279 | 'ogv:application/ogg' => 'video/ogg', |
||
280 | 'zip:application/x-zip' => 'application/zip', |
||
281 | ], |
||
282 | // An option to add MimeMap to the `mimeMap` option |
||
283 | // Array '[ext]:[detected mime type]' => '[normalized mime]' |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
50% 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. ![]() |
|||
284 | 'additionalMimeMap' => [], |
||
285 | // MIME regex of send HTTP header "Content-Disposition: inline" or allow preview in quicklook |
||
286 | // '.' is allow inline of all of MIME types |
||
287 | // '$^' is not allow inline of all of MIME types |
||
288 | 'dispInlineRegex' => '^(?:(?:image|video|audio)|(?:text/plain|application/pdf)$)', |
||
289 | // temporary content URL's base path |
||
290 | 'tmpLinkPath' => '', |
||
291 | // temporary content URL's base URL |
||
292 | 'tmpLinkUrl' => '', |
||
293 | // directory for thumbnails |
||
294 | 'tmbPath' => '.tmb', |
||
295 | // mode to create thumbnails dir |
||
296 | 'tmbPathMode' => 0777, |
||
297 | // thumbnails dir URL. Set it if store thumbnails outside root directory |
||
298 | 'tmbURL' => '', |
||
299 | // thumbnails size (px) |
||
300 | 'tmbSize' => 48, |
||
301 | // thumbnails crop (true - crop, false - scale image to fit thumbnail size) |
||
302 | 'tmbCrop' => true, |
||
303 | // thumbnails background color (hex #rrggbb or 'transparent') |
||
304 | 'tmbBgColor' => 'transparent', |
||
305 | // image rotate fallback background color (hex #rrggbb) |
||
306 | 'bgColorFb' => '#ffffff', |
||
307 | // image manipulations library |
||
308 | 'imgLib' => 'auto', |
||
309 | // Fallback self image to thumbnail (nothing imgLib) |
||
310 | 'tmbFbSelf' => true, |
||
311 | // Video to Image converters ['TYPE or MIME' => ['func' => function($file){ /* Converts $file to Image */ return true; }, 'maxlen' => (int)TransferLength]] |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
39% 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. ![]() |
|||
312 | 'imgConverter' => [], |
||
313 | // Max length of transfer to image converter |
||
314 | 'tmbVideoConvLen' => 10000000, |
||
315 | // Captre point seccond |
||
316 | 'tmbVideoConvSec' => 6, |
||
317 | // Resource path of fallback icon images defailt: php/resouces |
||
318 | 'resourcePath' => '', |
||
319 | // Jpeg image saveing quality |
||
320 | 'jpgQuality' => 100, |
||
321 | // on paste file - if true - old file will be replaced with new one, if false new file get name - original_name-number.ext |
||
322 | 'copyOverwrite' => true, |
||
323 | // if true - join new and old directories content on paste |
||
324 | 'copyJoin' => true, |
||
325 | // on upload - if true - old file will be replaced with new one, if false new file get name - original_name-number.ext |
||
326 | 'uploadOverwrite' => true, |
||
327 | // mimetypes allowed to upload |
||
328 | 'uploadAllow' => [], |
||
329 | // mimetypes not allowed to upload |
||
330 | 'uploadDeny' => [], |
||
331 | // order to proccess uploadAllow and uploadDeny options |
||
332 | 'uploadOrder' => ['deny', 'allow'], |
||
333 | // maximum upload file size. NOTE - this is size for every uploaded files |
||
334 | 'uploadMaxSize' => 0, |
||
335 | // maximum number of chunked upload connection. `-1` to disable chunked upload |
||
336 | 'uploadMaxConn' => 3, |
||
337 | // maximum get file size. NOTE - Maximum value is 50% of PHP memory_limit |
||
338 | 'getMaxSize' => 0, |
||
339 | // files dates format |
||
340 | 'dateFormat' => 'j M Y H:i', |
||
341 | // files time format |
||
342 | 'timeFormat' => 'H:i', |
||
343 | // if true - every folder will be check for children folders, -1 - every folder will be check asynchronously, false - all folders will be marked as having subfolders |
||
344 | 'checkSubfolders' => true, // true, false or -1 |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
50% 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. ![]() |
|||
345 | // allow to copy from this volume to other ones? |
||
346 | 'copyFrom' => true, |
||
347 | // allow to copy from other volumes to this one? |
||
348 | 'copyTo' => true, |
||
349 | // cmd duplicate suffix format e.g. '_%s_' to without spaces |
||
350 | 'duplicateSuffix' => ' %s ', |
||
351 | // unique name numbar format e.g. '(%d)' to (1), (2)... |
||
352 | 'uniqueNumFormat' => '%d', |
||
353 | // list of commands disabled on this root |
||
354 | 'disabled' => [], |
||
355 | // enable file owner, group & mode info, `false` to inactivate "chmod" command. |
||
356 | 'statOwner' => false, |
||
357 | // allow exec chmod of read-only files |
||
358 | 'allowChmodReadOnly' => false, |
||
359 | // regexp or function name to validate new file name |
||
360 | 'acceptedName' => '/^[^\.].*/', // Notice: overwritten it in some volume drivers contractor |
||
361 | // regexp or function name to validate new directory name |
||
362 | 'acceptedDirname' => '', // used `acceptedName` if empty value |
||
363 | // function/class method to control files permissions |
||
364 | 'accessControl' => null, |
||
365 | // some data required by access control |
||
366 | 'accessControlData' => null, |
||
367 | // default permissions. |
||
368 | 'defaults' => [ |
||
369 | 'read' => true, |
||
370 | 'write' => true, |
||
371 | 'locked' => false, |
||
372 | 'hidden' => false, |
||
373 | ], |
||
374 | // files attributes |
||
375 | 'attributes' => [], |
||
376 | // max allowed archive files size (0 - no limit) |
||
377 | 'maxArcFilesSize' => 0, |
||
378 | // Allowed archive's mimetypes to create. Leave empty for all available types. |
||
379 | 'archiveMimes' => [], |
||
380 | // Manual config for archivers. See example below. Leave empty for auto detect |
||
381 | 'archivers' => [], |
||
382 | // plugin settings |
||
383 | 'plugin' => [], |
||
384 | // Is support parent directory time stamp update on add|remove|rename item |
||
385 | // Default `null` is auto detection that is LocalFileSystem, FTP or Dropbox are `true` |
||
386 | 'syncChkAsTs' => null, |
||
387 | // Long pooling sync checker function for syncChkAsTs is true |
||
388 | // Calls with args (TARGET DIRCTORY PATH, STAND-BY(sec), OLD TIMESTAMP, VOLUME DRIVER INSTANCE, ELFINDER INSTANCE) |
||
389 | // This function must return the following values. Changed: New Timestamp or Same: Old Timestamp or Error: false |
||
390 | // Default `null` is try use elFinderVolumeLocalFileSystem::localFileSystemInotify() on LocalFileSystem driver |
||
391 | // another driver use elFinder stat() checker |
||
392 | 'syncCheckFunc' => null, |
||
393 | // Long polling sync stand-by time (sec) |
||
394 | 'plStandby' => 30, |
||
395 | // Sleep time (sec) for elFinder stat() checker (syncChkAsTs is true) |
||
396 | 'tsPlSleep' => 10, |
||
397 | // Sleep time (sec) for elFinder ls() checker (syncChkAsTs is false) |
||
398 | 'lsPlSleep' => 30, |
||
399 | // Client side sync interval minimum (ms) |
||
400 | // Default `null` is auto set to ('tsPlSleep' or 'lsPlSleep') * 1000 |
||
401 | // `0` to disable auto sync |
||
402 | 'syncMinMs' => null, |
||
403 | // required to fix bug on macos |
||
404 | // However, we recommend to use the Normalizer plugin instead this option |
||
405 | 'utf8fix' => false, |
||
406 | // й ё Й Ё Ø Å |
||
407 | 'utf8patterns' => ["\u0438\u0306", "\u0435\u0308", "\u0418\u0306", "\u0415\u0308", "\u00d8A", "\u030a"], |
||
408 | 'utf8replace' => ["\u0439", "\u0451", "\u0419", "\u0401", "\u00d8", "\u00c5"], |
||
409 | ]; |
||
410 | |||
411 | /** |
||
412 | * Defaults permissions. |
||
413 | * |
||
414 | * @var array |
||
415 | **/ |
||
416 | protected $defaults = [ |
||
417 | 'read' => true, |
||
418 | 'write' => true, |
||
419 | 'locked' => false, |
||
420 | 'hidden' => false, |
||
421 | ]; |
||
422 | |||
423 | /** |
||
424 | * Access control function/class. |
||
425 | * |
||
426 | * @var mixed |
||
427 | **/ |
||
428 | protected $attributes = []; |
||
429 | |||
430 | /** |
||
431 | * Access control function/class. |
||
432 | * |
||
433 | * @var mixed |
||
434 | **/ |
||
435 | protected $access = null; |
||
436 | |||
437 | /** |
||
438 | * Mime types allowed to upload. |
||
439 | * |
||
440 | * @var array |
||
441 | **/ |
||
442 | protected $uploadAllow = []; |
||
443 | |||
444 | /** |
||
445 | * Mime types denied to upload. |
||
446 | * |
||
447 | * @var array |
||
448 | **/ |
||
449 | protected $uploadDeny = []; |
||
450 | |||
451 | /** |
||
452 | * Order to validate uploadAllow and uploadDeny. |
||
453 | * |
||
454 | * @var array |
||
455 | **/ |
||
456 | protected $uploadOrder = []; |
||
457 | |||
458 | /** |
||
459 | * Maximum allowed upload file size. |
||
460 | * Set as number or string with unit - "10M", "500K", "1G". |
||
461 | * |
||
462 | * @var int|string |
||
463 | **/ |
||
464 | protected $uploadMaxSize = 0; |
||
465 | |||
466 | /** |
||
467 | * Run time setting of overwrite items on upload. |
||
468 | * |
||
469 | * @var string |
||
470 | */ |
||
471 | protected $uploadOverwrite = true; |
||
472 | |||
473 | /** |
||
474 | * Maximum allowed get file size. |
||
475 | * Set as number or string with unit - "10M", "500K", "1G". |
||
476 | * |
||
477 | * @var int|string |
||
478 | **/ |
||
479 | protected $getMaxSize = -1; |
||
480 | |||
481 | /** |
||
482 | * Mimetype detect method. |
||
483 | * |
||
484 | * @var string |
||
485 | **/ |
||
486 | protected $mimeDetect = 'auto'; |
||
487 | |||
488 | /** |
||
489 | * Finfo object for mimeDetect == 'finfo'. |
||
490 | * |
||
491 | * @var object |
||
492 | **/ |
||
493 | protected $finfo = null; |
||
494 | |||
495 | /** |
||
496 | * List of disabled client's commands. |
||
497 | * |
||
498 | * @var array |
||
499 | **/ |
||
500 | protected $disabled = []; |
||
501 | |||
502 | /** |
||
503 | * default extensions/mimetypes for mimeDetect == 'internal'. |
||
504 | * |
||
505 | * @var array |
||
506 | **/ |
||
507 | protected static $mimetypes = [ |
||
508 | // applications |
||
509 | 'ai' => 'application/postscript', |
||
510 | 'eps' => 'application/postscript', |
||
511 | 'exe' => 'application/x-executable', |
||
512 | 'doc' => 'application/msword', |
||
513 | 'dot' => 'application/msword', |
||
514 | 'xls' => 'application/vnd.ms-excel', |
||
515 | 'xlt' => 'application/vnd.ms-excel', |
||
516 | 'xla' => 'application/vnd.ms-excel', |
||
517 | 'ppt' => 'application/vnd.ms-powerpoint', |
||
518 | 'pps' => 'application/vnd.ms-powerpoint', |
||
519 | 'pdf' => 'application/pdf', |
||
520 | 'xml' => 'application/xml', |
||
521 | 'swf' => 'application/x-shockwave-flash', |
||
522 | 'torrent' => 'application/x-bittorrent', |
||
523 | 'jar' => 'application/x-jar', |
||
524 | // open office (finfo detect as application/zip) |
||
525 | 'odt' => 'application/vnd.oasis.opendocument.text', |
||
526 | 'ott' => 'application/vnd.oasis.opendocument.text-template', |
||
527 | 'oth' => 'application/vnd.oasis.opendocument.text-web', |
||
528 | 'odm' => 'application/vnd.oasis.opendocument.text-master', |
||
529 | 'odg' => 'application/vnd.oasis.opendocument.graphics', |
||
530 | 'otg' => 'application/vnd.oasis.opendocument.graphics-template', |
||
531 | 'odp' => 'application/vnd.oasis.opendocument.presentation', |
||
532 | 'otp' => 'application/vnd.oasis.opendocument.presentation-template', |
||
533 | 'ods' => 'application/vnd.oasis.opendocument.spreadsheet', |
||
534 | 'ots' => 'application/vnd.oasis.opendocument.spreadsheet-template', |
||
535 | 'odc' => 'application/vnd.oasis.opendocument.chart', |
||
536 | 'odf' => 'application/vnd.oasis.opendocument.formula', |
||
537 | 'odb' => 'application/vnd.oasis.opendocument.database', |
||
538 | 'odi' => 'application/vnd.oasis.opendocument.image', |
||
539 | 'oxt' => 'application/vnd.openofficeorg.extension', |
||
540 | // MS office 2007 (finfo detect as application/zip) |
||
541 | 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', |
||
542 | 'docm' => 'application/vnd.ms-word.document.macroEnabled.12', |
||
543 | 'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template', |
||
544 | 'dotm' => 'application/vnd.ms-word.template.macroEnabled.12', |
||
545 | 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', |
||
546 | 'xlsm' => 'application/vnd.ms-excel.sheet.macroEnabled.12', |
||
547 | 'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template', |
||
548 | 'xltm' => 'application/vnd.ms-excel.template.macroEnabled.12', |
||
549 | 'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12', |
||
550 | 'xlam' => 'application/vnd.ms-excel.addin.macroEnabled.12', |
||
551 | 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', |
||
552 | 'pptm' => 'application/vnd.ms-powerpoint.presentation.macroEnabled.12', |
||
553 | 'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow', |
||
554 | 'ppsm' => 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12', |
||
555 | 'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template', |
||
556 | 'potm' => 'application/vnd.ms-powerpoint.template.macroEnabled.12', |
||
557 | 'ppam' => 'application/vnd.ms-powerpoint.addin.macroEnabled.12', |
||
558 | 'sldx' => 'application/vnd.openxmlformats-officedocument.presentationml.slide', |
||
559 | 'sldm' => 'application/vnd.ms-powerpoint.slide.macroEnabled.12', |
||
560 | // archives |
||
561 | 'gz' => 'application/x-gzip', |
||
562 | 'tgz' => 'application/x-gzip', |
||
563 | 'bz' => 'application/x-bzip2', |
||
564 | 'bz2' => 'application/x-bzip2', |
||
565 | 'tbz' => 'application/x-bzip2', |
||
566 | 'xz' => 'application/x-xz', |
||
567 | 'zip' => 'application/zip', |
||
568 | 'rar' => 'application/x-rar', |
||
569 | 'tar' => 'application/x-tar', |
||
570 | '7z' => 'application/x-7z-compressed', |
||
571 | // texts |
||
572 | 'txt' => 'text/plain', |
||
573 | 'php' => 'text/x-php', |
||
574 | 'html' => 'text/html', |
||
575 | 'htm' => 'text/html', |
||
576 | 'js' => 'text/javascript', |
||
577 | 'css' => 'text/css', |
||
578 | 'rtf' => 'text/rtf', |
||
579 | 'rtfd' => 'text/rtfd', |
||
580 | 'py' => 'text/x-python', |
||
581 | 'java' => 'text/x-java-source', |
||
582 | 'rb' => 'text/x-ruby', |
||
583 | 'sh' => 'text/x-shellscript', |
||
584 | 'pl' => 'text/x-perl', |
||
585 | //'xml' => 'text/xml', |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
67% 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. ![]() |
|||
586 | 'sql' => 'text/x-sql', |
||
587 | 'c' => 'text/x-csrc', |
||
588 | 'h' => 'text/x-chdr', |
||
589 | 'cpp' => 'text/x-c++src', |
||
590 | 'hh' => 'text/x-c++hdr', |
||
591 | 'log' => 'text/plain', |
||
592 | 'csv' => 'text/csv', |
||
593 | 'md' => 'text/x-markdown', |
||
594 | 'markdown' => 'text/x-markdown', |
||
595 | // images |
||
596 | 'bmp' => 'image/x-ms-bmp', |
||
597 | 'jpg' => 'image/jpeg', |
||
598 | 'jpeg' => 'image/jpeg', |
||
599 | 'gif' => 'image/gif', |
||
600 | 'png' => 'image/png', |
||
601 | 'tif' => 'image/tiff', |
||
602 | 'tiff' => 'image/tiff', |
||
603 | 'tga' => 'image/x-targa', |
||
604 | 'psd' => 'image/vnd.adobe.photoshop', |
||
605 | //'ai' => 'image/vnd.adobe.photoshop', |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
67% 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. ![]() |
|||
606 | 'xbm' => 'image/xbm', |
||
607 | 'pxm' => 'image/pxm', |
||
608 | //audio |
||
609 | 'mp3' => 'audio/mpeg', |
||
610 | 'mid' => 'audio/midi', |
||
611 | 'ogg' => 'audio/ogg', |
||
612 | 'oga' => 'audio/ogg', |
||
613 | 'm4a' => 'audio/mp4', |
||
614 | 'wav' => 'audio/wav', |
||
615 | 'wma' => 'audio/x-ms-wma', |
||
616 | // video |
||
617 | 'avi' => 'video/x-msvideo', |
||
618 | 'dv' => 'video/x-dv', |
||
619 | 'mp4' => 'video/mp4', |
||
620 | 'mpeg' => 'video/mpeg', |
||
621 | 'mpg' => 'video/mpeg', |
||
622 | 'mov' => 'video/quicktime', |
||
623 | 'wm' => 'video/x-ms-wmv', |
||
624 | 'flv' => 'video/x-flv', |
||
625 | 'mkv' => 'video/x-matroska', |
||
626 | 'webm' => 'video/webm', |
||
627 | 'ogv' => 'video/ogg', |
||
628 | 'ogm' => 'video/ogg', |
||
629 | ]; |
||
630 | |||
631 | /** |
||
632 | * Directory separator - required by client. |
||
633 | * |
||
634 | * @var string |
||
635 | **/ |
||
636 | protected $separator = DIRECTORY_SEPARATOR; |
||
637 | |||
638 | /** |
||
639 | * System Root path (Unix like: '/', Windows: '\', 'C:\' or 'D:\'...). |
||
640 | * |
||
641 | * @var string |
||
642 | **/ |
||
643 | protected $systemRoot = DIRECTORY_SEPARATOR; |
||
644 | |||
645 | /** |
||
646 | * Mimetypes allowed to display. |
||
647 | * |
||
648 | * @var array |
||
649 | **/ |
||
650 | protected $onlyMimes = []; |
||
651 | |||
652 | /** |
||
653 | * Store files moved or overwrited files info. |
||
654 | * |
||
655 | * @var array |
||
656 | **/ |
||
657 | protected $removed = []; |
||
658 | |||
659 | /** |
||
660 | * Store files added files info. |
||
661 | * |
||
662 | * @var array |
||
663 | **/ |
||
664 | protected $added = []; |
||
665 | |||
666 | /** |
||
667 | * Cache storage. |
||
668 | * |
||
669 | * @var array |
||
670 | **/ |
||
671 | protected $cache = []; |
||
672 | |||
673 | /** |
||
674 | * Cache by folders. |
||
675 | * |
||
676 | * @var array |
||
677 | **/ |
||
678 | protected $dirsCache = []; |
||
679 | |||
680 | /** |
||
681 | * You should use `$this->sessionCache['subdirs']` instead. |
||
682 | * |
||
683 | * @var array |
||
684 | * @deprecated |
||
685 | */ |
||
686 | protected $subdirsCache = []; |
||
687 | |||
688 | /** |
||
689 | * This volume session cache. |
||
690 | * |
||
691 | * @var array |
||
692 | */ |
||
693 | protected $sessionCache; |
||
694 | |||
695 | /** |
||
696 | * Session caching item list. |
||
697 | * |
||
698 | * @var array |
||
699 | */ |
||
700 | protected $sessionCaching = ['rootstat' => true, 'subdirs' => true]; |
||
701 | |||
702 | /** |
||
703 | * elFinder session wrapper object. |
||
704 | * |
||
705 | * @var elFinderSessionInterface |
||
706 | */ |
||
707 | protected $session; |
||
708 | |||
709 | /** |
||
710 | * Search start time. |
||
711 | * |
||
712 | * @var int |
||
713 | */ |
||
714 | protected $searchStart; |
||
715 | |||
716 | /** |
||
717 | * Current query word on doSearch. |
||
718 | * |
||
719 | * @var string |
||
720 | **/ |
||
721 | protected $doSearchCurrentQuery = []; |
||
722 | |||
723 | /** |
||
724 | * Is root modified (for clear root stat cache). |
||
725 | * |
||
726 | * @var bool |
||
727 | */ |
||
728 | protected $rootModified = false; |
||
729 | |||
730 | /** |
||
731 | * Is disable of command `url`. |
||
732 | * |
||
733 | * @var string |
||
734 | */ |
||
735 | protected $disabledGetUrl = false; |
||
736 | |||
737 | /** |
||
738 | * Accepted filename validator. |
||
739 | * |
||
740 | * @var string | callable |
||
741 | */ |
||
742 | protected $nameValidator; |
||
743 | |||
744 | /** |
||
745 | * Accepted dirname validator. |
||
746 | * |
||
747 | * @var string | callable |
||
748 | */ |
||
749 | protected $dirnameValidator; |
||
750 | |||
751 | /** |
||
752 | * Flag - mimetypes from externail file was loaded. |
||
753 | * |
||
754 | * @var bool |
||
755 | **/ |
||
756 | private static $mimetypesLoaded = false; |
||
757 | |||
758 | /*********************************************************************/ |
||
759 | /* PUBLIC API */ |
||
760 | /*********************************************************************/ |
||
761 | |||
762 | /** |
||
763 | * Return driver id. Used as a part of volume id. |
||
764 | * |
||
765 | * @return string |
||
766 | * @author Dmitry (dio) Levashov |
||
767 | **/ |
||
768 | public function driverId() |
||
769 | { |
||
770 | return $this->driverId; |
||
771 | } |
||
772 | |||
773 | /** |
||
774 | * Return volume id. |
||
775 | * |
||
776 | * @return string |
||
777 | * @author Dmitry (dio) Levashov |
||
778 | **/ |
||
779 | public function id() |
||
780 | { |
||
781 | return $this->id; |
||
782 | } |
||
783 | |||
784 | /** |
||
785 | * Assign elFinder session wrapper object. |
||
786 | * |
||
787 | * @param $session elFinderSessionInterface |
||
788 | */ |
||
789 | public function setSession($session) |
||
790 | { |
||
791 | $this->session = $session; |
||
792 | } |
||
793 | |||
794 | /** |
||
795 | * Save session cache data |
||
796 | * Calls this function before umount this volume on elFinder::exec(). |
||
797 | * |
||
798 | * @return void |
||
799 | */ |
||
800 | public function saveSessionCache() |
||
801 | { |
||
802 | $this->session->set($this->id, $this->sessionCache); |
||
803 | } |
||
804 | |||
805 | /** |
||
806 | * Return debug info for client. |
||
807 | * |
||
808 | * @return array |
||
809 | * @author Dmitry (dio) Levashov |
||
810 | **/ |
||
811 | public function debug() |
||
812 | { |
||
813 | return [ |
||
814 | 'id' => $this->id(), |
||
815 | 'name' => strtolower(substr(get_class($this), strlen('elfinderdriver'))), |
||
816 | 'mimeDetect' => $this->mimeDetect, |
||
817 | 'imgLib' => $this->imgLib, |
||
818 | ]; |
||
819 | } |
||
820 | |||
821 | /** |
||
822 | * chmod a file or folder. |
||
823 | * |
||
824 | * @param string $hash file or folder hash to chmod |
||
825 | * @param string $mode octal string representing new permissions |
||
826 | * @return array|false |
||
827 | * @author David Bartle |
||
828 | **/ |
||
829 | public function chmod($hash, $mode) |
||
830 | { |
||
831 | if ($this->commandDisabled('chmod')) { |
||
832 | return $this->setError(elFinder::ERROR_PERM_DENIED); |
||
833 | } |
||
834 | |||
835 | if (! ($file = $this->file($hash))) { |
||
836 | return $this->setError(elFinder::ERROR_FILE_NOT_FOUND); |
||
837 | } |
||
838 | |||
839 | View Code Duplication | if (! $this->options['allowChmodReadOnly']) { |
|
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. ![]() |
|||
840 | if (! $this->attr($this->decode($hash), 'write', null, ($file['mime'] === 'directory'))) { |
||
841 | return $this->setError(elFinder::ERROR_PERM_DENIED, $file['name']); |
||
842 | } |
||
843 | } |
||
844 | |||
845 | $path = $this->decode($hash); |
||
846 | $write = $file['write']; |
||
847 | |||
848 | View Code Duplication | if ($this->convEncOut(! $this->_chmod($this->convEncIn($path), $mode))) { |
|
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. ![]() |
|||
849 | return $this->setError(elFinder::ERROR_PERM_DENIED, $file['name']); |
||
850 | } |
||
851 | |||
852 | $this->clearcache(); |
||
853 | if ($path == $this->root) { |
||
854 | $this->rootModified = true; |
||
855 | } |
||
856 | |||
857 | if ($file = $this->stat($path)) { |
||
858 | $files = [$file]; |
||
859 | if ($file['mime'] === 'directory' && $write !== $file['write']) { |
||
860 | foreach ($this->getScandir($path) as $stat) { |
||
861 | if ($this->mimeAccepted($stat['mime'])) { |
||
862 | $files[] = $stat; |
||
863 | } |
||
864 | } |
||
865 | } |
||
866 | |||
867 | return $files; |
||
868 | } else { |
||
869 | return $this->setError(elFinder::ERROR_FILE_NOT_FOUND); |
||
870 | } |
||
871 | } |
||
872 | |||
873 | /** |
||
874 | * stat a file or folder for elFinder cmd exec. |
||
875 | * |
||
876 | * @param string $hash file or folder hash to chmod |
||
877 | * @return array |
||
878 | * @author Naoki Sawada |
||
879 | **/ |
||
880 | public function fstat($hash) |
||
881 | { |
||
882 | $path = $this->decode($hash); |
||
883 | |||
884 | return $this->stat($path); |
||
885 | } |
||
886 | |||
887 | /** |
||
888 | * Clear PHP stat cache & all of inner stat caches. |
||
889 | */ |
||
890 | public function clearstatcache() |
||
891 | { |
||
892 | clearstatcache(); |
||
893 | $this->clearcache(); |
||
894 | } |
||
895 | |||
896 | /** |
||
897 | * Clear inner stat caches for target hash. |
||
898 | * |
||
899 | * @param string $hash |
||
900 | */ |
||
901 | public function clearcaches($hash = null) |
||
902 | { |
||
903 | if ($hash === null) { |
||
904 | $this->clearcache(); |
||
905 | } else { |
||
906 | $path = $this->decode($hash); |
||
907 | unset($this->cache[$path], $this->dirsCache[$path]); |
||
908 | } |
||
909 | } |
||
910 | |||
911 | /** |
||
912 | * "Mount" volume. |
||
913 | * Return true if volume available for read or write, |
||
914 | * false - otherwise. |
||
915 | * |
||
916 | * @param array $opts |
||
917 | * @return bool |
||
918 | * @author Dmitry (dio) Levashov |
||
919 | * @author Alexey Sukhotin |
||
920 | */ |
||
921 | public function mount(array $opts) |
||
0 ignored issues
–
show
mount uses the super-global variable $_SERVER 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);
}
}
![]() mount 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);
}
}
![]() mount uses the super-global variable $_GET 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);
}
}
![]() |
|||
922 | { |
||
923 | $this->options = array_merge($this->options, $opts); |
||
924 | |||
925 | View Code Duplication | if (! isset($this->options['path']) || $this->options['path'] === '') { |
|
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. ![]() |
|||
926 | return $this->setError('Path undefined.'); |
||
927 | } |
||
928 | |||
929 | if (! $this->session) { |
||
930 | return $this->setError('Session wrapper dose not set. Need to `$volume->setSession(elFinderSessionInterface);` before mount.'); |
||
931 | } |
||
932 | if (! ($this->session instanceof elFinderSessionInterface)) { |
||
933 | return $this->setError('Session wrapper instance must be "elFinderSessionInterface".'); |
||
934 | } |
||
935 | |||
936 | // set driverId |
||
937 | if (! empty($this->options['driverId'])) { |
||
938 | $this->driverId = $this->options['driverId']; |
||
939 | } |
||
940 | |||
941 | $this->id = $this->driverId.(! empty($this->options['id']) ? $this->options['id'] : elFinder::$volumesCnt++).'_'; |
||
942 | $this->root = $this->normpathCE($this->options['path']); |
||
943 | $this->separator = isset($this->options['separator']) ? $this->options['separator'] : DIRECTORY_SEPARATOR; |
||
944 | $this->systemRoot = isset($this->options['systemRoot']) ? $this->options['systemRoot'] : $this->separator; |
||
945 | |||
946 | // set server encoding |
||
947 | if (! empty($this->options['encoding']) && strtoupper($this->options['encoding']) !== 'UTF-8') { |
||
948 | $this->encoding = $this->options['encoding']; |
||
949 | } else { |
||
950 | $this->encoding = null; |
||
951 | } |
||
952 | |||
953 | // set ARGS |
||
954 | $this->ARGS = $_SERVER['REQUEST_METHOD'] === 'POST' ? $_POST : $_GET; |
||
955 | |||
956 | $argInit = ! empty($this->ARGS['init']); |
||
957 | |||
958 | // session cache |
||
959 | if ($argInit) { |
||
960 | $this->session->set($this->id, []); |
||
961 | } |
||
962 | $this->sessionCache = $this->session->get($this->id, []); |
||
0 ignored issues
–
show
It seems like
$this->session->get($this->id, array()) of type * is incompatible with the declared type array of property $sessionCache .
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property. Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property.. ![]() |
|||
963 | |||
964 | // default file attribute |
||
965 | $this->defaults = [ |
||
966 | 'read' => isset($this->options['defaults']['read']) ? (bool) $this->options['defaults']['read'] : true, |
||
967 | 'write' => isset($this->options['defaults']['write']) ? (bool) $this->options['defaults']['write'] : true, |
||
968 | 'locked' => isset($this->options['defaults']['locked']) ? (bool) $this->options['defaults']['locked'] : false, |
||
969 | 'hidden' => isset($this->options['defaults']['hidden']) ? (bool) $this->options['defaults']['hidden'] : false, |
||
970 | ]; |
||
971 | |||
972 | // root attributes |
||
973 | $this->attributes[] = [ |
||
974 | 'pattern' => '~^'.preg_quote($this->separator).'$~', |
||
975 | 'locked' => true, |
||
976 | 'hidden' => false, |
||
977 | ]; |
||
978 | // set files attributes |
||
979 | View Code Duplication | if (! empty($this->options['attributes']) && is_array($this->options['attributes'])) { |
|
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. ![]() |
|||
980 | foreach ($this->options['attributes'] as $a) { |
||
981 | // attributes must contain pattern and at least one rule |
||
982 | if (! empty($a['pattern']) || count($a) > 1) { |
||
983 | $this->attributes[] = $a; |
||
984 | } |
||
985 | } |
||
986 | } |
||
987 | |||
988 | if (! empty($this->options['accessControl']) && is_callable($this->options['accessControl'])) { |
||
989 | $this->access = $this->options['accessControl']; |
||
990 | } |
||
991 | |||
992 | $this->today = mktime(0, 0, 0, date('m'), date('d'), date('Y')); |
||
993 | $this->yesterday = $this->today - 86400; |
||
994 | |||
995 | if (! $this->init()) { |
||
996 | return false; |
||
997 | } |
||
998 | |||
999 | // check some options is arrays |
||
1000 | $this->uploadAllow = isset($this->options['uploadAllow']) && is_array($this->options['uploadAllow']) |
||
1001 | ? $this->options['uploadAllow'] |
||
1002 | : []; |
||
1003 | |||
1004 | $this->uploadDeny = isset($this->options['uploadDeny']) && is_array($this->options['uploadDeny']) |
||
1005 | ? $this->options['uploadDeny'] |
||
1006 | : []; |
||
1007 | |||
1008 | $this->options['uiCmdMap'] = (isset($this->options['uiCmdMap']) && is_array($this->options['uiCmdMap'])) |
||
1009 | ? $this->options['uiCmdMap'] |
||
1010 | : []; |
||
1011 | |||
1012 | if (is_string($this->options['uploadOrder'])) { // telephat_mode on, compatibility with 1.x |
||
1013 | $parts = explode(',', isset($this->options['uploadOrder']) ? $this->options['uploadOrder'] : 'deny,allow'); |
||
1014 | $this->uploadOrder = [trim($parts[0]), trim($parts[1])]; |
||
1015 | } else { // telephat_mode off |
||
1016 | $this->uploadOrder = ! empty($this->options['uploadOrder']) ? $this->options['uploadOrder'] : ['deny', 'allow']; |
||
1017 | } |
||
1018 | |||
1019 | if (! empty($this->options['uploadMaxSize'])) { |
||
1020 | $this->uploadMaxSize = elFinder::getIniBytes('', $this->options['uploadMaxSize']); |
||
0 ignored issues
–
show
It seems like
\elFinder::getIniBytes('...tions['uploadMaxSize']) can also be of type double . However, the property $uploadMaxSize is declared as type integer|string . Maybe add an additional type check?
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly. For example, imagine you have a variable Either this assignment is in error or a type check should be added for that assignment. class Id
{
public $id;
public function __construct($id)
{
$this->id = $id;
}
}
class Account
{
/** @var Id $id */
public $id;
}
$account_id = false;
if (starsAreRight()) {
$account_id = new Id(42);
}
$account = new Account();
if ($account instanceof Id)
{
$account->id = $account_id;
}
![]() |
|||
1021 | } |
||
1022 | // Set maximum to PHP_INT_MAX |
||
1023 | if (! defined('PHP_INT_MAX')) { |
||
1024 | define('PHP_INT_MAX', 2147483647); |
||
1025 | } |
||
1026 | if ($this->uploadMaxSize < 1 || $this->uploadMaxSize > PHP_INT_MAX) { |
||
1027 | $this->uploadMaxSize = PHP_INT_MAX; |
||
1028 | } |
||
1029 | |||
1030 | // Set to get maximum size to 50% of memory_limit |
||
1031 | $memLimit = elFinder::getIniBytes('memory_limit') / 2; |
||
1032 | if ($memLimit > 0) { |
||
1033 | $this->getMaxSize = empty($this->options['getMaxSize']) ? $memLimit : min($memLimit, elFinder::getIniBytes('', $this->options['getMaxSize'])); |
||
0 ignored issues
–
show
It seems like
empty($this->options['ge...options['getMaxSize'])) can also be of type double . However, the property $getMaxSize is declared as type integer|string . Maybe add an additional type check?
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly. For example, imagine you have a variable Either this assignment is in error or a type check should be added for that assignment. class Id
{
public $id;
public function __construct($id)
{
$this->id = $id;
}
}
class Account
{
/** @var Id $id */
public $id;
}
$account_id = false;
if (starsAreRight()) {
$account_id = new Id(42);
}
$account = new Account();
if ($account instanceof Id)
{
$account->id = $account_id;
}
![]() |
|||
1034 | } else { |
||
1035 | $this->getMaxSize = -1; |
||
1036 | } |
||
1037 | |||
1038 | $this->disabled = isset($this->options['disabled']) && is_array($this->options['disabled']) |
||
1039 | ? array_values(array_diff($this->options['disabled'], ['open'])) // 'open' is required |
||
1040 | : []; |
||
1041 | |||
1042 | $this->cryptLib = $this->options['cryptLib']; |
||
1043 | $this->mimeDetect = $this->options['mimeDetect']; |
||
1044 | |||
1045 | // find available mimetype detect method |
||
1046 | $type = strtolower($this->options['mimeDetect']); |
||
1047 | $type = preg_match('/^(finfo|mime_content_type|internal|auto)$/i', $type) ? $type : 'auto'; |
||
1048 | $regexp = '/text\/x\-(php|c\+\+)/'; |
||
1049 | |||
1050 | if (($type == 'finfo' || $type == 'auto') |
||
1051 | && class_exists('finfo', false)) { |
||
1052 | $tmpFileInfo = explode(';', finfo_file(finfo_open(FILEINFO_MIME), __FILE__)); |
||
1053 | } else { |
||
1054 | $tmpFileInfo = false; |
||
1055 | } |
||
1056 | |||
1057 | $type = 'internal'; |
||
1058 | if ($tmpFileInfo && preg_match($regexp, array_shift($tmpFileInfo))) { |
||
1059 | $type = 'finfo'; |
||
1060 | $this->finfo = finfo_open(FILEINFO_MIME); |
||
1061 | } elseif (($type == 'mime_content_type' || $type == 'auto') && function_exists('mime_content_type')) { |
||
1062 | $_mimetypes = explode(';', mime_content_type(__FILE__)); |
||
1063 | if (preg_match($regexp, array_shift($_mimetypes))) { |
||
1064 | $type = 'mime_content_type'; |
||
1065 | } |
||
1066 | } |
||
1067 | $this->mimeDetect = $type; |
||
1068 | |||
1069 | // load mimes from external file for mimeDetect == 'internal' |
||
1070 | // based on Alexey Sukhotin idea and patch: http://elrte.org/redmine/issues/163 |
||
1071 | // file must be in file directory or in parent one |
||
1072 | if ($this->mimeDetect == 'internal' && ! self::$mimetypesLoaded) { |
||
1073 | self::$mimetypesLoaded = true; |
||
1074 | $this->mimeDetect = 'internal'; |
||
1075 | $file = false; |
||
1076 | if (! empty($this->options['mimefile']) && file_exists($this->options['mimefile'])) { |
||
1077 | $file = $this->options['mimefile']; |
||
1078 | } elseif (elFinder::$defaultMimefile && file_exists(elFinder::$defaultMimefile)) { |
||
1079 | $file = elFinder::$defaultMimefile; |
||
1080 | } elseif (file_exists(dirname(__FILE__).DIRECTORY_SEPARATOR.'mime.types')) { |
||
1081 | $file = dirname(__FILE__).DIRECTORY_SEPARATOR.'mime.types'; |
||
1082 | } elseif (file_exists(dirname(dirname(__FILE__)).DIRECTORY_SEPARATOR.'mime.types')) { |
||
1083 | $file = dirname(dirname(__FILE__)).DIRECTORY_SEPARATOR.'mime.types'; |
||
1084 | } |
||
1085 | |||
1086 | View Code Duplication | if ($file && file_exists($file)) { |
|
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. ![]() |
|||
1087 | $mimecf = file($file); |
||
1088 | |||
1089 | foreach ($mimecf as $line_num => $line) { |
||
1090 | if (! preg_match('/^\s*#/', $line)) { |
||
1091 | $mime = preg_split('/\s+/', $line, -1, PREG_SPLIT_NO_EMPTY); |
||
1092 | for ($i = 1, $size = count($mime); $i < $size; $i++) { |
||
1093 | if (! isset(self::$mimetypes[$mime[$i]])) { |
||
1094 | self::$mimetypes[$mime[$i]] = $mime[0]; |
||
1095 | } |
||
1096 | } |
||
1097 | } |
||
1098 | } |
||
1099 | } |
||
1100 | } |
||
1101 | |||
1102 | $this->rootName = empty($this->options['alias']) ? $this->basenameCE($this->root) : $this->options['alias']; |
||
1103 | |||
1104 | // This get's triggered if $this->root == '/' and alias is empty. |
||
1105 | // Maybe modify _basename instead? |
||
1106 | if ($this->rootName === '') { |
||
1107 | $this->rootName = $this->separator; |
||
1108 | } |
||
1109 | |||
1110 | $root = $this->stat($this->root); |
||
1111 | |||
1112 | if (! $root) { |
||
0 ignored issues
–
show
The expression
$root 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 ![]() |
|||
1113 | return $this->setError('Root folder does not exist.'); |
||
1114 | } |
||
1115 | if (! $root['read'] && ! $root['write']) { |
||
1116 | return $this->setError('Root folder has not read and write permissions.'); |
||
1117 | } |
||
1118 | |||
1119 | if ($root['read']) { |
||
1120 | if ($argInit) { |
||
1121 | // check startPath - path to open by default instead of root |
||
1122 | $startPath = $this->options['startPath'] ? $this->normpathCE($this->options['startPath']) : ''; |
||
1123 | if ($startPath) { |
||
1124 | $start = $this->stat($startPath); |
||
1125 | if (! empty($start) |
||
1126 | && $start['mime'] == 'directory' |
||
1127 | && $start['read'] |
||
1128 | && empty($start['hidden']) |
||
1129 | && $this->inpathCE($startPath, $this->root)) { |
||
1130 | $this->startPath = $startPath; |
||
1131 | if (substr($this->startPath, -1, 1) == $this->options['separator']) { |
||
1132 | $this->startPath = substr($this->startPath, 0, -1); |
||
1133 | } |
||
1134 | } |
||
1135 | } |
||
1136 | } |
||
1137 | } else { |
||
1138 | $this->options['URL'] = ''; |
||
1139 | $this->options['tmbURL'] = ''; |
||
1140 | $this->options['tmbPath'] = ''; |
||
1141 | // read only volume |
||
1142 | array_unshift($this->attributes, [ |
||
1143 | 'pattern' => '/.*/', |
||
1144 | 'read' => false, |
||
1145 | ]); |
||
1146 | } |
||
1147 | $this->treeDeep = $this->options['treeDeep'] > 0 ? (int) $this->options['treeDeep'] : 1; |
||
1148 | $this->tmbSize = $this->options['tmbSize'] > 0 ? (int) $this->options['tmbSize'] : 48; |
||
1149 | $this->URL = $this->options['URL']; |
||
1150 | if ($this->URL && preg_match('|[^/?&=]$|', $this->URL)) { |
||
1151 | $this->URL .= '/'; |
||
1152 | } |
||
1153 | if (strtolower($this->options['dirUrlOwn']) === 'auto') { |
||
1154 | $this->options['dirUrlOwn'] = $this->URL ? false : true; |
||
1155 | } else { |
||
1156 | $this->options['dirUrlOwn'] = (bool) $this->options['dirUrlOwn']; |
||
1157 | } |
||
1158 | |||
1159 | $this->tmbURL = ! empty($this->options['tmbURL']) ? $this->options['tmbURL'] : ''; |
||
1160 | if ($this->tmbURL && $this->tmbURL !== 'self' && preg_match('|[^/?&=]$|', $this->tmbURL)) { |
||
1161 | $this->tmbURL .= '/'; |
||
1162 | } |
||
1163 | |||
1164 | $this->nameValidator = ! empty($this->options['acceptedName']) && (is_string($this->options['acceptedName']) || is_callable($this->options['acceptedName'])) |
||
0 ignored issues
–
show
It seems like
!empty($this->options['a...ns['acceptedName'] : '' of type callable is incompatible with the declared type string of property $nameValidator .
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property. Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property.. ![]() |
|||
1165 | ? $this->options['acceptedName'] |
||
1166 | : ''; |
||
1167 | |||
1168 | $this->dirnameValidator = ! empty($this->options['acceptedDirname']) && (is_callable($this->options['acceptedDirname']) || (is_string($this->options['acceptedDirname']) && preg_match($this->options['acceptedDirname'], '') !== false)) |
||
0 ignored issues
–
show
It seems like
!empty($this->options['a... : $this->nameValidator of type callable is incompatible with the declared type string of property $dirnameValidator .
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property. Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property.. ![]() |
|||
1169 | ? $this->options['acceptedDirname'] |
||
1170 | : $this->nameValidator; |
||
1171 | |||
1172 | $this->_checkArchivers(); |
||
1173 | // manual control archive types to create |
||
1174 | View Code Duplication | if (! empty($this->options['archiveMimes']) && is_array($this->options['archiveMimes'])) { |
|
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. ![]() |
|||
1175 | foreach ($this->archivers['create'] as $mime => $v) { |
||
1176 | if (! in_array($mime, $this->options['archiveMimes'])) { |
||
1177 | unset($this->archivers['create'][$mime]); |
||
1178 | } |
||
1179 | } |
||
1180 | } |
||
1181 | |||
1182 | // manualy add archivers |
||
1183 | View Code Duplication | if (! empty($this->options['archivers']['create']) && is_array($this->options['archivers']['create'])) { |
|
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. ![]() |
|||
1184 | foreach ($this->options['archivers']['create'] as $mime => $conf) { |
||
1185 | if (strpos($mime, 'application/') === 0 |
||
1186 | && ! empty($conf['cmd']) |
||
1187 | && isset($conf['argc']) |
||
1188 | && ! empty($conf['ext']) |
||
1189 | && ! isset($this->archivers['create'][$mime])) { |
||
1190 | $this->archivers['create'][$mime] = $conf; |
||
1191 | } |
||
1192 | } |
||
1193 | } |
||
1194 | |||
1195 | View Code Duplication | if (! empty($this->options['archivers']['extract']) && is_array($this->options['archivers']['extract'])) { |
|
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. ![]() |
|||
1196 | foreach ($this->options['archivers']['extract'] as $mime => $conf) { |
||
1197 | if (strpos($mime, 'application/') === 0 |
||
1198 | && ! empty($conf['cmd']) |
||
1199 | && isset($conf['argc']) |
||
1200 | && ! empty($conf['ext']) |
||
1201 | && ! isset($this->archivers['extract'][$mime])) { |
||
1202 | $this->archivers['extract'][$mime] = $conf; |
||
1203 | } |
||
1204 | } |
||
1205 | } |
||
1206 | |||
1207 | if (! empty($this->options['noSessionCache']) && is_array($this->options['noSessionCache'])) { |
||
1208 | foreach ($this->options['noSessionCache'] as $_key) { |
||
1209 | $this->sessionCaching[$_key] = false; |
||
1210 | unset($this->sessionCache[$_key]); |
||
1211 | } |
||
1212 | } |
||
1213 | if ($this->sessionCaching['subdirs']) { |
||
1214 | if (! isset($this->sessionCache['subdirs'])) { |
||
1215 | $this->sessionCache['subdirs'] = []; |
||
1216 | } |
||
1217 | } |
||
1218 | |||
1219 | $this->configure(); |
||
1220 | |||
1221 | // Normarize disabled (array_merge`for type array of JSON) |
||
1222 | $this->disabled = array_values(array_unique($this->disabled)); |
||
1223 | |||
1224 | // fix sync interval |
||
1225 | View Code Duplication | if ($this->options['syncMinMs'] !== 0) { |
|
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. ![]() |
|||
1226 | $this->options['syncMinMs'] = max($this->options[$this->options['syncChkAsTs'] ? 'tsPlSleep' : 'lsPlSleep'] * 1000, intval($this->options['syncMinMs'])); |
||
1227 | } |
||
1228 | |||
1229 | // ` copyJoin` is required for the trash function |
||
1230 | if ($this->options['trashHash'] && empty($this->options['copyJoin'])) { |
||
1231 | $this->options['trashHash'] = ''; |
||
1232 | } |
||
1233 | |||
1234 | // set tmpLinkPath |
||
1235 | if (elFinder::$tmpLinkPath && ! $this->options['tmpLinkPath']) { |
||
1236 | $this->options['tmpLinkPath'] = elFinder::$tmpLinkPath; |
||
1237 | } |
||
1238 | if ($this->options['tmpLinkPath'] && is_writable($this->options['tmpLinkPath'])) { |
||
1239 | $this->tmpLinkPath = realpath($this->options['tmpLinkPath']); |
||
1240 | } elseif (! $this->options['URL'] && is_writable('../files/.tmb')) { |
||
1241 | $this->tmpLinkPath = realpath('../files/.tmb'); |
||
1242 | $this->options['tmpLinkUrl'] = ''; |
||
1243 | if (! elFinder::$tmpLinkPath) { |
||
1244 | elFinder::$tmpLinkPath = $this->tmpLinkPath; |
||
1245 | elFinder::$tmpLinkUrl = ''; |
||
1246 | } |
||
1247 | } |
||
1248 | |||
1249 | // set tmpLinkUrl |
||
1250 | if (elFinder::$tmpLinkUrl && ! $this->options['tmpLinkUrl']) { |
||
1251 | $this->options['tmpLinkUrl'] = elFinder::$tmpLinkUrl; |
||
1252 | } |
||
1253 | if ($this->options['tmpLinkUrl']) { |
||
1254 | $this->tmpLinkUrl = $this->options['tmpLinkUrl']; |
||
1255 | } |
||
1256 | if ($this->tmpLinkPath && ! $this->tmpLinkUrl) { |
||
1257 | $cur = realpath('./'); |
||
1258 | $i = 0; |
||
1259 | while ($cur !== $this->systemRoot && strpos($this->tmpLinkPath, $cur) !== 0) { |
||
1260 | $i++; |
||
1261 | $cur = dirname($cur); |
||
1262 | } |
||
1263 | list($req) = explode('?', $_SERVER['REQUEST_URI']); |
||
1264 | $reqs = explode('/', dirname($req)); |
||
1265 | $uri = implode('/', array_slice($reqs, 0, count($reqs) - 1)).substr($this->tmpLinkPath, strlen($cur)); |
||
1266 | $https = (isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off'); |
||
1267 | $this->tmpLinkUrl = ($https ? 'https://' : 'http://') |
||
1268 | .$_SERVER['SERVER_NAME'] // host |
||
1269 | .(((! $https && $_SERVER['SERVER_PORT'] == 80) || ($https && $_SERVER['SERVER_PORT'] == 443)) ? '' : (':'.$_SERVER['SERVER_PORT'])) // port |
||
1270 | .$uri; |
||
1271 | if (! elFinder::$tmpLinkUrl) { |
||
1272 | elFinder::$tmpLinkUrl = $this->tmpLinkUrl; |
||
1273 | } |
||
1274 | } |
||
1275 | |||
1276 | // remove last '/' |
||
1277 | if ($this->tmpLinkPath) { |
||
1278 | $this->tmpLinkPath = rtrim($this->tmpLinkPath, '/'); |
||
1279 | } |
||
1280 | if ($this->tmpLinkUrl) { |
||
1281 | $this->tmpLinkUrl = rtrim($this->tmpLinkUrl, '/'); |
||
1282 | } |
||
1283 | |||
1284 | // to update options cache |
||
1285 | $this->updateCache($this->root, $root); |
||
1286 | |||
1287 | return $this->mounted = true; |
||
1288 | } |
||
1289 | |||
1290 | /** |
||
1291 | * Some "unmount" stuffs - may be required by virtual fs. |
||
1292 | * |
||
1293 | * @return void |
||
1294 | * @author Dmitry (dio) Levashov |
||
1295 | **/ |
||
1296 | public function umount() |
||
1297 | { |
||
1298 | } |
||
1299 | |||
1300 | /** |
||
1301 | * Remove session cache of this volume. |
||
1302 | */ |
||
1303 | public function clearSessionCache() |
||
1304 | { |
||
1305 | $this->sessionCache = []; |
||
1306 | } |
||
1307 | |||
1308 | /** |
||
1309 | * Return error message from last failed action. |
||
1310 | * |
||
1311 | * @return array |
||
1312 | * @author Dmitry (dio) Levashov |
||
1313 | **/ |
||
1314 | public function error() |
||
1315 | { |
||
1316 | return $this->error; |
||
1317 | } |
||
1318 | |||
1319 | /** |
||
1320 | * Return is uploadable that given file name. |
||
1321 | * |
||
1322 | * @param string $name file name |
||
1323 | * @param bool $allowUnknown |
||
1324 | * @return bool |
||
1325 | * @author Naoki Sawada |
||
1326 | **/ |
||
1327 | public function isUploadableByName($name, $allowUnknown = false) |
||
1328 | { |
||
1329 | $mimeByName = $this->mimetype($name, true); |
||
1330 | |||
1331 | return ($allowUnknown && $mimeByName === 'unknown') || $this->allowPutMime($mimeByName); |
||
1332 | } |
||
1333 | |||
1334 | /** |
||
1335 | * Return Extention/MIME Table (elFinderVolumeDriver::$mimetypes). |
||
1336 | * |
||
1337 | * @return array |
||
1338 | * @author Naoki Sawada |
||
1339 | */ |
||
1340 | public function getMimeTable() |
||
1341 | { |
||
1342 | // load mime.types |
||
1343 | ! self::$mimetypesLoaded && self::mimetypeInternalDetect(); |
||
1344 | |||
1345 | return self::$mimetypes; |
||
1346 | } |
||
1347 | |||
1348 | /** |
||
1349 | * Return file extention detected by MIME type. |
||
1350 | * |
||
1351 | * @param string $mime MIME type |
||
1352 | * @param string $suffix Additional suffix |
||
1353 | * @return string |
||
1354 | * @author Naoki Sawada |
||
1355 | */ |
||
1356 | public function getExtentionByMime($mime, $suffix = '') |
||
1357 | { |
||
1358 | static $extTable = null; |
||
1359 | |||
1360 | if (is_null($extTable)) { |
||
1361 | $extTable = array_flip(array_unique($this->getMimeTable())); |
||
1362 | foreach (array_keys($this->options['mimeMap']) as $pair) { |
||
1363 | list($ext, $_mime) = explode(':', $pair); |
||
1364 | if ($_mime !== '*' && ! isset($extTable[$_mime])) { |
||
1365 | $extTable[$_mime] = $ext; |
||
1366 | } |
||
1367 | } |
||
1368 | } |
||
1369 | |||
1370 | if ($mime && isset($extTable[$mime])) { |
||
1371 | return $suffix ? ($extTable[$mime].$suffix) : $extTable[$mime]; |
||
1372 | } |
||
1373 | |||
1374 | return ''; |
||
1375 | } |
||
1376 | |||
1377 | /** |
||
1378 | * Set mimetypes allowed to display to client. |
||
1379 | * |
||
1380 | * @param array $mimes |
||
1381 | * @return void |
||
1382 | * @author Dmitry (dio) Levashov |
||
1383 | **/ |
||
1384 | public function setMimesFilter($mimes) |
||
1385 | { |
||
1386 | if (is_array($mimes)) { |
||
1387 | $this->onlyMimes = $mimes; |
||
1388 | } |
||
1389 | } |
||
1390 | |||
1391 | /** |
||
1392 | * Return root folder hash. |
||
1393 | * |
||
1394 | * @return string |
||
1395 | * @author Dmitry (dio) Levashov |
||
1396 | **/ |
||
1397 | public function root() |
||
1398 | { |
||
1399 | return $this->encode($this->root); |
||
1400 | } |
||
1401 | |||
1402 | /** |
||
1403 | * Return target path hash. |
||
1404 | * |
||
1405 | * @param string $path |
||
1406 | * @param string $name |
||
1407 | * @author Naoki Sawada |
||
1408 | * @return string |
||
1409 | */ |
||
1410 | public function getHash($path, $name = '') |
||
1411 | { |
||
1412 | if ($name !== '') { |
||
1413 | $path = $this->joinPathCE($path, $name); |
||
1414 | } |
||
1415 | |||
1416 | return $this->encode($path); |
||
1417 | } |
||
1418 | |||
1419 | /** |
||
1420 | * Return decoded path of target hash |
||
1421 | * This method do not check the stat of target |
||
1422 | * Use method `realpath()` to do check of the stat of target. |
||
1423 | * |
||
1424 | * @param string $hash |
||
1425 | * @author Naoki Sawada |
||
1426 | * @return string |
||
1427 | */ |
||
1428 | public function getPath($hash) |
||
1429 | { |
||
1430 | return $this->decode($hash); |
||
1431 | } |
||
1432 | |||
1433 | /** |
||
1434 | * Return root or startPath hash. |
||
1435 | * |
||
1436 | * @return string |
||
1437 | * @author Dmitry (dio) Levashov |
||
1438 | **/ |
||
1439 | public function defaultPath() |
||
1440 | { |
||
1441 | return $this->encode($this->startPath ? $this->startPath : $this->root); |
||
1442 | } |
||
1443 | |||
1444 | /** |
||
1445 | * Return volume options required by client:. |
||
1446 | * |
||
1447 | * @param $hash |
||
1448 | * @return array |
||
1449 | * @author Dmitry (dio) Levashov |
||
1450 | */ |
||
1451 | public function options($hash) |
||
1452 | { |
||
1453 | $create = $createext = []; |
||
1454 | if (isset($this->archivers['create']) && is_array($this->archivers['create'])) { |
||
1455 | foreach ($this->archivers['create'] as $m => $v) { |
||
1456 | $create[] = $m; |
||
1457 | $createext[$m] = $v['ext']; |
||
1458 | } |
||
1459 | } |
||
1460 | $opts = [ |
||
1461 | 'path' => $hash ? $this->path($hash) : '', |
||
1462 | 'url' => $this->URL, |
||
1463 | 'tmbUrl' => (! $this->imgLib && $this->options['tmbFbSelf']) ? 'self' : $this->tmbURL, |
||
1464 | 'disabled' => $this->disabled, |
||
1465 | 'separator' => $this->separator, |
||
1466 | 'copyOverwrite' => intval($this->options['copyOverwrite']), |
||
1467 | 'uploadOverwrite' => intval($this->options['uploadOverwrite']), |
||
1468 | 'uploadMaxSize' => intval($this->uploadMaxSize), |
||
1469 | 'uploadMaxConn' => intval($this->options['uploadMaxConn']), |
||
1470 | 'uploadMime' => [ |
||
1471 | 'firstOrder' => isset($this->uploadOrder[0]) ? $this->uploadOrder[0] : 'deny', |
||
1472 | 'allow' => $this->uploadAllow, |
||
1473 | 'deny' => $this->uploadDeny, |
||
1474 | ], |
||
1475 | 'dispInlineRegex' => $this->options['dispInlineRegex'], |
||
1476 | 'jpgQuality' => intval($this->options['jpgQuality']), |
||
1477 | 'archivers' => [ |
||
1478 | 'create' => $create, |
||
1479 | 'extract' => isset($this->archivers['extract']) && is_array($this->archivers['extract']) ? array_keys($this->archivers['extract']) : [], |
||
1480 | 'createext' => $createext, |
||
1481 | ], |
||
1482 | 'uiCmdMap' => (isset($this->options['uiCmdMap']) && is_array($this->options['uiCmdMap'])) ? $this->options['uiCmdMap'] : [], |
||
1483 | 'syncChkAsTs' => intval($this->options['syncChkAsTs']), |
||
1484 | 'syncMinMs' => intval($this->options['syncMinMs']), |
||
1485 | 'i18nFolderName' => intval($this->options['i18nFolderName']), |
||
1486 | 'tmbCrop' => intval($this->options['tmbCrop']), |
||
1487 | ]; |
||
1488 | if (! empty($this->options['trashHash'])) { |
||
1489 | $opts['trashHash'] = $this->options['trashHash']; |
||
1490 | } |
||
1491 | if ($hash === null) { |
||
1492 | // call from getRootStatExtra() |
||
1493 | if (! empty($this->options['icon'])) { |
||
1494 | $opts['icon'] = $this->options['icon']; |
||
1495 | } |
||
1496 | if (! empty($this->options['rootCssClass'])) { |
||
1497 | $opts['csscls'] = $this->options['rootCssClass']; |
||
1498 | } |
||
1499 | if (isset($this->options['netkey'])) { |
||
1500 | $opts['netkey'] = $this->options['netkey']; |
||
1501 | } |
||
1502 | } |
||
1503 | |||
1504 | return $opts; |
||
1505 | } |
||
1506 | |||
1507 | /** |
||
1508 | * Get option value of this volume. |
||
1509 | * |
||
1510 | * @param string $name target option name |
||
1511 | * @return null|mixed target option value |
||
1512 | * @author Naoki Sawada |
||
1513 | */ |
||
1514 | public function getOption($name) |
||
1515 | { |
||
1516 | return isset($this->options[$name]) ? $this->options[$name] : null; |
||
1517 | } |
||
1518 | |||
1519 | /** |
||
1520 | * Get plugin values of this options. |
||
1521 | * |
||
1522 | * @param string $name Plugin name |
||
1523 | * @return null|array Plugin values |
||
1524 | * @author Naoki Sawada |
||
1525 | */ |
||
1526 | public function getOptionsPlugin($name = '') |
||
1527 | { |
||
1528 | if ($name) { |
||
1529 | return isset($this->options['plugin'][$name]) ? $this->options['plugin'][$name] : []; |
||
1530 | } else { |
||
1531 | return $this->options['plugin']; |
||
1532 | } |
||
1533 | } |
||
1534 | |||
1535 | /** |
||
1536 | * Return true if command disabled in options. |
||
1537 | * |
||
1538 | * @param string $cmd command name |
||
1539 | * @return bool |
||
1540 | * @author Dmitry (dio) Levashov |
||
1541 | **/ |
||
1542 | public function commandDisabled($cmd) |
||
1543 | { |
||
1544 | return in_array($cmd, $this->disabled); |
||
1545 | } |
||
1546 | |||
1547 | /** |
||
1548 | * Return true if mime is required mimes list. |
||
1549 | * |
||
1550 | * @param string $mime mime type to check |
||
1551 | * @param array $mimes allowed mime types list or not set to use client mimes list |
||
1552 | * @param bool|null $empty what to return on empty list |
||
1553 | * @return bool|null |
||
1554 | * @author Dmitry (dio) Levashov |
||
1555 | * @author Troex Nevelin |
||
1556 | **/ |
||
1557 | public function mimeAccepted($mime, $mimes = null, $empty = true) |
||
1558 | { |
||
1559 | $mimes = is_array($mimes) ? $mimes : $this->onlyMimes; |
||
1560 | if (empty($mimes)) { |
||
1561 | return $empty; |
||
1562 | } |
||
1563 | |||
1564 | return $mime == 'directory' |
||
1565 | || in_array('all', $mimes) |
||
1566 | || in_array('All', $mimes) |
||
1567 | || in_array($mime, $mimes) |
||
1568 | || in_array(substr($mime, 0, strpos($mime, '/')), $mimes); |
||
1569 | } |
||
1570 | |||
1571 | /** |
||
1572 | * Return true if voume is readable. |
||
1573 | * |
||
1574 | * @return bool |
||
1575 | * @author Dmitry (dio) Levashov |
||
1576 | **/ |
||
1577 | public function isReadable() |
||
1578 | { |
||
1579 | $stat = $this->stat($this->root); |
||
1580 | |||
1581 | return $stat['read']; |
||
1582 | } |
||
1583 | |||
1584 | /** |
||
1585 | * Return true if copy from this volume allowed. |
||
1586 | * |
||
1587 | * @return bool |
||
1588 | * @author Dmitry (dio) Levashov |
||
1589 | **/ |
||
1590 | public function copyFromAllowed() |
||
1591 | { |
||
1592 | return (bool) $this->options['copyFrom']; |
||
1593 | } |
||
1594 | |||
1595 | /** |
||
1596 | * Return file path related to root with convert encoging. |
||
1597 | * |
||
1598 | * @param string $hash file hash |
||
1599 | * @return string |
||
1600 | * @author Dmitry (dio) Levashov |
||
1601 | **/ |
||
1602 | public function path($hash) |
||
1603 | { |
||
1604 | return $this->convEncOut($this->_path($this->convEncIn($this->decode($hash)))); |
||
1605 | } |
||
1606 | |||
1607 | /** |
||
1608 | * Return file real path if file exists. |
||
1609 | * |
||
1610 | * @param string $hash file hash |
||
1611 | * @return string | false |
||
1612 | * @author Dmitry (dio) Levashov |
||
1613 | **/ |
||
1614 | public function realpath($hash) |
||
1615 | { |
||
1616 | $path = $this->decode($hash); |
||
1617 | |||
1618 | return $this->stat($path) ? $path : false; |
||
1619 | } |
||
1620 | |||
1621 | /** |
||
1622 | * Return list of moved/overwrited files. |
||
1623 | * |
||
1624 | * @return array |
||
1625 | * @author Dmitry (dio) Levashov |
||
1626 | **/ |
||
1627 | public function removed() |
||
1628 | { |
||
1629 | if ($this->removed) { |
||
0 ignored issues
–
show
The expression
$this->removed 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 ![]() |
|||
1630 | $unsetSubdir = isset($this->sessionCache['subdirs']) ? true : false; |
||
1631 | foreach ($this->removed as $item) { |
||
1632 | if ($item['mime'] === 'directory') { |
||
1633 | $path = $this->decode($item['hash']); |
||
1634 | if ($unsetSubdir) { |
||
1635 | unset($this->sessionCache['subdirs'][$path]); |
||
1636 | } |
||
1637 | if ($item['phash'] !== '') { |
||
1638 | $parent = $this->decode($item['phash']); |
||
1639 | unset($this->cache[$parent]); |
||
1640 | if ($unsetSubdir) { |
||
1641 | unset($this->sessionCache['subdirs'][$parent]); |
||
1642 | } |
||
1643 | } |
||
1644 | } |
||
1645 | } |
||
1646 | } |
||
1647 | |||
1648 | return $this->removed; |
||
1649 | } |
||
1650 | |||
1651 | /** |
||
1652 | * Return list of added files. |
||
1653 | * |
||
1654 | * @deprecated |
||
1655 | * @return array |
||
1656 | * @author Naoki Sawada |
||
1657 | **/ |
||
1658 | public function added() |
||
1659 | { |
||
1660 | return $this->added; |
||
1661 | } |
||
1662 | |||
1663 | /** |
||
1664 | * Clean removed files list. |
||
1665 | * |
||
1666 | * @return void |
||
1667 | * @author Dmitry (dio) Levashov |
||
1668 | **/ |
||
1669 | public function resetRemoved() |
||
1670 | { |
||
1671 | $this->resetResultStat(); |
||
1672 | } |
||
1673 | |||
1674 | /** |
||
1675 | * Clean added/removed files list. |
||
1676 | * |
||
1677 | * @return void |
||
1678 | **/ |
||
1679 | public function resetResultStat() |
||
1680 | { |
||
1681 | $this->removed = []; |
||
1682 | $this->added = []; |
||
1683 | } |
||
1684 | |||
1685 | /** |
||
1686 | * Return file/dir hash or first founded child hash with required attr == $val. |
||
1687 | * |
||
1688 | * @param string $hash file hash |
||
1689 | * @param string $attr attribute name |
||
1690 | * @param bool $val attribute value |
||
1691 | * @return string|false |
||
1692 | * @author Dmitry (dio) Levashov |
||
1693 | **/ |
||
1694 | public function closest($hash, $attr, $val) |
||
1695 | { |
||
1696 | return ($path = $this->closestByAttr($this->decode($hash), $attr, $val)) ? $this->encode($path) : false; |
||
1697 | } |
||
1698 | |||
1699 | /** |
||
1700 | * Return file info or false on error. |
||
1701 | * |
||
1702 | * @param string $hash file hash |
||
1703 | * @return array|false |
||
1704 | * @internal param bool $realpath add realpath field to file info |
||
1705 | * @author Dmitry (dio) Levashov |
||
1706 | */ |
||
1707 | public function file($hash) |
||
1708 | { |
||
1709 | $file = $this->stat($this->decode($hash)); |
||
1710 | |||
1711 | return ($file) ? $file : $this->setError(elFinder::ERROR_FILE_NOT_FOUND); |
||
1712 | } |
||
1713 | |||
1714 | /** |
||
1715 | * Return folder info. |
||
1716 | * |
||
1717 | * @param string $hash folder hash |
||
1718 | * @param bool $resolveLink |
||
1719 | * @return array|false |
||
1720 | * @internal param bool $hidden return hidden file info |
||
1721 | * @author Dmitry (dio) Levashov |
||
1722 | */ |
||
1723 | public function dir($hash, $resolveLink = false) |
||
1724 | { |
||
1725 | if (($dir = $this->file($hash)) == false) { |
||
1726 | return $this->setError(elFinder::ERROR_DIR_NOT_FOUND); |
||
1727 | } |
||
1728 | |||
1729 | if ($resolveLink && ! empty($dir['thash'])) { |
||
1730 | $dir = $this->file($dir['thash']); |
||
1731 | } |
||
1732 | |||
1733 | return $dir && $dir['mime'] == 'directory' && empty($dir['hidden']) |
||
1734 | ? $dir |
||
1735 | : $this->setError(elFinder::ERROR_NOT_DIR); |
||
1736 | } |
||
1737 | |||
1738 | /** |
||
1739 | * Return directory content or false on error. |
||
1740 | * |
||
1741 | * @param string $hash file hash |
||
1742 | * @return array|false |
||
1743 | * @author Dmitry (dio) Levashov |
||
1744 | **/ |
||
1745 | public function scandir($hash) |
||
1746 | { |
||
1747 | if (($dir = $this->dir($hash)) == false) { |
||
1748 | return false; |
||
1749 | } |
||
1750 | |||
1751 | $path = $this->decode($hash); |
||
1752 | if ($res = $dir['read'] |
||
1753 | ? $this->getScandir($path) |
||
1754 | : $this->setError(elFinder::ERROR_PERM_DENIED)) { |
||
1755 | $dirs = null; |
||
1756 | View Code Duplication | if ($this->sessionCaching['subdirs'] && isset($this->sessionCache['subdirs'][$path])) { |
|
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. ![]() |
|||
1757 | $dirs = $this->sessionCache['subdirs'][$path]; |
||
1758 | } |
||
1759 | if ($dirs !== null || (isset($dir['dirs']) && $dir['dirs'] != 1)) { |
||
1760 | $_dir = $dir; |
||
1761 | if ($dirs || $this->subdirs($hash)) { |
||
1762 | $dir['dirs'] = 1; |
||
1763 | } else { |
||
1764 | unset($dir['dirs']); |
||
1765 | } |
||
1766 | if ($dir !== $_dir) { |
||
1767 | $this->updateCache($path, $dir); |
||
0 ignored issues
–
show
It seems like
$dir defined by $this->dir($hash) on line 1747 can also be of type boolean ; however, elFinderVolumeDriver::updateCache() does only seem to accept array , maybe add an additional type check?
If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check: /**
* @return array|string
*/
function returnsDifferentValues($x) {
if ($x) {
return 'foo';
}
return array();
}
$x = returnsDifferentValues($y);
if (is_array($x)) {
// $x is an array.
}
If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue. ![]() |
|||
1768 | } |
||
1769 | } |
||
1770 | } |
||
1771 | |||
1772 | return $res; |
||
1773 | } |
||
1774 | |||
1775 | /** |
||
1776 | * Return dir files names list. |
||
1777 | * |
||
1778 | * @param string $hash file hash |
||
1779 | * @param null $intersect |
||
1780 | * @return array |
||
1781 | * @author Dmitry (dio) Levashov |
||
1782 | */ |
||
1783 | public function ls($hash, $intersect = null) |
||
1784 | { |
||
1785 | if (($dir = $this->dir($hash)) == false || ! $dir['read']) { |
||
1786 | return false; |
||
1787 | } |
||
1788 | |||
1789 | $list = []; |
||
1790 | $path = $this->decode($hash); |
||
1791 | |||
1792 | $check = []; |
||
1793 | if ($intersect) { |
||
1794 | $check = array_flip($intersect); |
||
1795 | } |
||
1796 | |||
1797 | foreach ($this->getScandir($path) as $stat) { |
||
1798 | if (empty($stat['hidden']) && (! $check || isset($check[$stat['name']])) && $this->mimeAccepted($stat['mime'])) { |
||
0 ignored issues
–
show
The expression
$check 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 ![]() |
|||
1799 | $list[$stat['hash']] = $stat['name']; |
||
1800 | } |
||
1801 | } |
||
1802 | |||
1803 | return $list; |
||
1804 | } |
||
1805 | |||
1806 | /** |
||
1807 | * Return subfolders for required folder or false on error. |
||
1808 | * |
||
1809 | * @param string $hash folder hash or empty string to get tree from root folder |
||
1810 | * @param int $deep subdir deep |
||
1811 | * @param string $exclude dir hash which subfolders must be exluded from result, required to not get stat twice on cwd subfolders |
||
1812 | * @return array|false |
||
1813 | * @author Dmitry (dio) Levashov |
||
1814 | **/ |
||
1815 | public function tree($hash = '', $deep = 0, $exclude = '') |
||
1816 | { |
||
1817 | $path = $hash ? $this->decode($hash) : $this->root; |
||
1818 | |||
1819 | View Code Duplication | if (($dir = $this->stat($path)) == false || $dir['mime'] != 'directory') { |
|
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. ![]() |
|||
1820 | return false; |
||
1821 | } |
||
1822 | |||
1823 | $dirs = $this->gettree($path, $deep > 0 ? $deep - 1 : $this->treeDeep - 1, $exclude ? $this->decode($exclude) : null); |
||
1824 | array_unshift($dirs, $dir); |
||
1825 | |||
1826 | return $dirs; |
||
1827 | } |
||
1828 | |||
1829 | /** |
||
1830 | * Return part of dirs tree from required dir up to root dir. |
||
1831 | * |
||
1832 | * @param string $hash directory hash |
||
1833 | * @param bool|null $lineal only lineal parents |
||
1834 | * @param string $until hash that is enough to that extent >= 2.1.24 |
||
0 ignored issues
–
show
There is no parameter named
$until . Was it maybe removed?
This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. Consider the following example. The parameter /**
* @param array $germany
* @param array $island
* @param array $italy
*/
function finale($germany, $island) {
return "2:1";
}
The most likely cause is that the parameter was removed, but the annotation was not. ![]() |
|||
1835 | * @return array |
||
1836 | * @author Dmitry (dio) Levashov |
||
1837 | **/ |
||
1838 | public function parents($hash, $lineal = false) |
||
1839 | { |
||
1840 | if (($current = $this->dir($hash)) == false) { |
||
1841 | return false; |
||
1842 | } |
||
1843 | |||
1844 | $args = func_get_args(); |
||
1845 | // checks 3rd param `$until` (elFinder >= 2.1.24) |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
39% 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. ![]() |
|||
1846 | $until = ''; |
||
1847 | if (isset($args[2])) { |
||
1848 | $until = $args[2]; |
||
1849 | } |
||
1850 | |||
1851 | $path = $this->decode($hash); |
||
1852 | $tree = []; |
||
1853 | |||
1854 | while ($path && $path != $this->root) { |
||
0 ignored issues
–
show
The expression
$path 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
![]() |
|||
1855 | elFinder::extendTimeLimit(); |
||
1856 | $path = $this->dirnameCE($path); |
||
1857 | if (! ($stat = $this->stat($path)) || ! empty($stat['hidden']) || ! $stat['read']) { |
||
1858 | return false; |
||
1859 | } |
||
1860 | |||
1861 | array_unshift($tree, $stat); |
||
1862 | if (! $lineal) { |
||
0 ignored issues
–
show
The expression
$lineal of type boolean|null is loosely compared to false ; this is ambiguous if the boolean can be false. You might want to explicitly use !== null instead.
If an expression can have both $a = canBeFalseAndNull();
// Instead of
if ( ! $a) { }
// Better use one of the explicit versions:
if ($a !== null) { }
if ($a !== false) { }
if ($a !== null && $a !== false) { }
![]() |
|||
1863 | foreach ($this->gettree($path, 0) as $dir) { |
||
1864 | elFinder::extendTimeLimit(); |
||
1865 | if (! isset($tree[$dir['hash']])) { |
||
1866 | $tree[$dir['hash']] = $dir; |
||
1867 | } |
||
1868 | } |
||
1869 | } |
||
1870 | |||
1871 | if ($until && $until === $this->encode($path)) { |
||
1872 | break; |
||
1873 | } |
||
1874 | } |
||
1875 | |||
1876 | return $tree ? array_values($tree) : [$current]; |
||
1877 | } |
||
1878 | |||
1879 | /** |
||
1880 | * Create thumbnail for required file and return its name of false on failed. |
||
1881 | * |
||
1882 | * @param $hash |
||
1883 | * @return false|string |
||
1884 | * @author Dmitry (dio) Levashov |
||
1885 | */ |
||
1886 | public function tmb($hash) |
||
1887 | { |
||
1888 | $path = $this->decode($hash); |
||
1889 | $stat = $this->stat($path); |
||
1890 | |||
1891 | if (isset($stat['tmb'])) { |
||
1892 | $res = $stat['tmb'] == '1' ? $this->createTmb($path, $stat) : $stat['tmb']; |
||
1893 | if (! $res) { |
||
1894 | list($type) = explode('/', $stat['mime']); |
||
1895 | $fallback = $this->options['resourcePath'].DIRECTORY_SEPARATOR.strtolower($type).'.png'; |
||
1896 | if (is_file($fallback)) { |
||
1897 | $res = $this->tmbname($stat); |
||
1898 | if (! copy($fallback, $this->tmbPath.DIRECTORY_SEPARATOR.$res)) { |
||
1899 | $res = false; |
||
1900 | } |
||
1901 | } |
||
1902 | } |
||
1903 | |||
1904 | return $res; |
||
1905 | } |
||
1906 | |||
1907 | return false; |
||
1908 | } |
||
1909 | |||
1910 | /** |
||
1911 | * Return file size / total directory size. |
||
1912 | * |
||
1913 | * @param string file hash |
||
1914 | * @return int |
||
1915 | * @author Dmitry (dio) Levashov |
||
1916 | **/ |
||
1917 | public function size($hash) |
||
1918 | { |
||
1919 | return $this->countSize($this->decode($hash)); |
||
1920 | } |
||
1921 | |||
1922 | /** |
||
1923 | * Open file for reading and return file pointer. |
||
1924 | * |
||
1925 | * @param string file hash |
||
1926 | * @return resource |
||
1927 | * @author Dmitry (dio) Levashov |
||
1928 | **/ |
||
1929 | public function open($hash) |
||
1930 | { |
||
1931 | View Code Duplication | if (($file = $this->file($hash)) == 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. ![]() |
|||
1932 | || $file['mime'] == 'directory') { |
||
1933 | return false; |
||
1934 | } |
||
1935 | |||
1936 | return $this->fopenCE($this->decode($hash), 'rb'); |
||
1937 | } |
||
1938 | |||
1939 | /** |
||
1940 | * Close file pointer. |
||
1941 | * |
||
1942 | * @param resource $fp file pointer |
||
1943 | * @param string $hash file hash |
||
1944 | * @return void |
||
1945 | * @author Dmitry (dio) Levashov |
||
1946 | **/ |
||
1947 | public function close($fp, $hash) |
||
1948 | { |
||
1949 | $this->fcloseCE($fp, $this->decode($hash)); |
||
1950 | } |
||
1951 | |||
1952 | /** |
||
1953 | * Create directory and return dir info. |
||
1954 | * |
||
1955 | * @param string $dsthash destination directory hash |
||
1956 | * @param string $name directory name |
||
1957 | * @return array|false |
||
1958 | * @author Dmitry (dio) Levashov |
||
1959 | **/ |
||
1960 | public function mkdir($dsthash, $name) |
||
1961 | { |
||
1962 | if ($this->commandDisabled('mkdir')) { |
||
1963 | return $this->setError(elFinder::ERROR_PERM_DENIED); |
||
1964 | } |
||
1965 | |||
1966 | if (! $this->nameAccepted($name, true)) { |
||
1967 | return $this->setError(elFinder::ERROR_INVALID_DIRNAME); |
||
1968 | } |
||
1969 | |||
1970 | if (($dir = $this->dir($dsthash)) == false) { |
||
1971 | return $this->setError(elFinder::ERROR_TRGDIR_NOT_FOUND, '#'.$dsthash); |
||
1972 | } |
||
1973 | |||
1974 | $path = $this->decode($dsthash); |
||
1975 | |||
1976 | if (! $dir['write'] || ! $this->allowCreate($path, $name, true)) { |
||
1977 | return $this->setError(elFinder::ERROR_PERM_DENIED); |
||
1978 | } |
||
1979 | |||
1980 | $dst = $this->joinPathCE($path, $name); |
||
1981 | $stat = $this->isNameExists($dst); |
||
1982 | if (! empty($stat)) { |
||
1983 | return $this->setError(elFinder::ERROR_EXISTS, $name); |
||
1984 | } |
||
1985 | $this->clearcache(); |
||
1986 | |||
1987 | $mkpath = $this->convEncOut($this->_mkdir($this->convEncIn($path), $this->convEncIn($name))); |
||
1988 | if ($mkpath) { |
||
1989 | $this->updateSubdirsCache($path, true); |
||
1990 | $this->updateSubdirsCache($mkpath, false); |
||
1991 | } |
||
1992 | |||
1993 | return $mkpath ? $this->stat($mkpath) : false; |
||
1994 | } |
||
1995 | |||
1996 | /** |
||
1997 | * Create empty file and return its info. |
||
1998 | * |
||
1999 | * @param string $dst destination directory |
||
2000 | * @param string $name file name |
||
2001 | * @return array|false |
||
2002 | * @author Dmitry (dio) Levashov |
||
2003 | **/ |
||
2004 | public function mkfile($dst, $name) |
||
2005 | { |
||
2006 | if ($this->commandDisabled('mkfile')) { |
||
2007 | return $this->setError(elFinder::ERROR_PERM_DENIED); |
||
2008 | } |
||
2009 | |||
2010 | if (! $this->nameAccepted($name, false)) { |
||
2011 | return $this->setError(elFinder::ERROR_INVALID_NAME); |
||
2012 | } |
||
2013 | |||
2014 | $mimeByName = $this->mimetype($name, true); |
||
2015 | if ($mimeByName && ! $this->allowPutMime($mimeByName)) { |
||
2016 | return $this->setError(elFinder::ERROR_UPLOAD_FILE_MIME, $name); |
||
2017 | } |
||
2018 | |||
2019 | View Code Duplication | if (($dir = $this->dir($dst)) == 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. ![]() |
|||
2020 | return $this->setError(elFinder::ERROR_TRGDIR_NOT_FOUND, '#'.$dst); |
||
2021 | } |
||
2022 | |||
2023 | $path = $this->decode($dst); |
||
2024 | |||
2025 | if (! $dir['write'] || ! $this->allowCreate($path, $name, false)) { |
||
2026 | return $this->setError(elFinder::ERROR_PERM_DENIED); |
||
2027 | } |
||
2028 | |||
2029 | if ($this->isNameExists($this->joinPathCE($path, $name))) { |
||
2030 | return $this->setError(elFinder::ERROR_EXISTS, $name); |
||
2031 | } |
||
2032 | |||
2033 | $this->clearcache(); |
||
2034 | |||
2035 | return ($path = $this->convEncOut($this->_mkfile($this->convEncIn($path), $this->convEncIn($name)))) ? $this->stat($path) : false; |
||
2036 | } |
||
2037 | |||
2038 | /** |
||
2039 | * Rename file and return file info. |
||
2040 | * |
||
2041 | * @param string $hash file hash |
||
2042 | * @param string $name new file name |
||
2043 | * @return array|false |
||
2044 | * @author Dmitry (dio) Levashov |
||
2045 | **/ |
||
2046 | public function rename($hash, $name) |
||
2047 | { |
||
2048 | if ($this->commandDisabled('rename')) { |
||
2049 | return $this->setError(elFinder::ERROR_PERM_DENIED); |
||
2050 | } |
||
2051 | |||
2052 | if (! ($file = $this->file($hash))) { |
||
2053 | return $this->setError(elFinder::ERROR_FILE_NOT_FOUND); |
||
2054 | } |
||
2055 | |||
2056 | if ($name === $file['name']) { |
||
2057 | return $file; |
||
2058 | } |
||
2059 | |||
2060 | if (! empty($file['locked'])) { |
||
2061 | return $this->setError(elFinder::ERROR_LOCKED, $file['name']); |
||
2062 | } |
||
2063 | |||
2064 | $isDir = ($file['mime'] === 'directory'); |
||
2065 | |||
2066 | if (! $this->nameAccepted($name, $isDir)) { |
||
2067 | return $this->setError(elFinder::ERROR_INVALID_DIRNAME); |
||
2068 | } |
||
2069 | |||
2070 | if (! $isDir) { |
||
2071 | $mimeByName = $this->mimetype($name, true); |
||
2072 | if ($mimeByName && ! $this->allowPutMime($mimeByName)) { |
||
2073 | return $this->setError(elFinder::ERROR_UPLOAD_FILE_MIME, $name); |
||
2074 | } |
||
2075 | } |
||
2076 | |||
2077 | $path = $this->decode($hash); |
||
2078 | $dir = $this->dirnameCE($path); |
||
2079 | $stat = $this->isNameExists($this->joinPathCE($dir, $name)); |
||
2080 | if ($stat) { |
||
0 ignored issues
–
show
The expression
$stat 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 ![]() |
|||
2081 | return $this->setError(elFinder::ERROR_EXISTS, $name); |
||
2082 | } |
||
2083 | |||
2084 | if (! $this->allowCreate($dir, $name, ($file['mime'] === 'directory'))) { |
||
2085 | return $this->setError(elFinder::ERROR_PERM_DENIED); |
||
2086 | } |
||
2087 | |||
2088 | $this->rmTmb($file); // remove old name tmbs, we cannot do this after dir move |
||
0 ignored issues
–
show
$file is of type array|boolean , 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);
![]() |
|||
2089 | |||
2090 | if ($path = $this->convEncOut($this->_move($this->convEncIn($path), $this->convEncIn($dir), $this->convEncIn($name)))) { |
||
2091 | $this->clearcache(); |
||
2092 | |||
2093 | return $this->stat($path); |
||
2094 | } |
||
2095 | |||
2096 | return false; |
||
2097 | } |
||
2098 | |||
2099 | /** |
||
2100 | * Create file copy with suffix "copy number" and return its info. |
||
2101 | * |
||
2102 | * @param string $hash file hash |
||
2103 | * @param string $suffix suffix to add to file name |
||
2104 | * @return array|false |
||
2105 | * @author Dmitry (dio) Levashov |
||
2106 | **/ |
||
2107 | public function duplicate($hash, $suffix = 'copy') |
||
2108 | { |
||
2109 | if ($this->commandDisabled('duplicate')) { |
||
2110 | return $this->setError(elFinder::ERROR_COPY, '#'.$hash, elFinder::ERROR_PERM_DENIED); |
||
2111 | } |
||
2112 | |||
2113 | if (($file = $this->file($hash)) == false) { |
||
2114 | return $this->setError(elFinder::ERROR_COPY, elFinder::ERROR_FILE_NOT_FOUND); |
||
2115 | } |
||
2116 | |||
2117 | $path = $this->decode($hash); |
||
2118 | $dir = $this->dirnameCE($path); |
||
2119 | $name = $this->uniqueName($dir, $file['name'], sprintf($this->options['duplicateSuffix'], $suffix)); |
||
2120 | |||
2121 | if (! $this->allowCreate($dir, $name, ($file['mime'] === 'directory'))) { |
||
2122 | return $this->setError(elFinder::ERROR_PERM_DENIED); |
||
2123 | } |
||
2124 | |||
2125 | return ($path = $this->copy($path, $dir, $name)) == false |
||
2126 | ? false |
||
2127 | : $this->stat($path); |
||
0 ignored issues
–
show
It seems like
$path defined by $this->copy($path, $dir, $name) on line 2125 can also be of type boolean or null ; however, elFinderVolumeDriver::stat() does only seem to accept string , maybe add an additional type check?
If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check: /**
* @return array|string
*/
function returnsDifferentValues($x) {
if ($x) {
return 'foo';
}
return array();
}
$x = returnsDifferentValues($y);
if (is_array($x)) {
// $x is an array.
}
If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue. ![]() |
|||
2128 | } |
||
2129 | |||
2130 | /** |
||
2131 | * Save uploaded file. |
||
2132 | * On success return array with new file stat and with removed file hash (if existed file was replaced). |
||
2133 | * |
||
2134 | * @param resource $fp file pointer |
||
2135 | * @param string $dst destination folder hash |
||
2136 | * @param $name |
||
2137 | * @param string $tmpname file tmp name - required to detect mime type |
||
2138 | * @param array $hashes exists files hash array with filename as key |
||
2139 | * @return array|false |
||
2140 | * @internal param string $src file name |
||
2141 | * @author Dmitry (dio) Levashov |
||
2142 | */ |
||
2143 | public function upload($fp, $dst, $name, $tmpname, $hashes = []) |
||
2144 | { |
||
2145 | if ($this->commandDisabled('upload')) { |
||
2146 | return $this->setError(elFinder::ERROR_PERM_DENIED); |
||
2147 | } |
||
2148 | |||
2149 | View Code Duplication | if (($dir = $this->dir($dst)) == 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. ![]() |
|||
2150 | return $this->setError(elFinder::ERROR_TRGDIR_NOT_FOUND, '#'.$dst); |
||
2151 | } |
||
2152 | |||
2153 | if (empty($dir['write'])) { |
||
2154 | return $this->setError(elFinder::ERROR_PERM_DENIED); |
||
2155 | } |
||
2156 | |||
2157 | if (! $this->nameAccepted($name, false)) { |
||
2158 | return $this->setError(elFinder::ERROR_INVALID_NAME); |
||
2159 | } |
||
2160 | |||
2161 | $mimeByName = ''; |
||
2162 | if ($this->mimeDetect === 'internal') { |
||
2163 | $mime = $this->mimetype($name, true); |
||
2164 | } else { |
||
2165 | $mime = $this->mimetype($tmpname, $name); |
||
2166 | $mimeByName = $this->mimetype($name, true); |
||
2167 | if ($mime === 'unknown') { |
||
2168 | $mime = $mimeByName; |
||
2169 | } |
||
2170 | } |
||
2171 | |||
2172 | View Code Duplication | if (! $this->allowPutMime($mime) || ($mimeByName && ! $this->allowPutMime($mimeByName))) { |
|
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. ![]() |
|||
2173 | return $this->setError(elFinder::ERROR_UPLOAD_FILE_MIME); |
||
2174 | } |
||
2175 | |||
2176 | $tmpsize = sprintf('%u', filesize($tmpname)); |
||
2177 | if ($this->uploadMaxSize > 0 && $tmpsize > $this->uploadMaxSize) { |
||
2178 | return $this->setError(elFinder::ERROR_UPLOAD_FILE_SIZE); |
||
2179 | } |
||
2180 | |||
2181 | $dstpath = $this->decode($dst); |
||
2182 | View Code Duplication | if (isset($hashes[$name])) { |
|
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. ![]() |
|||
2183 | $test = $this->decode($hashes[$name]); |
||
2184 | $file = $this->stat($test); |
||
2185 | } else { |
||
2186 | $test = $this->joinPathCE($dstpath, $name); |
||
2187 | $file = $this->isNameExists($test); |
||
2188 | } |
||
2189 | |||
2190 | $this->clearcache(); |
||
2191 | |||
2192 | if ($file && $file['name'] === $name) { // file exists and check filename for item ID based filesystem |
||
0 ignored issues
–
show
The expression
$file 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 ![]() |
|||
2193 | if ($this->uploadOverwrite) { |
||
2194 | View Code Duplication | if (! $file['write']) { |
|
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. ![]() |
|||
2195 | return $this->setError(elFinder::ERROR_PERM_DENIED); |
||
2196 | } elseif ($file['mime'] == 'directory') { |
||
2197 | return $this->setError(elFinder::ERROR_NOT_REPLACE, $name); |
||
2198 | } |
||
2199 | $this->remove($test); |
||
2200 | } else { |
||
2201 | $name = $this->uniqueName($dstpath, $name, '-', false); |
||
2202 | } |
||
2203 | } |
||
2204 | |||
2205 | $stat = [ |
||
2206 | 'mime' => $mime, |
||
2207 | 'width' => 0, |
||
2208 | 'height' => 0, |
||
2209 | 'size' => $tmpsize, ]; |
||
2210 | |||
2211 | // $w = $h = 0; |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
37% 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. ![]() |
|||
2212 | if (strpos($mime, 'image') === 0 && ($s = getimagesize($tmpname))) { |
||
2213 | $stat['width'] = $s[0]; |
||
2214 | $stat['height'] = $s[1]; |
||
2215 | } |
||
2216 | // $this->clearcache(); |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
72% 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. ![]() |
|||
2217 | if (($path = $this->saveCE($fp, $dstpath, $name, $stat)) == false) { |
||
2218 | return false; |
||
2219 | } |
||
2220 | |||
2221 | $stat = $this->stat($path); |
||
0 ignored issues
–
show
It seems like
$path defined by $this->saveCE($fp, $dstpath, $name, $stat) on line 2217 can also be of type boolean ; however, elFinderVolumeDriver::stat() does only seem to accept string , maybe add an additional type check?
If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check: /**
* @return array|string
*/
function returnsDifferentValues($x) {
if ($x) {
return 'foo';
}
return array();
}
$x = returnsDifferentValues($y);
if (is_array($x)) {
// $x is an array.
}
If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue. ![]() |
|||
2222 | // Try get URL |
||
2223 | if (empty($stat['url']) && ($url = $this->getContentUrl($stat['hash']))) { |
||
2224 | $stat['url'] = $url; |
||
2225 | } |
||
2226 | |||
2227 | return $stat; |
||
2228 | } |
||
2229 | |||
2230 | /** |
||
2231 | * Paste files. |
||
2232 | * |
||
2233 | * @param object $volume source volume |
||
2234 | * @param $src |
||
2235 | * @param string $dst destination dir hash |
||
2236 | * @param bool $rmSrc remove source after copy? |
||
2237 | * @param array $hashes |
||
2238 | * @return array|false |
||
2239 | * @internal param string $source file hash |
||
2240 | * @author Dmitry (dio) Levashov |
||
2241 | */ |
||
2242 | public function paste($volume, $src, $dst, $rmSrc = false, $hashes = []) |
||
2243 | { |
||
2244 | $err = $rmSrc ? elFinder::ERROR_MOVE : elFinder::ERROR_COPY; |
||
2245 | |||
2246 | if ($this->commandDisabled('paste')) { |
||
2247 | return $this->setError($err, '#'.$src, elFinder::ERROR_PERM_DENIED); |
||
2248 | } |
||
2249 | |||
2250 | if (($file = $volume->file($src, $rmSrc)) == false) { |
||
2251 | return $this->setError($err, '#'.$src, elFinder::ERROR_FILE_NOT_FOUND); |
||
2252 | } |
||
2253 | |||
2254 | $name = $file['name']; |
||
2255 | $errpath = $volume->path($file['hash']); |
||
2256 | |||
2257 | View Code Duplication | if (($dir = $this->dir($dst)) == 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. ![]() |
|||
2258 | return $this->setError($err, $errpath, elFinder::ERROR_TRGDIR_NOT_FOUND, '#'.$dst); |
||
2259 | } |
||
2260 | |||
2261 | if (! $dir['write'] || ! $file['read']) { |
||
2262 | return $this->setError($err, $errpath, elFinder::ERROR_PERM_DENIED); |
||
2263 | } |
||
2264 | |||
2265 | $destination = $this->decode($dst); |
||
2266 | |||
2267 | if (($test = $volume->closest($src, $rmSrc ? 'locked' : 'read', $rmSrc))) { |
||
2268 | return $rmSrc |
||
2269 | ? $this->setError($err, $errpath, elFinder::ERROR_LOCKED, $volume->path($test)) |
||
2270 | : $this->setError($err, $errpath, empty($file['thash']) ? elFinder::ERROR_PERM_DENIED : elFinder::ERROR_MKOUTLINK); |
||
2271 | } |
||
2272 | |||
2273 | View Code Duplication | if (isset($hashes[$name])) { |
|
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. ![]() |
|||
2274 | $test = $this->decode($hashes[$name]); |
||
2275 | $stat = $this->stat($test); |
||
2276 | } else { |
||
2277 | $test = $this->joinPathCE($destination, $name); |
||
2278 | $stat = $this->isNameExists($test); |
||
2279 | } |
||
2280 | $this->clearcache(); |
||
2281 | $dstDirExists = false; |
||
2282 | if ($stat && $stat['name'] === $name) { // file exists and check filename for item ID based filesystem |
||
0 ignored issues
–
show
The expression
$stat 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 ![]() |
|||
2283 | if ($this->options['copyOverwrite']) { |
||
2284 | // do not replace file with dir or dir with file |
||
2285 | if (! $this->isSameType($file['mime'], $stat['mime'])) { |
||
2286 | return $this->setError(elFinder::ERROR_NOT_REPLACE, $this->path($stat['hash'])); |
||
2287 | } |
||
2288 | // existed file is not writable |
||
2289 | if (! $stat['write']) { |
||
2290 | return $this->setError($err, $errpath, elFinder::ERROR_PERM_DENIED); |
||
2291 | } |
||
2292 | if ($this->options['copyJoin']) { |
||
2293 | if ($stat['locked']) { |
||
2294 | return $this->setError(elFinder::ERROR_LOCKED, $this->path($stat['hash'])); |
||
2295 | } |
||
2296 | } else { |
||
2297 | // existed file locked or has locked child |
||
2298 | if (($locked = $this->closestByAttr($test, 'locked', true))) { |
||
2299 | $stat = $this->stat($locked); |
||
2300 | |||
2301 | return $this->setError(elFinder::ERROR_LOCKED, $this->path($stat['hash'])); |
||
2302 | } |
||
2303 | } |
||
2304 | // target is entity file of alias |
||
2305 | if ($volume === $this && ((isset($file['target']) && $test == $file['target']) || $test == $this->decode($src))) { |
||
2306 | return $this->setError(elFinder::ERROR_REPLACE, $errpath); |
||
2307 | } |
||
2308 | // remove existed file |
||
2309 | if (! $this->options['copyJoin'] || $stat['mime'] !== 'directory') { |
||
2310 | if (! $this->remove($test)) { |
||
2311 | return $this->setError(elFinder::ERROR_REPLACE, $this->path($stat['hash'])); |
||
2312 | } |
||
2313 | } elseif ($stat['mime'] === 'directory') { |
||
2314 | $dstDirExists = true; |
||
2315 | } |
||
2316 | } else { |
||
2317 | $name = $this->uniqueName($destination, $name, ' ', false); |
||
2318 | } |
||
2319 | } |
||
2320 | |||
2321 | // copy/move inside current volume |
||
2322 | if ($volume === $this) { // changing == operand to === fixes issue #1285 - Paul Canning 24/03/2016 |
||
2323 | $source = $this->decode($src); |
||
2324 | // do not copy into itself |
||
2325 | if ($this->inpathCE($destination, $source)) { |
||
2326 | return $this->setError(elFinder::ERROR_COPY_INTO_ITSELF, $errpath); |
||
2327 | } |
||
2328 | $rmDir = false; |
||
2329 | if ($rmSrc) { |
||
2330 | if ($dstDirExists) { |
||
2331 | $rmDir = true; |
||
2332 | $method = 'copy'; |
||
2333 | } else { |
||
2334 | $method = 'move'; |
||
2335 | } |
||
2336 | } else { |
||
2337 | $method = 'copy'; |
||
2338 | } |
||
2339 | $this->clearcache(); |
||
2340 | if ($res = ($path = $this->$method($source, $destination, $name)) ? $this->stat($path) : false) { |
||
2341 | if ($rmDir) { |
||
2342 | $this->remove($source); |
||
2343 | } |
||
2344 | } else { |
||
2345 | return false; |
||
2346 | } |
||
2347 | } else { |
||
2348 | // copy/move from another volume |
||
2349 | if (! $this->options['copyTo'] || ! $volume->copyFromAllowed()) { |
||
2350 | return $this->setError(elFinder::ERROR_COPY, $errpath, elFinder::ERROR_PERM_DENIED); |
||
2351 | } |
||
2352 | |||
2353 | if (($path = $this->copyFrom($volume, $src, $destination, $name)) == false) { |
||
2354 | return false; |
||
2355 | } |
||
2356 | |||
2357 | if ($rmSrc) { |
||
2358 | if (! $volume->rm($src)) { |
||
2359 | return $this->setError(elFinder::ERROR_MOVE, $errpath, elFinder::ERROR_RM_SRC); |
||
2360 | } |
||
2361 | } |
||
2362 | $res = $this->stat($path); |
||
0 ignored issues
–
show
It seems like
$path defined by $this->copyFrom($volume,...c, $destination, $name) on line 2353 can also be of type boolean or null ; however, elFinderVolumeDriver::stat() does only seem to accept string , maybe add an additional type check?
If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check: /**
* @return array|string
*/
function returnsDifferentValues($x) {
if ($x) {
return 'foo';
}
return array();
}
$x = returnsDifferentValues($y);
if (is_array($x)) {
// $x is an array.
}
If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue. ![]() |
|||
2363 | } |
||
2364 | |||
2365 | return $res; |
||
2366 | } |
||
2367 | |||
2368 | /** |
||
2369 | * Return path to archive of target items. |
||
2370 | * |
||
2371 | * @param array $hashes |
||
2372 | * @return string archive path |
||
2373 | * @author Naoki Sawada |
||
2374 | */ |
||
2375 | public function zipdl($hashes) |
||
2376 | { |
||
2377 | if ($this->commandDisabled('zipdl')) { |
||
2378 | return $this->setError(elFinder::ERROR_PERM_DENIED); |
||
2379 | } |
||
2380 | |||
2381 | $archivers = $this->getArchivers(); |
||
2382 | $cmd = null; |
||
2383 | if (! $archivers || empty($archivers['create'])) { |
||
0 ignored issues
–
show
The expression
$archivers 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 ![]() |
|||
2384 | return false; |
||
2385 | } |
||
2386 | $archivers = $archivers['create']; |
||
2387 | foreach (['zip', 'tgz'] as $ext) { |
||
2388 | $mime = self::$mimetypes[$ext]; |
||
2389 | if (isset($archivers[$mime])) { |
||
2390 | $cmd = $archivers[$mime]; |
||
2391 | break; |
||
2392 | } |
||
2393 | } |
||
2394 | if (! $cmd) { |
||
2395 | $cmd = $archivers[0]; |
||
2396 | $ext = $cmd['ext']; |
||
2397 | $mime = $this->mimetype('file.'.$ext, true); |
||
2398 | } |
||
2399 | $res = false; |
||
2400 | $mixed = false; |
||
2401 | $hashes = array_values($hashes); |
||
2402 | $dirname = dirname(str_replace($this->separator, DIRECTORY_SEPARATOR, $this->path($hashes[0]))); |
||
2403 | $cnt = count($hashes); |
||
2404 | if ($cnt > 1) { |
||
2405 | for ($i = 1; $i < $cnt; $i++) { |
||
2406 | if ($dirname !== dirname(str_replace($this->separator, DIRECTORY_SEPARATOR, $this->path($hashes[$i])))) { |
||
2407 | $mixed = true; |
||
2408 | break; |
||
2409 | } |
||
2410 | } |
||
2411 | } |
||
2412 | if ($mixed || $this->root == $this->dirnameCE($this->decode($hashes[0]))) { |
||
2413 | $prefix = $this->rootName; |
||
2414 | } else { |
||
2415 | $prefix = basename($dirname); |
||
2416 | } |
||
2417 | if ($dir = $this->getItemsInHand($hashes)) { |
||
2418 | $tmppre = (substr(PHP_OS, 0, 3) === 'WIN') ? 'zdl' : 'elfzdl'; |
||
2419 | $pdir = dirname($dir); |
||
2420 | // garbage collection |
||
2421 | $ttl = 7200; // expire 2h |
||
2422 | $time = time(); |
||
2423 | foreach (glob($pdir.DIRECTORY_SEPARATOR.$tmppre.'*') as $_file) { |
||
2424 | if (filemtime($_file) + $ttl < $time) { |
||
2425 | unlink($_file); |
||
2426 | } |
||
2427 | } |
||
2428 | $files = self::localScandir($dir); |
||
2429 | if ($files && ($arc = tempnam($dir, $tmppre))) { |
||
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 ![]() |
|||
2430 | unlink($arc); |
||
2431 | $arc = $arc.'.'.$ext; |
||
0 ignored issues
–
show
The variable
$ext does not seem to be defined for all execution paths leading up to this point.
If you define a variable conditionally, it can happen that it is not defined for all execution paths. Let’s take a look at an example: function myFunction($a) {
switch ($a) {
case 'foo':
$x = 1;
break;
case 'bar':
$x = 2;
break;
}
// $x is potentially undefined here.
echo $x;
}
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined. Available Fixes
![]() |
|||
2432 | $name = basename($arc); |
||
2433 | if ($arc = $this->makeArchive($dir, $files, $name, $cmd)) { |
||
2434 | $file = tempnam($pdir, $tmppre); |
||
2435 | unlink($file); |
||
2436 | $res = rename($arc, $file); |
||
2437 | $this->rmdirRecursive($dir); |
||
2438 | } |
||
2439 | } |
||
2440 | } |
||
2441 | |||
2442 | return $res ? ['path' => $file, 'ext' => $ext, 'mime' => $mime, 'prefix' => $prefix] : false; |
||
0 ignored issues
–
show
The variable
$file does not seem to be defined for all execution paths leading up to this point.
If you define a variable conditionally, it can happen that it is not defined for all execution paths. Let’s take a look at an example: function myFunction($a) {
switch ($a) {
case 'foo':
$x = 1;
break;
case 'bar':
$x = 2;
break;
}
// $x is potentially undefined here.
echo $x;
}
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined. Available Fixes
![]() The variable
$mime does not seem to be defined for all execution paths leading up to this point.
If you define a variable conditionally, it can happen that it is not defined for all execution paths. Let’s take a look at an example: function myFunction($a) {
switch ($a) {
case 'foo':
$x = 1;
break;
case 'bar':
$x = 2;
break;
}
// $x is potentially undefined here.
echo $x;
}
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined. Available Fixes
![]() |
|||
2443 | } |
||
2444 | |||
2445 | /** |
||
2446 | * Return file contents. |
||
2447 | * |
||
2448 | * @param string $hash file hash |
||
2449 | * @return string|false |
||
2450 | * @author Dmitry (dio) Levashov |
||
2451 | **/ |
||
2452 | public function getContents($hash) |
||
2453 | { |
||
2454 | $file = $this->file($hash); |
||
2455 | |||
2456 | if (! $file) { |
||
2457 | return $this->setError(elFinder::ERROR_FILE_NOT_FOUND); |
||
2458 | } |
||
2459 | |||
2460 | if ($file['mime'] == 'directory') { |
||
2461 | return $this->setError(elFinder::ERROR_NOT_FILE); |
||
2462 | } |
||
2463 | |||
2464 | if (! $file['read']) { |
||
2465 | return $this->setError(elFinder::ERROR_PERM_DENIED); |
||
2466 | } |
||
2467 | |||
2468 | if ($this->getMaxSize > 0 && $file['size'] > $this->getMaxSize) { |
||
2469 | return $this->setError(elFinder::ERROR_UPLOAD_FILE_SIZE); |
||
2470 | } |
||
2471 | |||
2472 | return $this->_getContents($this->convEncIn($this->decode($hash), true)); |
||
2473 | } |
||
2474 | |||
2475 | /** |
||
2476 | * Put content in text file and return file info. |
||
2477 | * |
||
2478 | * @param string $hash file hash |
||
2479 | * @param string $content new file content |
||
2480 | * @return array |
||
2481 | * @author Dmitry (dio) Levashov |
||
2482 | **/ |
||
2483 | public function putContents($hash, $content) |
||
2484 | { |
||
2485 | if ($this->commandDisabled('edit')) { |
||
2486 | return $this->setError(elFinder::ERROR_PERM_DENIED); |
||
2487 | } |
||
2488 | |||
2489 | $path = $this->decode($hash); |
||
2490 | |||
2491 | if (! ($file = $this->file($hash))) { |
||
2492 | return $this->setError(elFinder::ERROR_FILE_NOT_FOUND); |
||
2493 | } |
||
2494 | |||
2495 | if (! $file['write']) { |
||
2496 | return $this->setError(elFinder::ERROR_PERM_DENIED); |
||
2497 | } |
||
2498 | |||
2499 | // check data cheme |
||
2500 | if (preg_match('~^data:(.+?/.+?);base64,~', $content, $m)) { |
||
2501 | $dMime = $m[1]; |
||
2502 | if ($file['size'] > 0 && $dMime !== $file['mime']) { |
||
2503 | return $this->setError(elFinder::ERROR_PERM_DENIED); |
||
2504 | } |
||
2505 | $content = base64_decode(substr($content, strlen($m[0]))); |
||
2506 | } |
||
2507 | |||
2508 | // check MIME |
||
2509 | $name = $this->basenameCE($path); |
||
2510 | $mime = ''; |
||
2511 | $mimeByName = $this->mimetype($name, true); |
||
2512 | if ($this->mimeDetect !== 'internal') { |
||
2513 | if ($tp = tmpfile()) { |
||
2514 | fwrite($tp, $content); |
||
2515 | $info = stream_get_meta_data($tp); |
||
2516 | $filepath = $info['uri']; |
||
2517 | $mime = $this->mimetype($filepath, $name); |
||
2518 | fclose($tp); |
||
2519 | } |
||
2520 | } |
||
2521 | View Code Duplication | if (! $this->allowPutMime($mimeByName) || ($mime && ! $this->allowPutMime($mime))) { |
|
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. ![]() |
|||
2522 | return $this->setError(elFinder::ERROR_UPLOAD_FILE_MIME); |
||
2523 | } |
||
2524 | |||
2525 | $this->clearcache(); |
||
2526 | |||
2527 | return $this->convEncOut($this->_filePutContents($this->convEncIn($path), $content)) ? $this->stat($path) : false; |
||
2528 | } |
||
2529 | |||
2530 | /** |
||
2531 | * Extract files from archive. |
||
2532 | * |
||
2533 | * @param string $hash archive hash |
||
2534 | * @param null $makedir |
||
2535 | * @return array|bool |
||
2536 | * @author Dmitry (dio) Levashov, |
||
2537 | * @author Alexey Sukhotin |
||
2538 | */ |
||
2539 | public function extract($hash, $makedir = null) |
||
2540 | { |
||
2541 | if ($this->commandDisabled('extract')) { |
||
2542 | return $this->setError(elFinder::ERROR_PERM_DENIED); |
||
2543 | } |
||
2544 | |||
2545 | if (($file = $this->file($hash)) == false) { |
||
2546 | return $this->setError(elFinder::ERROR_FILE_NOT_FOUND); |
||
2547 | } |
||
2548 | |||
2549 | $archiver = isset($this->archivers['extract'][$file['mime']]) |
||
2550 | ? $this->archivers['extract'][$file['mime']] |
||
2551 | : false; |
||
2552 | |||
2553 | if (! $archiver) { |
||
2554 | return $this->setError(elFinder::ERROR_NOT_ARCHIVE); |
||
2555 | } |
||
2556 | |||
2557 | $path = $this->decode($hash); |
||
2558 | $parent = $this->stat($this->dirnameCE($path)); |
||
2559 | |||
2560 | if (! $file['read'] || ! $parent['write']) { |
||
2561 | return $this->setError(elFinder::ERROR_PERM_DENIED); |
||
2562 | } |
||
2563 | $this->clearcache(); |
||
2564 | $this->extractToNewdir = is_null($makedir) ? 'auto' : (bool) $makedir; |
||
0 ignored issues
–
show
It seems like
is_null($makedir) ? 'auto' : (bool) $makedir of type string or boolean is incompatible with the declared type integer of property $extractToNewdir .
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property. Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property.. ![]() |
|||
2565 | |||
2566 | if ($path = $this->convEncOut($this->_extract($this->convEncIn($path), $archiver))) { |
||
2567 | if (is_array($path)) { |
||
2568 | foreach ($path as $_k => $_p) { |
||
2569 | $path[$_k] = $this->stat($_p); |
||
2570 | } |
||
2571 | } else { |
||
2572 | $path = $this->stat($path); |
||
2573 | } |
||
2574 | |||
2575 | return $path; |
||
2576 | } else { |
||
2577 | return false; |
||
2578 | } |
||
2579 | } |
||
2580 | |||
2581 | /** |
||
2582 | * Add files to archive. |
||
2583 | * |
||
2584 | * @param $hashes |
||
2585 | * @param $mime |
||
2586 | * @param string $name |
||
2587 | * @return array|bool |
||
2588 | */ |
||
2589 | public function archive($hashes, $mime, $name = '') |
||
2590 | { |
||
2591 | if ($this->commandDisabled('archive')) { |
||
2592 | return $this->setError(elFinder::ERROR_PERM_DENIED); |
||
2593 | } |
||
2594 | |||
2595 | if ($name !== '' && ! $this->nameAccepted($name, false)) { |
||
2596 | return $this->setError(elFinder::ERROR_INVALID_NAME); |
||
2597 | } |
||
2598 | |||
2599 | $archiver = isset($this->archivers['create'][$mime]) |
||
2600 | ? $this->archivers['create'][$mime] |
||
2601 | : false; |
||
2602 | |||
2603 | if (! $archiver) { |
||
2604 | return $this->setError(elFinder::ERROR_ARCHIVE_TYPE); |
||
2605 | } |
||
2606 | |||
2607 | $files = []; |
||
2608 | |||
2609 | foreach ($hashes as $hash) { |
||
2610 | View Code Duplication | if (($file = $this->file($hash)) == 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. ![]() |
|||
2611 | return $this->setError(elFinder::ERROR_FILE_NOT_FOUND, '#' + $hash); |
||
2612 | } |
||
2613 | if (! $file['read']) { |
||
2614 | return $this->setError(elFinder::ERROR_PERM_DENIED); |
||
2615 | } |
||
2616 | $path = $this->decode($hash); |
||
2617 | if (! isset($dir)) { |
||
2618 | $dir = $this->dirnameCE($path); |
||
2619 | $stat = $this->stat($dir); |
||
2620 | if (! $stat['write']) { |
||
2621 | return $this->setError(elFinder::ERROR_PERM_DENIED); |
||
2622 | } |
||
2623 | } |
||
2624 | |||
2625 | $files[] = $this->basenameCE($path); |
||
2626 | } |
||
2627 | |||
2628 | if ($name === '') { |
||
2629 | $name = count($files) == 1 ? $files[0] : 'Archive'; |
||
2630 | } else { |
||
2631 | $name = str_replace(['/', '\\'], '_', preg_replace('/\.'.preg_quote($archiver['ext'], '/').'$/i', '', $name)); |
||
2632 | } |
||
2633 | $name .= '.'.$archiver['ext']; |
||
2634 | $name = $this->uniqueName($dir, $name, ''); |
||
0 ignored issues
–
show
The variable
$dir does not seem to be defined for all execution paths leading up to this point.
If you define a variable conditionally, it can happen that it is not defined for all execution paths. Let’s take a look at an example: function myFunction($a) {
switch ($a) {
case 'foo':
$x = 1;
break;
case 'bar':
$x = 2;
break;
}
// $x is potentially undefined here.
echo $x;
}
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined. Available Fixes
![]() |
|||
2635 | $this->clearcache(); |
||
2636 | |||
2637 | return ($path = $this->convEncOut($this->_archive($this->convEncIn($dir), $this->convEncIn($files), $this->convEncIn($name), $archiver))) ? $this->stat($path) : false; |
||
2638 | } |
||
2639 | |||
2640 | /** |
||
2641 | * Resize image. |
||
2642 | * |
||
2643 | * @param string $hash image file |
||
2644 | * @param int $width new width |
||
2645 | * @param int $height new height |
||
2646 | * @param int $x X start poistion for crop |
||
2647 | * @param int $y Y start poistion for crop |
||
2648 | * @param string $mode action how to mainpulate image |
||
2649 | * @param string $bg background color |
||
2650 | * @param int $degree rotete degree |
||
2651 | * @param int $jpgQuality JEPG quality (1-100) |
||
2652 | * @return array|false |
||
2653 | * @author Dmitry (dio) Levashov |
||
2654 | * @author Alexey Sukhotin |
||
2655 | * @author nao-pon |
||
2656 | * @author Troex Nevelin |
||
2657 | **/ |
||
2658 | public function resize($hash, $width, $height, $x, $y, $mode = 'resize', $bg = '', $degree = 0, $jpgQuality = null) |
||
2659 | { |
||
2660 | if ($this->commandDisabled('resize')) { |
||
2661 | return $this->setError(elFinder::ERROR_PERM_DENIED); |
||
2662 | } |
||
2663 | |||
2664 | if (($file = $this->file($hash)) == false) { |
||
2665 | return $this->setError(elFinder::ERROR_FILE_NOT_FOUND); |
||
2666 | } |
||
2667 | |||
2668 | if (! $file['write'] || ! $file['read']) { |
||
2669 | return $this->setError(elFinder::ERROR_PERM_DENIED); |
||
2670 | } |
||
2671 | |||
2672 | $path = $this->decode($hash); |
||
2673 | |||
2674 | $work_path = $this->getWorkFile($this->encoding ? $this->convEncIn($path, true) : $path); |
||
2675 | |||
2676 | if (! $work_path || ! is_writable($work_path)) { |
||
0 ignored issues
–
show
The expression
$work_path 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
![]() |
|||
2677 | if ($work_path && $path !== $work_path && is_file($work_path)) { |
||
0 ignored issues
–
show
The expression
$work_path of type string|false is loosely compared to true ; 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
![]() |
|||
2678 | unlink($work_path); |
||
2679 | } |
||
2680 | |||
2681 | return $this->setError(elFinder::ERROR_PERM_DENIED); |
||
2682 | } |
||
2683 | |||
2684 | if ($this->imgLib !== 'imagick' && $this->imgLib !== 'convert') { |
||
2685 | if (elFinder::isAnimationGif($work_path)) { |
||
2686 | return $this->setError(elFinder::ERROR_UNSUPPORT_TYPE); |
||
2687 | } |
||
2688 | } |
||
2689 | |||
2690 | switch ($mode) { |
||
2691 | |||
2692 | View Code Duplication | case 'propresize': |
|
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. ![]() |
|||
2693 | $result = $this->imgResize($work_path, $width, $height, true, true, null, $jpgQuality); |
||
2694 | break; |
||
2695 | |||
2696 | case 'crop': |
||
2697 | $result = $this->imgCrop($work_path, $width, $height, $x, $y, null, $jpgQuality); |
||
0 ignored issues
–
show
$x is of type integer , but the function expects a boolean .
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);
![]() $y is of type integer , but the function expects a boolean .
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);
![]() |
|||
2698 | break; |
||
2699 | |||
2700 | case 'fitsquare': |
||
2701 | $result = $this->imgSquareFit($work_path, $width, $height, 'center', 'middle', ($bg ? $bg : $this->options['tmbBgColor']), null, $jpgQuality); |
||
2702 | break; |
||
2703 | |||
2704 | case 'rotate': |
||
2705 | $result = $this->imgRotate($work_path, $degree, ($bg ? $bg : $this->options['bgColorFb']), null, $jpgQuality); |
||
2706 | break; |
||
2707 | |||
2708 | View Code Duplication | default: |
|
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. ![]() |
|||
2709 | $result = $this->imgResize($work_path, $width, $height, false, true, null, $jpgQuality); |
||
2710 | break; |
||
2711 | } |
||
2712 | |||
2713 | $ret = false; |
||
2714 | if ($result) { |
||
0 ignored issues
–
show
The expression
$result of type false|string is loosely compared to true ; 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
![]() |
|||
2715 | $this->rmTmb($file); |
||
0 ignored issues
–
show
$file is of type array|boolean , 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);
![]() |
|||
2716 | $this->clearstatcache(); |
||
2717 | $stat = $this->stat($path); |
||
2718 | $fstat = stat($work_path); |
||
2719 | $stat['size'] = $fstat['size']; |
||
2720 | $stat['ts'] = $fstat['mtime']; |
||
2721 | if ($imgsize = getimagesize($work_path)) { |
||
2722 | $stat['width'] = $imgsize[0]; |
||
2723 | $stat['height'] = $imgsize[1]; |
||
2724 | $stat['mime'] = $imgsize['mime']; |
||
2725 | } |
||
2726 | if ($path !== $work_path) { |
||
2727 | if ($fp = fopen($work_path, 'rb')) { |
||
2728 | $ret = $this->saveCE($fp, $this->dirnameCE($path), $this->basenameCE($path), $stat); |
||
2729 | fclose($fp); |
||
2730 | } |
||
2731 | } else { |
||
2732 | $ret = true; |
||
2733 | } |
||
2734 | if ($ret) { |
||
2735 | $this->clearcache(); |
||
2736 | $ret = $this->stat($path); |
||
2737 | $ret['width'] = $stat['width']; |
||
2738 | $ret['height'] = $stat['height']; |
||
2739 | } |
||
2740 | } |
||
2741 | if ($path !== $work_path) { |
||
2742 | is_file($work_path) && unlink($work_path); |
||
2743 | } |
||
2744 | |||
2745 | return $ret; |
||
2746 | } |
||
2747 | |||
2748 | /** |
||
2749 | * Remove file/dir. |
||
2750 | * |
||
2751 | * @param string $hash file hash |
||
2752 | * @return bool |
||
2753 | * @author Dmitry (dio) Levashov |
||
2754 | **/ |
||
2755 | public function rm($hash) |
||
2756 | { |
||
2757 | return $this->commandDisabled('rm') |
||
2758 | ? $this->setError(elFinder::ERROR_PERM_DENIED) |
||
2759 | : $this->remove($this->decode($hash)); |
||
2760 | } |
||
2761 | |||
2762 | /** |
||
2763 | * Search files. |
||
2764 | * |
||
2765 | * @param string $q search string |
||
2766 | * @param array $mimes |
||
2767 | * @param null $hash |
||
2768 | * @return array |
||
2769 | * @author Dmitry (dio) Levashov |
||
2770 | */ |
||
2771 | public function search($q, $mimes, $hash = null) |
||
2772 | { |
||
2773 | $dir = null; |
||
2774 | if ($hash) { |
||
2775 | $dir = $this->decode($hash); |
||
2776 | $stat = $this->stat($dir); |
||
2777 | if (! $stat || $stat['mime'] !== 'directory' || ! $stat['read']) { |
||
0 ignored issues
–
show
The expression
$stat 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 ![]() |
|||
2778 | $q = ''; |
||
2779 | } |
||
2780 | } |
||
2781 | if ($mimes && $this->onlyMimes) { |
||
0 ignored issues
–
show
The expression
$mimes 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 ![]() The expression
$this->onlyMimes 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 ![]() |
|||
2782 | $mimes = array_intersect($mimes, $this->onlyMimes); |
||
2783 | if (! $mimes) { |
||
0 ignored issues
–
show
The expression
$mimes 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 ![]() |
|||
2784 | $q = ''; |
||
2785 | } |
||
2786 | } |
||
2787 | $this->searchStart = time(); |
||
2788 | |||
2789 | $qs = preg_split('/"([^"]+)"| +/', $q, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE); |
||
2790 | $query = $excludes = []; |
||
2791 | foreach ($qs as $_q) { |
||
2792 | $_q = trim($_q); |
||
2793 | if ($_q !== '') { |
||
2794 | if ($_q[0] === '-') { |
||
2795 | if (isset($_q[1])) { |
||
2796 | $excludes[] = substr($_q, 1); |
||
2797 | } |
||
2798 | } else { |
||
2799 | $query[] = $_q; |
||
2800 | } |
||
2801 | } |
||
2802 | } |
||
2803 | if (! $query) { |
||
0 ignored issues
–
show
The expression
$query 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 ![]() |
|||
2804 | $q = ''; |
||
2805 | } else { |
||
2806 | $q = implode(' ', $query); |
||
2807 | $this->doSearchCurrentQuery = [ |
||
0 ignored issues
–
show
It seems like
array('q' => $q, 'excludes' => $excludes) of type array<string,string|arra...g","excludes":"array"}> is incompatible with the declared type string of property $doSearchCurrentQuery .
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property. Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property.. ![]() |
|||
2808 | 'q' => $q, |
||
2809 | 'excludes' => $excludes, |
||
2810 | ]; |
||
2811 | } |
||
2812 | |||
2813 | // valided regex $this->options['searchExDirReg'] |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
46% 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. ![]() |
|||
2814 | View Code Duplication | if ($this->options['searchExDirReg']) { |
|
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. ![]() |
|||
2815 | if (false === preg_match($this->options['searchExDirReg'], '')) { |
||
2816 | $this->options['searchExDirReg'] = ''; |
||
2817 | } |
||
2818 | } |
||
2819 | |||
2820 | return ($q === '' || $this->commandDisabled('search')) |
||
2821 | ? [] |
||
2822 | : $this->doSearch(is_null($dir) ? $this->root : $dir, $q, $mimes); |
||
2823 | } |
||
2824 | |||
2825 | /** |
||
2826 | * Return image dimensions. |
||
2827 | * |
||
2828 | * @param string $hash file hash |
||
2829 | * @return array |
||
2830 | * @author Dmitry (dio) Levashov |
||
2831 | **/ |
||
2832 | public function dimensions($hash) |
||
2833 | { |
||
2834 | if (($file = $this->file($hash)) == false) { |
||
2835 | return false; |
||
2836 | } |
||
2837 | |||
2838 | return $this->convEncOut($this->_dimensions($this->convEncIn($this->decode($hash)), $file['mime'])); |
||
2839 | } |
||
2840 | |||
2841 | /** |
||
2842 | * Return has subdirs. |
||
2843 | * |
||
2844 | * @param string $hash file hash |
||
2845 | * @return bool |
||
2846 | * @author Naoki Sawada |
||
2847 | **/ |
||
2848 | public function subdirs($hash) |
||
2849 | { |
||
2850 | return (bool) $this->subdirsCE($this->decode($hash)); |
||
2851 | } |
||
2852 | |||
2853 | /** |
||
2854 | * Return content URL (for netmout volume driver) |
||
2855 | * If file.url == 1 requests from JavaScript client with XHR. |
||
2856 | * |
||
2857 | * @param string $hash file hash |
||
2858 | * @param array $options options array |
||
2859 | * @return bool|string |
||
2860 | * @author Naoki Sawada |
||
2861 | */ |
||
2862 | public function getContentUrl($hash, $options = []) |
||
2863 | { |
||
2864 | if (($file = $this->file($hash)) === false) { |
||
2865 | return false; |
||
2866 | } |
||
2867 | if (empty($file['url'])) { |
||
2868 | if ($this->URL) { |
||
2869 | $path = str_replace($this->separator, '/', substr($this->decode($hash), strlen($this->root) + 1)); |
||
2870 | if ($this->encoding) { |
||
2871 | $path = $this->convEncIn($path, true); |
||
2872 | } |
||
2873 | $path = str_replace('%2F', '/', rawurlencode($path)); |
||
2874 | |||
2875 | return $this->URL.$path; |
||
2876 | } |
||
2877 | |||
2878 | return false; |
||
2879 | } else { |
||
2880 | if ($file['url'] != 1) { |
||
2881 | return $file['url']; |
||
2882 | } elseif (! empty($options['temporary']) && $this->tmpLinkPath) { |
||
2883 | $name = 'temp_'.md5($hash); |
||
2884 | $path = $this->tmpLinkPath.DIRECTORY_SEPARATOR.$name; |
||
2885 | $contents = $this->getContents($hash); |
||
0 ignored issues
–
show
$contents 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 ![]() |
|||
2886 | $gc = create_function('$p,$t', 'foreach(glob($p) as $f) { (filemtime($f) < (time() - $t)) && unlink($f); }'); |
||
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; }
![]() |
|||
2887 | /*$gc = function($p,$t) { |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
61% 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. ![]() |
|||
2888 | foreach(glob($p) as $f) { |
||
2889 | (filemtime($f) < (time() - $t)) && unlink($f); |
||
2890 | } |
||
2891 | };*/ |
||
2892 | register_shutdown_function($gc, $this->tmpLinkPath.DIRECTORY_SEPARATOR.'temp_*', elFinder::$tmpLinkLifeTime); |
||
2893 | if (file_put_contents($path, $this->getContents($hash))) { |
||
2894 | return $this->tmpLinkUrl.'/'.$name; |
||
2895 | } |
||
2896 | } |
||
2897 | |||
2898 | return false; |
||
2899 | } |
||
2900 | } |
||
2901 | |||
2902 | /** |
||
2903 | * Return temp path. |
||
2904 | * |
||
2905 | * @return string |
||
2906 | * @author Naoki Sawada |
||
2907 | */ |
||
2908 | public function getTempPath() |
||
2909 | { |
||
2910 | $tempPath = null; |
||
2911 | if (isset($this->tmpPath) && $this->tmpPath && is_writable($this->tmpPath)) { |
||
2912 | $tempPath = $this->tmpPath; |
||
0 ignored issues
–
show
The property
tmpPath does not exist. Did you maybe forget to declare it?
In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code: class MyClass { }
$x = new MyClass();
$x->foo = true;
Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion: class MyClass {
public $foo;
}
$x = new MyClass();
$x->foo = true;
![]() |
|||
2913 | } elseif (isset($this->tmp) && $this->tmp && is_writable($this->tmp)) { |
||
0 ignored issues
–
show
The property
tmp does not exist. Did you maybe forget to declare it?
In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code: class MyClass { }
$x = new MyClass();
$x->foo = true;
Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion: class MyClass {
public $foo;
}
$x = new MyClass();
$x->foo = true;
![]() |
|||
2914 | $tempPath = $this->tmp; |
||
2915 | } elseif (function_exists('sys_get_temp_dir')) { |
||
2916 | $tempPath = sys_get_temp_dir(); |
||
2917 | } elseif ($this->tmbPathWritable) { |
||
2918 | $tempPath = $this->tmbPath; |
||
2919 | } |
||
2920 | if ($tempPath && DIRECTORY_SEPARATOR !== '/') { |
||
2921 | $tempPath = str_replace('/', DIRECTORY_SEPARATOR, $tempPath); |
||
2922 | } |
||
2923 | |||
2924 | return $tempPath; |
||
2925 | } |
||
2926 | |||
2927 | /** |
||
2928 | * (Make &) Get upload taget dirctory hash. |
||
2929 | * |
||
2930 | * @param string $baseTargetHash |
||
2931 | * @param string $path |
||
2932 | * @param array $result |
||
2933 | * @return bool|string |
||
2934 | * @author Naoki Sawada |
||
2935 | */ |
||
2936 | public function getUploadTaget($baseTargetHash, $path, &$result) |
||
2937 | { |
||
2938 | $base = $this->decode($baseTargetHash); |
||
2939 | $targetHash = $baseTargetHash; |
||
2940 | $path = ltrim($path, $this->separator); |
||
2941 | $dirs = explode($this->separator, $path); |
||
2942 | array_pop($dirs); |
||
2943 | foreach ($dirs as $dir) { |
||
2944 | $targetPath = $this->joinPathCE($base, $dir); |
||
2945 | if (! $_realpath = $this->realpath($this->encode($targetPath))) { |
||
2946 | if ($stat = $this->mkdir($targetHash, $dir)) { |
||
2947 | $result['added'][] = $stat; |
||
2948 | $targetHash = $stat['hash']; |
||
2949 | $base = $this->decode($targetHash); |
||
2950 | } else { |
||
2951 | return false; |
||
2952 | } |
||
2953 | } else { |
||
2954 | $targetHash = $this->encode($_realpath); |
||
2955 | if ($this->dir($targetHash)) { |
||
2956 | $base = $this->decode($targetHash); |
||
2957 | } else { |
||
2958 | return false; |
||
2959 | } |
||
2960 | } |
||
2961 | } |
||
2962 | |||
2963 | return $targetHash; |
||
2964 | } |
||
2965 | |||
2966 | /** |
||
2967 | * Return this uploadMaxSize value. |
||
2968 | * |
||
2969 | * @return int |
||
2970 | * @author Naoki Sawada |
||
2971 | */ |
||
2972 | public function getUploadMaxSize() |
||
2973 | { |
||
2974 | return $this->uploadMaxSize; |
||
2975 | } |
||
2976 | |||
2977 | public function setUploadOverwrite($var) |
||
2978 | { |
||
2979 | $this->uploadOverwrite = (bool) $var; |
||
0 ignored issues
–
show
The property
$uploadOverwrite was declared of type string , but (bool) $var is of type boolean . Maybe add a type cast?
This check looks for assignments to scalar types that may be of the wrong type. To ensure the code behaves as expected, it may be a good idea to add an explicit type cast. $answer = 42;
$correct = false;
$correct = (bool) $answer;
![]() |
|||
2980 | } |
||
2981 | |||
2982 | /** |
||
2983 | * Image file utility. |
||
2984 | * |
||
2985 | * @param string $mode 'resize', 'rotate', 'propresize', 'crop', 'fitsquare' |
||
2986 | * @param string $src Image file local path |
||
2987 | * @param array $options excute options |
||
2988 | * @return bool |
||
2989 | * @author Naoki Sawada |
||
2990 | */ |
||
2991 | public function imageUtil($mode, $src, $options = []) |
||
2992 | { |
||
2993 | if (! isset($options['jpgQuality'])) { |
||
2994 | $options['jpgQuality'] = intval($this->options['jpgQuality']); |
||
2995 | } |
||
2996 | if (! isset($options['bgcolor'])) { |
||
2997 | $options['bgcolor'] = '#ffffff'; |
||
2998 | } |
||
2999 | if (! isset($options['bgColorFb'])) { |
||
3000 | $options['bgColorFb'] = $this->options['bgColorFb']; |
||
3001 | } |
||
3002 | |||
3003 | // check 'width' ,'height' |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
43% 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. ![]() |
|||
3004 | if (in_array($mode, ['resize', 'propresize', 'crop', 'fitsquare'])) { |
||
3005 | if (empty($options['width']) || empty($options['height'])) { |
||
3006 | return false; |
||
3007 | } |
||
3008 | } |
||
3009 | |||
3010 | switch ($mode) { |
||
3011 | case 'rotate': |
||
3012 | if (empty($options['degree'])) { |
||
3013 | return true; |
||
3014 | } |
||
3015 | |||
3016 | return (bool) $this->imgRotate($src, $options['degree'], $options['bgColorFb'], null, $options['jpgQuality']); |
||
3017 | |||
3018 | View Code Duplication | case 'resize': |
|
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. ![]() |
|||
3019 | return (bool) $this->imgResize($src, $options['width'], $options['height'], false, true, null, $options['jpgQuality'], $options); |
||
3020 | |||
3021 | View Code Duplication | case 'propresize': |
|
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. ![]() |
|||
3022 | return (bool) $this->imgResize($src, $options['width'], $options['height'], true, true, null, $options['jpgQuality'], $options); |
||
3023 | |||
3024 | case 'crop': |
||
3025 | if (isset($options['x']) && isset($options['y'])) { |
||
3026 | return (bool) $this->imgCrop($src, $options['width'], $options['height'], $options['x'], $options['y'], null, $options['jpgQuality']); |
||
3027 | } |
||
3028 | break; |
||
3029 | |||
3030 | case 'fitsquare': |
||
3031 | return (bool) $this->imgSquareFit($src, $options['width'], $options['height'], 'center', 'middle', $options['bgcolor'], null, $options['jpgQuality']); |
||
3032 | |||
3033 | } |
||
3034 | |||
3035 | return false; |
||
3036 | } |
||
3037 | |||
3038 | /** |
||
3039 | * Convert Video To Image by ffmpeg. |
||
3040 | * |
||
3041 | * @param $file video source file path |
||
3042 | * @param $stat file stat array |
||
3043 | * @return bool |
||
3044 | * @author Naoki Sawada |
||
3045 | */ |
||
3046 | public function ffmpegToImg($file, $stat) |
||
0 ignored issues
–
show
ffmpegToImg uses the super-global variable $GLOBALS 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);
}
}
![]() |
|||
3047 | { |
||
3048 | $name = basename($file); |
||
3049 | $path = dirname($file); |
||
3050 | $tmp = $path.DIRECTORY_SEPARATOR.md5($name); |
||
3051 | $GLOBALS['elFinderTempFiles'][] = $tmp; // regist to remove at the end |
||
3052 | if (rename($file, $tmp)) { |
||
3053 | // specific start time by file name (xxx^[sec].[extention] - video^3.mp4) |
||
3054 | if (preg_match('/\^(\d+(?:\.\d+)?)\.[^.]+$/', $stat['name'], $_m)) { |
||
3055 | $ss = $_m[1]; |
||
3056 | } else { |
||
3057 | $ss = $this->options['tmbVideoConvSec']; |
||
3058 | } |
||
3059 | $cmd = sprintf('ffmpeg -i %s -ss 00:00:%.3f -vframes 1 -f image2 %s', escapeshellarg($tmp), $ss, escapeshellarg($file)); |
||
3060 | $r = $this->procExec($cmd); |
||
3061 | unlink($tmp); |
||
3062 | |||
3063 | return $r === 0; |
||
3064 | } |
||
3065 | |||
3066 | return false; |
||
3067 | } |
||
3068 | |||
3069 | /** |
||
3070 | * Return new unique name based on file name and suffix. |
||
3071 | * |
||
3072 | * @param $dir |
||
3073 | * @param $name |
||
3074 | * @param string $suffix suffix append to name |
||
3075 | * @param bool $checkNum |
||
3076 | * @param int $start |
||
3077 | * @return string |
||
3078 | * @internal param string $path file path |
||
3079 | * @author Dmitry (dio) Levashov |
||
3080 | */ |
||
3081 | public function uniqueName($dir, $name, $suffix = ' copy', $checkNum = true, $start = 1) |
||
3082 | { |
||
3083 | $ext = ''; |
||
3084 | |||
3085 | if (preg_match('/\.((tar\.(gz|bz|bz2|z|lzo))|cpio\.gz|ps\.gz|xcf\.(gz|bz2)|[a-z0-9]{1,4})$/i', $name, $m)) { |
||
3086 | $ext = '.'.$m[1]; |
||
3087 | $name = substr($name, 0, strlen($name) - strlen($m[0])); |
||
3088 | } |
||
3089 | |||
3090 | if ($checkNum && preg_match('/('.preg_quote($suffix, '/').')(\d*)$/i', $name, $m)) { |
||
3091 | $i = (int) $m[2]; |
||
3092 | $name = substr($name, 0, strlen($name) - strlen($m[2])); |
||
3093 | } else { |
||
3094 | $i = $start; |
||
3095 | $name .= $suffix; |
||
3096 | } |
||
3097 | $max = $i + 100000; |
||
3098 | |||
3099 | while ($i <= $max) { |
||
3100 | $n = $name.($i > 0 ? sprintf($this->options['uniqueNumFormat'], $i) : '').$ext; |
||
3101 | |||
3102 | if (! $this->isNameExists($this->joinPathCE($dir, $n))) { |
||
3103 | $this->clearcache(); |
||
3104 | |||
3105 | return $n; |
||
3106 | } |
||
3107 | $i++; |
||
3108 | } |
||
3109 | |||
3110 | return $name.md5($dir).$ext; |
||
3111 | } |
||
3112 | |||
3113 | /** |
||
3114 | * Converts character encoding from UTF-8 to server's one. |
||
3115 | * |
||
3116 | * @param mixed $var target string or array var |
||
3117 | * @param bool $restoreLocale do retore global locale, default is false |
||
3118 | * @param string $unknown replaces character for unknown |
||
3119 | * @return mixed |
||
3120 | * @author Naoki Sawada |
||
3121 | */ |
||
3122 | public function convEncIn($var = null, $restoreLocale = false, $unknown = '_') |
||
3123 | { |
||
3124 | return (! $this->encoding) ? $var : $this->convEnc($var, 'UTF-8', $this->encoding, $this->options['locale'], $restoreLocale, $unknown); |
||
3125 | } |
||
3126 | |||
3127 | /** |
||
3128 | * Converts character encoding from server's one to UTF-8. |
||
3129 | * |
||
3130 | * @param mixed $var target string or array var |
||
3131 | * @param bool $restoreLocale do retore global locale, default is true |
||
3132 | * @param string $unknown replaces character for unknown |
||
3133 | * @return mixed |
||
3134 | * @author Naoki Sawada |
||
3135 | */ |
||
3136 | public function convEncOut($var = null, $restoreLocale = true, $unknown = '_') |
||
3137 | { |
||
3138 | return (! $this->encoding) ? $var : $this->convEnc($var, $this->encoding, 'UTF-8', $this->options['locale'], $restoreLocale, $unknown); |
||
3139 | } |
||
3140 | |||
3141 | /** |
||
3142 | * Get image size array with `dimensions`. |
||
3143 | * |
||
3144 | * @param string $path path need convert encoding to server encoding |
||
3145 | * @param string $mime file mime type |
||
3146 | * @return array|false |
||
3147 | */ |
||
3148 | public function getImageSize($path, $mime = '') |
||
3149 | { |
||
3150 | $size = false; |
||
3151 | if ($mime === '' || strtolower(substr($mime, 0, 5)) === 'image') { |
||
3152 | if ($work = $this->getWorkFile($path)) { |
||
3153 | if ($size = getimagesize($work)) { |
||
3154 | $size['dimensions'] = $size[0].'x'.$size[1]; |
||
3155 | } |
||
3156 | } |
||
3157 | is_file($work) && unlink($work); |
||
3158 | } |
||
3159 | |||
3160 | return $size; |
||
3161 | } |
||
3162 | |||
3163 | /** |
||
3164 | * Remove directory recursive on local file system. |
||
3165 | * |
||
3166 | * @param string $dir Target dirctory path |
||
3167 | * @return bool |
||
3168 | * @author Naoki Sawada |
||
3169 | */ |
||
3170 | public function rmdirRecursive($dir) |
||
3171 | { |
||
3172 | return self::localRmdirRecursive($dir); |
||
3173 | } |
||
3174 | |||
3175 | /*********************************************************************/ |
||
3176 | /* INITIALIZATION */ |
||
3177 | /*********************************************************************/ |
||
3178 | |||
3179 | /** |
||
3180 | * Prepare driver before mount volume. |
||
3181 | * Return true if volume is ready. |
||
3182 | * |
||
3183 | * @return bool |
||
3184 | * @author Dmitry (dio) Levashov |
||
3185 | **/ |
||
3186 | protected function init() |
||
3187 | { |
||
3188 | return true; |
||
3189 | } |
||
3190 | |||
3191 | /** |
||
3192 | * Configure after successfull mount. |
||
3193 | * By default set thumbnails path and image manipulation library. |
||
3194 | * |
||
3195 | * @return void |
||
3196 | * @author Dmitry (dio) Levashov |
||
3197 | **/ |
||
3198 | protected function configure() |
||
3199 | { |
||
3200 | // set thumbnails path |
||
3201 | $path = $this->options['tmbPath']; |
||
3202 | if ($path) { |
||
3203 | View Code Duplication | if (! file_exists($path)) { |
|
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. ![]() |
|||
3204 | if (mkdir($path)) { |
||
3205 | chmod($path, $this->options['tmbPathMode']); |
||
3206 | } else { |
||
3207 | $path = ''; |
||
3208 | } |
||
3209 | } |
||
3210 | |||
3211 | if (is_dir($path) && is_readable($path)) { |
||
3212 | $this->tmbPath = $path; |
||
3213 | $this->tmbPathWritable = is_writable($path); |
||
3214 | } |
||
3215 | } |
||
3216 | // set resouce path |
||
3217 | if (! is_dir($this->options['resourcePath'])) { |
||
3218 | $this->options['resourcePath'] = dirname(__FILE__).DIRECTORY_SEPARATOR.'resources'; |
||
3219 | } |
||
3220 | |||
3221 | // set image manipulation library |
||
3222 | $type = preg_match('/^(imagick|gd|convert|auto)$/i', $this->options['imgLib']) |
||
3223 | ? strtolower($this->options['imgLib']) |
||
3224 | : 'auto'; |
||
3225 | |||
3226 | $imgLibFallback = extension_loaded('imagick') ? 'imagick' : (function_exists('gd_info') ? 'gd' : ''); |
||
0 ignored issues
–
show
$imgLibFallback 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 ![]() |
|||
3227 | if (($type === 'imagick' || $type === 'auto') && extension_loaded('imagick')) { |
||
3228 | $this->imgLib = 'imagick'; |
||
3229 | } elseif (($type === 'gd' || $type === 'auto') && function_exists('gd_info')) { |
||
3230 | $this->imgLib = 'gd'; |
||
3231 | } else { |
||
3232 | $convertCache = 'imgLibConvert'; |
||
3233 | if (($convertCmd = $this->session->get($convertCache, false)) !== false) { |
||
3234 | $this->imgLib = $convertCmd; |
||
3235 | } else { |
||
3236 | $this->imgLib = ($this->procExec('convert -version') === 0) ? 'convert' : ''; |
||
3237 | $this->session->set($convertCache, $this->imgLib); |
||
3238 | } |
||
3239 | } |
||
3240 | if ($type !== 'auto' && $this->imgLib === '') { |
||
3241 | // fallback |
||
3242 | $this->imgLib = extension_loaded('imagick') ? 'imagick' : (function_exists('gd_info') ? 'gd' : ''); |
||
3243 | } |
||
3244 | |||
3245 | // check video to img converter |
||
3246 | View Code Duplication | if (! empty($this->options['imgConverter']) && is_array($this->options['imgConverter'])) { |
|
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. ![]() |
|||
3247 | foreach ($this->options['imgConverter'] as $_type => $_converter) { |
||
3248 | if (isset($_converter['func'])) { |
||
3249 | $this->imgConverter[strtolower($_type)] = $_converter; |
||
3250 | } |
||
3251 | } |
||
3252 | } |
||
3253 | if (! isset($this->imgConverter['video'])) { |
||
3254 | $videoLibCache = 'videoLib'; |
||
3255 | if (($videoLibCmd = $this->session->get($videoLibCache, false)) === false) { |
||
3256 | $videoLibCmd = ($this->procExec('ffmpeg -version') === 0) ? 'ffmpeg' : ''; |
||
3257 | $this->session->set($videoLibCache, $videoLibCmd); |
||
3258 | } |
||
3259 | if ($videoLibCmd) { |
||
3260 | $this->imgConverter['video'] = [ |
||
3261 | 'func' => [$this, $videoLibCmd.'ToImg'], |
||
3262 | 'maxlen' => $this->options['tmbVideoConvLen'], |
||
3263 | ]; |
||
3264 | } |
||
3265 | } |
||
3266 | |||
3267 | // check archivers |
||
3268 | if (empty($this->archivers['create'])) { |
||
3269 | $this->disabled[] = 'archive'; |
||
3270 | } |
||
3271 | if (empty($this->archivers['extract'])) { |
||
3272 | $this->disabled[] = 'extract'; |
||
3273 | } |
||
3274 | $_arc = $this->getArchivers(); |
||
3275 | if (empty($_arc['create'])) { |
||
3276 | $this->disabled[] = 'zipdl'; |
||
3277 | } |
||
3278 | |||
3279 | // check 'statOwner' for command `chmod` |
||
3280 | if (empty($this->options['statOwner'])) { |
||
3281 | $this->disabled[] = 'chmod'; |
||
3282 | } |
||
3283 | |||
3284 | // check 'mimeMap' |
||
3285 | if (! is_array($this->options['mimeMap'])) { |
||
3286 | $this->options['mimeMap'] = []; |
||
3287 | } |
||
3288 | View Code Duplication | if (is_array($this->options['staticMineMap']) && $this->options['staticMineMap']) { |
|
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. ![]() |
|||
3289 | $this->options['mimeMap'] = array_merge($this->options['mimeMap'], $this->options['staticMineMap']); |
||
3290 | } |
||
3291 | View Code Duplication | if (is_array($this->options['additionalMimeMap']) && $this->options['additionalMimeMap']) { |
|
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. ![]() |
|||
3292 | $this->options['mimeMap'] = array_merge($this->options['mimeMap'], $this->options['additionalMimeMap']); |
||
3293 | } |
||
3294 | |||
3295 | // check 'url' in disabled commands |
||
3296 | if (in_array('url', $this->disabled)) { |
||
3297 | $this->disabledGetUrl = true; |
||
0 ignored issues
–
show
The property
$disabledGetUrl was declared of type string , but true is of type boolean . Maybe add a type cast?
This check looks for assignments to scalar types that may be of the wrong type. To ensure the code behaves as expected, it may be a good idea to add an explicit type cast. $answer = 42;
$correct = false;
$correct = (bool) $answer;
![]() |
|||
3298 | } |
||
3299 | |||
3300 | // set run time setting uploadOverwrite |
||
3301 | $this->uploadOverwrite = $this->options['uploadOverwrite']; |
||
3302 | } |
||
3303 | |||
3304 | /** |
||
3305 | * @deprecated |
||
3306 | */ |
||
3307 | protected function sessionRestart() |
||
3308 | { |
||
3309 | $this->sessionCache = $this->session->start()->get($this->id, []); |
||
0 ignored issues
–
show
It seems like
$this->session->start()->get($this->id, array()) of type * is incompatible with the declared type array of property $sessionCache .
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property. Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property.. ![]() |
|||
3310 | |||
3311 | return true; |
||
3312 | } |
||
3313 | |||
3314 | /** |
||
3315 | * Save error message. |
||
3316 | * |
||
3317 | * @param array error |
||
3318 | * @return false |
||
3319 | * @author Naoki Sawada |
||
3320 | **/ |
||
3321 | protected function setError() |
||
3322 | { |
||
3323 | $this->error = []; |
||
3324 | $this->addError(func_get_args()); |
||
3325 | |||
3326 | return false; |
||
3327 | } |
||
3328 | |||
3329 | /** |
||
3330 | * Add error message. |
||
3331 | * |
||
3332 | * @param array error |
||
3333 | * @return false |
||
3334 | * @author Dmitry(dio) Levashov |
||
3335 | **/ |
||
3336 | protected function addError() |
||
3337 | { |
||
3338 | foreach (func_get_args() as $err) { |
||
3339 | if (is_array($err)) { |
||
3340 | $this->error = array_merge($this->error, $err); |
||
3341 | } else { |
||
3342 | $this->error[] = $err; |
||
3343 | } |
||
3344 | } |
||
3345 | |||
3346 | return false; |
||
3347 | } |
||
3348 | |||
3349 | /*********************************************************************/ |
||
3350 | /* FS API */ |
||
3351 | /*********************************************************************/ |
||
3352 | |||
3353 | /***************** server encoding support *******************/ |
||
3354 | |||
3355 | /** |
||
3356 | * Return parent directory path (with convert encoding). |
||
3357 | * |
||
3358 | * @param string $path file path |
||
3359 | * @return string |
||
3360 | * @author Naoki Sawada |
||
3361 | **/ |
||
3362 | protected function dirnameCE($path) |
||
3363 | { |
||
3364 | $dirname = (! $this->encoding) ? $this->_dirname($path) : $this->convEncOut($this->_dirname($this->convEncIn($path))); |
||
3365 | // check to infinite loop prevention |
||
3366 | return ($dirname != $path) ? $dirname : ''; |
||
3367 | } |
||
3368 | |||
3369 | /** |
||
3370 | * Return file name (with convert encoding). |
||
3371 | * |
||
3372 | * @param string $path file path |
||
3373 | * @return string |
||
3374 | * @author Naoki Sawada |
||
3375 | **/ |
||
3376 | protected function basenameCE($path) |
||
3377 | { |
||
3378 | return (! $this->encoding) ? $this->_basename($path) : $this->convEncOut($this->_basename($this->convEncIn($path))); |
||
3379 | } |
||
3380 | |||
3381 | /** |
||
3382 | * Join dir name and file name and return full path. (with convert encoding) |
||
3383 | * Some drivers (db) use int as path - so we give to concat path to driver itself. |
||
3384 | * |
||
3385 | * @param string $dir dir path |
||
3386 | * @param string $name file name |
||
3387 | * @return string |
||
3388 | * @author Naoki Sawada |
||
3389 | **/ |
||
3390 | protected function joinPathCE($dir, $name) |
||
3391 | { |
||
3392 | return (! $this->encoding) ? $this->_joinPath($dir, $name) : $this->convEncOut($this->_joinPath($this->convEncIn($dir), $this->convEncIn($name))); |
||
3393 | } |
||
3394 | |||
3395 | /** |
||
3396 | * Return normalized path (with convert encoding). |
||
3397 | * |
||
3398 | * @param string $path file path |
||
3399 | * @return string |
||
3400 | * @author Naoki Sawada |
||
3401 | **/ |
||
3402 | protected function normpathCE($path) |
||
3403 | { |
||
3404 | return (! $this->encoding) ? $this->_normpath($path) : $this->convEncOut($this->_normpath($this->convEncIn($path))); |
||
3405 | } |
||
3406 | |||
3407 | /** |
||
3408 | * Return file path related to root dir (with convert encoding). |
||
3409 | * |
||
3410 | * @param string $path file path |
||
3411 | * @return string |
||
3412 | * @author Naoki Sawada |
||
3413 | **/ |
||
3414 | protected function relpathCE($path) |
||
3415 | { |
||
3416 | return (! $this->encoding) ? $this->_relpath($path) : $this->convEncOut($this->_relpath($this->convEncIn($path))); |
||
3417 | } |
||
3418 | |||
3419 | /** |
||
3420 | * Convert path related to root dir into real path (with convert encoding). |
||
3421 | * |
||
3422 | * @param string $path rel file path |
||
3423 | * @return string |
||
3424 | * @author Naoki Sawada |
||
3425 | **/ |
||
3426 | protected function abspathCE($path) |
||
3427 | { |
||
3428 | return (! $this->encoding) ? $this->_abspath($path) : $this->convEncOut($this->_abspath($this->convEncIn($path))); |
||
3429 | } |
||
3430 | |||
3431 | /** |
||
3432 | * Return true if $path is children of $parent (with convert encoding). |
||
3433 | * |
||
3434 | * @param string $path path to check |
||
3435 | * @param string $parent parent path |
||
3436 | * @return bool |
||
3437 | * @author Naoki Sawada |
||
3438 | **/ |
||
3439 | protected function inpathCE($path, $parent) |
||
3440 | { |
||
3441 | return (! $this->encoding) ? $this->_inpath($path, $parent) : $this->convEncOut($this->_inpath($this->convEncIn($path), $this->convEncIn($parent))); |
||
3442 | } |
||
3443 | |||
3444 | /** |
||
3445 | * Open file and return file pointer (with convert encoding). |
||
3446 | * |
||
3447 | * @param string $path file path |
||
3448 | * @param string $mode |
||
3449 | * @return false|resource |
||
3450 | * @internal param bool $write open file for writing |
||
3451 | * @author Naoki Sawada |
||
3452 | */ |
||
3453 | protected function fopenCE($path, $mode = 'rb') |
||
3454 | { |
||
3455 | return (! $this->encoding) ? $this->_fopen($path, $mode) : $this->convEncOut($this->_fopen($this->convEncIn($path), $mode)); |
||
3456 | } |
||
3457 | |||
3458 | /** |
||
3459 | * Close opened file (with convert encoding). |
||
3460 | * |
||
3461 | * @param resource $fp file pointer |
||
3462 | * @param string $path file path |
||
3463 | * @return bool |
||
3464 | * @author Naoki Sawada |
||
3465 | **/ |
||
3466 | protected function fcloseCE($fp, $path = '') |
||
3467 | { |
||
3468 | return (! $this->encoding) ? $this->_fclose($fp, $path) : $this->convEncOut($this->_fclose($fp, $this->convEncIn($path))); |
||
3469 | } |
||
3470 | |||
3471 | /** |
||
3472 | * Create new file and write into it from file pointer. (with convert encoding) |
||
3473 | * Return new file path or false on error. |
||
3474 | * |
||
3475 | * @param resource $fp file pointer |
||
3476 | * @param string $dir target dir path |
||
3477 | * @param string $name file name |
||
3478 | * @param array $stat file stat (required by some virtual fs) |
||
3479 | * @return bool|string |
||
3480 | * @author Naoki Sawada |
||
3481 | **/ |
||
3482 | protected function saveCE($fp, $dir, $name, $stat) |
||
3483 | { |
||
3484 | return (! $this->encoding) ? $this->_save($fp, $dir, $name, $stat) : $this->convEncOut($this->_save($fp, $this->convEncIn($dir), $this->convEncIn($name), $this->convEncIn($stat))); |
||
3485 | } |
||
3486 | |||
3487 | /** |
||
3488 | * Return true if path is dir and has at least one childs directory (with convert encoding). |
||
3489 | * |
||
3490 | * @param string $path dir path |
||
3491 | * @return bool |
||
3492 | * @author Naoki Sawada |
||
3493 | **/ |
||
3494 | protected function subdirsCE($path) |
||
3495 | { |
||
3496 | View Code Duplication | if ($this->sessionCaching['subdirs']) { |
|
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. ![]() |
|||
3497 | if (isset($this->sessionCache['subdirs'][$path]) && ! $this->isMyReload()) { |
||
3498 | return $this->sessionCache['subdirs'][$path]; |
||
3499 | } |
||
3500 | } |
||
3501 | $hasdir = (bool) ((! $this->encoding) ? $this->_subdirs($path) : $this->convEncOut($this->_subdirs($this->convEncIn($path)))); |
||
3502 | $this->updateSubdirsCache($path, $hasdir); |
||
3503 | |||
3504 | return $hasdir; |
||
3505 | } |
||
3506 | |||
3507 | /** |
||
3508 | * Return files list in directory (with convert encoding). |
||
3509 | * |
||
3510 | * @param string $path dir path |
||
3511 | * @return array |
||
3512 | * @author Naoki Sawada |
||
3513 | **/ |
||
3514 | protected function scandirCE($path) |
||
3515 | { |
||
3516 | return (! $this->encoding) ? $this->_scandir($path) : $this->convEncOut($this->_scandir($this->convEncIn($path))); |
||
3517 | } |
||
3518 | |||
3519 | /** |
||
3520 | * Create symlink (with convert encoding). |
||
3521 | * |
||
3522 | * @param string $source file to link to |
||
3523 | * @param string $targetDir folder to create link in |
||
3524 | * @param string $name symlink name |
||
3525 | * @return bool |
||
3526 | * @author Naoki Sawada |
||
3527 | **/ |
||
3528 | protected function symlinkCE($source, $targetDir, $name) |
||
3529 | { |
||
3530 | return (! $this->encoding) ? $this->_symlink($source, $targetDir, $name) : $this->convEncOut($this->_symlink($this->convEncIn($source), $this->convEncIn($targetDir), $this->convEncIn($name))); |
||
3531 | } |
||
3532 | |||
3533 | /***************** paths *******************/ |
||
3534 | |||
3535 | /** |
||
3536 | * Encode path into hash. |
||
3537 | * |
||
3538 | * @param string file path |
||
3539 | * @return string |
||
3540 | * @author Dmitry (dio) Levashov |
||
3541 | * @author Troex Nevelin |
||
3542 | **/ |
||
3543 | protected function encode($path) |
||
3544 | { |
||
3545 | if ($path !== '') { |
||
3546 | |||
3547 | // cut ROOT from $path for security reason, even if hacker decodes the path he will not know the root |
||
3548 | $p = $this->relpathCE($path); |
||
3549 | // if reqesting root dir $path will be empty, then assign '/' as we cannot leave it blank for crypt |
||
3550 | if ($p === '') { |
||
3551 | $p = $this->separator; |
||
3552 | } |
||
3553 | |||
3554 | // TODO crypt path and return hash |
||
3555 | $hash = $this->crypt($p); |
||
3556 | // hash is used as id in HTML that means it must contain vaild chars |
||
3557 | // make base64 html safe and append prefix in begining |
||
3558 | $hash = strtr(base64_encode($hash), '+/=', '-_.'); |
||
3559 | // remove dots '.' at the end, before it was '=' in base64 |
||
3560 | $hash = rtrim($hash, '.'); |
||
3561 | // append volume id to make hash unique |
||
3562 | return $this->id.$hash; |
||
3563 | } |
||
3564 | //TODO: Add return statement here |
||
3565 | } |
||
3566 | |||
3567 | /** |
||
3568 | * Decode path from hash. |
||
3569 | * |
||
3570 | * @param string file hash |
||
3571 | * @return string |
||
3572 | * @author Dmitry (dio) Levashov |
||
3573 | * @author Troex Nevelin |
||
3574 | **/ |
||
3575 | protected function decode($hash) |
||
3576 | { |
||
3577 | if (strpos($hash, $this->id) === 0) { |
||
3578 | // cut volume id after it was prepended in encode |
||
3579 | $h = substr($hash, strlen($this->id)); |
||
3580 | // replace HTML safe base64 to normal |
||
3581 | $h = base64_decode(strtr($h, '-_.', '+/=')); |
||
3582 | // TODO uncrypt hash and return path |
||
3583 | $path = $this->uncrypt($h); |
||
3584 | // append ROOT to path after it was cut in encode |
||
3585 | return $this->abspathCE($path); //$this->root.($path === $this->separator ? '' : $this->separator.$path); |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
54% 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. ![]() |
|||
3586 | } |
||
3587 | //TODO: Add return statement here |
||
3588 | } |
||
3589 | |||
3590 | /** |
||
3591 | * Return crypted path |
||
3592 | * Not implemented. |
||
3593 | * |
||
3594 | * @param string path |
||
3595 | * @return mixed |
||
3596 | * @author Dmitry (dio) Levashov |
||
3597 | **/ |
||
3598 | protected function crypt($path) |
||
3599 | { |
||
3600 | return $path; |
||
3601 | } |
||
3602 | |||
3603 | /** |
||
3604 | * Return uncrypted path |
||
3605 | * Not implemented. |
||
3606 | * |
||
3607 | * @param mixed hash |
||
3608 | * @return mixed |
||
3609 | * @author Dmitry (dio) Levashov |
||
3610 | **/ |
||
3611 | protected function uncrypt($hash) |
||
3612 | { |
||
3613 | return $hash; |
||
3614 | } |
||
3615 | |||
3616 | /** |
||
3617 | * Validate file name based on $this->options['acceptedName'] regexp or function. |
||
3618 | * |
||
3619 | * @param string $name file name |
||
3620 | * @return bool |
||
3621 | * @author Dmitry (dio) Levashov |
||
3622 | **/ |
||
3623 | protected function nameAccepted($name, $isDir = false) |
||
3624 | { |
||
3625 | if (json_encode($name) === false) { |
||
3626 | return false; |
||
3627 | } |
||
3628 | $nameValidator = $isDir ? $this->dirnameValidator : $this->nameValidator; |
||
3629 | if ($nameValidator) { |
||
3630 | if (is_callable($nameValidator)) { |
||
3631 | $res = call_user_func($nameValidator, $name); |
||
3632 | |||
3633 | return $res; |
||
3634 | } |
||
3635 | if (preg_match($nameValidator, '') !== false) { |
||
3636 | return preg_match($nameValidator, $name); |
||
3637 | } |
||
3638 | } |
||
3639 | |||
3640 | return true; |
||
3641 | } |
||
3642 | |||
3643 | /** |
||
3644 | * Return session rootstat cache key. |
||
3645 | * |
||
3646 | * @return string |
||
3647 | */ |
||
3648 | protected function getRootstatCachekey() |
||
3649 | { |
||
3650 | return md5($this->root.(isset($this->options['alias']) ? $this->options['alias'] : '')); |
||
3651 | } |
||
3652 | |||
3653 | /** |
||
3654 | * Converts character encoding (base function). |
||
3655 | * |
||
3656 | * @param mixed $var target string or array var |
||
3657 | * @param string $from from character encoding |
||
3658 | * @param string $to to character encoding |
||
3659 | * @param string $locale local locale |
||
3660 | * @param $restoreLocale |
||
3661 | * @param string $unknown replaces character for unknown |
||
3662 | * @return mixed |
||
3663 | */ |
||
3664 | protected function convEnc($var, $from, $to, $locale, $restoreLocale, $unknown = '_') |
||
3665 | { |
||
3666 | if (strtoupper($from) !== strtoupper($to)) { |
||
3667 | if ($locale) { |
||
3668 | setlocale(LC_ALL, $locale); |
||
3669 | } |
||
3670 | if (is_array($var)) { |
||
3671 | $_ret = []; |
||
3672 | foreach ($var as $_k => $_v) { |
||
3673 | $_ret[$_k] = $this->convEnc($_v, $from, $to, '', false, $unknown = '_'); |
||
3674 | } |
||
3675 | $var = $_ret; |
||
3676 | } else { |
||
3677 | $_var = false; |
||
3678 | if (is_string($var)) { |
||
3679 | $_var = $var; |
||
3680 | if (false !== ($_var = iconv($from, $to.'//TRANSLIT', $_var))) { |
||
3681 | $_var = str_replace('?', $unknown, $_var); |
||
3682 | } |
||
3683 | } |
||
3684 | if ($_var !== false) { |
||
3685 | $var = $_var; |
||
3686 | } |
||
3687 | } |
||
3688 | if ($restoreLocale) { |
||
3689 | setlocale(LC_ALL, elFinder::$locale); |
||
3690 | } |
||
3691 | } |
||
3692 | |||
3693 | return $var; |
||
3694 | } |
||
3695 | |||
3696 | /*********************** util mainly for inheritance class *********************/ |
||
3697 | |||
3698 | /** |
||
3699 | * Get temporary filename. Tempfile will be removed when after script execution finishes or exit() is called. |
||
3700 | * When needing the unique file to a path, give $path to parameter. |
||
3701 | * |
||
3702 | * @param string $path for get unique file to a path |
||
3703 | * @return string|false |
||
3704 | * @author Naoki Sawada |
||
3705 | */ |
||
3706 | protected function getTempFile($path = '') |
||
3707 | { |
||
3708 | static $cache = []; |
||
3709 | static $rmfunc; |
||
3710 | |||
3711 | $key = ''; |
||
3712 | if ($path !== '') { |
||
3713 | $key = $this->id.'#'.$path; |
||
3714 | if (isset($cache[$key])) { |
||
3715 | return $cache[$key]; |
||
3716 | } |
||
3717 | } |
||
3718 | |||
3719 | if ($tmpdir = $this->getTempPath()) { |
||
3720 | if (! $rmfunc) { |
||
3721 | $rmfunc = create_function('$f', 'is_file($f) && unlink($f);'); |
||
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; }
![]() |
|||
3722 | } |
||
3723 | $name = tempnam($tmpdir, 'ELF'); |
||
3724 | if ($key) { |
||
3725 | $cache[$key] = $name; |
||
3726 | } |
||
3727 | register_shutdown_function($rmfunc, $name); |
||
3728 | |||
3729 | return $name; |
||
3730 | } |
||
3731 | |||
3732 | return false; |
||
3733 | } |
||
3734 | |||
3735 | /** |
||
3736 | * File path of local server side work file path. |
||
3737 | * |
||
3738 | * @param string $path path need convert encoding to server encoding |
||
3739 | * @return string |
||
3740 | * @author Naoki Sawada |
||
3741 | */ |
||
3742 | protected function getWorkFile($path) |
||
3743 | { |
||
3744 | if ($work = $this->getTempFile()) { |
||
3745 | if ($wfp = fopen($work, 'wb')) { |
||
3746 | if ($fp = $this->_fopen($path)) { |
||
3747 | while (! feof($fp)) { |
||
3748 | fwrite($wfp, fread($fp, 8192)); |
||
3749 | } |
||
3750 | $this->_fclose($fp, $path); |
||
3751 | fclose($wfp); |
||
3752 | |||
3753 | return $work; |
||
3754 | } |
||
3755 | } |
||
3756 | } |
||
3757 | |||
3758 | return false; |
||
3759 | } |
||
3760 | |||
3761 | /** |
||
3762 | * Delete dirctory trees. |
||
3763 | * |
||
3764 | * @param string $localpath path need convert encoding to server encoding |
||
3765 | * @return bool |
||
3766 | * @author Naoki Sawada |
||
3767 | */ |
||
3768 | protected function delTree($localpath) |
||
3769 | { |
||
3770 | foreach ($this->_scandir($localpath) as $p) { |
||
3771 | elFinder::extendTimeLimit(); |
||
3772 | $stat = $this->stat($this->convEncOut($p)); |
||
3773 | $this->convEncIn(); |
||
3774 | ($stat['mime'] === 'directory') ? $this->delTree($p) : $this->_unlink($p); |
||
3775 | } |
||
3776 | |||
3777 | return $this->_rmdir($localpath); |
||
3778 | } |
||
3779 | |||
3780 | /** |
||
3781 | * Copy items to a new temporary directory on the local server. |
||
3782 | * |
||
3783 | * @param array $hashes target hashes |
||
3784 | * @param string $dir destination directory (for recurcive) |
||
3785 | * @param string $canLink it can use link() (for recurcive) |
||
3786 | * @return string|false saved path name |
||
3787 | * @author Naoki Sawada |
||
3788 | */ |
||
3789 | protected function getItemsInHand($hashes, $dir = null, $canLink = null) |
||
3790 | { |
||
3791 | static $totalSize = 0; |
||
3792 | if (is_null($dir)) { |
||
3793 | $totalSize = 0; |
||
3794 | if (! $tmpDir = $this->getTempPath()) { |
||
3795 | return false; |
||
3796 | } |
||
3797 | $dir = tempnam($tmpDir, 'elf'); |
||
3798 | if (! unlink($dir) || ! mkdir($dir, 0700, true)) { |
||
3799 | return false; |
||
3800 | } |
||
3801 | register_shutdown_function([$this, 'rmdirRecursive'], $dir); |
||
3802 | } |
||
3803 | if (is_null($canLink)) { |
||
3804 | $canLink = ($this instanceof elFinderVolumeLocalFileSystem); |
||
3805 | } |
||
3806 | elFinder::extendTimeLimit(); |
||
3807 | $res = true; |
||
3808 | $files = []; |
||
3809 | foreach ($hashes as $hash) { |
||
3810 | if (($file = $this->file($hash)) == false) { |
||
3811 | continue; |
||
3812 | } |
||
3813 | if (! $file['read']) { |
||
3814 | continue; |
||
3815 | } |
||
3816 | |||
3817 | $name = $file['name']; |
||
3818 | // for call from search results |
||
3819 | if (isset($files[$name])) { |
||
3820 | $name = preg_replace('/^(.*?)(\..*)?$/', '$1_'.$files[$name]++.'$2', $name); |
||
3821 | } else { |
||
3822 | $files[$name] = 1; |
||
3823 | } |
||
3824 | $target = $dir.DIRECTORY_SEPARATOR.$name; |
||
3825 | |||
3826 | if ($file['mime'] === 'directory') { |
||
3827 | $chashes = []; |
||
3828 | $_files = $this->scandir($hash); |
||
3829 | foreach ($_files as $_file) { |
||
0 ignored issues
–
show
The expression
$_files of type array|boolean is not guaranteed to be traversable. How about adding an additional type check?
There are different options of fixing this problem.
![]() |
|||
3830 | if ($file['read']) { |
||
3831 | $chashes[] = $_file['hash']; |
||
3832 | } |
||
3833 | } |
||
3834 | if (($res = mkdir($target, 0700, true)) && $chashes) { |
||
0 ignored issues
–
show
The expression
$chashes 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 ![]() |
|||
3835 | $res = $this->getItemsInHand($chashes, $target, $canLink); |
||
0 ignored issues
–
show
It seems like
$canLink can also be of type boolean ; however, elFinderVolumeDriver::getItemsInHand() does only seem to accept string|null , maybe add an additional type check?
If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check: /**
* @return array|string
*/
function returnsDifferentValues($x) {
if ($x) {
return 'foo';
}
return array();
}
$x = returnsDifferentValues($y);
if (is_array($x)) {
// $x is an array.
}
If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue. ![]() |
|||
3836 | } |
||
3837 | if (! $res) { |
||
3838 | break; |
||
3839 | } |
||
3840 | ! empty($file['ts']) && touch($target, $file['ts']); |
||
3841 | } else { |
||
3842 | $path = $this->decode($hash); |
||
3843 | if (! $canLink || ! ($canLink = link($path, $target))) { |
||
3844 | if ($fp = $this->fopenCE($path)) { |
||
3845 | if ($tfp = fopen($target, 'wb')) { |
||
3846 | $totalSize += stream_copy_to_stream($fp, $tfp); |
||
3847 | fclose($tfp); |
||
3848 | } |
||
3849 | ! empty($file['ts']) && touch($target, $file['ts']); |
||
3850 | $this->fcloseCE($fp, $path); |
||
3851 | } |
||
3852 | } else { |
||
3853 | $totalSize += filesize($path); |
||
3854 | } |
||
3855 | if ($this->options['maxArcFilesSize'] > 0 && $this->options['maxArcFilesSize'] < $totalSize) { |
||
3856 | $res = $this->setError(elFinder::ERROR_ARC_MAXSIZE); |
||
3857 | } |
||
3858 | } |
||
3859 | } |
||
3860 | |||
3861 | return $res ? $dir : false; |
||
3862 | } |
||
3863 | |||
3864 | /*********************** file stat *********************/ |
||
3865 | |||
3866 | /** |
||
3867 | * Check file attribute. |
||
3868 | * |
||
3869 | * @param string $path file path |
||
3870 | * @param string $name attribute name (read|write|locked|hidden) |
||
3871 | * @param bool $val attribute value returned by file system |
||
3872 | * @param bool $isDir path is directory (true: directory, false: file) |
||
3873 | * @return bool |
||
3874 | * @author Dmitry (dio) Levashov |
||
3875 | **/ |
||
3876 | protected function attr($path, $name, $val = null, $isDir = null) |
||
3877 | { |
||
3878 | if (! isset($this->defaults[$name])) { |
||
3879 | return false; |
||
3880 | } |
||
3881 | |||
3882 | $relpath = $this->relpathCE($path); |
||
3883 | if ($this->separator !== '/') { |
||
3884 | $relpath = str_replace($this->separator, '/', $relpath); |
||
3885 | } |
||
3886 | $relpath = '/'.$relpath; |
||
3887 | |||
3888 | $perm = null; |
||
3889 | |||
3890 | if ($this->access) { |
||
3891 | $perm = call_user_func($this->access, $name, $path, $this->options['accessControlData'], $this, $isDir, $relpath); |
||
3892 | if ($perm !== null) { |
||
3893 | return (bool) $perm; |
||
3894 | } |
||
3895 | } |
||
3896 | |||
3897 | for ($i = 0, $c = count($this->attributes); $i < $c; $i++) { |
||
3898 | $attrs = $this->attributes[$i]; |
||
3899 | |||
3900 | if (isset($attrs[$name]) && isset($attrs['pattern']) && preg_match($attrs['pattern'], $relpath)) { |
||
3901 | $perm = $attrs[$name]; |
||
3902 | } |
||
3903 | } |
||
3904 | |||
3905 | return $perm === null ? (is_null($val) ? $this->defaults[$name] : $val) : (bool) $perm; |
||
3906 | } |
||
3907 | |||
3908 | /** |
||
3909 | * Return true if file with given name can be created in given folder. |
||
3910 | * |
||
3911 | * @param string $dir parent dir path |
||
3912 | * @param string $name new file name |
||
3913 | * @param null $isDir |
||
3914 | * @return bool |
||
3915 | * @author Dmitry (dio) Levashov |
||
3916 | */ |
||
3917 | protected function allowCreate($dir, $name, $isDir = null) |
||
3918 | { |
||
3919 | return $this->attr($this->joinPathCE($dir, $name), 'write', true, $isDir); |
||
3920 | } |
||
3921 | |||
3922 | /** |
||
3923 | * Return true if file MIME type can save with check uploadOrder config. |
||
3924 | * |
||
3925 | * @param string $mime |
||
3926 | * @return bool |
||
3927 | */ |
||
3928 | protected function allowPutMime($mime) |
||
3929 | { |
||
3930 | // logic based on http://httpd.apache.org/docs/2.2/mod/mod_authz_host.html#order |
||
3931 | $allow = $this->mimeAccepted($mime, $this->uploadAllow, null); |
||
3932 | $deny = $this->mimeAccepted($mime, $this->uploadDeny, null); |
||
3933 | $res = true; // default to allow |
||
0 ignored issues
–
show
$res 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 ![]() |
|||
3934 | if (strtolower($this->uploadOrder[0]) == 'allow') { // array('allow', 'deny'), default is to 'deny' |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
53% 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. ![]() |
|||
3935 | $res = false; // default is deny |
||
3936 | if (! $deny && ($allow === true)) { // match only allow |
||
0 ignored issues
–
show
The expression
$deny of type boolean|null is loosely compared to false ; this is ambiguous if the boolean can be false. You might want to explicitly use !== null instead.
If an expression can have both $a = canBeFalseAndNull();
// Instead of
if ( ! $a) { }
// Better use one of the explicit versions:
if ($a !== null) { }
if ($a !== false) { }
if ($a !== null && $a !== false) { }
![]() |
|||
3937 | $res = true; |
||
3938 | }// else (both match | no match | match only deny) { deny } |
||
3939 | } else { // array('deny', 'allow'), default is to 'allow' - this is the default rule |
||
3940 | $res = true; // default is allow |
||
3941 | if (($deny === true) && ! $allow) { // match only deny |
||
0 ignored issues
–
show
The expression
$allow of type boolean|null is loosely compared to false ; this is ambiguous if the boolean can be false. You might want to explicitly use !== null instead.
If an expression can have both $a = canBeFalseAndNull();
// Instead of
if ( ! $a) { }
// Better use one of the explicit versions:
if ($a !== null) { }
if ($a !== false) { }
if ($a !== null && $a !== false) { }
![]() |
|||
3942 | $res = false; |
||
3943 | } // else (both match | no match | match only allow) { allow } |
||
3944 | } |
||
3945 | |||
3946 | return $res; |
||
3947 | } |
||
3948 | |||
3949 | /** |
||
3950 | * Return fileinfo. |
||
3951 | * |
||
3952 | * @param string $path file cache |
||
3953 | * @return array |
||
3954 | * @author Dmitry (dio) Levashov |
||
3955 | **/ |
||
3956 | protected function stat($path) |
||
3957 | { |
||
3958 | if ($path === false || is_null($path)) { |
||
3959 | return false; |
||
3960 | } |
||
3961 | $is_root = ($path == $this->root); |
||
3962 | if ($is_root) { |
||
3963 | $rootKey = $this->getRootstatCachekey(); |
||
3964 | if ($this->sessionCaching['rootstat'] && ! isset($this->sessionCache['rootstat'])) { |
||
3965 | $this->sessionCache['rootstat'] = []; |
||
3966 | } |
||
3967 | if (! isset($this->cache[$path]) && ! $this->isMyReload()) { |
||
3968 | // need $path as key for netmount/netunmount |
||
3969 | if ($this->sessionCaching['rootstat'] && isset($this->sessionCache['rootstat'][$rootKey])) { |
||
3970 | if ($ret = $this->sessionCache['rootstat'][$rootKey]) { |
||
3971 | if ($this->options['rootRev'] === $ret['rootRev']) { |
||
3972 | View Code Duplication | if (isset($this->options['phash'])) { |
|
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. ![]() |
|||
3973 | $ret['isroot'] = 1; |
||
3974 | $ret['phash'] = $this->options['phash']; |
||
3975 | } |
||
3976 | |||
3977 | return $ret; |
||
3978 | } |
||
3979 | } |
||
3980 | } |
||
3981 | } |
||
3982 | } |
||
3983 | $ret = isset($this->cache[$path]) |
||
3984 | ? $this->cache[$path] |
||
3985 | : $this->updateCache($path, $this->convEncOut($this->_stat($this->convEncIn($path)))); |
||
3986 | if ($is_root && $this->sessionCaching['rootstat']) { |
||
3987 | if ($ret) { |
||
3988 | $this->rootModified = false; |
||
3989 | $this->sessionCache['rootstat'][$rootKey] = $ret; |
||
0 ignored issues
–
show
The variable
$rootKey does not seem to be defined for all execution paths leading up to this point.
If you define a variable conditionally, it can happen that it is not defined for all execution paths. Let’s take a look at an example: function myFunction($a) {
switch ($a) {
case 'foo':
$x = 1;
break;
case 'bar':
$x = 2;
break;
}
// $x is potentially undefined here.
echo $x;
}
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined. Available Fixes
![]() |
|||
3990 | View Code Duplication | if (isset($this->options['phash'])) { |
|
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. ![]() |
|||
3991 | $ret['isroot'] = 1; |
||
3992 | $ret['phash'] = $this->options['phash']; |
||
3993 | } |
||
3994 | } else { |
||
3995 | unset($this->sessionCache['rootstat'][$rootKey]); |
||
3996 | } |
||
3997 | } |
||
3998 | |||
3999 | return $ret; |
||
4000 | } |
||
4001 | |||
4002 | /** |
||
4003 | * Get root stat extra key values. |
||
4004 | * |
||
4005 | * @return array stat extras |
||
4006 | * @author Naoki Sawada |
||
4007 | */ |
||
4008 | protected function getRootStatExtra() |
||
4009 | { |
||
4010 | $stat = []; |
||
4011 | if ($this->rootName) { |
||
4012 | $stat['name'] = $this->rootName; |
||
4013 | } |
||
4014 | $stat['rootRev'] = $this->options['rootRev']; |
||
4015 | $stat['options'] = $this->options(null); |
||
4016 | |||
4017 | return $stat; |
||
4018 | } |
||
4019 | |||
4020 | /** |
||
4021 | * Return fileinfo based on filename |
||
4022 | * For item ID based path file system |
||
4023 | * Please override if needed on each drivers. |
||
4024 | * |
||
4025 | * @param string $path file cache |
||
4026 | * @return array |
||
4027 | */ |
||
4028 | protected function isNameExists($path) |
||
4029 | { |
||
4030 | return $this->stat($path); |
||
4031 | } |
||
4032 | |||
4033 | /** |
||
4034 | * Put file stat in cache and return it. |
||
4035 | * |
||
4036 | * @param string $path file path |
||
4037 | * @param array $stat file stat |
||
4038 | * @return array |
||
4039 | * @author Dmitry (dio) Levashov |
||
4040 | **/ |
||
4041 | protected function updateCache($path, $stat) |
||
4042 | { |
||
4043 | if (empty($stat) || ! is_array($stat)) { |
||
4044 | return $this->cache[$path] = []; |
||
4045 | } |
||
4046 | |||
4047 | $stat['hash'] = $this->encode($path); |
||
4048 | |||
4049 | $root = $path == $this->root; |
||
4050 | $parent = ''; |
||
4051 | |||
4052 | if ($root) { |
||
4053 | $stat = array_merge($stat, $this->getRootStatExtra()); |
||
4054 | } else { |
||
4055 | if (! isset($stat['name']) || $stat['name'] === '') { |
||
4056 | $stat['name'] = $this->basenameCE($path); |
||
4057 | } |
||
4058 | if (empty($stat['phash'])) { |
||
4059 | $parent = $this->dirnameCE($path); |
||
4060 | $stat['phash'] = $this->encode($parent); |
||
4061 | } else { |
||
4062 | $parent = $this->decode($stat['phash']); |
||
4063 | } |
||
4064 | } |
||
4065 | |||
4066 | // name check |
||
4067 | if (! $jeName = json_encode($stat['name'])) { |
||
4068 | return $this->cache[$path] = []; |
||
4069 | } |
||
4070 | // fix name if required |
||
4071 | if ($this->options['utf8fix'] && $this->options['utf8patterns'] && $this->options['utf8replace']) { |
||
4072 | $stat['name'] = json_decode(str_replace($this->options['utf8patterns'], $this->options['utf8replace'], $jeName)); |
||
4073 | } |
||
4074 | |||
4075 | if (empty($stat['mime'])) { |
||
4076 | $stat['mime'] = $this->mimetype($stat['name'], true); |
||
4077 | } |
||
4078 | |||
4079 | // @todo move dateformat to client |
||
4080 | // $stat['date'] = isset($stat['ts']) |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
74% 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. ![]() |
|||
4081 | // ? $this->formatDate($stat['ts']) |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
75% 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. ![]() |
|||
4082 | // : 'unknown'; |
||
4083 | |||
4084 | if (! isset($stat['size'])) { |
||
4085 | $stat['size'] = 'unknown'; |
||
4086 | } |
||
4087 | |||
4088 | if ($isDir = ($stat['mime'] === 'directory')) { |
||
4089 | $stat['volumeid'] = $this->id; |
||
4090 | } |
||
4091 | |||
4092 | $stat['read'] = intval($this->attr($path, 'read', isset($stat['read']) ? (bool) $stat['read'] : null, $isDir)); |
||
4093 | $stat['write'] = intval($this->attr($path, 'write', isset($stat['write']) ? (bool) $stat['write'] : null, $isDir)); |
||
4094 | if ($root) { |
||
4095 | $stat['locked'] = 1; |
||
4096 | if ($this->options['type'] !== '') { |
||
4097 | $stat['type'] = $this->options['type']; |
||
4098 | } |
||
4099 | } else { |
||
4100 | // lock when parent directory is not writable |
||
4101 | if (! isset($stat['locked'])) { |
||
4102 | $pstat = $this->stat($parent); |
||
4103 | if (isset($pstat['write']) && ! $pstat['write']) { |
||
4104 | $stat['locked'] = true; |
||
4105 | } |
||
4106 | } |
||
4107 | if ($this->attr($path, 'locked', isset($stat['locked']) ? (bool) $stat['locked'] : null, $isDir)) { |
||
4108 | $stat['locked'] = 1; |
||
4109 | } else { |
||
4110 | unset($stat['locked']); |
||
4111 | } |
||
4112 | } |
||
4113 | |||
4114 | if ($root) { |
||
4115 | unset($stat['hidden']); |
||
4116 | } elseif ($this->attr($path, 'hidden', isset($stat['hidden']) ? (bool) $stat['hidden'] : null, $isDir) |
||
4117 | || ! $this->mimeAccepted($stat['mime'])) { |
||
0 ignored issues
–
show
The expression
$this->mimeAccepted($stat['mime']) of type boolean|null is loosely compared to false ; this is ambiguous if the boolean can be false. You might want to explicitly use !== null instead.
If an expression can have both $a = canBeFalseAndNull();
// Instead of
if ( ! $a) { }
// Better use one of the explicit versions:
if ($a !== null) { }
if ($a !== false) { }
if ($a !== null && $a !== false) { }
![]() |
|||
4118 | $stat['hidden'] = 1; |
||
4119 | } else { |
||
4120 | unset($stat['hidden']); |
||
4121 | } |
||
4122 | |||
4123 | if ($stat['read'] && empty($stat['hidden'])) { |
||
4124 | if ($isDir) { |
||
4125 | // caching parent's subdirs |
||
4126 | if ($parent) { |
||
0 ignored issues
–
show
The expression
$parent 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
![]() |
|||
4127 | $this->updateSubdirsCache($parent, true); |
||
4128 | } |
||
4129 | // for dir - check for subdirs |
||
4130 | if ($this->options['checkSubfolders']) { |
||
4131 | if (! isset($stat['dirs']) && intval($this->options['checkSubfolders']) === -1) { |
||
4132 | $stat['dirs'] = -1; |
||
4133 | } |
||
4134 | if (isset($stat['dirs'])) { |
||
4135 | if ($stat['dirs']) { |
||
4136 | if ($stat['dirs'] == -1) { |
||
4137 | $stat['dirs'] = ($this->sessionCaching['subdirs'] && isset($this->sessionCache['subdirs'][$path])) ? (int) $this->sessionCache['subdirs'][$path] : -1; |
||
4138 | } else { |
||
4139 | $stat['dirs'] = 1; |
||
4140 | } |
||
4141 | } else { |
||
4142 | unset($stat['dirs']); |
||
4143 | } |
||
4144 | } elseif (! empty($stat['alias']) && ! empty($stat['target'])) { |
||
4145 | $stat['dirs'] = isset($this->cache[$stat['target']]) |
||
4146 | ? intval(isset($this->cache[$stat['target']]['dirs'])) |
||
4147 | : $this->subdirsCE($stat['target']); |
||
4148 | } elseif ($this->subdirsCE($path)) { |
||
4149 | $stat['dirs'] = 1; |
||
4150 | } |
||
4151 | } else { |
||
4152 | $stat['dirs'] = 1; |
||
4153 | } |
||
4154 | if ($this->options['dirUrlOwn'] === true) { |
||
4155 | $stat['url'] = '#elf_'.$stat['hash']; |
||
4156 | } |
||
4157 | } else { |
||
4158 | // for files - check for thumbnails |
||
4159 | $p = isset($stat['target']) ? $stat['target'] : $path; |
||
4160 | if ($this->tmbURL && ! isset($stat['tmb']) && $this->canCreateTmb($p, $stat)) { |
||
4161 | $tmb = $this->gettmb($p, $stat); |
||
4162 | $stat['tmb'] = $tmb ? $tmb : 1; |
||
4163 | } |
||
4164 | } |
||
4165 | if (! isset($stat['url']) && $this->URL && $this->encoding) { |
||
4166 | $_path = str_replace($this->separator, '/', substr($path, strlen($this->root) + 1)); |
||
4167 | $stat['url'] = rtrim($this->URL, '/').'/'.str_replace('%2F', '/', rawurlencode((substr(PHP_OS, 0, 3) === 'WIN') ? $_path : $this->convEncIn($_path, true))); |
||
4168 | } |
||
4169 | } else { |
||
4170 | if ($isDir) { |
||
4171 | unset($stat['dirs']); |
||
4172 | } |
||
4173 | } |
||
4174 | |||
4175 | if (! empty($stat['alias']) && ! empty($stat['target'])) { |
||
4176 | $stat['thash'] = $this->encode($stat['target']); |
||
4177 | //$this->cache[$stat['target']] = $stat; |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
72% 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. ![]() |
|||
4178 | unset($stat['target']); |
||
4179 | } |
||
4180 | |||
4181 | $this->cache[$path] = $stat; |
||
4182 | |||
4183 | if ($root && $this->sessionCaching['rootstat']) { |
||
4184 | // to update session cache |
||
4185 | $this->stat($path); |
||
4186 | } |
||
4187 | |||
4188 | return $stat; |
||
4189 | } |
||
4190 | |||
4191 | /** |
||
4192 | * Get stat for folder content and put in cache. |
||
4193 | * |
||
4194 | * @param string $path |
||
4195 | * @return void |
||
4196 | * @author Dmitry (dio) Levashov |
||
4197 | **/ |
||
4198 | protected function cacheDir($path) |
||
4199 | { |
||
4200 | $this->dirsCache[$path] = []; |
||
4201 | $hasDir = false; |
||
4202 | |||
4203 | foreach ($this->scandirCE($path) as $p) { |
||
4204 | if (($stat = $this->stat($p)) && empty($stat['hidden'])) { |
||
4205 | if (! $hasDir && $stat['mime'] === 'directory') { |
||
4206 | $hasDir = true; |
||
4207 | } |
||
4208 | $this->dirsCache[$path][] = $p; |
||
4209 | } |
||
4210 | } |
||
4211 | |||
4212 | $this->updateSubdirsCache($path, $hasDir); |
||
4213 | } |
||
4214 | |||
4215 | /** |
||
4216 | * Clean cache. |
||
4217 | * |
||
4218 | * @return void |
||
4219 | * @author Dmitry (dio) Levashov |
||
4220 | **/ |
||
4221 | protected function clearcache() |
||
4222 | { |
||
4223 | $this->cache = $this->dirsCache = []; |
||
4224 | } |
||
4225 | |||
4226 | /** |
||
4227 | * Return file mimetype. |
||
4228 | * |
||
4229 | * @param string $path file path |
||
4230 | * @param string|bool $name |
||
4231 | * @return string |
||
4232 | * @author Dmitry (dio) Levashov |
||
4233 | */ |
||
4234 | protected function mimetype($path, $name = '') |
||
4235 | { |
||
4236 | $type = ''; |
||
4237 | $nameCheck = false; |
||
4238 | |||
4239 | if ($name === '') { |
||
4240 | $name = $path; |
||
4241 | } elseif ($name === true) { |
||
4242 | $name = $path; |
||
4243 | $nameCheck = true; |
||
4244 | } |
||
4245 | $ext = (false === $pos = strrpos($name, '.')) ? '' : substr($name, $pos + 1); |
||
4246 | if (! $nameCheck && is_readable($path)) { |
||
4247 | if (filesize($path) > 0) { |
||
4248 | if ($this->mimeDetect == 'finfo') { |
||
4249 | if ($type = finfo_file($this->finfo, $path)) { |
||
4250 | if ($ext && preg_match('~^application/(?:octet-stream|(?:x-)?zip)~', $type)) { |
||
4251 | if (isset(self::$mimetypes[$ext])) { |
||
4252 | $type = self::$mimetypes[$ext]; |
||
4253 | } |
||
4254 | } elseif ($ext === 'js' && preg_match('~^text/~', $type)) { |
||
4255 | $type = 'text/javascript'; |
||
4256 | } |
||
4257 | } else { |
||
4258 | $type = 'unknown'; |
||
4259 | } |
||
4260 | } elseif ($this->mimeDetect == 'mime_content_type') { |
||
4261 | $type = mime_content_type($path); |
||
4262 | } |
||
4263 | } else { |
||
4264 | $type = 'text/plain'; |
||
4265 | } |
||
4266 | } |
||
4267 | if (! $type) { |
||
4268 | $type = self::mimetypeInternalDetect($path); |
||
4269 | } |
||
4270 | |||
4271 | if ($type === 'unknown' && $this->mimeDetect != 'internal') { |
||
4272 | $type = self::mimetypeInternalDetect($path); |
||
4273 | } |
||
4274 | |||
4275 | $type = explode(';', $type); |
||
4276 | $type = trim($type[0]); |
||
4277 | |||
4278 | if (in_array($type, ['application/x-empty', 'inode/x-empty'])) { |
||
4279 | // finfo return this mime for empty files |
||
4280 | $type = 'text/plain'; |
||
4281 | } |
||
4282 | |||
4283 | // mime type normalization |
||
4284 | $_checkKey = strtolower($ext.':'.$type); |
||
4285 | if (isset($this->options['mimeMap'][$_checkKey])) { |
||
4286 | $type = $this->options['mimeMap'][$_checkKey]; |
||
4287 | } else { |
||
4288 | $_checkKey = strtolower($ext.':*'); |
||
4289 | if (isset($this->options['mimeMap'][$_checkKey])) { |
||
4290 | $type = $this->options['mimeMap'][$_checkKey]; |
||
4291 | } |
||
4292 | } |
||
4293 | |||
4294 | return $type; |
||
4295 | } |
||
4296 | |||
4297 | /** |
||
4298 | * Detect file mimetype using "internal" method or Loading mime.types with $path = ''. |
||
4299 | * |
||
4300 | * @param string $path file path |
||
4301 | * @return string |
||
4302 | * @author Dmitry (dio) Levashov |
||
4303 | **/ |
||
4304 | protected static function mimetypeInternalDetect($path = '') |
||
4305 | { |
||
4306 | // load default MIME table file "mime.types" |
||
4307 | if (! self::$mimetypesLoaded) { |
||
4308 | self::$mimetypesLoaded = true; |
||
4309 | $file = elFinder::$defaultMimefile; |
||
4310 | if ($file === '' || ! is_readable($file)) { |
||
4311 | $file = dirname(__FILE__).DIRECTORY_SEPARATOR.'mime.types'; |
||
4312 | } |
||
4313 | View Code Duplication | if (is_readable($file)) { |
|
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. ![]() |
|||
4314 | $mimecf = file($file); |
||
4315 | foreach ($mimecf as $line_num => $line) { |
||
4316 | if (! preg_match('/^\s*#/', $line)) { |
||
4317 | $mime = preg_split('/\s+/', $line, -1, PREG_SPLIT_NO_EMPTY); |
||
4318 | for ($i = 1, $size = count($mime); $i < $size; $i++) { |
||
4319 | if (! isset(self::$mimetypes[$mime[$i]])) { |
||
4320 | self::$mimetypes[$mime[$i]] = $mime[0]; |
||
4321 | } |
||
4322 | } |
||
4323 | } |
||
4324 | } |
||
4325 | } |
||
4326 | } |
||
4327 | $ext = ''; |
||
4328 | if ($path) { |
||
4329 | $pinfo = pathinfo($path); |
||
4330 | $ext = isset($pinfo['extension']) ? strtolower($pinfo['extension']) : ''; |
||
4331 | } |
||
4332 | |||
4333 | return ($ext && isset(self::$mimetypes[$ext])) ? self::$mimetypes[$ext] : 'unknown'; |
||
4334 | } |
||
4335 | |||
4336 | /** |
||
4337 | * Return file/total directory size. |
||
4338 | * |
||
4339 | * @param string $path file path |
||
4340 | * @return int |
||
4341 | * @author Dmitry (dio) Levashov |
||
4342 | **/ |
||
4343 | protected function countSize($path) |
||
4344 | { |
||
4345 | elFinder::extendTimeLimit(); |
||
4346 | |||
4347 | $result = ['size' => 0, 'files' => 0, 'dirs' => 0]; |
||
4348 | $stat = $this->stat($path); |
||
4349 | |||
4350 | if (empty($stat) || ! $stat['read'] || ! empty($stat['hidden'])) { |
||
4351 | $result['size'] = 'unknown'; |
||
4352 | |||
4353 | return $result; |
||
4354 | } |
||
4355 | |||
4356 | if ($stat['mime'] != 'directory') { |
||
4357 | $result['size'] = intval($stat['size']); |
||
4358 | $result['files'] = 1; |
||
4359 | |||
4360 | return $result; |
||
4361 | } |
||
4362 | |||
4363 | $subdirs = $this->options['checkSubfolders']; |
||
4364 | $this->options['checkSubfolders'] = true; |
||
4365 | foreach ($this->getScandir($path) as $stat) { |
||
4366 | if ($isDir = ($stat['mime'] === 'directory' && $stat['read'])) { |
||
4367 | $result['dirs']++; |
||
4368 | } else { |
||
4369 | $result['files']++; |
||
4370 | } |
||
4371 | $res = $isDir |
||
4372 | ? $this->countSize($this->decode($stat['hash'])) |
||
4373 | : (isset($stat['size']) ? ['size' => intval($stat['size'])] : []); |
||
4374 | View Code Duplication | if (! empty($res['size']) && is_numeric($res['size'])) { |
|
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. ![]() |
|||
4375 | $result['size'] += $res['size']; |
||
4376 | } |
||
4377 | View Code Duplication | if (! empty($res['files']) && is_numeric($res['files'])) { |
|
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. ![]() |
|||
4378 | $result['files'] += $res['files']; |
||
4379 | } |
||
4380 | View Code Duplication | if (! empty($res['dirs']) && is_numeric($res['dirs'])) { |
|
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. ![]() |
|||
4381 | $result['dirs'] += $res['dirs']; |
||
4382 | } |
||
4383 | } |
||
4384 | $this->options['checkSubfolders'] = $subdirs; |
||
4385 | |||
4386 | return $result; |
||
4387 | } |
||
4388 | |||
4389 | /** |
||
4390 | * Return true if all mimes is directory or files. |
||
4391 | * |
||
4392 | * @param string $mime1 mimetype |
||
4393 | * @param string $mime2 mimetype |
||
4394 | * @return bool |
||
4395 | * @author Dmitry (dio) Levashov |
||
4396 | **/ |
||
4397 | protected function isSameType($mime1, $mime2) |
||
4398 | { |
||
4399 | return ($mime1 == 'directory' && $mime1 == $mime2) || ($mime1 != 'directory' && $mime2 != 'directory'); |
||
4400 | } |
||
4401 | |||
4402 | /** |
||
4403 | * If file has required attr == $val - return file path, |
||
4404 | * If dir has child with has required attr == $val - return child path. |
||
4405 | * |
||
4406 | * @param string $path file path |
||
4407 | * @param string $attr attribute name |
||
4408 | * @param bool $val attribute value |
||
4409 | * @return string|false |
||
4410 | * @author Dmitry (dio) Levashov |
||
4411 | **/ |
||
4412 | protected function closestByAttr($path, $attr, $val) |
||
4413 | { |
||
4414 | $stat = $this->stat($path); |
||
4415 | |||
4416 | if (empty($stat)) { |
||
4417 | return false; |
||
4418 | } |
||
4419 | |||
4420 | $v = isset($stat[$attr]) ? $stat[$attr] : false; |
||
4421 | |||
4422 | if ($v == $val) { |
||
4423 | return $path; |
||
4424 | } |
||
4425 | |||
4426 | return $stat['mime'] == 'directory' |
||
4427 | ? $this->childsByAttr($path, $attr, $val) |
||
4428 | : false; |
||
4429 | } |
||
4430 | |||
4431 | /** |
||
4432 | * Return first found children with required attr == $val. |
||
4433 | * |
||
4434 | * @param string $path file path |
||
4435 | * @param string $attr attribute name |
||
4436 | * @param bool $val attribute value |
||
4437 | * @return string|false |
||
4438 | * @author Dmitry (dio) Levashov |
||
4439 | **/ |
||
4440 | protected function childsByAttr($path, $attr, $val) |
||
4441 | { |
||
4442 | foreach ($this->scandirCE($path) as $p) { |
||
4443 | if (($_p = $this->closestByAttr($p, $attr, $val)) != false) { |
||
0 ignored issues
–
show
|
|||
4444 | return $_p; |
||
4445 | } |
||
4446 | } |
||
4447 | |||
4448 | return false; |
||
4449 | } |
||
4450 | |||
4451 | protected function isMyReload($target = '', $ARGtarget = '') |
||
4452 | { |
||
4453 | if ($this->rootModified || (! empty($this->ARGS['cmd']) && $this->ARGS['cmd'] === 'parents')) { |
||
4454 | return true; |
||
4455 | } |
||
4456 | if (! empty($this->ARGS['reload'])) { |
||
4457 | if ($ARGtarget === '') { |
||
4458 | $ARGtarget = isset($this->ARGS['target']) ? $this->ARGS['target'] |
||
4459 | : ((isset($this->ARGS['targets']) && is_array($this->ARGS['targets']) && count($this->ARGS['targets']) === 1) ? |
||
4460 | $this->ARGS['targets'][0] : ''); |
||
4461 | } |
||
4462 | if ($ARGtarget !== '') { |
||
4463 | $ARGtarget = strval($ARGtarget); |
||
4464 | if ($target === '') { |
||
4465 | return strpos($ARGtarget, $this->id) === 0; |
||
4466 | } else { |
||
4467 | $target = strval($target); |
||
4468 | |||
4469 | return $target === $ARGtarget; |
||
4470 | } |
||
4471 | } |
||
4472 | } |
||
4473 | |||
4474 | return false; |
||
4475 | } |
||
4476 | |||
4477 | /** |
||
4478 | * Update subdirs cache data. |
||
4479 | * |
||
4480 | * @param string $path |
||
4481 | * @param bool $subdirs |
||
4482 | * |
||
4483 | * @returnv void |
||
4484 | */ |
||
4485 | protected function updateSubdirsCache($path, $subdirs) |
||
4486 | { |
||
4487 | if (isset($this->cache[$path])) { |
||
4488 | if ($subdirs) { |
||
4489 | $this->cache[$path]['dirs'] = 1; |
||
4490 | } else { |
||
4491 | unset($this->cache[$path]['dirs']); |
||
4492 | } |
||
4493 | } |
||
4494 | if ($this->sessionCaching['subdirs']) { |
||
4495 | $this->sessionCache['subdirs'][$path] = $subdirs; |
||
4496 | } |
||
4497 | if ($this->sessionCaching['rootstat'] && $path == $this->root) { |
||
4498 | unset($this->sessionCache['rootstat'][$this->getRootstatCachekey()]); |
||
4499 | } |
||
4500 | } |
||
4501 | |||
4502 | /***************** get content *******************/ |
||
4503 | |||
4504 | /** |
||
4505 | * Return required dir's files info. |
||
4506 | * If onlyMimes is set - return only dirs and files of required mimes. |
||
4507 | * |
||
4508 | * @param string $path dir path |
||
4509 | * @return array |
||
4510 | * @author Dmitry (dio) Levashov |
||
4511 | **/ |
||
4512 | protected function getScandir($path) |
||
4513 | { |
||
4514 | $files = []; |
||
4515 | |||
4516 | ! isset($this->dirsCache[$path]) && $this->cacheDir($path); |
||
4517 | |||
4518 | foreach ($this->dirsCache[$path] as $p) { |
||
4519 | if (($stat = $this->stat($p)) && empty($stat['hidden'])) { |
||
4520 | $files[] = $stat; |
||
4521 | } |
||
4522 | } |
||
4523 | |||
4524 | return $files; |
||
4525 | } |
||
4526 | |||
4527 | /** |
||
4528 | * Return subdirs tree. |
||
4529 | * |
||
4530 | * @param string $path parent dir path |
||
4531 | * @param int $deep tree deep |
||
4532 | * @param string $exclude |
||
4533 | * @return array |
||
4534 | * @author Dmitry (dio) Levashov |
||
4535 | */ |
||
4536 | protected function gettree($path, $deep, $exclude = '') |
||
4537 | { |
||
4538 | $dirs = []; |
||
4539 | |||
4540 | ! isset($this->dirsCache[$path]) && $this->cacheDir($path); |
||
4541 | |||
4542 | foreach ($this->dirsCache[$path] as $p) { |
||
4543 | $stat = $this->stat($p); |
||
4544 | |||
4545 | if ($stat && empty($stat['hidden']) && $p != $exclude && $stat['mime'] == 'directory') { |
||
0 ignored issues
–
show
The expression
$stat 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 ![]() |
|||
4546 | $dirs[] = $stat; |
||
4547 | if ($deep > 0 && ! empty($stat['dirs'])) { |
||
4548 | $dirs = array_merge($dirs, $this->gettree($p, $deep - 1)); |
||
4549 | } |
||
4550 | } |
||
4551 | } |
||
4552 | |||
4553 | return $dirs; |
||
4554 | } |
||
4555 | |||
4556 | /** |
||
4557 | * Recursive files search. |
||
4558 | * |
||
4559 | * @param string $path dir path |
||
4560 | * @param string $q search string |
||
4561 | * @param array $mimes |
||
4562 | * @return array |
||
4563 | * @author Dmitry (dio) Levashov |
||
4564 | **/ |
||
4565 | protected function doSearch($path, $q, $mimes) |
||
4566 | { |
||
4567 | $result = []; |
||
4568 | |||
4569 | $timeout = $this->options['searchTimeout'] ? $this->searchStart + $this->options['searchTimeout'] : 0; |
||
4570 | View Code Duplication | if ($timeout && $timeout < time()) { |
|
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. ![]() |
|||
4571 | $this->setError(elFinder::ERROR_SEARCH_TIMEOUT, $this->path($this->encode($path))); |
||
4572 | |||
4573 | return $result; |
||
4574 | } |
||
4575 | |||
4576 | foreach ($this->scandirCE($path) as $p) { |
||
4577 | elFinder::extendTimeLimit($this->options['searchTimeout'] + 30); |
||
4578 | |||
4579 | View Code Duplication | if ($timeout && ($this->error || $timeout < time())) { |
|
0 ignored issues
–
show
The expression
$this->error 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 ![]() 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. ![]() |
|||
4580 | ! $this->error && $this->setError(elFinder::ERROR_SEARCH_TIMEOUT, $this->path($this->encode($path))); |
||
0 ignored issues
–
show
The expression
$this->error 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 ![]() |
|||
4581 | break; |
||
4582 | } |
||
4583 | |||
4584 | $stat = $this->stat($p); |
||
4585 | |||
4586 | if (! $stat) { // invalid links |
||
0 ignored issues
–
show
The expression
$stat 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 ![]() |
|||
4587 | continue; |
||
4588 | } |
||
4589 | |||
4590 | if (! empty($stat['hidden']) || ! $this->mimeAccepted($stat['mime'], $mimes)) { |
||
4591 | continue; |
||
4592 | } |
||
4593 | |||
4594 | $name = $stat['name']; |
||
4595 | |||
4596 | View Code Duplication | if ($this->doSearchCurrentQuery['excludes']) { |
|
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. ![]() |
|||
4597 | foreach ($this->doSearchCurrentQuery['excludes'] as $exclude) { |
||
0 ignored issues
–
show
|
|||
4598 | if ($this->stripos($name, $exclude) !== false) { |
||
4599 | continue 2; |
||
4600 | } |
||
4601 | } |
||
4602 | } |
||
4603 | |||
4604 | if ((! $mimes || $stat['mime'] !== 'directory') && $this->stripos($name, $q) !== false) { |
||
0 ignored issues
–
show
The expression
$mimes 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 ![]() |
|||
4605 | $stat['path'] = $this->path($stat['hash']); |
||
4606 | if ($this->URL && ! isset($stat['url'])) { |
||
4607 | $path = str_replace($this->separator, '/', substr($p, strlen($this->root) + 1)); |
||
4608 | if ($this->encoding) { |
||
4609 | $path = str_replace('%2F', '/', rawurlencode($this->convEncIn($path, true))); |
||
4610 | } else { |
||
4611 | $path = str_replace('%2F', '/', rawurlencode($path)); |
||
4612 | } |
||
4613 | $stat['url'] = $this->URL.$path; |
||
4614 | } |
||
4615 | |||
4616 | $result[] = $stat; |
||
4617 | } |
||
4618 | if ($stat['mime'] == 'directory' && $stat['read'] && ! isset($stat['alias'])) { |
||
4619 | if (! $this->options['searchExDirReg'] || ! preg_match($this->options['searchExDirReg'], $p)) { |
||
4620 | $result = array_merge($result, $this->doSearch($p, $q, $mimes)); |
||
4621 | } |
||
4622 | } |
||
4623 | } |
||
4624 | |||
4625 | return $result; |
||
4626 | } |
||
4627 | |||
4628 | /********************** manuipulations ******************/ |
||
4629 | |||
4630 | /** |
||
4631 | * Copy file/recursive copy dir only in current volume. |
||
4632 | * Return new file path or false. |
||
4633 | * |
||
4634 | * @param string $src source path |
||
4635 | * @param string $dst destination dir path |
||
4636 | * @param string $name new file name (optionaly) |
||
4637 | * @return string|false |
||
4638 | * @author Dmitry (dio) Levashov |
||
4639 | **/ |
||
4640 | protected function copy($src, $dst, $name) |
||
4641 | { |
||
4642 | elFinder::extendTimeLimit(); |
||
4643 | |||
4644 | $srcStat = $this->stat($src); |
||
4645 | |||
4646 | if (! empty($srcStat['thash'])) { |
||
4647 | $target = $this->decode($srcStat['thash']); |
||
4648 | if (! $this->inpathCE($target, $this->root)) { |
||
4649 | return $this->setError(elFinder::ERROR_COPY, $this->path($srcStat['hash']), elFinder::ERROR_MKOUTLINK); |
||
4650 | } |
||
4651 | $stat = $this->stat($target); |
||
4652 | $this->clearcache(); |
||
4653 | |||
4654 | return $stat && $this->symlinkCE($target, $dst, $name) |
||
0 ignored issues
–
show
The expression
$stat 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 ![]() |
|||
4655 | ? $this->joinPathCE($dst, $name) |
||
4656 | : $this->setError(elFinder::ERROR_COPY, $this->path($srcStat['hash'])); |
||
4657 | } |
||
4658 | |||
4659 | if ($srcStat['mime'] === 'directory') { |
||
4660 | $testStat = $this->isNameExists($this->joinPathCE($dst, $name)); |
||
4661 | $this->clearcache(); |
||
4662 | |||
4663 | View Code Duplication | if (($testStat && $testStat['mime'] !== 'directory') || (! $testStat && ! $testStat = $this->mkdir($this->encode($dst), $name))) { |
|
0 ignored issues
–
show
The expression
$testStat 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 ![]() The expression
$testStat 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 ![]() 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. ![]() |
|||
4664 | return $this->setError(elFinder::ERROR_COPY, $this->path($srcStat['hash'])); |
||
4665 | } |
||
4666 | |||
4667 | $dst = $this->decode($testStat['hash']); |
||
4668 | |||
4669 | foreach ($this->getScandir($src) as $stat) { |
||
4670 | if (empty($stat['hidden'])) { |
||
4671 | $name = $stat['name']; |
||
4672 | $_src = $this->decode($stat['hash']); |
||
4673 | if (! $this->copy($_src, $dst, $name)) { |
||
4674 | $this->remove($dst, true); // fall back |
||
4675 | return $this->setError($this->error, elFinder::ERROR_COPY, $this->_path($src)); |
||
4676 | } |
||
4677 | } |
||
4678 | } |
||
4679 | |||
4680 | $this->added[] = $testStat; |
||
4681 | |||
4682 | return $dst; |
||
4683 | } |
||
4684 | |||
4685 | View Code Duplication | if ($this->options['copyJoin']) { |
|
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. ![]() |
|||
4686 | $test = $this->joinPathCE($dst, $name); |
||
4687 | if ($testStat = $this->isNameExists($test)) { |
||
0 ignored issues
–
show
$testStat 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 ![]() |
|||
4688 | $this->remove($test); |
||
4689 | } |
||
4690 | } else { |
||
4691 | $testStat = false; |
||
0 ignored issues
–
show
$testStat 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 ![]() |
|||
4692 | } |
||
4693 | if ($res = $this->convEncOut($this->_copy($this->convEncIn($src), $this->convEncIn($dst), $this->convEncIn($name)))) { |
||
4694 | $path = is_string($res) ? $res : $this->joinPathCE($dst, $name); |
||
4695 | $this->clearcache(); |
||
4696 | if ($this->ARGS['cmd'] !== 'duplicate') { |
||
4697 | $this->added[] = $this->stat($path); |
||
4698 | } |
||
4699 | |||
4700 | return $path; |
||
4701 | } |
||
4702 | |||
4703 | return $this->setError(elFinder::ERROR_COPY, $this->path($srcStat['hash'])); |
||
4704 | } |
||
4705 | |||
4706 | /** |
||
4707 | * Move file |
||
4708 | * Return new file path or false. |
||
4709 | * |
||
4710 | * @param string $src source path |
||
4711 | * @param string $dst destination dir path |
||
4712 | * @param string $name new file name |
||
4713 | * @return string|false |
||
4714 | * @author Dmitry (dio) Levashov |
||
4715 | **/ |
||
4716 | protected function move($src, $dst, $name) |
||
4717 | { |
||
4718 | $stat = $this->stat($src); |
||
4719 | $stat['realpath'] = $src; |
||
4720 | $this->rmTmb($stat); // can not do rmTmb() after _move() |
||
0 ignored issues
–
show
$stat is of type array<string,string,{"realpath":"string"}> , 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);
![]() |
|||
4721 | $this->clearcache(); |
||
4722 | |||
4723 | if ($res = $this->convEncOut($this->_move($this->convEncIn($src), $this->convEncIn($dst), $this->convEncIn($name)))) { |
||
4724 | $this->removed[] = $stat; |
||
4725 | if ($stat['mime'] === 'directory') { |
||
4726 | $this->updateSubdirsCache($dst, true); |
||
4727 | } |
||
4728 | |||
4729 | return is_string($res) ? $res : $this->joinPathCE($dst, $name); |
||
4730 | } |
||
4731 | |||
4732 | return $this->setError(elFinder::ERROR_MOVE, $this->path($stat['hash'])); |
||
4733 | } |
||
4734 | |||
4735 | /** |
||
4736 | * Copy file from another volume. |
||
4737 | * Return new file path or false. |
||
4738 | * |
||
4739 | * @param object $volume source volume |
||
4740 | * @param string $src source file hash |
||
4741 | * @param string $destination destination dir path |
||
4742 | * @param string $name file name |
||
4743 | * @return string|false |
||
4744 | * @author Dmitry (dio) Levashov |
||
4745 | **/ |
||
4746 | protected function copyFrom($volume, $src, $destination, $name) |
||
4747 | { |
||
4748 | elFinder::extendTimeLimit(); |
||
4749 | |||
4750 | if (($source = $volume->file($src)) == false) { |
||
4751 | return $this->setError(elFinder::ERROR_COPY, '#'.$src, $volume->error()); |
||
4752 | } |
||
4753 | |||
4754 | $srcIsDir = ($source['mime'] === 'directory'); |
||
4755 | |||
4756 | $errpath = $volume->path($source['hash']); |
||
4757 | |||
4758 | if (! $this->nameAccepted($source['name'], $srcIsDir)) { |
||
4759 | return $this->setError(elFinder::ERROR_COPY, $errpath, $srcIsDir ? elFinder::ERROR_INVALID_DIRNAME : elFinder::ERROR_INVALID_NAME); |
||
4760 | } |
||
4761 | |||
4762 | if (! $source['read']) { |
||
4763 | return $this->setError(elFinder::ERROR_COPY, $errpath, elFinder::ERROR_PERM_DENIED); |
||
4764 | } |
||
4765 | |||
4766 | if ($srcIsDir) { |
||
4767 | $test = $this->isNameExists($this->joinPathCE($destination, $name)); |
||
4768 | $this->clearcache(); |
||
4769 | |||
4770 | View Code Duplication | if (($test && $test['mime'] != 'directory') || (! $test && ! $test = $this->mkdir($this->encode($destination), $name))) { |
|
0 ignored issues
–
show
The expression
$test 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 ![]() The expression
$test 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 ![]() 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. ![]() |
|||
4771 | return $this->setError(elFinder::ERROR_COPY, $errpath); |
||
4772 | } |
||
4773 | |||
4774 | //$path = $this->joinPathCE($destination, $name); |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
65% 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. ![]() |
|||
4775 | $path = $this->decode($test['hash']); |
||
4776 | |||
4777 | foreach ($volume->scandir($src) as $entr) { |
||
4778 | if (! $this->copyFrom($volume, $entr['hash'], $path, $entr['name'])) { |
||
4779 | $this->remove($path, true); // fall back |
||
4780 | return $this->setError($this->error, elFinder::ERROR_COPY, $errpath); |
||
4781 | } |
||
4782 | } |
||
4783 | |||
4784 | $this->added[] = $test; |
||
4785 | } else { |
||
4786 | // MIME check |
||
4787 | $mimeByName = $this->mimetype($source['name'], true); |
||
4788 | if ($source['mime'] === $mimeByName) { |
||
4789 | $mimeByName = ''; |
||
4790 | } |
||
4791 | View Code Duplication | if (! $this->allowPutMime($source['mime']) || ($mimeByName && ! $this->allowPutMime($mimeByName))) { |
|
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. ![]() |
|||
4792 | return $this->setError(elFinder::ERROR_UPLOAD_FILE_MIME, $errpath); |
||
4793 | } |
||
4794 | |||
4795 | if (strpos($source['mime'], 'image') === 0 && ($dim = $volume->dimensions($src))) { |
||
4796 | $s = explode('x', $dim); |
||
4797 | $source['width'] = $s[0]; |
||
4798 | $source['height'] = $s[1]; |
||
4799 | } |
||
4800 | |||
4801 | if (($fp = $volume->open($src)) == false |
||
4802 | || ($path = $this->saveCE($fp, $destination, $name, $source)) == false) { |
||
4803 | $fp && $volume->close($fp, $src); |
||
4804 | |||
4805 | return $this->setError(elFinder::ERROR_COPY, $errpath); |
||
4806 | } |
||
4807 | $volume->close($fp, $src); |
||
4808 | |||
4809 | $this->added[] = $this->stat($path); |
||
0 ignored issues
–
show
It seems like
$path defined by $this->saveCE($fp, $destination, $name, $source) on line 4802 can also be of type boolean ; however, elFinderVolumeDriver::stat() does only seem to accept string , maybe add an additional type check?
If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check: /**
* @return array|string
*/
function returnsDifferentValues($x) {
if ($x) {
return 'foo';
}
return array();
}
$x = returnsDifferentValues($y);
if (is_array($x)) {
// $x is an array.
}
If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue. ![]() |
|||
4810 | } |
||
4811 | |||
4812 | return $path; |
||
4813 | } |
||
4814 | |||
4815 | /** |
||
4816 | * Remove file/ recursive remove dir. |
||
4817 | * |
||
4818 | * @param string $path file path |
||
4819 | * @param bool $force try to remove even if file locked |
||
4820 | * @return bool |
||
4821 | * @author Dmitry (dio) Levashov |
||
4822 | **/ |
||
4823 | protected function remove($path, $force = false) |
||
4824 | { |
||
4825 | $stat = $this->stat($path); |
||
4826 | |||
4827 | if (empty($stat)) { |
||
4828 | return $this->setError(elFinder::ERROR_RM, $path, elFinder::ERROR_FILE_NOT_FOUND); |
||
4829 | } |
||
4830 | |||
4831 | $stat['realpath'] = $path; |
||
4832 | $this->rmTmb($stat); |
||
0 ignored issues
–
show
$stat is of type array<string,string,{"realpath":"string"}> , 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);
![]() |
|||
4833 | $this->clearcache(); |
||
4834 | |||
4835 | if (! $force && ! empty($stat['locked'])) { |
||
4836 | return $this->setError(elFinder::ERROR_LOCKED, $this->path($stat['hash'])); |
||
4837 | } |
||
4838 | |||
4839 | if ($stat['mime'] == 'directory' && empty($stat['thash'])) { |
||
4840 | $ret = $this->delTree($this->convEncIn($path)); |
||
4841 | $this->convEncOut(); |
||
4842 | if (! $ret) { |
||
4843 | return $this->setError(elFinder::ERROR_RM, $this->path($stat['hash'])); |
||
4844 | } |
||
4845 | 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. ![]() |
|||
4846 | if ($this->convEncOut(! $this->_unlink($this->convEncIn($path)))) { |
||
4847 | return $this->setError(elFinder::ERROR_RM, $this->path($stat['hash'])); |
||
4848 | } |
||
4849 | } |
||
4850 | |||
4851 | $this->removed[] = $stat; |
||
4852 | |||
4853 | return true; |
||
4854 | } |
||
4855 | |||
4856 | /************************* thumbnails **************************/ |
||
4857 | |||
4858 | /** |
||
4859 | * Return thumbnail file name for required file. |
||
4860 | * |
||
4861 | * @param array $stat file stat |
||
4862 | * @return string |
||
4863 | * @author Dmitry (dio) Levashov |
||
4864 | **/ |
||
4865 | protected function tmbname($stat) |
||
4866 | { |
||
4867 | return $stat['hash'].$stat['ts'].'.png'; |
||
4868 | } |
||
4869 | |||
4870 | /** |
||
4871 | * Return thumnbnail name if exists. |
||
4872 | * |
||
4873 | * @param string $path file path |
||
4874 | * @param array $stat file stat |
||
4875 | * @return string|false |
||
4876 | * @author Dmitry (dio) Levashov |
||
4877 | **/ |
||
4878 | protected function gettmb($path, $stat) |
||
4879 | { |
||
4880 | if ($this->tmbURL && $this->tmbPath) { |
||
4881 | // file itself thumnbnail |
||
4882 | if (strpos($path, $this->tmbPath) === 0) { |
||
4883 | return basename($path); |
||
4884 | } |
||
4885 | |||
4886 | $name = $this->tmbname($stat); |
||
4887 | if (file_exists($this->tmbPath.DIRECTORY_SEPARATOR.$name)) { |
||
4888 | return $name; |
||
4889 | } |
||
4890 | } |
||
4891 | |||
4892 | return false; |
||
4893 | } |
||
4894 | |||
4895 | /** |
||
4896 | * Return true if thumnbnail for required file can be created. |
||
4897 | * |
||
4898 | * @param string $path thumnbnail path |
||
4899 | * @param array $stat file stat |
||
4900 | * @param bool $checkTmbPath |
||
4901 | * @return string|bool |
||
4902 | * @author Dmitry (dio) Levashov |
||
4903 | **/ |
||
4904 | protected function canCreateTmb($path, $stat, $checkTmbPath = true) |
||
4905 | { |
||
4906 | if ((! $checkTmbPath || $this->tmbPathWritable) |
||
4907 | && (! $this->tmbPath || strpos($path, $this->tmbPath) === false) // do not create thumnbnail for thumnbnail |
||
4908 | ) { |
||
4909 | $mime = strtolower($stat['mime']); |
||
4910 | list($type) = explode('/', $mime); |
||
4911 | if (! empty($this->imgConverter)) { |
||
4912 | if (isset($this->imgConverter[$mime])) { |
||
4913 | return true; |
||
4914 | } |
||
4915 | if (isset($this->imgConverter[$type])) { |
||
4916 | return true; |
||
4917 | } |
||
4918 | } |
||
4919 | |||
4920 | return $this->imgLib |
||
4921 | && ($type === 'image') |
||
4922 | && ($this->imgLib == 'gd' ? in_array($stat['mime'], ['image/jpeg', 'image/png', 'image/gif', 'image/x-ms-bmp']) : true); |
||
4923 | } |
||
4924 | |||
4925 | return false; |
||
4926 | } |
||
4927 | |||
4928 | /** |
||
4929 | * Return true if required file can be resized. |
||
4930 | * By default - the same as canCreateTmb. |
||
4931 | * |
||
4932 | * @param string $path thumnbnail path |
||
4933 | * @param array $stat file stat |
||
4934 | * @return string|bool |
||
4935 | * @author Dmitry (dio) Levashov |
||
4936 | **/ |
||
4937 | protected function canResize($path, $stat) |
||
4938 | { |
||
4939 | return $this->canCreateTmb($path, $stat, false); |
||
4940 | } |
||
4941 | |||
4942 | /** |
||
4943 | * Create thumnbnail and return it's URL on success. |
||
4944 | * |
||
4945 | * @param string $path file path |
||
4946 | * @param $stat |
||
4947 | * @return false|string |
||
4948 | * @internal param string $mime file mime type |
||
4949 | * @author Dmitry (dio) Levashov |
||
4950 | */ |
||
4951 | protected function createTmb($path, $stat) |
||
4952 | { |
||
4953 | if (! $stat || ! $this->canCreateTmb($path, $stat)) { |
||
4954 | return false; |
||
4955 | } |
||
4956 | |||
4957 | $name = $this->tmbname($stat); |
||
4958 | $tmb = $this->tmbPath.DIRECTORY_SEPARATOR.$name; |
||
4959 | |||
4960 | $maxlength = -1; |
||
4961 | $imgConverter = null; |
||
4962 | |||
4963 | // check imgConverter |
||
4964 | $mime = strtolower($stat['mime']); |
||
4965 | list($type) = explode('/', $mime); |
||
4966 | if (isset($this->imgConverter[$mime])) { |
||
4967 | $imgConverter = $this->imgConverter[$mime]['func']; |
||
4968 | View Code Duplication | if (! empty($this->imgConverter[$mime]['maxlen'])) { |
|
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. ![]() |
|||
4969 | $maxlength = intval($this->imgConverter[$mime]['maxlen']); |
||
4970 | } |
||
4971 | } elseif (isset($this->imgConverter[$type])) { |
||
4972 | $imgConverter = $this->imgConverter[$type]['func']; |
||
4973 | View Code Duplication | if (! empty($this->imgConverter[$type]['maxlen'])) { |
|
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. ![]() |
|||
4974 | $maxlength = intval($this->imgConverter[$type]['maxlen']); |
||
4975 | } |
||
4976 | } |
||
4977 | if ($imgConverter && ! is_callable($imgConverter)) { |
||
4978 | return false; |
||
4979 | } |
||
4980 | |||
4981 | // copy image into tmbPath so some drivers does not store files on local fs |
||
4982 | if (($src = $this->fopenCE($path, 'rb')) == false) { |
||
4983 | return false; |
||
4984 | } |
||
4985 | |||
4986 | if (($trg = fopen($tmb, 'wb')) == false) { |
||
4987 | $this->fcloseCE($src, $path); |
||
4988 | |||
4989 | return false; |
||
4990 | } |
||
4991 | |||
4992 | stream_copy_to_stream($src, $trg, $maxlength); |
||
4993 | |||
4994 | $this->fcloseCE($src, $path); |
||
4995 | fclose($trg); |
||
4996 | |||
4997 | // call imgConverter |
||
4998 | if ($imgConverter) { |
||
4999 | if (! call_user_func_array($imgConverter, [$tmb, $stat, $this])) { |
||
5000 | file_exists($tmb) && unlink($tmb); |
||
5001 | |||
5002 | return false; |
||
5003 | } |
||
5004 | } |
||
5005 | |||
5006 | $result = false; |
||
5007 | |||
5008 | $tmbSize = $this->tmbSize; |
||
5009 | |||
5010 | if ($this->imgLib === 'imagick') { |
||
5011 | try { |
||
5012 | $imagickTest = new imagick($tmb); |
||
5013 | $imagickTest->clear(); |
||
5014 | $imagickTest = true; |
||
5015 | } catch (Exception $e) { |
||
5016 | $imagickTest = false; |
||
5017 | } |
||
5018 | } |
||
5019 | |||
5020 | if (($this->imgLib === 'imagick' && ! $imagickTest) || ($s = getimagesize($tmb)) === false) { |
||
0 ignored issues
–
show
The variable
$imagickTest does not seem to be defined for all execution paths leading up to this point.
If you define a variable conditionally, it can happen that it is not defined for all execution paths. Let’s take a look at an example: function myFunction($a) {
switch ($a) {
case 'foo':
$x = 1;
break;
case 'bar':
$x = 2;
break;
}
// $x is potentially undefined here.
echo $x;
}
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined. Available Fixes
![]() |
|||
5021 | if ($this->imgLib === 'imagick') { |
||
5022 | $bgcolor = $this->options['tmbBgColor']; |
||
5023 | if ($bgcolor === 'transparent') { |
||
5024 | $bgcolor = 'rgba(255, 255, 255, 0.0)'; |
||
5025 | } |
||
5026 | try { |
||
5027 | $imagick = new imagick(); |
||
5028 | $imagick->setBackgroundColor(new ImagickPixel($bgcolor)); |
||
5029 | $imagick->readImage($this->getExtentionByMime($stat['mime'], ':').$tmb); |
||
5030 | $imagick->setImageFormat('png'); |
||
5031 | $imagick->writeImage($tmb); |
||
5032 | $imagick->clear(); |
||
5033 | if (($s = getimagesize($tmb)) !== false) { |
||
5034 | $result = true; |
||
5035 | } |
||
5036 | } catch (Exception $e) { |
||
0 ignored issues
–
show
Coding Style
Comprehensibility
introduced
by
|
|||
5037 | } |
||
5038 | } |
||
5039 | if (! $result) { |
||
5040 | file_exists($tmb) && unlink($tmb); |
||
5041 | |||
5042 | return false; |
||
5043 | } |
||
5044 | $result = false; |
||
0 ignored issues
–
show
$result 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 ![]() |
|||
5045 | } |
||
5046 | |||
5047 | /* If image smaller or equal thumbnail size - just fitting to thumbnail square */ |
||
5048 | if ($s[0] <= $tmbSize && $s[1] <= $tmbSize) { |
||
5049 | $result = $this->imgSquareFit($tmb, $tmbSize, $tmbSize, 'center', 'middle', $this->options['tmbBgColor'], 'png'); |
||
5050 | } else { |
||
5051 | if ($this->options['tmbCrop']) { |
||
5052 | $result = $tmb; |
||
5053 | /* Resize and crop if image bigger than thumbnail */ |
||
5054 | if (! (($s[0] > $tmbSize && $s[1] <= $tmbSize) || ($s[0] <= $tmbSize && $s[1] > $tmbSize)) || ($s[0] > $tmbSize && $s[1] > $tmbSize)) { |
||
0 ignored issues
–
show
The variable
$s does not seem to be defined for all execution paths leading up to this point.
If you define a variable conditionally, it can happen that it is not defined for all execution paths. Let’s take a look at an example: function myFunction($a) {
switch ($a) {
case 'foo':
$x = 1;
break;
case 'bar':
$x = 2;
break;
}
// $x is potentially undefined here.
echo $x;
}
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined. Available Fixes
![]() |
|||
5055 | $result = $this->imgResize($tmb, $tmbSize, $tmbSize, true, false, 'png'); |
||
5056 | } |
||
5057 | |||
5058 | if ($result && ($s = getimagesize($tmb)) != false) { |
||
0 ignored issues
–
show
The expression
$result of type false|string is loosely compared to true ; 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
![]() |
|||
5059 | $x = $s[0] > $tmbSize ? intval(($s[0] - $tmbSize) / 2) : 0; |
||
5060 | $y = $s[1] > $tmbSize ? intval(($s[1] - $tmbSize) / 2) : 0; |
||
5061 | $result = $this->imgCrop($result, $tmbSize, $tmbSize, $x, $y, 'png'); |
||
0 ignored issues
–
show
$x is of type integer , but the function expects a boolean .
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);
![]() $y is of type integer , but the function expects a boolean .
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);
![]() |
|||
5062 | } else { |
||
5063 | $result = false; |
||
5064 | } |
||
5065 | } else { |
||
5066 | $result = $this->imgResize($tmb, $tmbSize, $tmbSize, true, true, 'png'); |
||
5067 | } |
||
5068 | |||
5069 | if ($result) { |
||
0 ignored issues
–
show
The expression
$result of type false|string is loosely compared to true ; 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
![]() |
|||
5070 | if ($s = getimagesize($tmb)) { |
||
5071 | if ($s[0] !== $tmbSize || $s[1] !== $tmbSize) { |
||
5072 | $result = $this->imgSquareFit($result, $tmbSize, $tmbSize, 'center', 'middle', $this->options['tmbBgColor'], 'png'); |
||
5073 | } |
||
5074 | } |
||
5075 | } |
||
5076 | } |
||
5077 | |||
5078 | if (! $result) { |
||
0 ignored issues
–
show
The expression
$result of type false|string 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
![]() |
|||
5079 | unlink($tmb); |
||
5080 | |||
5081 | return false; |
||
5082 | } |
||
5083 | |||
5084 | return $name; |
||
5085 | } |
||
5086 | |||
5087 | /** |
||
5088 | * Resize image. |
||
5089 | * |
||
5090 | * @param string $path image file |
||
5091 | * @param int $width new width |
||
5092 | * @param int $height new height |
||
5093 | * @param bool $keepProportions crop image |
||
5094 | * @param bool $resizeByBiggerSide resize image based on bigger side if true |
||
5095 | * @param string $destformat image destination format |
||
5096 | * @param int $jpgQuality JEPG quality (1-100) |
||
5097 | * @param array $options Other extra options |
||
5098 | * @return string|false |
||
5099 | * @author Dmitry (dio) Levashov |
||
5100 | * @author Alexey Sukhotin |
||
5101 | **/ |
||
5102 | protected function imgResize($path, $width, $height, $keepProportions = false, $resizeByBiggerSide = true, $destformat = null, $jpgQuality = null, $options = []) |
||
5103 | { |
||
5104 | if (($s = getimagesize($path)) == false) { |
||
5105 | return false; |
||
5106 | } |
||
5107 | |||
5108 | $result = false; |
||
0 ignored issues
–
show
$result 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 ![]() |
|||
5109 | |||
5110 | if (! $jpgQuality) { |
||
0 ignored issues
–
show
The expression
$jpgQuality of type integer|null is loosely compared to false ; this is ambiguous if the integer can be zero. You might want to explicitly use === null instead.
In PHP, under loose comparison (like For 0 == false // true
0 == null // true
123 == false // false
123 == null // false
// It is often better to use strict comparison
0 === false // false
0 === null // false
![]() |
|||
5111 | $jpgQuality = $this->options['jpgQuality']; |
||
5112 | } |
||
5113 | |||
5114 | list($orig_w, $orig_h) = [$s[0], $s[1]]; |
||
5115 | list($size_w, $size_h) = [$width, $height]; |
||
5116 | |||
5117 | if (empty($options['unenlarge']) || $orig_w > $size_w || $orig_h > $size_h) { |
||
5118 | if ($keepProportions == true) { |
||
0 ignored issues
–
show
|
|||
5119 | /* Resizing by biggest side */ |
||
5120 | if ($resizeByBiggerSide) { |
||
5121 | View Code Duplication | if ($orig_w > $orig_h) { |
|
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. ![]() |
|||
5122 | $size_h = round($orig_h * $width / $orig_w); |
||
5123 | $size_w = $width; |
||
5124 | } else { |
||
5125 | $size_w = round($orig_w * $height / $orig_h); |
||
5126 | $size_h = $height; |
||
5127 | } |
||
5128 | 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. ![]() |
|||
5129 | if ($orig_w > $orig_h) { |
||
5130 | $size_w = round($orig_w * $height / $orig_h); |
||
5131 | $size_h = $height; |
||
5132 | } else { |
||
5133 | $size_h = round($orig_h * $width / $orig_w); |
||
5134 | $size_w = $width; |
||
5135 | } |
||
5136 | } |
||
5137 | } |
||
5138 | } else { |
||
5139 | $size_w = $orig_w; |
||
5140 | $size_h = $orig_h; |
||
5141 | } |
||
5142 | |||
5143 | elFinder::extendTimeLimit(300); |
||
5144 | switch ($this->imgLib) { |
||
5145 | case 'imagick': |
||
0 ignored issues
–
show
The case body in a switch statement must start on the line following the statement.
According to the PSR-2, the body of a case statement must start on the line immediately following the case statement. switch ($expr) {
case "A":
doSomething(); //right
break;
case "B":
doSomethingElse(); //wrong
break;
} To learn more about the PSR-2 coding standard, please refer to the PHP-Fig. ![]() |
|||
5146 | |||
5147 | try { |
||
5148 | $img = new imagick($path); |
||
5149 | } catch (Exception $e) { |
||
5150 | return false; |
||
5151 | } |
||
5152 | |||
5153 | // Imagick::FILTER_BOX faster than FILTER_LANCZOS so use for createTmb |
||
5154 | // resize bench: http://app-mgng.rhcloud.com/9 |
||
5155 | // resize sample: http://www.dylanbeattie.net/magick/filters/result.html |
||
5156 | $filter = ($destformat === 'png' /* createTmb */) ? Imagick::FILTER_BOX : Imagick::FILTER_LANCZOS; |
||
5157 | |||
5158 | $ani = ($img->getNumberImages() > 1); |
||
5159 | if ($ani && is_null($destformat)) { |
||
5160 | $img = $img->coalesceImages(); |
||
5161 | do { |
||
5162 | $img->resizeImage($size_w, $size_h, $filter, 1); |
||
5163 | } while ($img->nextImage()); |
||
5164 | $img = $img->optimizeImageLayers(); |
||
5165 | $result = $img->writeImages($path, true); |
||
0 ignored issues
–
show
|
|||
5166 | } else { |
||
5167 | if ($ani) { |
||
5168 | $img->setFirstIterator(); |
||
5169 | } |
||
5170 | if (strtoupper($img->getImageFormat()) === 'JPEG') { |
||
5171 | $img->setImageCompression(imagick::COMPRESSION_JPEG); |
||
5172 | $img->setImageCompressionQuality($jpgQuality); |
||
5173 | if (isset($options['preserveExif']) && ! $options['preserveExif']) { |
||
5174 | try { |
||
5175 | $orientation = $img->getImageOrientation(); |
||
5176 | } catch (ImagickException $e) { |
||
5177 | $orientation = 0; |
||
5178 | } |
||
5179 | $img->stripImage(); |
||
5180 | if ($orientation) { |
||
5181 | $img->setImageOrientation($orientation); |
||
5182 | } |
||
5183 | } |
||
5184 | } |
||
5185 | $img->resizeImage($size_w, $size_h, $filter, true); |
||
5186 | if ($destformat) { |
||
0 ignored issues
–
show
The expression
$destformat 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
![]() |
|||
5187 | $result = $this->imagickImage($img, $path, $destformat, $jpgQuality); |
||
0 ignored issues
–
show
$img is of type object<Imagick> , but the function expects a resource .
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);
![]() |
|||
5188 | } else { |
||
5189 | $result = $img->writeImage($path); |
||
5190 | } |
||
5191 | } |
||
5192 | |||
5193 | $img->clear(); |
||
5194 | |||
5195 | return $result ? $path : false; |
||
5196 | |||
5197 | break; |
||
0 ignored issues
–
show
break is not strictly necessary here and could be removed.
The break statement is not necessary if it is preceded for example by a return statement: switch ($x) {
case 1:
return 'foo';
break; // This break is not necessary and can be left off.
}
If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive. ![]() |
|||
5198 | |||
5199 | case 'convert': |
||
5200 | extract($this->imageMagickConvertPrepare($path, $destformat, $jpgQuality, $s)); |
||
0 ignored issues
–
show
|
|||
5201 | $filter = ($destformat === 'png' /* createTmb */) ? '-filter Box' : '-filter Lanczos'; |
||
5202 | $strip = (isset($options['preserveExif']) && ! $options['preserveExif']) ? ' -strip' : ''; |
||
0 ignored issues
–
show
$strip 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 ![]() |
|||
5203 | //$cmd = sprintf('convert%s%s +repage %s -resize %dx%d +repage%s %s %s', $coalesce, $jpgQuality, $filter, $size_w, $size_h, $deconstruct, $quotedPath, $quotedDstPath); |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
64% 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. ![]() |
|||
5204 | $cmd = sprintf('convert %s%s%s %s -geometry %dx%d! %s %s', $quotedPath, $coalesce, $jpgQuality, $filter, $size_w, $size_h, $deconstruct, $quotedDstPath); |
||
5205 | |||
5206 | $result = false; |
||
5207 | if ($this->procExec($cmd) === 0) { |
||
5208 | $result = true; |
||
5209 | } |
||
5210 | |||
5211 | return $result ? $path : false; |
||
5212 | |||
5213 | break; |
||
0 ignored issues
–
show
break is not strictly necessary here and could be removed.
The break statement is not necessary if it is preceded for example by a return statement: switch ($x) {
case 1:
return 'foo';
break; // This break is not necessary and can be left off.
}
If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive. ![]() |
|||
5214 | |||
5215 | case 'gd': |
||
5216 | $img = $this->gdImageCreate($path, $s['mime']); |
||
5217 | |||
5218 | if ($img && false != ($tmp = imagecreatetruecolor($size_w, $size_h))) { |
||
5219 | $bgNum = false; |
||
5220 | View Code Duplication | if ($s[2] === IMAGETYPE_GIF && (! $destformat || $destformat === 'gif')) { |
|
0 ignored issues
–
show
The expression
$destformat of type string|null is loosely compared to false ; 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
![]() 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. ![]() |
|||
5221 | $bgIdx = imagecolortransparent($img); |
||
5222 | if ($bgIdx !== -1) { |
||
5223 | $c = imagecolorsforindex($img, $bgIdx); |
||
5224 | $bgNum = imagecolorallocate($tmp, $c['red'], $c['green'], $c['blue']); |
||
5225 | imagefill($tmp, 0, 0, $bgNum); |
||
5226 | imagecolortransparent($tmp, $bgNum); |
||
5227 | } |
||
5228 | } |
||
5229 | if ($bgNum === false) { |
||
5230 | $this->gdImageBackground($tmp, 'transparent'); |
||
5231 | } |
||
5232 | |||
5233 | if (! imagecopyresampled($tmp, $img, 0, 0, 0, 0, $size_w, $size_h, $s[0], $s[1])) { |
||
5234 | return false; |
||
5235 | } |
||
5236 | |||
5237 | $result = $this->gdImage($tmp, $path, $destformat, $s['mime'], $jpgQuality); |
||
5238 | |||
5239 | imagedestroy($img); |
||
5240 | imagedestroy($tmp); |
||
5241 | |||
5242 | return $result ? $path : false; |
||
5243 | } |
||
5244 | break; |
||
5245 | } |
||
5246 | |||
5247 | return false; |
||
5248 | } |
||
5249 | |||
5250 | /** |
||
5251 | * Crop image. |
||
5252 | * |
||
5253 | * @param string $path image file |
||
5254 | * @param int $width crop width |
||
5255 | * @param int $height crop height |
||
5256 | * @param bool $x crop left offset |
||
5257 | * @param bool $y crop top offset |
||
5258 | * @param string $destformat image destination format |
||
5259 | * @param int $jpgQuality JEPG quality (1-100) |
||
5260 | * @return string|false |
||
5261 | * @author Dmitry (dio) Levashov |
||
5262 | * @author Alexey Sukhotin |
||
5263 | **/ |
||
5264 | protected function imgCrop($path, $width, $height, $x, $y, $destformat = null, $jpgQuality = null) |
||
5265 | { |
||
5266 | if (($s = getimagesize($path)) == false) { |
||
5267 | return false; |
||
5268 | } |
||
5269 | |||
5270 | $result = false; |
||
0 ignored issues
–
show
$result 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 ![]() |
|||
5271 | |||
5272 | if (! $jpgQuality) { |
||
0 ignored issues
–
show
The expression
$jpgQuality of type integer|null is loosely compared to false ; this is ambiguous if the integer can be zero. You might want to explicitly use === null instead.
In PHP, under loose comparison (like For 0 == false // true
0 == null // true
123 == false // false
123 == null // false
// It is often better to use strict comparison
0 === false // false
0 === null // false
![]() |
|||
5273 | $jpgQuality = $this->options['jpgQuality']; |
||
5274 | } |
||
5275 | |||
5276 | elFinder::extendTimeLimit(300); |
||
5277 | switch ($this->imgLib) { |
||
5278 | case 'imagick': |
||
0 ignored issues
–
show
The case body in a switch statement must start on the line following the statement.
According to the PSR-2, the body of a case statement must start on the line immediately following the case statement. switch ($expr) {
case "A":
doSomething(); //right
break;
case "B":
doSomethingElse(); //wrong
break;
} To learn more about the PSR-2 coding standard, please refer to the PHP-Fig. ![]() |
|||
5279 | |||
5280 | try { |
||
5281 | $img = new imagick($path); |
||
5282 | } catch (Exception $e) { |
||
5283 | return false; |
||
5284 | } |
||
5285 | |||
5286 | $ani = ($img->getNumberImages() > 1); |
||
5287 | if ($ani && is_null($destformat)) { |
||
5288 | $img = $img->coalesceImages(); |
||
5289 | do { |
||
5290 | $img->setImagePage($s[0], $s[1], 0, 0); |
||
5291 | $img->cropImage($width, $height, $x, $y); |
||
5292 | $img->setImagePage($width, $height, 0, 0); |
||
5293 | } while ($img->nextImage()); |
||
5294 | $img = $img->optimizeImageLayers(); |
||
5295 | $result = $img->writeImages($path, true); |
||
0 ignored issues
–
show
|
|||
5296 | } else { |
||
5297 | if ($ani) { |
||
5298 | $img->setFirstIterator(); |
||
5299 | } |
||
5300 | $img->setImagePage($s[0], $s[1], 0, 0); |
||
5301 | $img->cropImage($width, $height, $x, $y); |
||
5302 | $img->setImagePage($width, $height, 0, 0); |
||
5303 | $result = $this->imagickImage($img, $path, $destformat, $jpgQuality); |
||
0 ignored issues
–
show
$img is of type object<Imagick> , but the function expects a resource .
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);
![]() |
|||
5304 | } |
||
5305 | |||
5306 | $img->clear(); |
||
5307 | |||
5308 | return $result ? $path : false; |
||
5309 | |||
5310 | break; |
||
0 ignored issues
–
show
break is not strictly necessary here and could be removed.
The break statement is not necessary if it is preceded for example by a return statement: switch ($x) {
case 1:
return 'foo';
break; // This break is not necessary and can be left off.
}
If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive. ![]() |
|||
5311 | |||
5312 | case 'convert': |
||
5313 | extract($this->imageMagickConvertPrepare($path, $destformat, $jpgQuality, $s)); |
||
0 ignored issues
–
show
|
|||
5314 | $cmd = sprintf('convert %s%s%s -crop %dx%d+%d+%d%s %s', $quotedPath, $coalesce, $jpgQuality, $width, $height, $x, $y, $deconstruct, $quotedDstPath); |
||
5315 | |||
5316 | $result = false; |
||
5317 | if ($this->procExec($cmd) === 0) { |
||
5318 | $result = true; |
||
5319 | } |
||
5320 | |||
5321 | return $result ? $path : false; |
||
5322 | |||
5323 | break; |
||
0 ignored issues
–
show
break is not strictly necessary here and could be removed.
The break statement is not necessary if it is preceded for example by a return statement: switch ($x) {
case 1:
return 'foo';
break; // This break is not necessary and can be left off.
}
If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive. ![]() |
|||
5324 | |||
5325 | case 'gd': |
||
5326 | $img = $this->gdImageCreate($path, $s['mime']); |
||
5327 | |||
5328 | if ($img && false != ($tmp = imagecreatetruecolor($width, $height))) { |
||
5329 | $bgNum = false; |
||
5330 | View Code Duplication | if ($s[2] === IMAGETYPE_GIF && (! $destformat || $destformat === 'gif')) { |
|
0 ignored issues
–
show
The expression
$destformat of type string|null is loosely compared to false ; 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
![]() 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. ![]() |
|||
5331 | $bgIdx = imagecolortransparent($img); |
||
5332 | if ($bgIdx !== -1) { |
||
5333 | $c = imagecolorsforindex($img, $bgIdx); |
||
5334 | $bgNum = imagecolorallocate($tmp, $c['red'], $c['green'], $c['blue']); |
||
5335 | imagefill($tmp, 0, 0, $bgNum); |
||
5336 | imagecolortransparent($tmp, $bgNum); |
||
5337 | } |
||
5338 | } |
||
5339 | if ($bgNum === false) { |
||
5340 | $this->gdImageBackground($tmp, 'transparent'); |
||
5341 | } |
||
5342 | |||
5343 | $size_w = $width; |
||
5344 | $size_h = $height; |
||
5345 | |||
5346 | if ($s[0] < $width || $s[1] < $height) { |
||
5347 | $size_w = $s[0]; |
||
5348 | $size_h = $s[1]; |
||
5349 | } |
||
5350 | |||
5351 | if (! imagecopy($tmp, $img, 0, 0, $x, $y, $size_w, $size_h)) { |
||
5352 | return false; |
||
5353 | } |
||
5354 | |||
5355 | $result = $this->gdImage($tmp, $path, $destformat, $s['mime'], $jpgQuality); |
||
5356 | |||
5357 | imagedestroy($img); |
||
5358 | imagedestroy($tmp); |
||
5359 | |||
5360 | return $result ? $path : false; |
||
5361 | } |
||
5362 | break; |
||
5363 | } |
||
5364 | |||
5365 | return false; |
||
5366 | } |
||
5367 | |||
5368 | /** |
||
5369 | * Put image to square. |
||
5370 | * |
||
5371 | * @param string $path image file |
||
5372 | * @param int $width square width |
||
5373 | * @param int $height square height |
||
5374 | * @param int|string $align reserved |
||
5375 | * @param int|string $valign reserved |
||
5376 | * @param string $bgcolor square background color in #rrggbb format |
||
5377 | * @param string $destformat image destination format |
||
5378 | * @param int $jpgQuality JEPG quality (1-100) |
||
5379 | * @return false|string |
||
5380 | * @author Dmitry (dio) Levashov |
||
5381 | * @author Alexey Sukhotin |
||
5382 | */ |
||
5383 | protected function imgSquareFit($path, $width, $height, $align = 'center', $valign = 'middle', $bgcolor = '#0000ff', $destformat = null, $jpgQuality = null) |
||
0 ignored issues
–
show
|
|||
5384 | { |
||
5385 | if (($s = getimagesize($path)) == false) { |
||
5386 | return false; |
||
5387 | } |
||
5388 | |||
5389 | $result = false; |
||
0 ignored issues
–
show
$result 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 ![]() |
|||
5390 | |||
5391 | /* Coordinates for image over square aligning */ |
||
5392 | $y = ceil(abs($height - $s[1]) / 2); |
||
5393 | $x = ceil(abs($width - $s[0]) / 2); |
||
5394 | |||
5395 | if (! $jpgQuality) { |
||
0 ignored issues
–
show
The expression
$jpgQuality of type integer|null is loosely compared to false ; this is ambiguous if the integer can be zero. You might want to explicitly use === null instead.
In PHP, under loose comparison (like For 0 == false // true
0 == null // true
123 == false // false
123 == null // false
// It is often better to use strict comparison
0 === false // false
0 === null // false
![]() |
|||
5396 | $jpgQuality = $this->options['jpgQuality']; |
||
5397 | } |
||
5398 | |||
5399 | elFinder::extendTimeLimit(300); |
||
5400 | switch ($this->imgLib) { |
||
5401 | case 'imagick': |
||
5402 | try { |
||
5403 | $img = new imagick($path); |
||
5404 | } catch (Exception $e) { |
||
5405 | return false; |
||
5406 | } |
||
5407 | |||
5408 | if ($bgcolor === 'transparent') { |
||
5409 | $bgcolor = 'rgba(255, 255, 255, 0.0)'; |
||
5410 | } |
||
5411 | $ani = ($img->getNumberImages() > 1); |
||
5412 | if ($ani && is_null($destformat)) { |
||
5413 | $img1 = new Imagick(); |
||
5414 | $img1->setFormat('gif'); |
||
5415 | $img = $img->coalesceImages(); |
||
5416 | do { |
||
5417 | $gif = new Imagick(); |
||
5418 | $gif->newImage($width, $height, new ImagickPixel($bgcolor)); |
||
5419 | $gif->setImageColorspace($img->getImageColorspace()); |
||
5420 | $gif->setImageFormat('gif'); |
||
5421 | $gif->compositeImage($img, imagick::COMPOSITE_OVER, $x, $y); |
||
5422 | $gif->setImageDelay($img->getImageDelay()); |
||
5423 | $gif->setImageIterations($img->getImageIterations()); |
||
5424 | $img1->addImage($gif); |
||
5425 | $gif->clear(); |
||
5426 | } while ($img->nextImage()); |
||
5427 | $img1 = $img1->optimizeImageLayers(); |
||
5428 | $result = $img1->writeImages($path, true); |
||
0 ignored issues
–
show
|
|||
5429 | } else { |
||
5430 | if ($ani) { |
||
5431 | $img->setFirstIterator(); |
||
5432 | } |
||
5433 | $img1 = new Imagick(); |
||
5434 | $img1->newImage($width, $height, new ImagickPixel($bgcolor)); |
||
5435 | $img1->setImageColorspace($img->getImageColorspace()); |
||
5436 | $img1->compositeImage($img, imagick::COMPOSITE_OVER, $x, $y); |
||
5437 | $result = $this->imagickImage($img1, $path, $destformat, $jpgQuality); |
||
0 ignored issues
–
show
$img1 is of type object<Imagick> , but the function expects a resource .
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);
![]() |
|||
5438 | } |
||
5439 | |||
5440 | $img1->clear(); |
||
5441 | $img->clear(); |
||
5442 | |||
5443 | return $result ? $path : false; |
||
5444 | |||
5445 | break; |
||
0 ignored issues
–
show
break is not strictly necessary here and could be removed.
The break statement is not necessary if it is preceded for example by a return statement: switch ($x) {
case 1:
return 'foo';
break; // This break is not necessary and can be left off.
}
If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive. ![]() |
|||
5446 | |||
5447 | case 'convert': |
||
5448 | extract($this->imageMagickConvertPrepare($path, $destformat, $jpgQuality, $s)); |
||
0 ignored issues
–
show
|
|||
5449 | if ($bgcolor === 'transparent') { |
||
5450 | $bgcolor = 'rgba(255, 255, 255, 0.0)'; |
||
5451 | } |
||
5452 | $cmd = sprintf('convert -size %dx%d "xc:%s" png:- | convert%s%s png:- %s -geometry +%d+%d -compose over -composite%s %s', $width, $height, $bgcolor, $coalesce, $jpgQuality, $quotedPath, $x, $y, $deconstruct, $quotedDstPath); |
||
5453 | |||
5454 | $result = false; |
||
5455 | if ($this->procExec($cmd) === 0) { |
||
5456 | $result = true; |
||
5457 | } |
||
5458 | |||
5459 | return $result ? $path : false; |
||
5460 | |||
5461 | break; |
||
0 ignored issues
–
show
break is not strictly necessary here and could be removed.
The break statement is not necessary if it is preceded for example by a return statement: switch ($x) {
case 1:
return 'foo';
break; // This break is not necessary and can be left off.
}
If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive. ![]() |
|||
5462 | |||
5463 | case 'gd': |
||
5464 | $img = $this->gdImageCreate($path, $s['mime']); |
||
5465 | |||
5466 | if ($img && false != ($tmp = imagecreatetruecolor($width, $height))) { |
||
5467 | $this->gdImageBackground($tmp, $bgcolor); |
||
5468 | if ($bgcolor === 'transparent' && ($destformat === 'png' || $s[2] === IMAGETYPE_PNG)) { |
||
5469 | $bgNum = imagecolorallocatealpha($tmp, 255, 255, 255, 127); |
||
5470 | imagefill($tmp, 0, 0, $bgNum); |
||
5471 | } |
||
5472 | |||
5473 | if (! imagecopy($tmp, $img, $x, $y, 0, 0, $s[0], $s[1])) { |
||
5474 | return false; |
||
5475 | } |
||
5476 | |||
5477 | $result = $this->gdImage($tmp, $path, $destformat, $s['mime'], $jpgQuality); |
||
5478 | |||
5479 | imagedestroy($img); |
||
5480 | imagedestroy($tmp); |
||
5481 | |||
5482 | return $result ? $path : false; |
||
5483 | } |
||
5484 | break; |
||
5485 | } |
||
5486 | |||
5487 | return false; |
||
5488 | } |
||
5489 | |||
5490 | /** |
||
5491 | * Rotate image. |
||
5492 | * |
||
5493 | * @param string $path image file |
||
5494 | * @param int $degree rotete degrees |
||
5495 | * @param string $bgcolor square background color in #rrggbb format |
||
5496 | * @param string $destformat image destination format |
||
5497 | * @param int $jpgQuality JEPG quality (1-100) |
||
5498 | * @return string|false |
||
5499 | * @author nao-pon |
||
5500 | * @author Troex Nevelin |
||
5501 | **/ |
||
5502 | protected function imgRotate($path, $degree, $bgcolor = '#ffffff', $destformat = null, $jpgQuality = null) |
||
5503 | { |
||
5504 | if (($s = getimagesize($path)) == false || $degree % 360 === 0) { |
||
5505 | return false; |
||
5506 | } |
||
5507 | |||
5508 | $result = false; |
||
5509 | |||
5510 | // try lossless rotate |
||
5511 | if ($degree % 90 === 0 && in_array($s[2], [IMAGETYPE_JPEG, IMAGETYPE_JPEG2000])) { |
||
5512 | $count = ($degree / 90) % 4; |
||
5513 | $exiftran = [ |
||
5514 | 1 => '-9', |
||
5515 | 2 => '-1', |
||
5516 | 3 => '-2', |
||
5517 | ]; |
||
5518 | $jpegtran = [ |
||
5519 | 1 => '90', |
||
5520 | 2 => '180', |
||
5521 | 3 => '270', |
||
5522 | ]; |
||
5523 | $quotedPath = escapeshellarg($path); |
||
5524 | $cmds = []; |
||
5525 | if ($this->procExec('exiftran -h') === 0) { |
||
5526 | $cmds[] = 'exiftran -i '.$exiftran[$count].' '.$path; |
||
5527 | } |
||
5528 | if ($this->procExec('jpegtran -version') === 0) { |
||
5529 | $cmds[] = 'jpegtran -rotate '.$jpegtran[$count].' -copy all -outfile '.$quotedPath.' '.$quotedPath; |
||
5530 | } |
||
5531 | foreach ($cmds as $cmd) { |
||
5532 | if ($this->procExec($cmd) === 0) { |
||
5533 | $result = true; |
||
5534 | break; |
||
5535 | } |
||
5536 | } |
||
5537 | if ($result) { |
||
5538 | return $path; |
||
5539 | } |
||
5540 | } |
||
5541 | |||
5542 | if (! $jpgQuality) { |
||
0 ignored issues
–
show
The expression
$jpgQuality of type integer|null is loosely compared to false ; this is ambiguous if the integer can be zero. You might want to explicitly use === null instead.
In PHP, under loose comparison (like For 0 == false // true
0 == null // true
123 == false // false
123 == null // false
// It is often better to use strict comparison
0 === false // false
0 === null // false
![]() |
|||
5543 | $jpgQuality = $this->options['jpgQuality']; |
||
5544 | } |
||
5545 | |||
5546 | elFinder::extendTimeLimit(300); |
||
5547 | switch ($this->imgLib) { |
||
5548 | case 'imagick': |
||
5549 | try { |
||
5550 | $img = new imagick($path); |
||
5551 | } catch (Exception $e) { |
||
5552 | return false; |
||
5553 | } |
||
5554 | |||
5555 | View Code Duplication | if ($s[2] === IMAGETYPE_GIF || $s[2] === IMAGETYPE_PNG) { |
|
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. ![]() |
|||
5556 | $bgcolor = 'rgba(255, 255, 255, 0.0)'; |
||
5557 | } |
||
5558 | if ($img->getNumberImages() > 1) { |
||
5559 | $img = $img->coalesceImages(); |
||
5560 | do { |
||
5561 | $img->rotateImage(new ImagickPixel($bgcolor), $degree); |
||
5562 | } while ($img->nextImage()); |
||
5563 | $img = $img->optimizeImageLayers(); |
||
5564 | $result = $img->writeImages($path, true); |
||
0 ignored issues
–
show
|
|||
5565 | } else { |
||
5566 | $img->rotateImage(new ImagickPixel($bgcolor), $degree); |
||
5567 | $result = $this->imagickImage($img, $path, $destformat, $jpgQuality); |
||
0 ignored issues
–
show
$img is of type object<Imagick> , but the function expects a resource .
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);
![]() |
|||
5568 | } |
||
5569 | $img->clear(); |
||
5570 | |||
5571 | return $result ? $path : false; |
||
5572 | |||
5573 | break; |
||
0 ignored issues
–
show
break is not strictly necessary here and could be removed.
The break statement is not necessary if it is preceded for example by a return statement: switch ($x) {
case 1:
return 'foo';
break; // This break is not necessary and can be left off.
}
If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive. ![]() |
|||
5574 | |||
5575 | case 'convert': |
||
5576 | extract($this->imageMagickConvertPrepare($path, $destformat, $jpgQuality, $s)); |
||
0 ignored issues
–
show
|
|||
5577 | View Code Duplication | if ($s[2] === IMAGETYPE_GIF || $s[2] === IMAGETYPE_PNG) { |
|
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. ![]() |
|||
5578 | $bgcolor = 'rgba(255, 255, 255, 0.0)'; |
||
5579 | } |
||
5580 | $cmd = sprintf('convert %s%s%s -background "%s" -rotate %d%s %s', $quotedPath, $coalesce, $jpgQuality, $bgcolor, $degree, $deconstruct, $quotedDstPath); |
||
5581 | |||
5582 | $result = false; |
||
5583 | if ($this->procExec($cmd) === 0) { |
||
5584 | $result = true; |
||
5585 | } |
||
5586 | |||
5587 | return $result ? $path : false; |
||
5588 | |||
5589 | break; |
||
0 ignored issues
–
show
break is not strictly necessary here and could be removed.
The break statement is not necessary if it is preceded for example by a return statement: switch ($x) {
case 1:
return 'foo';
break; // This break is not necessary and can be left off.
}
If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive. ![]() |
|||
5590 | |||
5591 | case 'gd': |
||
5592 | $img = $this->gdImageCreate($path, $s['mime']); |
||
5593 | |||
5594 | $degree = 360 - $degree; |
||
5595 | |||
5596 | $bgNum = -1; |
||
5597 | $bgIdx = false; |
||
5598 | if ($s[2] === IMAGETYPE_GIF) { |
||
5599 | $bgIdx = imagecolortransparent($img); |
||
5600 | if ($bgIdx !== -1) { |
||
5601 | $c = imagecolorsforindex($img, $bgIdx); |
||
5602 | $w = imagesx($img); |
||
5603 | $h = imagesy($img); |
||
5604 | $newImg = imagecreatetruecolor($w, $h); |
||
5605 | imagepalettecopy($newImg, $img); |
||
5606 | $bgNum = imagecolorallocate($newImg, $c['red'], $c['green'], $c['blue']); |
||
5607 | imagefill($newImg, 0, 0, $bgNum); |
||
5608 | imagecolortransparent($newImg, $bgNum); |
||
5609 | imagecopy($newImg, $img, 0, 0, 0, 0, $w, $h); |
||
5610 | imagedestroy($img); |
||
5611 | $img = $newImg; |
||
5612 | $newImg = null; |
||
0 ignored issues
–
show
$newImg 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 ![]() |
|||
5613 | } |
||
5614 | } elseif ($s[2] === IMAGETYPE_PNG) { |
||
5615 | $bgNum = imagecolorallocatealpha($img, 255, 255, 255, 127); |
||
5616 | } |
||
5617 | View Code Duplication | if ($bgNum === -1) { |
|
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. ![]() |
|||
5618 | list($r, $g, $b) = sscanf($bgcolor, '#%02x%02x%02x'); |
||
5619 | $bgNum = imagecolorallocate($img, $r, $g, $b); |
||
5620 | } |
||
5621 | |||
5622 | $tmp = imagerotate($img, $degree, $bgNum); |
||
5623 | if ($bgIdx !== -1) { |
||
5624 | imagecolortransparent($tmp, $bgNum); |
||
5625 | } |
||
5626 | |||
5627 | $result = $this->gdImage($tmp, $path, $destformat, $s['mime'], $jpgQuality); |
||
5628 | |||
5629 | imagedestroy($img); |
||
5630 | imagedestroy($tmp); |
||
5631 | |||
5632 | return $result ? $path : false; |
||
5633 | |||
5634 | break; |
||
0 ignored issues
–
show
break is not strictly necessary here and could be removed.
The break statement is not necessary if it is preceded for example by a return statement: switch ($x) {
case 1:
return 'foo';
break; // This break is not necessary and can be left off.
}
If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive. ![]() |
|||
5635 | } |
||
5636 | |||
5637 | return false; |
||
5638 | } |
||
5639 | |||
5640 | /** |
||
5641 | * Execute shell command. |
||
5642 | * |
||
5643 | * @param string $command command line |
||
5644 | * @param array $output stdout strings |
||
5645 | * @param array|int $return_var process exit code |
||
5646 | * @param array $error_output stderr strings |
||
5647 | * @return int exit code |
||
5648 | * @author Alexey Sukhotin |
||
5649 | */ |
||
5650 | protected function procExec($command, array &$output = null, &$return_var = -1, array &$error_output = null) |
||
5651 | { |
||
5652 | static $allowed = null; |
||
5653 | |||
5654 | if ($allowed === null) { |
||
5655 | if ($allowed = function_exists('proc_open')) { |
||
5656 | if ($disabled = ini_get('disable_functions')) { |
||
5657 | $funcs = array_map('trim', explode(',', $disabled)); |
||
5658 | $allowed = ! in_array('proc_open', $funcs); |
||
5659 | } |
||
5660 | } |
||
5661 | } |
||
5662 | |||
5663 | if (! $allowed) { |
||
0 ignored issues
–
show
The expression
$allowed of type boolean|null is loosely compared to false ; this is ambiguous if the boolean can be false. You might want to explicitly use !== null instead.
If an expression can have both $a = canBeFalseAndNull();
// Instead of
if ( ! $a) { }
// Better use one of the explicit versions:
if ($a !== null) { }
if ($a !== false) { }
if ($a !== null && $a !== false) { }
![]() |
|||
5664 | $return_var = -1; |
||
5665 | |||
5666 | return $return_var; |
||
5667 | } |
||
5668 | |||
5669 | if (! $command) { |
||
5670 | $return_var = 0; |
||
5671 | |||
5672 | return $return_var; |
||
5673 | } |
||
5674 | |||
5675 | $descriptorspec = [ |
||
5676 | 0 => ['pipe', 'r'], // stdin |
||
5677 | 1 => ['pipe', 'w'], // stdout |
||
5678 | 2 => ['pipe', 'w'], // stderr |
||
5679 | ]; |
||
5680 | |||
5681 | $process = proc_open($command, $descriptorspec, $pipes, null, null); |
||
5682 | |||
5683 | if (is_resource($process)) { |
||
5684 | fclose($pipes[0]); |
||
5685 | |||
5686 | $tmpout = ''; |
||
0 ignored issues
–
show
$tmpout 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 ![]() |
|||
5687 | $tmperr = ''; |
||
0 ignored issues
–
show
$tmperr 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 ![]() |
|||
5688 | |||
5689 | $output = stream_get_contents($pipes[1]); |
||
5690 | $error_output = stream_get_contents($pipes[2]); |
||
5691 | |||
5692 | fclose($pipes[1]); |
||
5693 | fclose($pipes[2]); |
||
5694 | $return_var = proc_close($process); |
||
5695 | } else { |
||
5696 | $return_var = -1; |
||
5697 | } |
||
5698 | |||
5699 | return $return_var; |
||
5700 | } |
||
5701 | |||
5702 | /** |
||
5703 | * Remove thumbnail, also remove recursively if stat is directory. |
||
5704 | * |
||
5705 | * @param string $stat file stat |
||
5706 | * @return void |
||
5707 | * @author Dmitry (dio) Levashov |
||
5708 | * @author Naoki Sawada |
||
5709 | * @author Troex Nevelin |
||
5710 | **/ |
||
5711 | protected function rmTmb($stat) |
||
5712 | { |
||
5713 | if ($stat['mime'] === 'directory') { |
||
5714 | foreach ($this->scandirCE($this->decode($stat['hash'])) as $p) { |
||
5715 | elFinder::extendTimeLimit(30); |
||
5716 | $name = $this->basenameCE($p); |
||
5717 | $name != '.' && $name != '..' && $this->rmTmb($this->stat($p)); |
||
0 ignored issues
–
show
$this->stat($p) is of type array , 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);
![]() |
|||
5718 | } |
||
5719 | } elseif (! empty($stat['tmb']) && $stat['tmb'] != '1') { |
||
5720 | $tmb = $this->tmbPath.DIRECTORY_SEPARATOR.$stat['tmb']; |
||
5721 | file_exists($tmb) && unlink($tmb); |
||
5722 | clearstatcache(); |
||
5723 | } |
||
5724 | } |
||
5725 | |||
5726 | /** |
||
5727 | * Create an gd image according to the specified mime type. |
||
5728 | * |
||
5729 | * @param string $path image file |
||
5730 | * @param string $mime |
||
5731 | * @return gd image resource identifier |
||
5732 | */ |
||
5733 | protected function gdImageCreate($path, $mime) |
||
5734 | { |
||
5735 | switch ($mime) { |
||
5736 | case 'image/jpeg': |
||
5737 | return imagecreatefromjpeg($path); |
||
5738 | |||
5739 | case 'image/png': |
||
5740 | return imagecreatefrompng($path); |
||
5741 | |||
5742 | case 'image/gif': |
||
5743 | return imagecreatefromgif($path); |
||
5744 | |||
5745 | case 'image/x-ms-bmp': |
||
5746 | if (! function_exists('imagecreatefrombmp')) { |
||
5747 | include_once dirname(__FILE__).'/libs/GdBmp.php'; |
||
5748 | } |
||
5749 | |||
5750 | return imagecreatefrombmp($path); |
||
5751 | |||
5752 | case 'image/xbm': |
||
5753 | return imagecreatefromxbm($path); |
||
5754 | |||
5755 | case 'image/xpm': |
||
5756 | return imagecreatefromxpm($path); |
||
5757 | } |
||
5758 | |||
5759 | return false; |
||
5760 | } |
||
5761 | |||
5762 | /** |
||
5763 | * Output gd image to file. |
||
5764 | * |
||
5765 | * @param resource $image gd image resource |
||
5766 | * @param string $filename The path to save the file to. |
||
5767 | * @param string $destformat The Image type to use for $filename |
||
5768 | * @param string $mime The original image mime type |
||
5769 | * @param int $jpgQuality JEPG quality (1-100) |
||
5770 | * @return bool |
||
5771 | */ |
||
5772 | protected function gdImage($image, $filename, $destformat, $mime, $jpgQuality = null) |
||
5773 | { |
||
5774 | if (! $jpgQuality) { |
||
0 ignored issues
–
show
The expression
$jpgQuality of type integer|null is loosely compared to false ; this is ambiguous if the integer can be zero. You might want to explicitly use === null instead.
In PHP, under loose comparison (like For 0 == false // true
0 == null // true
123 == false // false
123 == null // false
// It is often better to use strict comparison
0 === false // false
0 === null // false
![]() |
|||
5775 | $jpgQuality = $this->options['jpgQuality']; |
||
5776 | } |
||
5777 | if ($destformat) { |
||
5778 | switch ($destformat) { |
||
5779 | case 'jpg': |
||
5780 | $mime = 'image/jpeg'; |
||
5781 | break; |
||
5782 | case 'gif': |
||
5783 | $mime = 'image/gif'; |
||
5784 | break; |
||
5785 | case 'png': |
||
5786 | default: |
||
5787 | $mime = 'image/png'; |
||
5788 | break; |
||
5789 | } |
||
5790 | } |
||
5791 | switch ($mime) { |
||
5792 | case 'image/gif': |
||
5793 | return imagegif($image, $filename); |
||
5794 | case 'image/jpeg': |
||
5795 | return imagejpeg($image, $filename, $jpgQuality); |
||
5796 | case 'image/wbmp': |
||
5797 | return imagewbmp($image, $filename); |
||
5798 | case 'image/png': |
||
5799 | default: |
||
5800 | return imagepng($image, $filename); |
||
5801 | } |
||
5802 | } |
||
5803 | |||
5804 | /** |
||
5805 | * Output imagick image to file. |
||
5806 | * |
||
5807 | * @param resource $img imagick image resource |
||
5808 | * @param string $filename The path to save the file to. |
||
5809 | * @param string $destformat The Image type to use for $filename |
||
5810 | * @param int $jpgQuality JEPG quality (1-100) |
||
5811 | * @return bool |
||
5812 | */ |
||
5813 | protected function imagickImage($img, $filename, $destformat, $jpgQuality = null) |
||
5814 | { |
||
5815 | if (! $jpgQuality) { |
||
0 ignored issues
–
show
The expression
$jpgQuality of type integer|null is loosely compared to false ; this is ambiguous if the integer can be zero. You might want to explicitly use === null instead.
In PHP, under loose comparison (like For 0 == false // true
0 == null // true
123 == false // false
123 == null // false
// It is often better to use strict comparison
0 === false // false
0 === null // false
![]() |
|||
5816 | $jpgQuality = $this->options['jpgQuality']; |
||
5817 | } |
||
5818 | |||
5819 | try { |
||
5820 | if ($destformat) { |
||
5821 | if ($destformat === 'gif') { |
||
5822 | $img->setImageFormat('gif'); |
||
0 ignored issues
–
show
|
|||
5823 | } elseif ($destformat === 'png') { |
||
5824 | $img->setImageFormat('png'); |
||
0 ignored issues
–
show
|
|||
5825 | } elseif ($destformat === 'jpg') { |
||
5826 | $img->setImageFormat('jpeg'); |
||
0 ignored issues
–
show
|
|||
5827 | } |
||
5828 | } |
||
5829 | if (strtoupper($img->getImageFormat()) === 'JPEG') { |
||
0 ignored issues
–
show
|
|||
5830 | $img->setImageCompression(imagick::COMPRESSION_JPEG); |
||
0 ignored issues
–
show
|
|||
5831 | $img->setImageCompressionQuality($jpgQuality); |
||
0 ignored issues
–
show
|
|||
5832 | try { |
||
5833 | $orientation = $img->getImageOrientation(); |
||
0 ignored issues
–
show
|
|||
5834 | } catch (ImagickException $e) { |
||
5835 | $orientation = 0; |
||
5836 | } |
||
5837 | $img->stripImage(); |
||
0 ignored issues
–
show
|
|||
5838 | if ($orientation) { |
||
5839 | $img->setImageOrientation($orientation); |
||
0 ignored issues
–
show
|
|||
5840 | } |
||
5841 | } |
||
5842 | $result = $img->writeImage($filename); |
||
0 ignored issues
–
show
|
|||
5843 | } catch (Exception $e) { |
||
5844 | $result = false; |
||
5845 | } |
||
5846 | |||
5847 | return $result; |
||
5848 | } |
||
5849 | |||
5850 | /** |
||
5851 | * Assign the proper background to a gd image. |
||
5852 | * |
||
5853 | * @param resource $image gd image resource |
||
5854 | * @param string $bgcolor background color in #rrggbb format |
||
5855 | */ |
||
5856 | protected function gdImageBackground($image, $bgcolor) |
||
5857 | { |
||
5858 | if ($bgcolor === 'transparent') { |
||
5859 | imagealphablending($image, false); |
||
5860 | imagesavealpha($image, true); |
||
5861 | 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. ![]() |
|||
5862 | list($r, $g, $b) = sscanf($bgcolor, '#%02x%02x%02x'); |
||
5863 | $bgcolor1 = imagecolorallocate($image, $r, $g, $b); |
||
5864 | imagefill($image, 0, 0, $bgcolor1); |
||
5865 | } |
||
5866 | } |
||
5867 | |||
5868 | /** |
||
5869 | * Prepare variables for exec convert of ImageMagick. |
||
5870 | * |
||
5871 | * @param string $path |
||
5872 | * @param string $destformat |
||
5873 | * @param int $jpgQuality |
||
5874 | * @param array $imageSize |
||
5875 | * @return array |
||
5876 | */ |
||
5877 | protected function imageMagickConvertPrepare($path, $destformat, $jpgQuality, $imageSize = null) |
||
5878 | { |
||
5879 | if (is_null($imageSize)) { |
||
5880 | $imageSize = getimagesize($path); |
||
5881 | } |
||
5882 | if (! $imageSize) { |
||
0 ignored issues
–
show
The expression
$imageSize 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 ![]() |
|||
5883 | return []; |
||
5884 | } |
||
5885 | $srcType = $this->getExtentionByMime($imageSize['mime'], ':'); |
||
5886 | $ani = false; |
||
5887 | $cmd = 'identify '.escapeshellarg($srcType.$path); |
||
5888 | if ($this->procExec($cmd, $o) === 0) { |
||
5889 | $ani = preg_split('/(?:\r\n|\n|\r)/', trim($o)); |
||
5890 | if (count($ani) < 2) { |
||
5891 | $ani = false; |
||
5892 | } |
||
5893 | } |
||
5894 | $coalesce = $index = ''; |
||
5895 | $deconstruct = ' +repage'; |
||
5896 | if ($ani) { |
||
5897 | if (is_null($destformat)) { |
||
5898 | $coalesce = ' -coalesce -repage 0x0'; |
||
5899 | $deconstruct = ' +repage -deconstruct -layers optimize'; |
||
5900 | } else { |
||
5901 | $index = '[0]'; |
||
5902 | if ($srcType === 'ico:') { |
||
5903 | foreach ($ani as $_i => $_info) { |
||
5904 | if (preg_match('/ (\d+)x(\d+) /', $_info, $m)) { |
||
5905 | if ($m[1] == $imageSize[0] && $m[2] == $imageSize[1]) { |
||
5906 | $index = '['.$_i.']'; |
||
5907 | break; |
||
5908 | } |
||
5909 | } |
||
5910 | } |
||
5911 | } |
||
5912 | } |
||
5913 | } |
||
5914 | if ($imageSize[2] === IMAGETYPE_JPEG || $imageSize[2] === IMAGETYPE_JPEG2000) { |
||
5915 | $jpgQuality = ' -quality '.$jpgQuality; |
||
5916 | } else { |
||
5917 | $jpgQuality = ''; |
||
5918 | } |
||
5919 | $quotedPath = escapeshellarg($srcType.$path.$index); |
||
5920 | $quotedDstPath = escapeshellarg(($destformat ? ($destformat.':') : $srcType).$path); |
||
5921 | |||
5922 | return compact('ani', 'index', 'coalesce', 'deconstruct', 'jpgQuality', 'quotedPath', 'quotedDstPath'); |
||
5923 | } |
||
5924 | |||
5925 | /*********************** misc *************************/ |
||
5926 | |||
5927 | /** |
||
5928 | * Return smart formatted date. |
||
5929 | * |
||
5930 | * @param int $ts file timestamp |
||
5931 | * @return string |
||
5932 | * @author Dmitry (dio) Levashov |
||
5933 | **/ |
||
5934 | // protected function formatDate($ts) { |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
55% 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. ![]() |
|||
5935 | // if ($ts > $this->today) { |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
50% 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. ![]() |
|||
5936 | // return 'Today '.date($this->options['timeFormat'], $ts); |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
67% 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. ![]() |
|||
5937 | // } |
||
5938 | // |
||
5939 | // if ($ts > $this->yesterday) { |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
50% 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. ![]() |
|||
5940 | // return 'Yesterday '.date($this->options['timeFormat'], $ts); |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
67% 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. ![]() |
|||
5941 | // } |
||
5942 | // |
||
5943 | // return date($this->options['dateFormat'], $ts); |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
69% 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. ![]() |
|||
5944 | // } |
||
5945 | |||
5946 | /** |
||
5947 | * Find position of first occurrence of string in a string with multibyte support. |
||
5948 | * |
||
5949 | * @param string $haystack The string being checked. |
||
5950 | * @param string $needle The string to find in haystack. |
||
5951 | * @param int $offset The search offset. If it is not specified, 0 is used. |
||
5952 | * @return int|bool |
||
5953 | * @author Alexey Sukhotin |
||
5954 | **/ |
||
5955 | protected function stripos($haystack, $needle, $offset = 0) |
||
5956 | { |
||
5957 | if (function_exists('mb_stripos')) { |
||
5958 | return mb_stripos($haystack, $needle, $offset, 'UTF-8'); |
||
5959 | } elseif (function_exists('mb_strtolower') && function_exists('mb_strpos')) { |
||
5960 | return mb_strpos(mb_strtolower($haystack, 'UTF-8'), mb_strtolower($needle, 'UTF-8'), $offset); |
||
5961 | } |
||
5962 | |||
5963 | return stripos($haystack, $needle, $offset); |
||
5964 | } |
||
5965 | |||
5966 | /** |
||
5967 | * Get server side available archivers. |
||
5968 | * |
||
5969 | * @param bool $use_cache |
||
5970 | * @return array |
||
5971 | */ |
||
5972 | protected function getArchivers($use_cache = true) |
||
5973 | { |
||
5974 | $sessionKey = 'ARCHIVERS_CACHE'; |
||
5975 | if ($use_cache && isset($this->sessionCache[$sessionKey]) && is_array($this->sessionCache[$sessionKey])) { |
||
5976 | return $this->sessionCache[$sessionKey]; |
||
5977 | } |
||
5978 | |||
5979 | $arcs = [ |
||
5980 | 'create' => [], |
||
5981 | 'extract' => [], |
||
5982 | ]; |
||
5983 | |||
5984 | if ($this->procExec('') === 0) { |
||
5985 | $this->procExec('tar --version', $o, $ctar); |
||
5986 | |||
5987 | if ($ctar == 0) { |
||
5988 | $arcs['create']['application/x-tar'] = ['cmd' => 'tar', 'argc' => '-cf', 'ext' => 'tar']; |
||
5989 | $arcs['extract']['application/x-tar'] = ['cmd' => 'tar', 'argc' => '-xf', 'ext' => 'tar', 'toSpec' => '-C ']; |
||
5990 | unset($o); |
||
5991 | $this->procExec('gzip --version', $o, $c); |
||
5992 | View Code Duplication | if ($c == 0) { |
|
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. ![]() |
|||
5993 | $arcs['create']['application/x-gzip'] = ['cmd' => 'tar', 'argc' => '-czf', 'ext' => 'tgz']; |
||
5994 | $arcs['extract']['application/x-gzip'] = ['cmd' => 'tar', 'argc' => '-xzf', 'ext' => 'tgz', 'toSpec' => '-C ']; |
||
5995 | } |
||
5996 | unset($o); |
||
5997 | $this->procExec('bzip2 --version', $o, $c); |
||
5998 | View Code Duplication | if ($c == 0) { |
|
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. ![]() |
|||
5999 | $arcs['create']['application/x-bzip2'] = ['cmd' => 'tar', 'argc' => '-cjf', 'ext' => 'tbz']; |
||
6000 | $arcs['extract']['application/x-bzip2'] = ['cmd' => 'tar', 'argc' => '-xjf', 'ext' => 'tbz', 'toSpec' => '-C ']; |
||
6001 | } |
||
6002 | unset($o); |
||
6003 | $this->procExec('xz --version', $o, $c); |
||
6004 | View Code Duplication | if ($c == 0) { |
|
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. ![]() |
|||
6005 | $arcs['create']['application/x-xz'] = ['cmd' => 'tar', 'argc' => '-cJf', 'ext' => 'xz']; |
||
6006 | $arcs['extract']['application/x-xz'] = ['cmd' => 'tar', 'argc' => '-xJf', 'ext' => 'xz', 'toSpec' => '-C ']; |
||
6007 | } |
||
6008 | } |
||
6009 | unset($o); |
||
6010 | $this->procExec('zip -v', $o, $c); |
||
6011 | View Code Duplication | if ($c == 0) { |
|
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. ![]() |
|||
6012 | $arcs['create']['application/zip'] = ['cmd' => 'zip', 'argc' => '-r9', 'ext' => 'zip']; |
||
6013 | } |
||
6014 | unset($o); |
||
6015 | $this->procExec('unzip --help', $o, $c); |
||
6016 | View Code Duplication | if ($c == 0) { |
|
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. ![]() |
|||
6017 | $arcs['extract']['application/zip'] = ['cmd' => 'unzip', 'argc' => '', 'ext' => 'zip', 'toSpec' => '-d ']; |
||
6018 | } |
||
6019 | unset($o); |
||
6020 | $this->procExec('rar --version', $o, $c); |
||
6021 | View Code Duplication | if ($c == 0 || $c == 7) { |
|
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. ![]() |
|||
6022 | $arcs['create']['application/x-rar'] = ['cmd' => 'rar', 'argc' => 'a -inul', 'ext' => 'rar']; |
||
6023 | } |
||
6024 | unset($o); |
||
6025 | $this->procExec('unrar', $o, $c); |
||
6026 | View Code Duplication | if ($c == 0 || $c == 7) { |
|
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. ![]() |
|||
6027 | $arcs['extract']['application/x-rar'] = ['cmd' => 'unrar', 'argc' => 'x -y', 'ext' => 'rar', 'toSpec' => '']; |
||
6028 | } |
||
6029 | unset($o); |
||
6030 | $this->procExec('7za --help', $o, $c); |
||
6031 | if ($c == 0) { |
||
6032 | $arcs['create']['application/x-7z-compressed'] = ['cmd' => '7za', 'argc' => 'a', 'ext' => '7z']; |
||
6033 | $arcs['extract']['application/x-7z-compressed'] = ['cmd' => '7za', 'argc' => 'x -y', 'ext' => '7z', 'toSpec' => '-o']; |
||
6034 | |||
6035 | if (empty($arcs['create']['application/zip'])) { |
||
6036 | $arcs['create']['application/zip'] = ['cmd' => '7za', 'argc' => 'a -tzip', 'ext' => 'zip']; |
||
6037 | } |
||
6038 | View Code Duplication | if (empty($arcs['extract']['application/zip'])) { |
|
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. ![]() |
|||
6039 | $arcs['extract']['application/zip'] = ['cmd' => '7za', 'argc' => 'x -tzip -y', 'ext' => 'zip', 'toSpec' => '-o']; |
||
6040 | } |
||
6041 | if (empty($arcs['create']['application/x-tar'])) { |
||
6042 | $arcs['create']['application/x-tar'] = ['cmd' => '7za', 'argc' => 'a -ttar', 'ext' => 'tar']; |
||
6043 | } |
||
6044 | View Code Duplication | if (empty($arcs['extract']['application/x-tar'])) { |
|
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. ![]() |
|||
6045 | $arcs['extract']['application/x-tar'] = ['cmd' => '7za', 'argc' => 'x -ttar -y', 'ext' => 'tar', 'toSpec' => '-o']; |
||
6046 | } |
||
6047 | } elseif (substr(PHP_OS, 0, 3) === 'WIN') { |
||
6048 | // check `7z` for Windows server. |
||
6049 | unset($o); |
||
6050 | $this->procExec('7z', $o, $c); |
||
6051 | if ($c == 0) { |
||
6052 | $arcs['create']['application/x-7z-compressed'] = ['cmd' => '7z', 'argc' => 'a', 'ext' => '7z']; |
||
6053 | $arcs['extract']['application/x-7z-compressed'] = ['cmd' => '7z', 'argc' => 'x -y', 'ext' => '7z', 'toSpec' => '-o']; |
||
6054 | |||
6055 | if (empty($arcs['create']['application/zip'])) { |
||
6056 | $arcs['create']['application/zip'] = ['cmd' => '7z', 'argc' => 'a -tzip', 'ext' => 'zip']; |
||
6057 | } |
||
6058 | View Code Duplication | if (empty($arcs['extract']['application/zip'])) { |
|
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. ![]() |
|||
6059 | $arcs['extract']['application/zip'] = ['cmd' => '7z', 'argc' => 'x -tzip -y', 'ext' => 'zip', 'toSpec' => '-o']; |
||
6060 | } |
||
6061 | if (empty($arcs['create']['application/x-tar'])) { |
||
6062 | $arcs['create']['application/x-tar'] = ['cmd' => '7z', 'argc' => 'a -ttar', 'ext' => 'tar']; |
||
6063 | } |
||
6064 | View Code Duplication | if (empty($arcs['extract']['application/x-tar'])) { |
|
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. ![]() |
|||
6065 | $arcs['extract']['application/x-tar'] = ['cmd' => '7z', 'argc' => 'x -ttar -y', 'ext' => 'tar', 'toSpec' => '-o']; |
||
6066 | } |
||
6067 | View Code Duplication | if (empty($arcs['extract']['application/x-rar'])) { |
|
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. ![]() |
|||
6068 | $arcs['extract']['application/x-rar'] = ['cmd' => '7z', 'argc' => 'x -trar -y', 'ext' => 'rar', 'toSpec' => '-o']; |
||
6069 | } |
||
6070 | } |
||
6071 | } |
||
6072 | } |
||
6073 | |||
6074 | // Use PHP ZipArchive Class |
||
6075 | if (class_exists('ZipArchive', false)) { |
||
6076 | if (empty($arcs['create']['application/zip'])) { |
||
6077 | $arcs['create']['application/zip'] = ['cmd' => 'phpfunction', 'argc' => ['self', 'zipArchiveZip'], 'ext' => 'zip']; |
||
6078 | } |
||
6079 | if (empty($arcs['extract']['application/zip'])) { |
||
6080 | $arcs['extract']['application/zip'] = ['cmd' => 'phpfunction', 'argc' => ['self', 'zipArchiveUnzip'], 'ext' => 'zip']; |
||
6081 | } |
||
6082 | } |
||
6083 | |||
6084 | $this->sessionCache[$sessionKey] = $arcs; |
||
6085 | |||
6086 | return $arcs; |
||
6087 | } |
||
6088 | |||
6089 | /** |
||
6090 | * Resolve relative / (Unix-like)absolute path. |
||
6091 | * |
||
6092 | * @param string $path target path |
||
6093 | * @param string $base base path |
||
6094 | * @return string |
||
6095 | */ |
||
6096 | protected function getFullPath($path, $base) |
||
6097 | { |
||
6098 | $separator = $this->separator; |
||
6099 | $systemroot = $this->systemRoot; |
||
6100 | |||
6101 | if ($base[0] === $separator && strpos($base, 0, strlen($systemroot)) !== $systemroot) { |
||
0 ignored issues
–
show
|
|||
6102 | $base = $systemroot.substr($base, 1); |
||
6103 | } |
||
6104 | |||
6105 | // 'Here' |
||
6106 | if ($path === '' || $path === '.'.$separator) { |
||
6107 | return $base; |
||
6108 | } |
||
6109 | |||
6110 | $sepquoted = preg_quote($separator, '#'); |
||
6111 | |||
6112 | if (substr($path, 0, 3) === '..'.$separator) { |
||
6113 | $path = $base.$separator.$path; |
||
6114 | } |
||
6115 | // normalize `/../` |
||
6116 | $normreg = '#('.$sepquoted.')[^'.$sepquoted.']+'.$sepquoted.'\.\.'.$sepquoted.'#'; // '#(/)[^\/]+/\.\./#' |
||
6117 | while (preg_match($normreg, $path)) { |
||
6118 | $path = preg_replace($normreg, '$1', $path, 1); |
||
6119 | } |
||
6120 | |||
6121 | // Absolute path |
||
6122 | if ($path[0] === $separator || strpos($path, $systemroot) === 0) { |
||
6123 | return $path; |
||
6124 | } |
||
6125 | |||
6126 | $preg_separator = '#'.$sepquoted.'#'; |
||
6127 | |||
6128 | // Relative path from 'Here' |
||
6129 | if (substr($path, 0, 2) === '.'.$separator || $path[0] !== '.') { |
||
6130 | $arrn = preg_split($preg_separator, $path, -1, PREG_SPLIT_NO_EMPTY); |
||
6131 | if ($arrn[0] !== '.') { |
||
6132 | array_unshift($arrn, '.'); |
||
6133 | } |
||
6134 | $arrn[0] = $base; |
||
6135 | |||
6136 | return implode($separator, $arrn); |
||
6137 | } |
||
6138 | |||
6139 | return $path; |
||
6140 | } |
||
6141 | |||
6142 | /** |
||
6143 | * Create archive and return its path. |
||
6144 | * |
||
6145 | * @param string $dir target dir |
||
6146 | * @param array $files files names list |
||
6147 | * @param string $name archive name |
||
6148 | * @param array $arc archiver options |
||
6149 | * @return string|bool |
||
6150 | * @author Dmitry (dio) Levashov, |
||
6151 | * @author Alexey Sukhotin |
||
6152 | * @author Naoki Sawada |
||
6153 | **/ |
||
6154 | protected function makeArchive($dir, $files, $name, $arc) |
||
6155 | { |
||
6156 | if ($arc['cmd'] === 'phpfunction') { |
||
6157 | View Code Duplication | if (is_callable($arc['argc'])) { |
|
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. ![]() |
|||
6158 | call_user_func_array($arc['argc'], [$dir, $files, $name]); |
||
6159 | } |
||
6160 | } else { |
||
6161 | $cwd = getcwd(); |
||
6162 | if (chdir($dir)) { |
||
6163 | foreach ($files as $i => $file) { |
||
6164 | $files[$i] = '.'.DIRECTORY_SEPARATOR.$file; |
||
6165 | } |
||
6166 | $files = array_map('escapeshellarg', $files); |
||
6167 | |||
6168 | $cmd = $arc['cmd'].' '.$arc['argc'].' '.escapeshellarg($name).' '.implode(' ', $files); |
||
6169 | $this->procExec($cmd, $o, $c); |
||
6170 | chdir($cwd); |
||
6171 | } else { |
||
6172 | return false; |
||
6173 | } |
||
6174 | } |
||
6175 | $path = $dir.DIRECTORY_SEPARATOR.$name; |
||
6176 | |||
6177 | return file_exists($path) ? $path : false; |
||
6178 | } |
||
6179 | |||
6180 | /** |
||
6181 | * Unpack archive. |
||
6182 | * |
||
6183 | * @param string $path archive path |
||
6184 | * @param array $arc archiver command and arguments (same as in $this->archivers) |
||
6185 | * @param bool|string $mode bool: remove archive ( unlink($path) ) | string: extract to directory |
||
6186 | * @return void |
||
6187 | * @author Dmitry (dio) Levashov |
||
6188 | * @author Alexey Sukhotin |
||
6189 | * @author Naoki Sawada |
||
6190 | **/ |
||
6191 | protected function unpackArchive($path, $arc, $mode = true) |
||
6192 | { |
||
6193 | if (is_string($mode)) { |
||
6194 | $dir = $mode; |
||
6195 | $chdir = null; |
||
6196 | $remove = false; |
||
6197 | } else { |
||
6198 | $dir = dirname($path); |
||
6199 | $chdir = $dir; |
||
6200 | $remove = $mode; |
||
6201 | } |
||
6202 | $dir = realpath($dir); |
||
6203 | $path = realpath($path); |
||
6204 | if ($arc['cmd'] === 'phpfunction') { |
||
6205 | View Code Duplication | if (is_callable($arc['argc'])) { |
|
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. ![]() |
|||
6206 | call_user_func_array($arc['argc'], [$path, $dir]); |
||
6207 | } |
||
6208 | } else { |
||
6209 | $cwd = getcwd(); |
||
6210 | if (! $chdir || chdir($dir)) { |
||
0 ignored issues
–
show
The expression
$chdir of type null|string is loosely compared to false ; 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
![]() |
|||
6211 | if ($chdir) { |
||
0 ignored issues
–
show
The expression
$chdir of type null|string 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
![]() |
|||
6212 | $cmd = $arc['cmd'].' '.$arc['argc'].' '.escapeshellarg(basename($path)); |
||
6213 | } else { |
||
6214 | $cmd = $arc['cmd'].' '.$arc['argc'].' '.escapeshellarg($path).' '.$arc['toSpec'].escapeshellarg($dir); |
||
6215 | } |
||
6216 | $this->procExec($cmd, $o, $c); |
||
6217 | $chdir && chdir($cwd); |
||
0 ignored issues
–
show
The expression
$chdir of type null|string 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
![]() |
|||
6218 | } |
||
6219 | } |
||
6220 | $remove && unlink($path); |
||
6221 | } |
||
6222 | |||
6223 | /** |
||
6224 | * Check and filter the extracted items. |
||
6225 | * |
||
6226 | * @param string $path target local path |
||
6227 | * @param array $checks types to check default: ['symlink', 'name', 'writable', 'mime'] |
||
6228 | * @return array ['symlinks' => [], 'names' => [], 'writables' => [], 'mimes' => [], 'rmNames' => [], 'totalSize' => 0] |
||
6229 | * @author Naoki Sawada |
||
6230 | */ |
||
6231 | protected function checkExtractItems($path, $checks = null) |
||
6232 | { |
||
6233 | if (is_null($checks) || ! is_array($checks)) { |
||
6234 | $checks = ['symlink', 'name', 'writable', 'mime']; |
||
6235 | } |
||
6236 | $chkSymlink = in_array('symlink', $checks); |
||
6237 | $chkName = in_array('name', $checks); |
||
6238 | $chkWritable = in_array('writable', $checks); |
||
6239 | $chkMime = in_array('mime', $checks); |
||
6240 | |||
6241 | $res = [ |
||
6242 | 'symlinks' => [], |
||
6243 | 'names' => [], |
||
6244 | 'writables' => [], |
||
6245 | 'mimes' => [], |
||
6246 | 'rmNames' => [], |
||
6247 | 'totalSize' => 0, |
||
6248 | ]; |
||
6249 | |||
6250 | if (is_dir($path)) { |
||
6251 | foreach (self::localScandir($path) as $name) { |
||
6252 | $p = $path.DIRECTORY_SEPARATOR.$name; |
||
6253 | if ($chkSymlink && is_link($p)) { |
||
6254 | self::localRmdirRecursive($p); |
||
6255 | $res['symlinks'][] = $p; |
||
6256 | $res['rmNames'][] = $name; |
||
6257 | continue; |
||
6258 | } |
||
6259 | $isDir = is_dir($p); |
||
6260 | if ($chkName && ! $this->nameAccepted($name, $isDir)) { |
||
6261 | self::localRmdirRecursive($p); |
||
6262 | $res['names'][] = $p; |
||
6263 | $res['rmNames'][] = $name; |
||
6264 | continue; |
||
6265 | } |
||
6266 | if ($chkWritable && ! $this->attr($p, 'write', null, $isDir)) { |
||
6267 | self::localRmdirRecursive($p); |
||
6268 | $res['writables'][] = $p; |
||
6269 | $res['rmNames'][] = $name; |
||
6270 | continue; |
||
6271 | } |
||
6272 | View Code Duplication | if ($chkMime && ($mimeByName = self::mimetypeInternalDetect($name)) && $mimeByName !== 'unknown' && ! $this->allowPutMime($mimeByName)) { |
|
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. ![]() |
|||
6273 | self::localRmdirRecursive($p); |
||
6274 | $res['mimes'][] = $p; |
||
6275 | $res['rmNames'][] = $name; |
||
6276 | continue; |
||
6277 | } |
||
6278 | if ($isDir) { |
||
6279 | $cRes = $this->checkExtractItems($p, $checks); |
||
6280 | foreach ($cRes as $k => $v) { |
||
6281 | if (is_array($v)) { |
||
6282 | $res[$k] = array_merge($res[$k], $cRes[$k]); |
||
6283 | } else { |
||
6284 | $res[$k] += $cRes[$k]; |
||
6285 | } |
||
6286 | } |
||
6287 | } else { |
||
6288 | $res['totalSize'] += sprintf('%u', filesize($p)); |
||
6289 | } |
||
6290 | } |
||
6291 | $res['rmNames'] = array_unique($res['rmNames']); |
||
6292 | } else { |
||
6293 | if ($chkSymlink && is_link($path)) { |
||
6294 | unlink($path); |
||
6295 | $res['symlinks'][] = $path; |
||
6296 | $res['rmNames'][] = basename($path); |
||
6297 | } elseif ($chkName && ! $this->nameAccepted($name, false)) { |
||
0 ignored issues
–
show
The variable
$name seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?
This error can happen if you refactor code and forget to move the variable initialization. Let’s take a look at a simple example: function someFunction() {
$x = 5;
echo $x;
}
The above code is perfectly fine. Now imagine that we re-order the statements: function someFunction() {
echo $x;
$x = 5;
}
In that case, ![]() |
|||
6298 | unlink($path); |
||
6299 | $res['names'][] = $path; |
||
6300 | $res['rmNames'][] = $name; |
||
0 ignored issues
–
show
The variable
$name seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?
This error can happen if you refactor code and forget to move the variable initialization. Let’s take a look at a simple example: function someFunction() {
$x = 5;
echo $x;
}
The above code is perfectly fine. Now imagine that we re-order the statements: function someFunction() {
echo $x;
$x = 5;
}
In that case, ![]() |
|||
6301 | } elseif ($chkWritable && ! $this->attr($path, 'write', null, $isDir)) { |
||
0 ignored issues
–
show
The variable
$isDir seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?
This error can happen if you refactor code and forget to move the variable initialization. Let’s take a look at a simple example: function someFunction() {
$x = 5;
echo $x;
}
The above code is perfectly fine. Now imagine that we re-order the statements: function someFunction() {
echo $x;
$x = 5;
}
In that case, ![]() |
|||
6302 | unlink($path); |
||
6303 | $res['writables'][] = $path; |
||
6304 | $res['rmNames'][] = $name; |
||
0 ignored issues
–
show
The variable
$name seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?
This error can happen if you refactor code and forget to move the variable initialization. Let’s take a look at a simple example: function someFunction() {
$x = 5;
echo $x;
}
The above code is perfectly fine. Now imagine that we re-order the statements: function someFunction() {
echo $x;
$x = 5;
}
In that case, ![]() |
|||
6305 | View Code Duplication | } elseif ($chkMime && ($mimeByName = self::mimetypeInternalDetect($name)) && $mimeByName !== 'unknown' && ! $this->allowPutMime($mimeByName)) { |
|
0 ignored issues
–
show
The variable
$name seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?
This error can happen if you refactor code and forget to move the variable initialization. Let’s take a look at a simple example: function someFunction() {
$x = 5;
echo $x;
}
The above code is perfectly fine. Now imagine that we re-order the statements: function someFunction() {
echo $x;
$x = 5;
}
In that case, ![]() 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. ![]() |
|||
6306 | unlink($path); |
||
6307 | $res['mimes'][] = $path; |
||
6308 | $res['rmNames'][] = $name; |
||
0 ignored issues
–
show
The variable
$name seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?
This error can happen if you refactor code and forget to move the variable initialization. Let’s take a look at a simple example: function someFunction() {
$x = 5;
echo $x;
}
The above code is perfectly fine. Now imagine that we re-order the statements: function someFunction() {
echo $x;
$x = 5;
}
In that case, ![]() |
|||
6309 | } else { |
||
6310 | $res['totalSize'] += sprintf('%u', filesize($path)); |
||
6311 | } |
||
6312 | } |
||
6313 | |||
6314 | return $res; |
||
6315 | } |
||
6316 | |||
6317 | /** |
||
6318 | * Return files of target directory that is dotfiles excludes. |
||
6319 | * |
||
6320 | * @param string $dir target directory path |
||
6321 | * @return array |
||
6322 | * @throws Exception |
||
6323 | * @author Naoki Sawada |
||
6324 | */ |
||
6325 | protected static function localScandir($dir) |
||
6326 | { |
||
6327 | // PHP function scandir() is not work well in specific environment. I dont know why. |
||
6328 | // ref. https://github.com/Studio-42/elFinder/issues/1248 |
||
6329 | $files = []; |
||
6330 | if ($dh = opendir($dir)) { |
||
6331 | while (false !== ($file = readdir($dh))) { |
||
6332 | if ($file !== '.' && $file !== '..') { |
||
6333 | $files[] = $file; |
||
6334 | } |
||
6335 | } |
||
6336 | closedir($dh); |
||
6337 | } else { |
||
6338 | throw new Exception('Can not open local directory.'); |
||
6339 | } |
||
6340 | |||
6341 | return $files; |
||
6342 | } |
||
6343 | |||
6344 | /** |
||
6345 | * Remove directory recursive on local file system. |
||
6346 | * |
||
6347 | * @param string $dir Target dirctory path |
||
6348 | * @return bool |
||
6349 | * @author Naoki Sawada |
||
6350 | */ |
||
6351 | protected static function localRmdirRecursive($dir) |
||
6352 | { |
||
6353 | if (! is_link($dir) && is_dir($dir)) { |
||
6354 | chmod($dir, 0777); |
||
6355 | if ($handle = opendir($dir)) { |
||
6356 | while (false !== ($file = readdir($handle))) { |
||
6357 | if ($file === '.' || $file === '..') { |
||
6358 | continue; |
||
6359 | } |
||
6360 | elFinder::extendTimeLimit(30); |
||
6361 | $path = $dir.DIRECTORY_SEPARATOR.$file; |
||
6362 | if (! is_link($dir) && is_dir($path)) { |
||
6363 | self::localRmdirRecursive($path); |
||
6364 | } else { |
||
6365 | chmod($path, 0666); |
||
6366 | unlink($path); |
||
6367 | } |
||
6368 | } |
||
6369 | closedir($handle); |
||
6370 | } |
||
6371 | |||
6372 | return rmdir($dir); |
||
6373 | } elseif (is_file($dir) || is_link($dir)) { |
||
6374 | chmod($dir, 0666); |
||
6375 | |||
6376 | return unlink($dir); |
||
6377 | } |
||
6378 | |||
6379 | return false; |
||
6380 | } |
||
6381 | |||
6382 | /** |
||
6383 | * Move item recursive on local file system. |
||
6384 | * |
||
6385 | * @param string $src |
||
6386 | * @param string $target |
||
6387 | * @param string $overWrite |
||
6388 | * @param string $copyJoin |
||
6389 | * @return bool |
||
6390 | * @author Naoki Sawada |
||
6391 | */ |
||
6392 | protected static function localMoveRecursive($src, $target, $overWrite = true, $copyJoin = true) |
||
6393 | { |
||
6394 | $res = false; |
||
6395 | if (! file_exists($target)) { |
||
6396 | return rename($src, $target); |
||
6397 | } |
||
6398 | if (! $copyJoin || ! is_dir($target)) { |
||
6399 | if ($overWrite) { |
||
6400 | if (is_dir($target)) { |
||
6401 | $del = self::localRmdirRecursive($target); |
||
6402 | } else { |
||
6403 | $del = unlink($target); |
||
6404 | } |
||
6405 | if ($del) { |
||
6406 | return rename($src, $target); |
||
6407 | } |
||
6408 | } |
||
6409 | } else { |
||
6410 | foreach (self::localScandir($src) as $item) { |
||
6411 | $res |= self::localMoveRecursive($src.DIRECTORY_SEPARATOR.$item, $target.DIRECTORY_SEPARATOR.$item, $overWrite, $copyJoin); |
||
6412 | } |
||
6413 | } |
||
6414 | |||
6415 | return (bool) $res; |
||
6416 | } |
||
6417 | |||
6418 | /** |
||
6419 | * Create Zip archive using PHP class ZipArchive. |
||
6420 | * |
||
6421 | * @param string $dir target dir |
||
6422 | * @param array $files files names list |
||
6423 | * @param string|object $zipPath Zip archive name |
||
6424 | * @return bool |
||
6425 | * @author Naoki Sawada |
||
6426 | */ |
||
6427 | protected static function zipArchiveZip($dir, $files, $zipPath) |
||
6428 | { |
||
6429 | try { |
||
6430 | if ($start = is_string($zipPath)) { |
||
6431 | $zip = new ZipArchive(); |
||
6432 | if ($zip->open($dir.DIRECTORY_SEPARATOR.$zipPath, ZipArchive::CREATE) !== true) { |
||
6433 | $zip = false; |
||
6434 | } |
||
6435 | } else { |
||
6436 | $zip = $zipPath; |
||
6437 | } |
||
6438 | if ($zip) { |
||
6439 | foreach ($files as $file) { |
||
6440 | $path = $dir.DIRECTORY_SEPARATOR.$file; |
||
6441 | if (is_dir($path)) { |
||
6442 | $zip->addEmptyDir($file); |
||
6443 | $_files = []; |
||
6444 | if ($handle = opendir($path)) { |
||
6445 | while (false !== ($entry = readdir($handle))) { |
||
6446 | if ($entry !== '.' && $entry !== '..') { |
||
6447 | $_files[] = $file.DIRECTORY_SEPARATOR.$entry; |
||
6448 | } |
||
6449 | } |
||
6450 | closedir($handle); |
||
6451 | } |
||
6452 | 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 ![]() |
|||
6453 | self::zipArchiveZip($dir, $_files, $zip); |
||
6454 | } |
||
6455 | } else { |
||
6456 | $zip->addFile($path, $file); |
||
6457 | } |
||
6458 | } |
||
6459 | $start && $zip->close(); |
||
6460 | } |
||
6461 | } catch (Exception $e) { |
||
6462 | return false; |
||
6463 | } |
||
6464 | |||
6465 | return true; |
||
6466 | } |
||
6467 | |||
6468 | /** |
||
6469 | * Unpack Zip archive using PHP class ZipArchive. |
||
6470 | * |
||
6471 | * @param string $zipPath Zip archive name |
||
6472 | * @param string $toDir Extract to path |
||
6473 | * @return bool |
||
6474 | * @author Naoki Sawada |
||
6475 | */ |
||
6476 | protected static function zipArchiveUnzip($zipPath, $toDir) |
||
6477 | { |
||
6478 | try { |
||
6479 | $zip = new ZipArchive(); |
||
6480 | if ($zip->open($zipPath) === true) { |
||
6481 | $zip->extractTo($toDir); |
||
6482 | $zip->close(); |
||
6483 | } |
||
6484 | } catch (Exception $e) { |
||
6485 | return false; |
||
6486 | } |
||
6487 | |||
6488 | return true; |
||
6489 | } |
||
6490 | |||
6491 | /** |
||
6492 | * Recursive symlinks search. |
||
6493 | * |
||
6494 | * @param string $path file/dir path |
||
6495 | * @return bool |
||
6496 | * @author Dmitry (dio) Levashov |
||
6497 | **/ |
||
6498 | protected static function localFindSymlinks($path) |
||
6499 | { |
||
6500 | if (is_link($path)) { |
||
6501 | return true; |
||
6502 | } |
||
6503 | |||
6504 | if (is_dir($path)) { |
||
6505 | foreach (self::localScandir($path) as $name) { |
||
6506 | $p = $path.DIRECTORY_SEPARATOR.$name; |
||
6507 | if (is_link($p)) { |
||
6508 | return true; |
||
6509 | } |
||
6510 | if (is_dir($p) && $this->_findSymlinks($p)) { |
||
0 ignored issues
–
show
|
|||
6511 | return true; |
||
6512 | } |
||
6513 | } |
||
6514 | } |
||
6515 | |||
6516 | return false; |
||
6517 | } |
||
6518 | |||
6519 | /**==================================* abstract methods *====================================**/ |
||
6520 | |||
6521 | /*********************** paths/urls *************************/ |
||
6522 | |||
6523 | /** |
||
6524 | * Return parent directory path. |
||
6525 | * |
||
6526 | * @param string $path file path |
||
6527 | * @return string |
||
6528 | * @author Dmitry (dio) Levashov |
||
6529 | **/ |
||
6530 | abstract protected function _dirname($path); |
||
6531 | |||
6532 | /** |
||
6533 | * Return file name. |
||
6534 | * |
||
6535 | * @param string $path file path |
||
6536 | * @return string |
||
6537 | * @author Dmitry (dio) Levashov |
||
6538 | **/ |
||
6539 | abstract protected function _basename($path); |
||
6540 | |||
6541 | /** |
||
6542 | * Join dir name and file name and return full path. |
||
6543 | * Some drivers (db) use int as path - so we give to concat path to driver itself. |
||
6544 | * |
||
6545 | * @param string $dir dir path |
||
6546 | * @param string $name file name |
||
6547 | * @return string |
||
6548 | * @author Dmitry (dio) Levashov |
||
6549 | **/ |
||
6550 | abstract protected function _joinPath($dir, $name); |
||
6551 | |||
6552 | /** |
||
6553 | * Return normalized path. |
||
6554 | * |
||
6555 | * @param string $path file path |
||
6556 | * @return string |
||
6557 | * @author Dmitry (dio) Levashov |
||
6558 | **/ |
||
6559 | abstract protected function _normpath($path); |
||
6560 | |||
6561 | /** |
||
6562 | * Return file path related to root dir. |
||
6563 | * |
||
6564 | * @param string $path file path |
||
6565 | * @return string |
||
6566 | * @author Dmitry (dio) Levashov |
||
6567 | **/ |
||
6568 | abstract protected function _relpath($path); |
||
6569 | |||
6570 | /** |
||
6571 | * Convert path related to root dir into real path. |
||
6572 | * |
||
6573 | * @param string $path rel file path |
||
6574 | * @return string |
||
6575 | * @author Dmitry (dio) Levashov |
||
6576 | **/ |
||
6577 | abstract protected function _abspath($path); |
||
6578 | |||
6579 | /** |
||
6580 | * Return fake path started from root dir. |
||
6581 | * Required to show path on client side. |
||
6582 | * |
||
6583 | * @param string $path file path |
||
6584 | * @return string |
||
6585 | * @author Dmitry (dio) Levashov |
||
6586 | **/ |
||
6587 | abstract protected function _path($path); |
||
6588 | |||
6589 | /** |
||
6590 | * Return true if $path is children of $parent. |
||
6591 | * |
||
6592 | * @param string $path path to check |
||
6593 | * @param string $parent parent path |
||
6594 | * @return bool |
||
6595 | * @author Dmitry (dio) Levashov |
||
6596 | **/ |
||
6597 | abstract protected function _inpath($path, $parent); |
||
6598 | |||
6599 | /** |
||
6600 | * Return stat for given path. |
||
6601 | * Stat contains following fields: |
||
6602 | * - (int) size file size in b. required |
||
6603 | * - (int) ts file modification time in unix time. required |
||
6604 | * - (string) mime mimetype. required for folders, others - optionally |
||
6605 | * - (bool) read read permissions. required |
||
6606 | * - (bool) write write permissions. required |
||
6607 | * - (bool) locked is object locked. optionally |
||
6608 | * - (bool) hidden is object hidden. optionally |
||
6609 | * - (string) alias for symlinks - link target path relative to root path. optionally |
||
6610 | * - (string) target for symlinks - link target path. optionally. |
||
6611 | * |
||
6612 | * If file does not exists - returns empty array or false. |
||
6613 | * |
||
6614 | * @param string $path file path |
||
6615 | * @return array|false |
||
6616 | * @author Dmitry (dio) Levashov |
||
6617 | **/ |
||
6618 | abstract protected function _stat($path); |
||
6619 | |||
6620 | /***************** file stat ********************/ |
||
6621 | |||
6622 | /** |
||
6623 | * Return true if path is dir and has at least one childs directory. |
||
6624 | * |
||
6625 | * @param string $path dir path |
||
6626 | * @return bool |
||
6627 | * @author Dmitry (dio) Levashov |
||
6628 | **/ |
||
6629 | abstract protected function _subdirs($path); |
||
6630 | |||
6631 | /** |
||
6632 | * Return object width and height |
||
6633 | * Ususaly used for images, but can be realize for video etc... |
||
6634 | * |
||
6635 | * @param string $path file path |
||
6636 | * @param string $mime file mime type |
||
6637 | * @return string |
||
6638 | * @author Dmitry (dio) Levashov |
||
6639 | **/ |
||
6640 | abstract protected function _dimensions($path, $mime); |
||
6641 | |||
6642 | /******************** file/dir content *********************/ |
||
6643 | |||
6644 | /** |
||
6645 | * Return files list in directory. |
||
6646 | * |
||
6647 | * @param string $path dir path |
||
6648 | * @return array |
||
6649 | * @author Dmitry (dio) Levashov |
||
6650 | **/ |
||
6651 | abstract protected function _scandir($path); |
||
6652 | |||
6653 | /** |
||
6654 | * Open file and return file pointer. |
||
6655 | * |
||
6656 | * @param string $path file path |
||
6657 | * @param string $mode open mode |
||
6658 | * @return resource|false |
||
6659 | * @author Dmitry (dio) Levashov |
||
6660 | **/ |
||
6661 | abstract protected function _fopen($path, $mode = 'rb'); |
||
6662 | |||
6663 | /** |
||
6664 | * Close opened file. |
||
6665 | * |
||
6666 | * @param resource $fp file pointer |
||
6667 | * @param string $path file path |
||
6668 | * @return bool |
||
6669 | * @author Dmitry (dio) Levashov |
||
6670 | **/ |
||
6671 | abstract protected function _fclose($fp, $path = ''); |
||
6672 | |||
6673 | /******************** file/dir manipulations *************************/ |
||
6674 | |||
6675 | /** |
||
6676 | * Create dir and return created dir path or false on failed. |
||
6677 | * |
||
6678 | * @param string $path parent dir path |
||
6679 | * @param string $name new directory name |
||
6680 | * @return string|bool |
||
6681 | * @author Dmitry (dio) Levashov |
||
6682 | **/ |
||
6683 | abstract protected function _mkdir($path, $name); |
||
6684 | |||
6685 | /** |
||
6686 | * Create file and return it's path or false on failed. |
||
6687 | * |
||
6688 | * @param string $path parent dir path |
||
6689 | * @param string $name new file name |
||
6690 | * @return string|bool |
||
6691 | * @author Dmitry (dio) Levashov |
||
6692 | **/ |
||
6693 | abstract protected function _mkfile($path, $name); |
||
6694 | |||
6695 | /** |
||
6696 | * Create symlink. |
||
6697 | * |
||
6698 | * @param string $source file to link to |
||
6699 | * @param string $targetDir folder to create link in |
||
6700 | * @param string $name symlink name |
||
6701 | * @return bool |
||
6702 | * @author Dmitry (dio) Levashov |
||
6703 | **/ |
||
6704 | abstract protected function _symlink($source, $targetDir, $name); |
||
6705 | |||
6706 | /** |
||
6707 | * Copy file into another file (only inside one volume). |
||
6708 | * |
||
6709 | * @param string $source source file path |
||
6710 | * @param $targetDir |
||
6711 | * @param string $name file name |
||
6712 | * @return bool|string |
||
6713 | * @internal param string $target target dir path |
||
6714 | * @author Dmitry (dio) Levashov |
||
6715 | */ |
||
6716 | abstract protected function _copy($source, $targetDir, $name); |
||
6717 | |||
6718 | /** |
||
6719 | * Move file into another parent dir. |
||
6720 | * Return new file path or false. |
||
6721 | * |
||
6722 | * @param string $source source file path |
||
6723 | * @param $targetDir |
||
6724 | * @param string $name file name |
||
6725 | * @return bool|string |
||
6726 | * @internal param string $target target dir path |
||
6727 | * @author Dmitry (dio) Levashov |
||
6728 | */ |
||
6729 | abstract protected function _move($source, $targetDir, $name); |
||
6730 | |||
6731 | /** |
||
6732 | * Remove file. |
||
6733 | * |
||
6734 | * @param string $path file path |
||
6735 | * @return bool |
||
6736 | * @author Dmitry (dio) Levashov |
||
6737 | **/ |
||
6738 | abstract protected function _unlink($path); |
||
6739 | |||
6740 | /** |
||
6741 | * Remove dir. |
||
6742 | * |
||
6743 | * @param string $path dir path |
||
6744 | * @return bool |
||
6745 | * @author Dmitry (dio) Levashov |
||
6746 | **/ |
||
6747 | abstract protected function _rmdir($path); |
||
6748 | |||
6749 | /** |
||
6750 | * Create new file and write into it from file pointer. |
||
6751 | * Return new file path or false on error. |
||
6752 | * |
||
6753 | * @param resource $fp file pointer |
||
6754 | * @param string $dir target dir path |
||
6755 | * @param string $name file name |
||
6756 | * @param array $stat file stat (required by some virtual fs) |
||
6757 | * @return bool|string |
||
6758 | * @author Dmitry (dio) Levashov |
||
6759 | **/ |
||
6760 | abstract protected function _save($fp, $dir, $name, $stat); |
||
6761 | |||
6762 | /** |
||
6763 | * Get file contents. |
||
6764 | * |
||
6765 | * @param string $path file path |
||
6766 | * @return string|false |
||
6767 | * @author Dmitry (dio) Levashov |
||
6768 | **/ |
||
6769 | abstract protected function _getContents($path); |
||
6770 | |||
6771 | /** |
||
6772 | * Write a string to a file. |
||
6773 | * |
||
6774 | * @param string $path file path |
||
6775 | * @param string $content new file content |
||
6776 | * @return bool |
||
6777 | * @author Dmitry (dio) Levashov |
||
6778 | **/ |
||
6779 | abstract protected function _filePutContents($path, $content); |
||
6780 | |||
6781 | /** |
||
6782 | * Extract files from archive. |
||
6783 | * |
||
6784 | * @param string $path file path |
||
6785 | * @param array $arc archiver options |
||
6786 | * @return bool |
||
6787 | * @author Dmitry (dio) Levashov, |
||
6788 | * @author Alexey Sukhotin |
||
6789 | **/ |
||
6790 | abstract protected function _extract($path, $arc); |
||
6791 | |||
6792 | /** |
||
6793 | * Create archive and return its path. |
||
6794 | * |
||
6795 | * @param string $dir target dir |
||
6796 | * @param array $files files names list |
||
6797 | * @param string $name archive name |
||
6798 | * @param array $arc archiver options |
||
6799 | * @return string|bool |
||
6800 | * @author Dmitry (dio) Levashov, |
||
6801 | * @author Alexey Sukhotin |
||
6802 | **/ |
||
6803 | abstract protected function _archive($dir, $files, $name, $arc); |
||
6804 | |||
6805 | /** |
||
6806 | * Detect available archivers. |
||
6807 | * |
||
6808 | * @return void |
||
6809 | * @author Dmitry (dio) Levashov, |
||
6810 | * @author Alexey Sukhotin |
||
6811 | **/ |
||
6812 | abstract protected function _checkArchivers(); |
||
6813 | |||
6814 | /** |
||
6815 | * Change file mode (chmod). |
||
6816 | * |
||
6817 | * @param string $path file path |
||
6818 | * @param string $mode octal string such as '0755' |
||
6819 | * @return bool |
||
6820 | * @author David Bartle, |
||
6821 | **/ |
||
6822 | abstract protected function _chmod($path, $mode); |
||
6823 | } // END class |
||
6824 |
You can fix this by adding a namespace to your class:
When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.