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 |
||
0 ignored issues
–
show
|
|||
2 | defined('PH7') or exit('Restricted access'); |
||
3 | if (!\PH7\Admin::auth()) exit('Restricted access'); // Accessible only for admins |
||
4 | |||
5 | /** |
||
6 | * Base class for elFinder volume. |
||
7 | * Provide 2 layers: |
||
8 | * 1. Public API (commands) |
||
9 | * 2. abstract fs API |
||
10 | * |
||
11 | * All abstract methods begin with "_" |
||
12 | * |
||
13 | * @author Dmitry (dio) Levashov |
||
14 | * @author Troex Nevelin |
||
15 | * @author Alexey Sukhotin |
||
16 | **/ |
||
17 | abstract class elFinderVolumeDriver { |
||
18 | |||
19 | /** |
||
20 | * Net mount key |
||
21 | * |
||
22 | * @var string |
||
23 | **/ |
||
24 | public $netMountKey = ''; |
||
25 | |||
26 | /** |
||
27 | * Request args |
||
28 | * $_POST or $_GET values |
||
29 | * |
||
30 | * @var array |
||
31 | */ |
||
32 | protected $ARGS = array(); |
||
33 | |||
34 | /** |
||
35 | * Driver id |
||
36 | * Must be started from letter and contains [a-z0-9] |
||
37 | * Used as part of volume id |
||
38 | * |
||
39 | * @var string |
||
40 | **/ |
||
41 | protected $driverId = 'a'; |
||
42 | |||
43 | /** |
||
44 | * Volume id - used as prefix for files hashes |
||
45 | * |
||
46 | * @var string |
||
47 | **/ |
||
48 | protected $id = ''; |
||
49 | |||
50 | /** |
||
51 | * Flag - volume "mounted" and available |
||
52 | * |
||
53 | * @var bool |
||
54 | **/ |
||
55 | protected $mounted = false; |
||
56 | |||
57 | /** |
||
58 | * Root directory path |
||
59 | * |
||
60 | * @var string |
||
61 | **/ |
||
62 | protected $root = ''; |
||
63 | |||
64 | /** |
||
65 | * Root basename | alias |
||
66 | * |
||
67 | * @var string |
||
68 | **/ |
||
69 | protected $rootName = ''; |
||
70 | |||
71 | /** |
||
72 | * Default directory to open |
||
73 | * |
||
74 | * @var string |
||
75 | **/ |
||
76 | protected $startPath = ''; |
||
77 | |||
78 | /** |
||
79 | * Base URL |
||
80 | * |
||
81 | * @var string |
||
82 | **/ |
||
83 | protected $URL = ''; |
||
84 | |||
85 | /** |
||
86 | * Thumbnails dir path |
||
87 | * |
||
88 | * @var string |
||
89 | **/ |
||
90 | protected $tmbPath = ''; |
||
91 | |||
92 | /** |
||
93 | * Is thumbnails dir writable |
||
94 | * |
||
95 | * @var bool |
||
96 | **/ |
||
97 | protected $tmbPathWritable = false; |
||
98 | |||
99 | /** |
||
100 | * Thumbnails base URL |
||
101 | * |
||
102 | * @var string |
||
103 | **/ |
||
104 | protected $tmbURL = ''; |
||
105 | |||
106 | /** |
||
107 | * Thumbnails size in px |
||
108 | * |
||
109 | * @var int |
||
110 | **/ |
||
111 | protected $tmbSize = 48; |
||
112 | |||
113 | /** |
||
114 | * Image manipulation lib name |
||
115 | * auto|imagick|gd|convert |
||
116 | * |
||
117 | * @var string |
||
118 | **/ |
||
119 | protected $imgLib = 'auto'; |
||
120 | |||
121 | /** |
||
122 | * Video to Image converter |
||
123 | * |
||
124 | * @var array |
||
125 | */ |
||
126 | protected $imgConverter = array(); |
||
127 | |||
128 | /** |
||
129 | * Library to crypt files name |
||
130 | * |
||
131 | * @var string |
||
132 | **/ |
||
133 | protected $cryptLib = ''; |
||
134 | |||
135 | /** |
||
136 | * Archivers config |
||
137 | * |
||
138 | * @var array |
||
139 | **/ |
||
140 | protected $archivers = array( |
||
141 | 'create' => array(), |
||
142 | 'extract' => array() |
||
143 | ); |
||
144 | |||
145 | /** |
||
146 | * Server character encoding |
||
147 | * |
||
148 | * @var string or null |
||
149 | **/ |
||
150 | protected $encoding = null; |
||
151 | |||
152 | /** |
||
153 | * How many subdirs levels return for tree |
||
154 | * |
||
155 | * @var int |
||
156 | **/ |
||
157 | protected $treeDeep = 1; |
||
158 | |||
159 | /** |
||
160 | * Errors from last failed action |
||
161 | * |
||
162 | * @var array |
||
163 | **/ |
||
164 | protected $error = array(); |
||
165 | |||
166 | /** |
||
167 | * Today 24:00 timestamp |
||
168 | * |
||
169 | * @var int |
||
170 | **/ |
||
171 | protected $today = 0; |
||
172 | |||
173 | /** |
||
174 | * Yesterday 24:00 timestamp |
||
175 | * |
||
176 | * @var int |
||
177 | **/ |
||
178 | protected $yesterday = 0; |
||
179 | |||
180 | /** |
||
181 | * Force make dirctory on extract |
||
182 | * |
||
183 | * @var int |
||
184 | **/ |
||
185 | protected $extractToNewdir = 'auto'; |
||
186 | |||
187 | /** |
||
188 | * Object configuration |
||
189 | * |
||
190 | * @var array |
||
191 | **/ |
||
192 | protected $options = array( |
||
193 | 'id' => '', |
||
194 | // revision id of root directory that uses for caching control of root stat |
||
195 | 'rootRev' => '', |
||
196 | // driver type it uses volume root's CSS class name. e.g. 'group' -> Adds 'elfinder-group' to CSS class name. |
||
197 | 'type' => '', |
||
198 | // root directory path |
||
199 | 'path' => '', |
||
200 | // Folder hash value on elFinder to be the parent of this volume |
||
201 | 'phash' => '', |
||
202 | // open this path on initial request instead of root path |
||
203 | 'startPath' => '', |
||
204 | // how many subdirs levels return per request |
||
205 | 'treeDeep' => 1, |
||
206 | // root url, not set to disable sending URL to client (replacement for old "fileURL" option) |
||
207 | 'URL' => '', |
||
208 | // directory link url to own manager url with folder hash (`true`, `false` or default `'auto'`: URL is empty then `true` else `false`) |
||
209 | 'dirUrlOwn' => 'auto', |
||
210 | // directory separator. required by client to show paths correctly |
||
211 | 'separator' => DIRECTORY_SEPARATOR, |
||
212 | // Server character encoding (default is '': UTF-8) |
||
213 | 'encoding' => '', |
||
214 | // for convert character encoding (default is '': Not change locale) |
||
215 | 'locale' => '', |
||
216 | // URL of volume icon (16x16 pixel image file) |
||
217 | 'icon' => '', |
||
218 | // CSS Class of volume root in tree |
||
219 | 'rootCssClass' => '', |
||
220 | // enable i18n folder name that convert name to elFinderInstance.messages['folder_'+name] |
||
221 | 'i18nFolderName' => false, |
||
222 | // Search timeout (sec) |
||
223 | 'searchTimeout' => 30, |
||
224 | // Search exclusion directory regex pattern (require demiliter e.g. '#/path/to/exclude_directory#i') |
||
225 | 'searchExDirReg' => '', |
||
226 | // library to crypt/uncrypt files names (not implemented) |
||
227 | 'cryptLib' => '', |
||
228 | // how to detect files mimetypes. (auto/internal/finfo/mime_content_type) |
||
229 | 'mimeDetect' => 'auto', |
||
230 | // mime.types file path (for mimeDetect==internal) |
||
231 | 'mimefile' => '', |
||
232 | // mime type normalize map : Array '[ext]:[detected mime type]' => '[normalized mime]' |
||
233 | 'mimeMap' => array( |
||
234 | 'md:application/x-genesis-rom' => 'text/x-markdown', |
||
235 | 'md:text/plain' => 'text/x-markdown', |
||
236 | 'markdown:text/plain' => 'text/x-markdown', |
||
237 | 'css:text/x-asm' => 'text/css', |
||
238 | 'ico:image/vnd.microsoft.icon' => 'image/x-icon', |
||
239 | 'csv:text/plain' => 'text/csv', |
||
240 | 'm4a:video/mp4' => 'audio/mp4', |
||
241 | 'oga:application/ogg' => 'audio/ogg', |
||
242 | 'ogv:application/ogg' => 'video/ogg' |
||
243 | ), |
||
244 | // MIME regex of send HTTP header "Content-Disposition: inline" |
||
245 | // '.' is allow inline of all of MIME types |
||
246 | // '$^' is not allow inline of all of MIME types |
||
247 | 'dispInlineRegex' => '^(?:(?:image|text)|application/x-shockwave-flash$)', |
||
248 | // directory for thumbnails |
||
249 | 'tmbPath' => '.tmb', |
||
250 | // mode to create thumbnails dir |
||
251 | 'tmbPathMode' => 0777, |
||
252 | // thumbnails dir URL. Set it if store thumbnails outside root directory |
||
253 | 'tmbURL' => '', |
||
254 | // thumbnails size (px) |
||
255 | 'tmbSize' => 48, |
||
256 | // thumbnails crop (true - crop, false - scale image to fit thumbnail size) |
||
257 | 'tmbCrop' => true, |
||
258 | // thumbnails background color (hex #rrggbb or 'transparent') |
||
259 | 'tmbBgColor' => 'transparent', |
||
260 | // image rotate fallback background color (hex #rrggbb) |
||
261 | 'bgColorFb' => '#ffffff', |
||
262 | // image manipulations library |
||
263 | 'imgLib' => 'auto', |
||
264 | // Fallback self image to thumbnail (nothing imgLib) |
||
265 | 'tmbFbSelf' => true, |
||
266 | // 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.
Loading history...
|
|||
267 | 'imgConverter' => array(), |
||
268 | // Max length of transfer to image converter |
||
269 | 'tmbVideoConvLen' => 10000000, |
||
270 | // Captre point seccond |
||
271 | 'tmbVideoConvSec' => 6, |
||
272 | // Resource path of fallback icon images defailt: php/resouces |
||
273 | 'resourcePath' => '', |
||
274 | // Jpeg image saveing quality |
||
275 | 'jpgQuality' => 100, |
||
276 | // on paste file - if true - old file will be replaced with new one, if false new file get name - original_name-number.ext |
||
277 | 'copyOverwrite' => true, |
||
278 | // if true - join new and old directories content on paste |
||
279 | 'copyJoin' => true, |
||
280 | // on upload - if true - old file will be replaced with new one, if false new file get name - original_name-number.ext |
||
281 | 'uploadOverwrite' => true, |
||
282 | // mimetypes allowed to upload |
||
283 | 'uploadAllow' => array(), |
||
284 | // mimetypes not allowed to upload |
||
285 | 'uploadDeny' => array(), |
||
286 | // order to proccess uploadAllow and uploadDeny options |
||
287 | 'uploadOrder' => array('deny', 'allow'), |
||
288 | // maximum upload file size. NOTE - this is size for every uploaded files |
||
289 | 'uploadMaxSize' => 0, |
||
290 | // maximum number of chunked upload connection. `-1` to disable chunked upload |
||
291 | 'uploadMaxConn' => 3, |
||
292 | // files dates format |
||
293 | 'dateFormat' => 'j M Y H:i', |
||
294 | // files time format |
||
295 | 'timeFormat' => 'H:i', |
||
296 | // if true - every folder will be check for children folders, otherwise all folders will be marked as having subfolders |
||
297 | 'checkSubfolders' => true, |
||
298 | // allow to copy from this volume to other ones? |
||
299 | 'copyFrom' => true, |
||
300 | // allow to copy from other volumes to this one? |
||
301 | 'copyTo' => true, |
||
302 | // cmd duplicate suffix format e.g. '_%s_' to without spaces |
||
303 | 'duplicateSuffix' => ' %s ', |
||
304 | // unique name numbar format e.g. '(%d)' to (1), (2)... |
||
305 | 'uniqueNumFormat' => '%d', |
||
306 | // list of commands disabled on this root |
||
307 | 'disabled' => array(), |
||
308 | // enable file owner, group & mode info, `false` to inactivate "chmod" command. |
||
309 | 'statOwner' => false, |
||
310 | // allow exec chmod of read-only files |
||
311 | 'allowChmodReadOnly' => false, |
||
312 | // regexp or function name to validate new file name |
||
313 | 'acceptedName' => '/^[^\.].*/', //<-- DONT touch this! Use constructor options to overwrite it! |
||
314 | // function/class method to control files permissions |
||
315 | 'accessControl' => null, |
||
316 | // some data required by access control |
||
317 | 'accessControlData' => null, |
||
318 | // default permissions. |
||
319 | 'defaults' => array( |
||
320 | 'read' => true, |
||
321 | 'write' => true, |
||
322 | 'locked' => false, |
||
323 | 'hidden' => false |
||
324 | ), |
||
325 | // files attributes |
||
326 | 'attributes' => array(), |
||
327 | // max allowed archive files size (0 - no limit) |
||
328 | 'maxArcFilesSize' => 0, |
||
329 | // Allowed archive's mimetypes to create. Leave empty for all available types. |
||
330 | 'archiveMimes' => array(), |
||
331 | // Manual config for archivers. See example below. Leave empty for auto detect |
||
332 | 'archivers' => array(), |
||
333 | // plugin settings |
||
334 | 'plugin' => array(), |
||
335 | // Is support parent directory time stamp update on add|remove|rename item |
||
336 | // Default `null` is auto detection that is LocalFileSystem, FTP or Dropbox are `true` |
||
337 | 'syncChkAsTs' => null, |
||
338 | // Long pooling sync checker function for syncChkAsTs is true |
||
339 | // Calls with args (TARGET DIRCTORY PATH, STAND-BY(sec), OLD TIMESTAMP, VOLUME DRIVER INSTANCE, ELFINDER INSTANCE) |
||
340 | // This function must return the following values. Changed: New Timestamp or Same: Old Timestamp or Error: false |
||
341 | // Default `null` is try use elFinderVolumeLocalFileSystem::localFileSystemInotify() on LocalFileSystem driver |
||
342 | // another driver use elFinder stat() checker |
||
343 | 'syncCheckFunc'=> null, |
||
344 | // Long polling sync stand-by time (sec) |
||
345 | 'plStandby' => 30, |
||
346 | // Sleep time (sec) for elFinder stat() checker (syncChkAsTs is true) |
||
347 | 'tsPlSleep' => 10, |
||
348 | // Sleep time (sec) for elFinder ls() checker (syncChkAsTs is false) |
||
349 | 'lsPlSleep' => 30, |
||
350 | // Client side sync interval minimum (ms) |
||
351 | // Default `null` is auto set to ('tsPlSleep' or 'lsPlSleep') * 1000 |
||
352 | // `0` to disable auto sync |
||
353 | 'syncMinMs' => null, |
||
354 | // required to fix bug on macos |
||
355 | 'utf8fix' => false, |
||
356 | // й ё Й Ё Ø Å |
||
357 | 'utf8patterns' => array("\u0438\u0306", "\u0435\u0308", "\u0418\u0306", "\u0415\u0308", "\u00d8A", "\u030a"), |
||
358 | 'utf8replace' => array("\u0439", "\u0451", "\u0419", "\u0401", "\u00d8", "\u00c5") |
||
359 | ); |
||
360 | |||
361 | /** |
||
362 | * Defaults permissions |
||
363 | * |
||
364 | * @var array |
||
365 | **/ |
||
366 | protected $defaults = array( |
||
367 | 'read' => true, |
||
368 | 'write' => true, |
||
369 | 'locked' => false, |
||
370 | 'hidden' => false |
||
371 | ); |
||
372 | |||
373 | /** |
||
374 | * Access control function/class |
||
375 | * |
||
376 | * @var mixed |
||
377 | **/ |
||
378 | protected $attributes = array(); |
||
379 | |||
380 | /** |
||
381 | * Access control function/class |
||
382 | * |
||
383 | * @var mixed |
||
384 | **/ |
||
385 | protected $access = null; |
||
386 | |||
387 | /** |
||
388 | * Mime types allowed to upload |
||
389 | * |
||
390 | * @var array |
||
391 | **/ |
||
392 | protected $uploadAllow = array(); |
||
393 | |||
394 | /** |
||
395 | * Mime types denied to upload |
||
396 | * |
||
397 | * @var array |
||
398 | **/ |
||
399 | protected $uploadDeny = array(); |
||
400 | |||
401 | /** |
||
402 | * Order to validate uploadAllow and uploadDeny |
||
403 | * |
||
404 | * @var array |
||
405 | **/ |
||
406 | protected $uploadOrder = array(); |
||
407 | |||
408 | /** |
||
409 | * Maximum allowed upload file size. |
||
410 | * Set as number or string with unit - "10M", "500K", "1G" |
||
411 | * |
||
412 | * @var int|string |
||
413 | **/ |
||
414 | protected $uploadMaxSize = 0; |
||
415 | |||
416 | /** |
||
417 | * Mimetype detect method |
||
418 | * |
||
419 | * @var string |
||
420 | **/ |
||
421 | protected $mimeDetect = 'auto'; |
||
422 | |||
423 | /** |
||
424 | * Flag - mimetypes from externail file was loaded |
||
425 | * |
||
426 | * @var bool |
||
427 | **/ |
||
428 | private static $mimetypesLoaded = false; |
||
429 | |||
430 | /** |
||
431 | * Finfo object for mimeDetect == 'finfo' |
||
432 | * |
||
433 | * @var object |
||
434 | **/ |
||
435 | protected $finfo = null; |
||
436 | |||
437 | /** |
||
438 | * List of disabled client's commands |
||
439 | * |
||
440 | * @var array |
||
441 | **/ |
||
442 | protected $disabled = array(); |
||
443 | |||
444 | /** |
||
445 | * default extensions/mimetypes for mimeDetect == 'internal' |
||
446 | * |
||
447 | * @var array |
||
448 | **/ |
||
449 | protected static $mimetypes = array( |
||
450 | // applications |
||
451 | 'ai' => 'application/postscript', |
||
452 | 'eps' => 'application/postscript', |
||
453 | 'exe' => 'application/x-executable', |
||
454 | 'doc' => 'application/msword', |
||
455 | 'dot' => 'application/msword', |
||
456 | 'xls' => 'application/vnd.ms-excel', |
||
457 | 'xlt' => 'application/vnd.ms-excel', |
||
458 | 'xla' => 'application/vnd.ms-excel', |
||
459 | 'ppt' => 'application/vnd.ms-powerpoint', |
||
460 | 'pps' => 'application/vnd.ms-powerpoint', |
||
461 | 'pdf' => 'application/pdf', |
||
462 | 'xml' => 'application/xml', |
||
463 | 'swf' => 'application/x-shockwave-flash', |
||
464 | 'torrent' => 'application/x-bittorrent', |
||
465 | 'jar' => 'application/x-jar', |
||
466 | // open office (finfo detect as application/zip) |
||
467 | 'odt' => 'application/vnd.oasis.opendocument.text', |
||
468 | 'ott' => 'application/vnd.oasis.opendocument.text-template', |
||
469 | 'oth' => 'application/vnd.oasis.opendocument.text-web', |
||
470 | 'odm' => 'application/vnd.oasis.opendocument.text-master', |
||
471 | 'odg' => 'application/vnd.oasis.opendocument.graphics', |
||
472 | 'otg' => 'application/vnd.oasis.opendocument.graphics-template', |
||
473 | 'odp' => 'application/vnd.oasis.opendocument.presentation', |
||
474 | 'otp' => 'application/vnd.oasis.opendocument.presentation-template', |
||
475 | 'ods' => 'application/vnd.oasis.opendocument.spreadsheet', |
||
476 | 'ots' => 'application/vnd.oasis.opendocument.spreadsheet-template', |
||
477 | 'odc' => 'application/vnd.oasis.opendocument.chart', |
||
478 | 'odf' => 'application/vnd.oasis.opendocument.formula', |
||
479 | 'odb' => 'application/vnd.oasis.opendocument.database', |
||
480 | 'odi' => 'application/vnd.oasis.opendocument.image', |
||
481 | 'oxt' => 'application/vnd.openofficeorg.extension', |
||
482 | // MS office 2007 (finfo detect as application/zip) |
||
483 | 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', |
||
484 | 'docm' => 'application/vnd.ms-word.document.macroEnabled.12', |
||
485 | 'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template', |
||
486 | 'dotm' => 'application/vnd.ms-word.template.macroEnabled.12', |
||
487 | 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', |
||
488 | 'xlsm' => 'application/vnd.ms-excel.sheet.macroEnabled.12', |
||
489 | 'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template', |
||
490 | 'xltm' => 'application/vnd.ms-excel.template.macroEnabled.12', |
||
491 | 'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12', |
||
492 | 'xlam' => 'application/vnd.ms-excel.addin.macroEnabled.12', |
||
493 | 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', |
||
494 | 'pptm' => 'application/vnd.ms-powerpoint.presentation.macroEnabled.12', |
||
495 | 'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow', |
||
496 | 'ppsm' => 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12', |
||
497 | 'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template', |
||
498 | 'potm' => 'application/vnd.ms-powerpoint.template.macroEnabled.12', |
||
499 | 'ppam' => 'application/vnd.ms-powerpoint.addin.macroEnabled.12', |
||
500 | 'sldx' => 'application/vnd.openxmlformats-officedocument.presentationml.slide', |
||
501 | 'sldm' => 'application/vnd.ms-powerpoint.slide.macroEnabled.12', |
||
502 | // archives |
||
503 | 'gz' => 'application/x-gzip', |
||
504 | 'tgz' => 'application/x-gzip', |
||
505 | 'bz' => 'application/x-bzip2', |
||
506 | 'bz2' => 'application/x-bzip2', |
||
507 | 'tbz' => 'application/x-bzip2', |
||
508 | 'xz' => 'application/x-xz', |
||
509 | 'zip' => 'application/zip', |
||
510 | 'rar' => 'application/x-rar', |
||
511 | 'tar' => 'application/x-tar', |
||
512 | '7z' => 'application/x-7z-compressed', |
||
513 | // texts |
||
514 | 'txt' => 'text/plain', |
||
515 | 'php' => 'text/x-php', |
||
516 | 'html' => 'text/html', |
||
517 | 'htm' => 'text/html', |
||
518 | 'js' => 'text/javascript', |
||
519 | 'css' => 'text/css', |
||
520 | 'rtf' => 'text/rtf', |
||
521 | 'rtfd' => 'text/rtfd', |
||
522 | 'py' => 'text/x-python', |
||
523 | 'java' => 'text/x-java-source', |
||
524 | 'rb' => 'text/x-ruby', |
||
525 | 'sh' => 'text/x-shellscript', |
||
526 | 'pl' => 'text/x-perl', |
||
527 | //'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.
Loading history...
|
|||
528 | 'sql' => 'text/x-sql', |
||
529 | 'c' => 'text/x-csrc', |
||
530 | 'h' => 'text/x-chdr', |
||
531 | 'cpp' => 'text/x-c++src', |
||
532 | 'hh' => 'text/x-c++hdr', |
||
533 | 'log' => 'text/plain', |
||
534 | 'csv' => 'text/csv', |
||
535 | 'md' => 'text/x-markdown', |
||
536 | 'markdown' => 'text/x-markdown', |
||
537 | // images |
||
538 | 'bmp' => 'image/x-ms-bmp', |
||
539 | 'jpg' => 'image/jpeg', |
||
540 | 'jpeg' => 'image/jpeg', |
||
541 | 'gif' => 'image/gif', |
||
542 | 'png' => 'image/png', |
||
543 | 'tif' => 'image/tiff', |
||
544 | 'tiff' => 'image/tiff', |
||
545 | 'tga' => 'image/x-targa', |
||
546 | 'psd' => 'image/vnd.adobe.photoshop', |
||
547 | //'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.
Loading history...
|
|||
548 | 'xbm' => 'image/xbm', |
||
549 | 'pxm' => 'image/pxm', |
||
550 | //audio |
||
551 | 'mp3' => 'audio/mpeg', |
||
552 | 'mid' => 'audio/midi', |
||
553 | 'ogg' => 'audio/ogg', |
||
554 | 'oga' => 'audio/ogg', |
||
555 | 'm4a' => 'audio/mp4', |
||
556 | 'wav' => 'audio/wav', |
||
557 | 'wma' => 'audio/x-ms-wma', |
||
558 | // video |
||
559 | 'avi' => 'video/x-msvideo', |
||
560 | 'dv' => 'video/x-dv', |
||
561 | 'mp4' => 'video/mp4', |
||
562 | 'mpeg' => 'video/mpeg', |
||
563 | 'mpg' => 'video/mpeg', |
||
564 | 'mov' => 'video/quicktime', |
||
565 | 'wm' => 'video/x-ms-wmv', |
||
566 | 'flv' => 'video/x-flv', |
||
567 | 'mkv' => 'video/x-matroska', |
||
568 | 'webm' => 'video/webm', |
||
569 | 'ogv' => 'video/ogg', |
||
570 | 'ogm' => 'video/ogg' |
||
571 | ); |
||
572 | |||
573 | /** |
||
574 | * Directory separator - required by client |
||
575 | * |
||
576 | * @var string |
||
577 | **/ |
||
578 | protected $separator = DIRECTORY_SEPARATOR; |
||
579 | |||
580 | /** |
||
581 | * System Root path (Unix like: '/', Windows: '\', 'C:\' or 'D:\'...) |
||
582 | * |
||
583 | * @var string |
||
584 | **/ |
||
585 | protected $systemRoot = DIRECTORY_SEPARATOR; |
||
586 | |||
587 | /** |
||
588 | * Mimetypes allowed to display |
||
589 | * |
||
590 | * @var array |
||
591 | **/ |
||
592 | protected $onlyMimes = array(); |
||
593 | |||
594 | /** |
||
595 | * Store files moved or overwrited files info |
||
596 | * |
||
597 | * @var array |
||
598 | **/ |
||
599 | protected $removed = array(); |
||
600 | |||
601 | /** |
||
602 | * Store files added files info |
||
603 | * |
||
604 | * @var array |
||
605 | **/ |
||
606 | protected $added = array(); |
||
607 | |||
608 | /** |
||
609 | * Cache storage |
||
610 | * |
||
611 | * @var array |
||
612 | **/ |
||
613 | protected $cache = array(); |
||
614 | |||
615 | /** |
||
616 | * Cache by folders |
||
617 | * |
||
618 | * @var array |
||
619 | **/ |
||
620 | protected $dirsCache = array(); |
||
621 | |||
622 | /** |
||
623 | * Cache for subdirsCE() |
||
624 | * |
||
625 | * @var array |
||
626 | */ |
||
627 | protected $subdirsCache = array(); |
||
628 | |||
629 | /** |
||
630 | * This volume session cache |
||
631 | * |
||
632 | * @var array |
||
633 | */ |
||
634 | protected $sessionCache; |
||
635 | |||
636 | /** |
||
637 | * elFinder session wrapper object |
||
638 | * |
||
639 | * @var elFinderSessionInterface |
||
640 | */ |
||
641 | protected $session; |
||
642 | |||
643 | /** |
||
644 | * Search start time |
||
645 | * |
||
646 | * @var int |
||
647 | */ |
||
648 | protected $searchStart; |
||
649 | |||
650 | /** |
||
651 | * Current query word on doSearch |
||
652 | * |
||
653 | * @var string |
||
654 | **/ |
||
655 | protected $doSearchCurrentQuery = array(); |
||
656 | |||
657 | /** |
||
658 | * Is root modified (for clear root stat cache) |
||
659 | * |
||
660 | * @var bool |
||
661 | */ |
||
662 | protected $rootModified = false; |
||
663 | |||
664 | /*********************************************************************/ |
||
665 | /* INITIALIZATION */ |
||
666 | /*********************************************************************/ |
||
667 | |||
668 | /** |
||
669 | * Prepare driver before mount volume. |
||
670 | * Return true if volume is ready. |
||
671 | * |
||
672 | * @return bool |
||
673 | * @author Dmitry (dio) Levashov |
||
674 | **/ |
||
675 | protected function init() { |
||
676 | return true; |
||
677 | } |
||
678 | |||
679 | /** |
||
680 | * Configure after successfull mount. |
||
681 | * By default set thumbnails path and image manipulation library. |
||
682 | * |
||
683 | * @return void |
||
684 | * @author Dmitry (dio) Levashov |
||
685 | **/ |
||
686 | protected function configure() { |
||
0 ignored issues
–
show
configure 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);
}
}
Loading history...
configure 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);
}
}
Loading history...
configure 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);
}
}
Loading history...
|
|||
687 | // set ARGS |
||
688 | $this->ARGS = $_SERVER['REQUEST_METHOD'] === 'POST'? $_POST : $_GET; |
||
689 | // set thumbnails path |
||
690 | $path = $this->options['tmbPath']; |
||
691 | if ($path) { |
||
692 | if (!file_exists($path)) { |
||
693 | if (mkdir($path)) { |
||
694 | chmod($path, $this->options['tmbPathMode']); |
||
695 | } else { |
||
696 | $path = ''; |
||
697 | } |
||
698 | } |
||
699 | |||
700 | if (is_dir($path) && is_readable($path)) { |
||
701 | $this->tmbPath = $path; |
||
702 | $this->tmbPathWritable = is_writable($path); |
||
703 | } |
||
704 | } |
||
705 | // set resouce path |
||
706 | if (! is_dir($this->options['resourcePath'])) { |
||
707 | $this->options['resourcePath'] = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'resources'; |
||
708 | } |
||
709 | |||
710 | // set image manipulation library |
||
711 | $type = preg_match('/^(imagick|gd|convert|auto)$/i', $this->options['imgLib']) |
||
712 | ? strtolower($this->options['imgLib']) |
||
713 | : 'auto'; |
||
714 | |||
715 | $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
Loading history...
|
|||
716 | if (($type === 'imagick' || $type === 'auto') && extension_loaded('imagick')) { |
||
717 | $this->imgLib = 'imagick'; |
||
718 | } else if (($type === 'gd' || $type === 'auto') && function_exists('gd_info')) { |
||
719 | $this->imgLib = 'gd'; |
||
720 | } else { |
||
721 | $convertCache = 'imgLibConvert'; |
||
722 | if (($convertCmd = $this->session->get($convertCache, false)) !== false) { |
||
723 | $this->imgLib = $convertCmd; |
||
724 | } else { |
||
725 | $this->imgLib = ($this->procExec('convert -version') === 0)? 'convert' : ''; |
||
726 | $this->session->set($convertCache, $this->imgLib); |
||
727 | } |
||
728 | } |
||
729 | if ($type !== 'auto' && $this->imgLib === '') { |
||
730 | // fallback |
||
731 | $this->imgLib = extension_loaded('imagick')? 'imagick' : (function_exists('gd_info')? 'gd' : ''); |
||
732 | } |
||
733 | |||
734 | // check video to img converter |
||
735 | if (! empty($this->options['imgConverter']) && is_array($this->options['imgConverter'])) { |
||
736 | foreach($this->options['imgConverter'] as $_type => $_converter) { |
||
737 | if (isset($_converter['func'])) { |
||
738 | $this->imgConverter[strtolower($_type)] = $_converter; |
||
739 | } |
||
740 | } |
||
741 | } |
||
742 | if (! isset($this->imgConverter['video'])) { |
||
743 | $videoLibCache = 'videoLib'; |
||
744 | if (($videoLibCmd = $this->session->get($videoLibCache, false)) === false) { |
||
745 | $videoLibCmd = ($this->procExec('ffmpeg -version') === 0)? 'ffmpeg' : ''; |
||
746 | $this->session->set($videoLibCache, $videoLibCmd); |
||
747 | } |
||
748 | if ($videoLibCmd) { |
||
749 | $this->imgConverter['video'] = array( |
||
750 | 'func' => array($this, $videoLibCmd . 'ToImg'), |
||
751 | 'maxlen' => $this->options['tmbVideoConvLen'] |
||
752 | ); |
||
753 | } |
||
754 | } |
||
755 | |||
756 | // check archivers |
||
757 | if (empty($this->archivers['create'])) { |
||
758 | $this->disabled[] ='archive'; |
||
759 | } |
||
760 | if (empty($this->archivers['extract'])) { |
||
761 | $this->disabled[] ='extract'; |
||
762 | } |
||
763 | $_arc = $this->getArchivers(); |
||
764 | if (empty($_arc['create'])) { |
||
765 | $this->disabled[] ='zipdl'; |
||
766 | } |
||
767 | |||
768 | // check 'statOwner' for command `chmod` |
||
769 | if (empty($this->options['statOwner'])) { |
||
770 | $this->disabled[] ='chmod'; |
||
771 | } |
||
772 | |||
773 | // check 'mimeMap' |
||
774 | if (!is_array($this->options['mimeMap'])) { |
||
775 | $this->options['mimeMap'] = array(); |
||
776 | } |
||
777 | } |
||
778 | |||
779 | /** |
||
780 | * @deprecated |
||
781 | */ |
||
782 | protected function sessionRestart() { |
||
783 | $this->sessionCache = $this->session->start()->get($this->id, array()); |
||
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..
Loading history...
|
|||
784 | return true; |
||
785 | } |
||
786 | |||
787 | /*********************************************************************/ |
||
788 | /* PUBLIC API */ |
||
789 | /*********************************************************************/ |
||
790 | |||
791 | /** |
||
792 | * Return driver id. Used as a part of volume id. |
||
793 | * |
||
794 | * @return string |
||
795 | * @author Dmitry (dio) Levashov |
||
796 | **/ |
||
797 | public function driverId() { |
||
798 | return $this->driverId; |
||
799 | } |
||
800 | |||
801 | /** |
||
802 | * Return volume id |
||
803 | * |
||
804 | * @return string |
||
805 | * @author Dmitry (dio) Levashov |
||
806 | **/ |
||
807 | public function id() { |
||
808 | return $this->id; |
||
809 | } |
||
810 | |||
811 | /** |
||
812 | * Assign elFinder session wrapper object |
||
813 | * |
||
814 | * @param $session elFinderSessionInterface |
||
815 | */ |
||
816 | public function setSession($session) { |
||
817 | $this->session = $session; |
||
818 | } |
||
819 | |||
820 | /** |
||
821 | * Return debug info for client |
||
822 | * |
||
823 | * @return array |
||
824 | * @author Dmitry (dio) Levashov |
||
825 | **/ |
||
826 | public function debug() { |
||
827 | return array( |
||
828 | 'id' => $this->id(), |
||
829 | 'name' => strtolower(substr(get_class($this), strlen('elfinderdriver'))), |
||
830 | 'mimeDetect' => $this->mimeDetect, |
||
831 | 'imgLib' => $this->imgLib |
||
832 | ); |
||
833 | } |
||
834 | |||
835 | /** |
||
836 | * chmod a file or folder |
||
837 | * |
||
838 | * @param string $hash file or folder hash to chmod |
||
839 | * @param string $mode octal string representing new permissions |
||
840 | * @return array|false |
||
841 | * @author David Bartle |
||
842 | **/ |
||
843 | public function chmod($hash, $mode) { |
||
844 | if ($this->commandDisabled('chmod')) { |
||
845 | return $this->setError(elFinder::ERROR_PERM_DENIED); |
||
846 | } |
||
847 | |||
848 | if (!($file = $this->file($hash))) { |
||
849 | return $this->setError(elFinder::ERROR_FILE_NOT_FOUND); |
||
850 | } |
||
851 | |||
852 | if (!$this->options['allowChmodReadOnly']) { |
||
853 | if (!$this->attr($this->decode($hash), 'write', null, ($file['mime'] === 'directory'))) { |
||
854 | return $this->setError(elFinder::ERROR_PERM_DENIED, $file['name']); |
||
855 | } |
||
856 | } |
||
857 | |||
858 | $path = $this->decode($hash); |
||
859 | $write = $file['write']; |
||
860 | |||
861 | if ($this->convEncOut(!$this->_chmod($this->convEncIn($path), $mode))) { |
||
862 | return $this->setError(elFinder::ERROR_PERM_DENIED, $file['name']); |
||
863 | } |
||
864 | |||
865 | $this->clearcache(); |
||
866 | if ($path == $this->root) { |
||
867 | $this->rootModified = true; |
||
868 | } |
||
869 | |||
870 | if ($file = $this->stat($path)) { |
||
871 | $files = array($file); |
||
872 | if ($file['mime'] === 'directory' && $write !== $file['write']) { |
||
873 | foreach ($this->getScandir($path) as $stat) { |
||
874 | if ($this->mimeAccepted($stat['mime'])) { |
||
875 | $files[] = $stat; |
||
876 | } |
||
877 | } |
||
878 | } |
||
879 | return $files; |
||
880 | } else { |
||
881 | return $this->setError(elFinder::ERROR_FILE_NOT_FOUND); |
||
882 | } |
||
883 | } |
||
884 | |||
885 | /** |
||
886 | * stat a file or folder for elFinder cmd exec |
||
887 | * |
||
888 | * @param string $hash file or folder hash to chmod |
||
889 | * @return array |
||
890 | * @author Naoki Sawada |
||
891 | **/ |
||
892 | public function fstat($hash) { |
||
893 | $path = $this->decode($hash); |
||
894 | return $this->stat($path); |
||
895 | } |
||
896 | |||
897 | |||
898 | public function clearstatcache() { |
||
899 | clearstatcache(); |
||
900 | $this->clearcache(); |
||
901 | } |
||
902 | |||
903 | /** |
||
904 | * "Mount" volume. |
||
905 | * Return true if volume available for read or write, |
||
906 | * false - otherwise |
||
907 | * |
||
908 | * @param array $opts |
||
909 | * @return bool |
||
910 | * @author Dmitry (dio) Levashov |
||
911 | * @author Alexey Sukhotin |
||
912 | */ |
||
913 | public function mount(array $opts) { |
||
914 | $this->options = array_merge($this->options, $opts); |
||
915 | |||
916 | if (!isset($this->options['path']) || $this->options['path'] === '') { |
||
917 | return $this->setError('Path undefined.'); |
||
918 | } |
||
919 | |||
920 | if (! $this->session) { |
||
921 | return $this->setError('Session wrapper dose not set. Need to `$volume->setSession(elFinderSessionInterface);` before mount.'); |
||
922 | } |
||
923 | if (! ($this->session instanceof elFinderSessionInterface)) { |
||
924 | return $this->setError('Session wrapper instance must be "elFinderSessionInterface".'); |
||
925 | } |
||
926 | |||
927 | $this->id = $this->driverId.(!empty($this->options['id']) ? $this->options['id'] : elFinder::$volumesCnt++).'_'; |
||
928 | $this->root = $this->normpathCE($this->options['path']); |
||
929 | $this->separator = isset($this->options['separator']) ? $this->options['separator'] : DIRECTORY_SEPARATOR; |
||
930 | $this->systemRoot = isset($this->options['systemRoot']) ? $this->options['systemRoot'] : $this->separator; |
||
931 | |||
932 | // set server encoding |
||
933 | if (!empty($this->options['encoding']) && strtoupper($this->options['encoding']) !== 'UTF-8') { |
||
934 | $this->encoding = $this->options['encoding']; |
||
935 | } else { |
||
936 | $this->encoding = null; |
||
937 | } |
||
938 | |||
939 | $argInit = !empty($this->ARGS['init']); |
||
940 | |||
941 | // session cache |
||
942 | if ($argInit) { |
||
943 | $this->session->set($this->id, array()); |
||
944 | } |
||
945 | $this->sessionCache = $this->session->get($this->id, array()); |
||
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..
Loading history...
|
|||
946 | |||
947 | // default file attribute |
||
948 | $this->defaults = array( |
||
949 | 'read' => isset($this->options['defaults']['read']) ? !!$this->options['defaults']['read'] : true, |
||
950 | 'write' => isset($this->options['defaults']['write']) ? !!$this->options['defaults']['write'] : true, |
||
951 | 'locked' => isset($this->options['defaults']['locked']) ? !!$this->options['defaults']['locked'] : false, |
||
952 | 'hidden' => isset($this->options['defaults']['hidden']) ? !!$this->options['defaults']['hidden'] : false |
||
953 | ); |
||
954 | |||
955 | // root attributes |
||
956 | $this->attributes[] = array( |
||
957 | 'pattern' => '~^'.preg_quote($this->separator).'$~', |
||
958 | 'locked' => true, |
||
959 | 'hidden' => false |
||
960 | ); |
||
961 | // set files attributes |
||
962 | if (!empty($this->options['attributes']) && is_array($this->options['attributes'])) { |
||
963 | |||
964 | foreach ($this->options['attributes'] as $a) { |
||
965 | // attributes must contain pattern and at least one rule |
||
966 | if (!empty($a['pattern']) || count($a) > 1) { |
||
967 | $this->attributes[] = $a; |
||
968 | } |
||
969 | } |
||
970 | } |
||
971 | |||
972 | if (!empty($this->options['accessControl']) && is_callable($this->options['accessControl'])) { |
||
973 | $this->access = $this->options['accessControl']; |
||
974 | } |
||
975 | |||
976 | $this->today = mktime(0,0,0, date('m'), date('d'), date('Y')); |
||
977 | $this->yesterday = $this->today-86400; |
||
978 | |||
979 | // debug($this->attributes); |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
63% 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.
Loading history...
|
|||
980 | if (!$this->init()) { |
||
981 | return false; |
||
982 | } |
||
983 | |||
984 | // check some options is arrays |
||
985 | $this->uploadAllow = isset($this->options['uploadAllow']) && is_array($this->options['uploadAllow']) |
||
986 | ? $this->options['uploadAllow'] |
||
987 | : array(); |
||
988 | |||
989 | $this->uploadDeny = isset($this->options['uploadDeny']) && is_array($this->options['uploadDeny']) |
||
990 | ? $this->options['uploadDeny'] |
||
991 | : array(); |
||
992 | |||
993 | $this->options['uiCmdMap'] = (isset($this->options['uiCmdMap']) && is_array($this->options['uiCmdMap'])) |
||
994 | ? $this->options['uiCmdMap'] |
||
995 | : array(); |
||
996 | |||
997 | if (is_string($this->options['uploadOrder'])) { // telephat_mode on, compatibility with 1.x |
||
998 | $parts = explode(',', isset($this->options['uploadOrder']) ? $this->options['uploadOrder'] : 'deny,allow'); |
||
999 | $this->uploadOrder = array(trim($parts[0]), trim($parts[1])); |
||
1000 | } else { // telephat_mode off |
||
1001 | $this->uploadOrder = ! empty($this->options['uploadOrder'])? $this->options['uploadOrder'] : array('deny', 'allow'); |
||
1002 | } |
||
1003 | |||
1004 | if (!empty($this->options['uploadMaxSize'])) { |
||
1005 | $size = ''.$this->options['uploadMaxSize']; |
||
1006 | $unit = strtolower(substr($size, strlen($size) - 1)); |
||
1007 | $n = 1; |
||
1008 | switch ($unit) { |
||
1009 | case 'k': |
||
1010 | $n = 1024; |
||
1011 | break; |
||
1012 | case 'm': |
||
1013 | $n = 1048576; |
||
1014 | break; |
||
1015 | case 'g': |
||
1016 | $n = 1073741824; |
||
1017 | } |
||
1018 | $this->uploadMaxSize = intval($size)*$n; |
||
1019 | } |
||
1020 | // Set maximum to PHP_INT_MAX |
||
1021 | if (!defined('PHP_INT_MAX')) { |
||
1022 | define('PHP_INT_MAX', 2147483647); |
||
1023 | } |
||
1024 | if ($this->uploadMaxSize < 1 || $this->uploadMaxSize > PHP_INT_MAX) { |
||
1025 | $this->uploadMaxSize = PHP_INT_MAX; |
||
1026 | } |
||
1027 | |||
1028 | $this->disabled = isset($this->options['disabled']) && is_array($this->options['disabled']) |
||
1029 | ? array_values(array_diff($this->options['disabled'], array('open'))) // 'open' is required |
||
1030 | : array(); |
||
1031 | |||
1032 | $this->cryptLib = $this->options['cryptLib']; |
||
1033 | $this->mimeDetect = $this->options['mimeDetect']; |
||
1034 | |||
1035 | // find available mimetype detect method |
||
1036 | $type = strtolower($this->options['mimeDetect']); |
||
1037 | $type = preg_match('/^(finfo|mime_content_type|internal|auto)$/i', $type) ? $type : 'auto'; |
||
1038 | $regexp = '/text\/x\-(php|c\+\+)/'; |
||
1039 | |||
1040 | if (($type == 'finfo' || $type == 'auto') |
||
1041 | && class_exists('finfo', false)) { |
||
1042 | $tmpFileInfo = explode(';', finfo_file(finfo_open(FILEINFO_MIME), __FILE__)); |
||
1043 | } else { |
||
1044 | $tmpFileInfo = false; |
||
1045 | } |
||
1046 | |||
1047 | $type = 'internal'; |
||
1048 | if ($tmpFileInfo && preg_match($regexp, array_shift($tmpFileInfo))) { |
||
1049 | $type = 'finfo'; |
||
1050 | $this->finfo = finfo_open(FILEINFO_MIME); |
||
1051 | } elseif (($type == 'mime_content_type' || $type == 'auto') && function_exists('mime_content_type')) { |
||
1052 | $_mimetypes = explode(';', mime_content_type(__FILE__)); |
||
1053 | if (preg_match($regexp, array_shift($_mimetypes))) { |
||
1054 | $type = 'mime_content_type'; |
||
1055 | } |
||
1056 | } |
||
1057 | $this->mimeDetect = $type; |
||
1058 | |||
1059 | // load mimes from external file for mimeDetect == 'internal' |
||
1060 | // based on Alexey Sukhotin idea and patch: http://elrte.org/redmine/issues/163 |
||
1061 | // file must be in file directory or in parent one |
||
1062 | if ($this->mimeDetect == 'internal' && !self::$mimetypesLoaded) { |
||
1063 | self::$mimetypesLoaded = true; |
||
1064 | $this->mimeDetect = 'internal'; |
||
1065 | $file = false; |
||
1066 | if (!empty($this->options['mimefile']) && file_exists($this->options['mimefile'])) { |
||
1067 | $file = $this->options['mimefile']; |
||
1068 | } elseif (elFinder::$defaultMimefile && file_exists(elFinder::$defaultMimefile)) { |
||
1069 | $file = elFinder::$defaultMimefile; |
||
1070 | } elseif (file_exists(dirname(__FILE__).DIRECTORY_SEPARATOR.'mime.types')) { |
||
1071 | $file = dirname(__FILE__).DIRECTORY_SEPARATOR.'mime.types'; |
||
1072 | } elseif (file_exists(dirname(dirname(__FILE__)).DIRECTORY_SEPARATOR.'mime.types')) { |
||
1073 | $file = dirname(dirname(__FILE__)).DIRECTORY_SEPARATOR.'mime.types'; |
||
1074 | } |
||
1075 | |||
1076 | if ($file && file_exists($file)) { |
||
1077 | $mimecf = file($file); |
||
1078 | |||
1079 | foreach ($mimecf as $line_num => $line) { |
||
1080 | if (!preg_match('/^\s*#/', $line)) { |
||
1081 | $mime = preg_split('/\s+/', $line, -1, PREG_SPLIT_NO_EMPTY); |
||
1082 | for ($i = 1, $size = count($mime); $i < $size ; $i++) { |
||
1083 | if (!isset(self::$mimetypes[$mime[$i]])) { |
||
1084 | self::$mimetypes[$mime[$i]] = $mime[0]; |
||
1085 | } |
||
1086 | } |
||
1087 | } |
||
1088 | } |
||
1089 | } |
||
1090 | } |
||
1091 | |||
1092 | $this->rootName = empty($this->options['alias']) ? $this->basenameCE($this->root) : $this->options['alias']; |
||
1093 | |||
1094 | // This get's triggered if $this->root == '/' and alias is empty. |
||
1095 | // Maybe modify _basename instead? |
||
1096 | if ($this->rootName === '') $this->rootName = $this->separator; |
||
1097 | |||
1098 | $root = $this->stat($this->root); |
||
1099 | |||
1100 | 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
Loading history...
|
|||
1101 | return $this->setError('Root folder does not exist.'); |
||
1102 | } |
||
1103 | if (!$root['read'] && !$root['write']) { |
||
1104 | return $this->setError('Root folder has not read and write permissions.'); |
||
1105 | } |
||
1106 | |||
1107 | // debug($root); |
||
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.
Loading history...
|
|||
1108 | |||
1109 | if ($root['read']) { |
||
1110 | // check startPath - path to open by default instead of root |
||
1111 | $startPath = $this->options['startPath']? $this->normpathCE($this->options['startPath']) : ''; |
||
1112 | if ($startPath) { |
||
1113 | $start = $this->stat($startPath); |
||
1114 | if (!empty($start) |
||
1115 | && $start['mime'] == 'directory' |
||
1116 | && $start['read'] |
||
1117 | && empty($start['hidden']) |
||
1118 | && $this->inpathCE($startPath, $this->root)) { |
||
1119 | $this->startPath = $startPath; |
||
1120 | if (substr($this->startPath, -1, 1) == $this->options['separator']) { |
||
1121 | $this->startPath = substr($this->startPath, 0, -1); |
||
1122 | } |
||
1123 | } |
||
1124 | } |
||
1125 | } else { |
||
1126 | $this->options['URL'] = ''; |
||
1127 | $this->options['tmbURL'] = ''; |
||
1128 | $this->options['tmbPath'] = ''; |
||
1129 | // read only volume |
||
1130 | array_unshift($this->attributes, array( |
||
1131 | 'pattern' => '/.*/', |
||
1132 | 'read' => false |
||
1133 | )); |
||
1134 | } |
||
1135 | $this->treeDeep = $this->options['treeDeep'] > 0 ? (int)$this->options['treeDeep'] : 1; |
||
1136 | $this->tmbSize = $this->options['tmbSize'] > 0 ? (int)$this->options['tmbSize'] : 48; |
||
1137 | $this->URL = $this->options['URL']; |
||
1138 | if ($this->URL && preg_match("|[^/?&=]$|", $this->URL)) { |
||
1139 | $this->URL .= '/'; |
||
1140 | } |
||
1141 | if (strtolower($this->options['dirUrlOwn']) === 'auto') { |
||
1142 | $this->options['dirUrlOwn'] = $this->URL? false : true; |
||
1143 | } else { |
||
1144 | $this->options['dirUrlOwn'] = (bool)$this->options['dirUrlOwn']; |
||
1145 | } |
||
1146 | |||
1147 | $this->tmbURL = !empty($this->options['tmbURL']) ? $this->options['tmbURL'] : ''; |
||
1148 | if ($this->tmbURL && $this->tmbURL !== 'self' && preg_match("|[^/?&=]$|", $this->tmbURL)) { |
||
1149 | $this->tmbURL .= '/'; |
||
1150 | } |
||
1151 | |||
1152 | $this->nameValidator = !empty($this->options['acceptedName']) && (is_string($this->options['acceptedName']) || is_callable($this->options['acceptedName'])) |
||
1153 | ? $this->options['acceptedName'] |
||
1154 | : ''; |
||
1155 | |||
1156 | $this->_checkArchivers(); |
||
1157 | // manual control archive types to create |
||
1158 | if (!empty($this->options['archiveMimes']) && is_array($this->options['archiveMimes'])) { |
||
1159 | foreach ($this->archivers['create'] as $mime => $v) { |
||
1160 | if (!in_array($mime, $this->options['archiveMimes'])) { |
||
1161 | unset($this->archivers['create'][$mime]); |
||
1162 | } |
||
1163 | } |
||
1164 | } |
||
1165 | |||
1166 | // manualy add archivers |
||
1167 | if (!empty($this->options['archivers']['create']) && is_array($this->options['archivers']['create'])) { |
||
1168 | foreach ($this->options['archivers']['create'] as $mime => $conf) { |
||
1169 | if (strpos($mime, 'application/') === 0 |
||
1170 | && !empty($conf['cmd']) |
||
1171 | && isset($conf['argc']) |
||
1172 | && !empty($conf['ext']) |
||
1173 | && !isset($this->archivers['create'][$mime])) { |
||
1174 | $this->archivers['create'][$mime] = $conf; |
||
1175 | } |
||
1176 | } |
||
1177 | } |
||
1178 | |||
1179 | if (!empty($this->options['archivers']['extract']) && is_array($this->options['archivers']['extract'])) { |
||
1180 | foreach ($this->options['archivers']['extract'] as $mime => $conf) { |
||
1181 | if (strpos($mime, 'application/') === 0 |
||
1182 | && !empty($conf['cmd']) |
||
1183 | && isset($conf['argc']) |
||
1184 | && !empty($conf['ext']) |
||
1185 | && !isset($this->archivers['extract'][$mime])) { |
||
1186 | $this->archivers['extract'][$mime] = $conf; |
||
1187 | } |
||
1188 | } |
||
1189 | } |
||
1190 | |||
1191 | $this->configure(); |
||
1192 | |||
1193 | // Normarize disabled (array_merge`for type array of JSON) |
||
1194 | $this->disabled = array_values(array_unique($this->disabled)); |
||
1195 | |||
1196 | // fix sync interval |
||
1197 | if ($this->options['syncMinMs'] !== 0) { |
||
1198 | $this->options['syncMinMs'] = max($this->options[$this->options['syncChkAsTs']? 'tsPlSleep' : 'lsPlSleep'] * 1000, intval($this->options['syncMinMs'])); |
||
1199 | } |
||
1200 | |||
1201 | return $this->mounted = true; |
||
1202 | } |
||
1203 | |||
1204 | /** |
||
1205 | * Some "unmount" stuffs - may be required by virtual fs |
||
1206 | * |
||
1207 | * @return void |
||
1208 | * @author Dmitry (dio) Levashov |
||
1209 | **/ |
||
1210 | public function umount() { |
||
1211 | } |
||
1212 | |||
1213 | /** |
||
1214 | * Return error message from last failed action |
||
1215 | * |
||
1216 | * @return array |
||
1217 | * @author Dmitry (dio) Levashov |
||
1218 | **/ |
||
1219 | public function error() { |
||
1220 | return $this->error; |
||
1221 | } |
||
1222 | |||
1223 | /** |
||
1224 | * Return is uploadable that given file name |
||
1225 | * |
||
1226 | * @param string $name file name |
||
1227 | * @param bool $allowUnknown |
||
1228 | * @return bool |
||
1229 | * @author Naoki Sawada |
||
1230 | **/ |
||
1231 | public function isUploadableByName($name, $allowUnknown = true) { |
||
1232 | $mimeByName = elFinderVolumeDriver::mimetypeInternalDetect($name); |
||
1233 | return (($allowUnknown && $mimeByName === 'unknown') || $this->allowPutMime($mimeByName)); |
||
1234 | } |
||
1235 | |||
1236 | /** |
||
1237 | * Return Extention/MIME Table (elFinderVolumeDriver::$mimetypes) |
||
1238 | * |
||
1239 | * @return array |
||
1240 | * @author Naoki Sawada |
||
1241 | */ |
||
1242 | public function getMimeTable() { |
||
1243 | // load mime.types |
||
1244 | ! elFinderVolumeDriver::$mimetypesLoaded && elFinderVolumeDriver::mimetypeInternalDetect(); |
||
1245 | return elFinderVolumeDriver::$mimetypes; |
||
1246 | } |
||
1247 | |||
1248 | /** |
||
1249 | * Return file extention detected by MIME type |
||
1250 | * |
||
1251 | * @param string $mime MIME type |
||
1252 | * @param string $suffix Additional suffix |
||
1253 | * @return string |
||
1254 | * @author Naoki Sawada |
||
1255 | */ |
||
1256 | public function getExtentionByMime($mime, $suffix = '') { |
||
1257 | static $extTable = null; |
||
1258 | |||
1259 | if (is_null($extTable)) { |
||
1260 | $extTable = array_flip(array_unique($this->getMimeTable())); |
||
1261 | foreach(array_keys($this->options['mimeMap']) as $pair) { |
||
1262 | list($ext, $_mime) = explode(':', $pair); |
||
1263 | if (! isset($extTable[$_mime])) { |
||
1264 | $extTable[$_mime] = $ext; |
||
1265 | } |
||
1266 | } |
||
1267 | } |
||
1268 | |||
1269 | if ($mime && isset($extTable[$mime])) { |
||
1270 | return $suffix? ($extTable[$mime] . $suffix) : $extTable[$mime]; |
||
1271 | } |
||
1272 | return ''; |
||
1273 | } |
||
1274 | |||
1275 | /** |
||
1276 | * Set mimetypes allowed to display to client |
||
1277 | * |
||
1278 | * @param array $mimes |
||
1279 | * @return void |
||
1280 | * @author Dmitry (dio) Levashov |
||
1281 | **/ |
||
1282 | public function setMimesFilter($mimes) { |
||
1283 | if (is_array($mimes)) { |
||
1284 | $this->onlyMimes = $mimes; |
||
1285 | } |
||
1286 | } |
||
1287 | |||
1288 | /** |
||
1289 | * Return root folder hash |
||
1290 | * |
||
1291 | * @return string |
||
1292 | * @author Dmitry (dio) Levashov |
||
1293 | **/ |
||
1294 | public function root() { |
||
1295 | return $this->encode($this->root); |
||
1296 | } |
||
1297 | |||
1298 | /** |
||
1299 | * Return target path hash |
||
1300 | * |
||
1301 | * @param string $path |
||
1302 | * @param string $name |
||
1303 | * @author Naoki Sawada |
||
1304 | * @return string |
||
1305 | */ |
||
1306 | public function getHash($path, $name = '') { |
||
1307 | if ($name !== '') { |
||
1308 | $path = $this->joinPathCE($path, $name); |
||
1309 | } |
||
1310 | return $this->encode($path); |
||
1311 | } |
||
1312 | |||
1313 | /** |
||
1314 | * Return decoded path of target hash |
||
1315 | * This method do not check the stat of target |
||
1316 | * Use method `realpath()` to do check of the stat of target |
||
1317 | * |
||
1318 | * @param string $hash |
||
1319 | * @author Naoki Sawada |
||
1320 | * @return string |
||
1321 | */ |
||
1322 | public function getPath($hash) { |
||
1323 | return $this->decode($hash); |
||
1324 | } |
||
1325 | |||
1326 | /** |
||
1327 | * Return root or startPath hash |
||
1328 | * |
||
1329 | * @return string |
||
1330 | * @author Dmitry (dio) Levashov |
||
1331 | **/ |
||
1332 | public function defaultPath() { |
||
1333 | return $this->encode($this->startPath ? $this->startPath : $this->root); |
||
1334 | } |
||
1335 | |||
1336 | /** |
||
1337 | * Return volume options required by client: |
||
1338 | * |
||
1339 | * @param $hash |
||
1340 | * @return array |
||
1341 | * @author Dmitry (dio) Levashov |
||
1342 | */ |
||
1343 | public function options($hash) { |
||
1344 | $create = $createext = array(); |
||
1345 | if (isset($this->archivers['create']) && is_array($this->archivers['create'])) { |
||
1346 | foreach($this->archivers['create'] as $m => $v) { |
||
1347 | $create[] = $m; |
||
1348 | $createext[$m] = $v['ext']; |
||
1349 | } |
||
1350 | } |
||
1351 | $opts = array( |
||
1352 | 'path' => $hash? $this->path($hash) : '', |
||
1353 | 'url' => $this->URL, |
||
1354 | 'tmbUrl' => (! $this->imgLib && $this->options['tmbFbSelf'])? 'self' : $this->tmbURL, |
||
1355 | 'disabled' => $this->disabled, |
||
1356 | 'separator' => $this->separator, |
||
1357 | 'copyOverwrite' => intval($this->options['copyOverwrite']), |
||
1358 | 'uploadOverwrite' => intval($this->options['uploadOverwrite']), |
||
1359 | 'uploadMaxSize' => intval($this->uploadMaxSize), |
||
1360 | 'uploadMaxConn' => intval($this->options['uploadMaxConn']), |
||
1361 | 'uploadMime' => array( |
||
1362 | 'firstOrder' => isset($this->uploadOrder[0])? $this->uploadOrder[0] : 'deny', |
||
1363 | 'allow' => $this->uploadAllow, |
||
1364 | 'deny' => $this->uploadDeny |
||
1365 | ), |
||
1366 | 'dispInlineRegex' => $this->options['dispInlineRegex'], |
||
1367 | 'jpgQuality' => intval($this->options['jpgQuality']), |
||
1368 | 'archivers' => array( |
||
1369 | 'create' => $create, |
||
1370 | 'extract' => isset($this->archivers['extract']) && is_array($this->archivers['extract']) ? array_keys($this->archivers['extract']) : array(), |
||
1371 | 'createext' => $createext |
||
1372 | ), |
||
1373 | 'uiCmdMap' => (isset($this->options['uiCmdMap']) && is_array($this->options['uiCmdMap']))? $this->options['uiCmdMap'] : array(), |
||
1374 | 'syncChkAsTs' => intval($this->options['syncChkAsTs']), |
||
1375 | 'syncMinMs' => intval($this->options['syncMinMs']), |
||
1376 | 'i18nFolderName' => intval($this->options['i18nFolderName']) |
||
1377 | ); |
||
1378 | if ($hash === null) { |
||
1379 | // call from getRootStatExtra() |
||
1380 | if (! empty($this->options['icon'])) { |
||
1381 | $opts['icon'] = $this->options['icon']; |
||
1382 | } |
||
1383 | if (! empty($this->options['rootCssClass'])) { |
||
1384 | $opts['csscls'] = $this->options['rootCssClass']; |
||
1385 | } |
||
1386 | if (isset($this->options['netkey'])) { |
||
1387 | $opts['netkey'] = $this->options['netkey']; |
||
1388 | } |
||
1389 | } |
||
1390 | return $opts; |
||
1391 | } |
||
1392 | |||
1393 | /** |
||
1394 | * Get option value of this volume |
||
1395 | * |
||
1396 | * @param string $name target option name |
||
1397 | * @return NULL|mixed target option value |
||
1398 | * @author Naoki Sawada |
||
1399 | */ |
||
1400 | public function getOption($name) { |
||
1401 | return isset($this->options[$name])? $this->options[$name] : null; |
||
1402 | } |
||
1403 | |||
1404 | /** |
||
1405 | * Get plugin values of this options |
||
1406 | * |
||
1407 | * @param string $name Plugin name |
||
1408 | * @return NULL|array Plugin values |
||
1409 | * @author Naoki Sawada |
||
1410 | */ |
||
1411 | public function getOptionsPlugin($name = '') { |
||
1412 | if ($name) { |
||
1413 | return isset($this->options['plugin'][$name])? $this->options['plugin'][$name] : array(); |
||
1414 | } else { |
||
1415 | return $this->options['plugin']; |
||
1416 | } |
||
1417 | } |
||
1418 | |||
1419 | /** |
||
1420 | * Return true if command disabled in options |
||
1421 | * |
||
1422 | * @param string $cmd command name |
||
1423 | * @return bool |
||
1424 | * @author Dmitry (dio) Levashov |
||
1425 | **/ |
||
1426 | public function commandDisabled($cmd) { |
||
1427 | return in_array($cmd, $this->disabled); |
||
1428 | } |
||
1429 | |||
1430 | /** |
||
1431 | * Return true if mime is required mimes list |
||
1432 | * |
||
1433 | * @param string $mime mime type to check |
||
1434 | * @param array $mimes allowed mime types list or not set to use client mimes list |
||
1435 | * @param bool|null $empty what to return on empty list |
||
1436 | * @return bool|null |
||
1437 | * @author Dmitry (dio) Levashov |
||
1438 | * @author Troex Nevelin |
||
1439 | **/ |
||
1440 | public function mimeAccepted($mime, $mimes = null, $empty = true) { |
||
1441 | $mimes = is_array($mimes) ? $mimes : $this->onlyMimes; |
||
1442 | if (empty($mimes)) { |
||
1443 | return $empty; |
||
1444 | } |
||
1445 | return $mime == 'directory' |
||
1446 | || in_array('all', $mimes) |
||
1447 | || in_array('All', $mimes) |
||
1448 | || in_array($mime, $mimes) |
||
1449 | || in_array(substr($mime, 0, strpos($mime, '/')), $mimes); |
||
1450 | } |
||
1451 | |||
1452 | /** |
||
1453 | * Return true if voume is readable. |
||
1454 | * |
||
1455 | * @return bool |
||
1456 | * @author Dmitry (dio) Levashov |
||
1457 | **/ |
||
1458 | public function isReadable() { |
||
1459 | $stat = $this->stat($this->root); |
||
1460 | return $stat['read']; |
||
1461 | } |
||
1462 | |||
1463 | /** |
||
1464 | * Return true if copy from this volume allowed |
||
1465 | * |
||
1466 | * @return bool |
||
1467 | * @author Dmitry (dio) Levashov |
||
1468 | **/ |
||
1469 | public function copyFromAllowed() { |
||
1470 | return !!$this->options['copyFrom']; |
||
1471 | } |
||
1472 | |||
1473 | /** |
||
1474 | * Return file path related to root with convert encoging |
||
1475 | * |
||
1476 | * @param string $hash file hash |
||
1477 | * @return string |
||
1478 | * @author Dmitry (dio) Levashov |
||
1479 | **/ |
||
1480 | public function path($hash) { |
||
1481 | return $this->convEncOut($this->_path($this->convEncIn($this->decode($hash)))); |
||
1482 | } |
||
1483 | |||
1484 | /** |
||
1485 | * Return file real path if file exists |
||
1486 | * |
||
1487 | * @param string $hash file hash |
||
1488 | * @return string | false |
||
1489 | * @author Dmitry (dio) Levashov |
||
1490 | **/ |
||
1491 | public function realpath($hash) { |
||
1492 | $path = $this->decode($hash); |
||
1493 | return $this->stat($path) ? $path : false; |
||
1494 | } |
||
1495 | |||
1496 | /** |
||
1497 | * Return list of moved/overwrited files |
||
1498 | * |
||
1499 | * @return array |
||
1500 | * @author Dmitry (dio) Levashov |
||
1501 | **/ |
||
1502 | public function removed() { |
||
1503 | return $this->removed; |
||
1504 | } |
||
1505 | |||
1506 | /** |
||
1507 | * Return list of added files |
||
1508 | * |
||
1509 | * @deprecated |
||
1510 | * @return array |
||
1511 | * @author Naoki Sawada |
||
1512 | **/ |
||
1513 | public function added() { |
||
1514 | return $this->added; |
||
1515 | } |
||
1516 | |||
1517 | /** |
||
1518 | * Clean removed files list |
||
1519 | * |
||
1520 | * @return void |
||
1521 | * @author Dmitry (dio) Levashov |
||
1522 | **/ |
||
1523 | public function resetRemoved() { |
||
1524 | $this->resetResultStat(); |
||
1525 | } |
||
1526 | |||
1527 | /** |
||
1528 | * Clean added/removed files list |
||
1529 | * |
||
1530 | * @return void |
||
1531 | **/ |
||
1532 | public function resetResultStat() { |
||
1533 | $this->removed = array(); |
||
1534 | $this->added = array(); |
||
1535 | } |
||
1536 | |||
1537 | /** |
||
1538 | * Return file/dir hash or first founded child hash with required attr == $val |
||
1539 | * |
||
1540 | * @param string $hash file hash |
||
1541 | * @param string $attr attribute name |
||
1542 | * @param bool $val attribute value |
||
1543 | * @return string|false |
||
1544 | * @author Dmitry (dio) Levashov |
||
1545 | **/ |
||
1546 | public function closest($hash, $attr, $val) { |
||
1547 | return ($path = $this->closestByAttr($this->decode($hash), $attr, $val)) ? $this->encode($path) : false; |
||
1548 | } |
||
1549 | |||
1550 | /** |
||
1551 | * Return file info or false on error |
||
1552 | * |
||
1553 | * @param string $hash file hash |
||
1554 | * @return array|false |
||
1555 | * @internal param bool $realpath add realpath field to file info |
||
1556 | * @author Dmitry (dio) Levashov |
||
1557 | */ |
||
1558 | public function file($hash) { |
||
1559 | $path = $this->decode($hash); |
||
1560 | $isRoot = ($path == $this->root); |
||
1561 | |||
1562 | $file = $this->stat($path); |
||
1563 | |||
1564 | if ($isRoot) { |
||
1565 | $file = array_merge($file, $this->getRootStatExtra()); |
||
1566 | } |
||
1567 | |||
1568 | return ($file) ? $file : $this->setError(elFinder::ERROR_FILE_NOT_FOUND); |
||
1569 | } |
||
1570 | |||
1571 | /** |
||
1572 | * Return folder info |
||
1573 | * |
||
1574 | * @param string $hash folder hash |
||
1575 | * @param bool $resolveLink |
||
1576 | * @return array|false |
||
1577 | * @internal param bool $hidden return hidden file info |
||
1578 | * @author Dmitry (dio) Levashov |
||
1579 | */ |
||
1580 | public function dir($hash, $resolveLink=false) { |
||
1581 | if (($dir = $this->file($hash)) == false) { |
||
1582 | return $this->setError(elFinder::ERROR_DIR_NOT_FOUND); |
||
1583 | } |
||
1584 | |||
1585 | if ($resolveLink && !empty($dir['thash'])) { |
||
1586 | $dir = $this->file($dir['thash']); |
||
1587 | } |
||
1588 | |||
1589 | return $dir && $dir['mime'] == 'directory' && empty($dir['hidden']) |
||
1590 | ? $dir |
||
1591 | : $this->setError(elFinder::ERROR_NOT_DIR); |
||
1592 | } |
||
1593 | |||
1594 | /** |
||
1595 | * Return directory content or false on error |
||
1596 | * |
||
1597 | * @param string $hash file hash |
||
1598 | * @return array|false |
||
1599 | * @author Dmitry (dio) Levashov |
||
1600 | **/ |
||
1601 | public function scandir($hash) { |
||
1602 | if (($dir = $this->dir($hash)) == false) { |
||
1603 | return false; |
||
1604 | } |
||
1605 | |||
1606 | return $dir['read'] |
||
1607 | ? $this->getScandir($this->decode($hash)) |
||
1608 | : $this->setError(elFinder::ERROR_PERM_DENIED); |
||
1609 | } |
||
1610 | |||
1611 | /** |
||
1612 | * Return dir files names list |
||
1613 | * |
||
1614 | * @param string $hash file hash |
||
1615 | * @param null $intersect |
||
1616 | * @return array |
||
1617 | * @author Dmitry (dio) Levashov |
||
1618 | */ |
||
1619 | public function ls($hash, $intersect = null) { |
||
1620 | if (($dir = $this->dir($hash)) == false || !$dir['read']) { |
||
1621 | return false; |
||
1622 | } |
||
1623 | |||
1624 | $list = array(); |
||
1625 | $path = $this->decode($hash); |
||
1626 | |||
1627 | $check = array(); |
||
1628 | if ($intersect) { |
||
1629 | $check = array_flip($intersect); |
||
1630 | } |
||
1631 | |||
1632 | foreach ($this->getScandir($path) as $stat) { |
||
1633 | 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
Loading history...
|
|||
1634 | $list[$stat['hash']] = $stat['name']; |
||
1635 | } |
||
1636 | } |
||
1637 | |||
1638 | return $list; |
||
1639 | } |
||
1640 | |||
1641 | /** |
||
1642 | * Return subfolders for required folder or false on error |
||
1643 | * |
||
1644 | * @param string $hash folder hash or empty string to get tree from root folder |
||
1645 | * @param int $deep subdir deep |
||
1646 | * @param string $exclude dir hash which subfolders must be exluded from result, required to not get stat twice on cwd subfolders |
||
1647 | * @return array|false |
||
1648 | * @author Dmitry (dio) Levashov |
||
1649 | **/ |
||
1650 | public function tree($hash='', $deep=0, $exclude='') { |
||
1651 | $path = $hash ? $this->decode($hash) : $this->root; |
||
1652 | |||
1653 | if (($dir = $this->stat($path)) == false || $dir['mime'] != 'directory') { |
||
1654 | return false; |
||
1655 | } |
||
1656 | |||
1657 | $dirs = $this->gettree($path, $deep > 0 ? $deep -1 : $this->treeDeep-1, $exclude ? $this->decode($exclude) : null); |
||
1658 | array_unshift($dirs, $dir); |
||
1659 | return $dirs; |
||
1660 | } |
||
1661 | |||
1662 | /** |
||
1663 | * Return part of dirs tree from required dir up to root dir |
||
1664 | * |
||
1665 | * @param string $hash directory hash |
||
1666 | * @param bool|null $lineal only lineal parents |
||
1667 | * @return array |
||
1668 | * @author Dmitry (dio) Levashov |
||
1669 | **/ |
||
1670 | public function parents($hash, $lineal = false) { |
||
1671 | if (($current = $this->dir($hash)) == false) { |
||
1672 | return false; |
||
1673 | } |
||
1674 | |||
1675 | $path = $this->decode($hash); |
||
1676 | $tree = array(); |
||
1677 | |||
1678 | 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
Loading history...
|
|||
1679 | $path = $this->dirnameCE($path); |
||
1680 | if (!($stat = $this->stat($path)) || !empty($stat['hidden']) || !$stat['read']) { |
||
1681 | return false; |
||
1682 | } |
||
1683 | |||
1684 | array_unshift($tree, $stat); |
||
1685 | 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) { }
Loading history...
|
|||
1686 | foreach ($this->gettree($path, 0) as $dir) { |
||
1687 | if (!in_array($dir, $tree)) { |
||
1688 | $tree[] = $dir; |
||
1689 | } |
||
1690 | } |
||
1691 | } |
||
1692 | } |
||
1693 | |||
1694 | return $tree ? $tree : array($current); |
||
1695 | } |
||
1696 | |||
1697 | /** |
||
1698 | * Create thumbnail for required file and return its name of false on failed |
||
1699 | * |
||
1700 | * @param $hash |
||
1701 | * @return false|string |
||
1702 | * @author Dmitry (dio) Levashov |
||
1703 | */ |
||
1704 | public function tmb($hash) { |
||
1705 | $path = $this->decode($hash); |
||
1706 | $stat = $this->stat($path); |
||
1707 | |||
1708 | if (isset($stat['tmb'])) { |
||
1709 | $res = $stat['tmb'] == "1" ? $this->createTmb($path, $stat) : $stat['tmb']; |
||
1710 | if (! $res) { |
||
1711 | list($type) = explode('/', $stat['mime']); |
||
1712 | $fallback = $this->options['resourcePath'] . DIRECTORY_SEPARATOR . strtolower($type) . '.png'; |
||
1713 | if (is_file($fallback)) { |
||
1714 | $res = $this->tmbname($stat); |
||
1715 | if (! copy($fallback, $this->tmbPath . DIRECTORY_SEPARATOR . $res)) { |
||
1716 | $res = false; |
||
1717 | } |
||
1718 | } |
||
1719 | } |
||
1720 | return $res; |
||
1721 | } |
||
1722 | return false; |
||
1723 | } |
||
1724 | |||
1725 | /** |
||
1726 | * Return file size / total directory size |
||
1727 | * |
||
1728 | * @param string file hash |
||
1729 | * @return int |
||
1730 | * @author Dmitry (dio) Levashov |
||
1731 | **/ |
||
1732 | public function size($hash) { |
||
1733 | return $this->countSize($this->decode($hash)); |
||
1734 | } |
||
1735 | |||
1736 | /** |
||
1737 | * Open file for reading and return file pointer |
||
1738 | * |
||
1739 | * @param string file hash |
||
1740 | * @return Resource |
||
1741 | * @author Dmitry (dio) Levashov |
||
1742 | **/ |
||
1743 | public function open($hash) { |
||
1744 | if (($file = $this->file($hash)) == false |
||
1745 | || $file['mime'] == 'directory') { |
||
1746 | return false; |
||
1747 | } |
||
1748 | |||
1749 | return $this->fopenCE($this->decode($hash), 'rb'); |
||
1750 | } |
||
1751 | |||
1752 | /** |
||
1753 | * Close file pointer |
||
1754 | * |
||
1755 | * @param Resource $fp file pointer |
||
1756 | * @param string $hash file hash |
||
1757 | * @return void |
||
1758 | * @author Dmitry (dio) Levashov |
||
1759 | **/ |
||
1760 | public function close($fp, $hash) { |
||
1761 | $this->fcloseCE($fp, $this->decode($hash)); |
||
1762 | } |
||
1763 | |||
1764 | /** |
||
1765 | * Create directory and return dir info |
||
1766 | * |
||
1767 | * @param string $dsthash destination directory hash |
||
1768 | * @param string $name directory name |
||
1769 | * @return array|false |
||
1770 | * @author Dmitry (dio) Levashov |
||
1771 | **/ |
||
1772 | public function mkdir($dsthash, $name) { |
||
1773 | if ($this->commandDisabled('mkdir')) { |
||
1774 | return $this->setError(elFinder::ERROR_PERM_DENIED); |
||
1775 | } |
||
1776 | |||
1777 | if (!$this->nameAccepted($name)) { |
||
1778 | return $this->setError(elFinder::ERROR_INVALID_NAME); |
||
1779 | } |
||
1780 | |||
1781 | if (($dir = $this->dir($dsthash)) == false) { |
||
1782 | return $this->setError(elFinder::ERROR_TRGDIR_NOT_FOUND, '#'.$dsthash); |
||
1783 | } |
||
1784 | |||
1785 | $path = $this->decode($dsthash); |
||
1786 | |||
1787 | if (!$dir['write'] || !$this->allowCreate($path, $name, true)) { |
||
1788 | return $this->setError(elFinder::ERROR_PERM_DENIED); |
||
1789 | } |
||
1790 | |||
1791 | $dst = $this->joinPathCE($path, $name); |
||
1792 | $stat = $this->stat($dst); |
||
1793 | if (!empty($stat)) { |
||
1794 | return $this->setError(elFinder::ERROR_EXISTS, $name); |
||
1795 | } |
||
1796 | $this->clearcache(); |
||
1797 | return ($path = $this->convEncOut($this->_mkdir($this->convEncIn($path), $this->convEncIn($name)))) ? $this->stat($path) : false; |
||
1798 | } |
||
1799 | |||
1800 | /** |
||
1801 | * Create empty file and return its info |
||
1802 | * |
||
1803 | * @param string $dst destination directory |
||
1804 | * @param string $name file name |
||
1805 | * @return array|false |
||
1806 | * @author Dmitry (dio) Levashov |
||
1807 | **/ |
||
1808 | public function mkfile($dst, $name) { |
||
1809 | if ($this->commandDisabled('mkfile')) { |
||
1810 | return $this->setError(elFinder::ERROR_PERM_DENIED); |
||
1811 | } |
||
1812 | |||
1813 | if (!$this->nameAccepted($name)) { |
||
1814 | return $this->setError(elFinder::ERROR_INVALID_NAME); |
||
1815 | } |
||
1816 | |||
1817 | $mimeByName = elFinderVolumeDriver::mimetypeInternalDetect($name); |
||
1818 | if ($mimeByName && $mimeByName !== 'unknown' && !$this->allowPutMime($mimeByName)) { |
||
1819 | return $this->setError(elFinder::ERROR_UPLOAD_FILE_MIME, $name); |
||
1820 | } |
||
1821 | |||
1822 | if (($dir = $this->dir($dst)) == false) { |
||
1823 | return $this->setError(elFinder::ERROR_TRGDIR_NOT_FOUND, '#'.$dst); |
||
1824 | } |
||
1825 | |||
1826 | $path = $this->decode($dst); |
||
1827 | |||
1828 | if (!$dir['write'] || !$this->allowCreate($path, $name, false)) { |
||
1829 | return $this->setError(elFinder::ERROR_PERM_DENIED); |
||
1830 | } |
||
1831 | |||
1832 | if ($this->stat($this->joinPathCE($path, $name))) { |
||
1833 | return $this->setError(elFinder::ERROR_EXISTS, $name); |
||
1834 | } |
||
1835 | |||
1836 | $this->clearcache(); |
||
1837 | return ($path = $this->convEncOut($this->_mkfile($this->convEncIn($path), $this->convEncIn($name)))) ? $this->stat($path) : false; |
||
1838 | } |
||
1839 | |||
1840 | /** |
||
1841 | * Rename file and return file info |
||
1842 | * |
||
1843 | * @param string $hash file hash |
||
1844 | * @param string $name new file name |
||
1845 | * @return array|false |
||
1846 | * @author Dmitry (dio) Levashov |
||
1847 | **/ |
||
1848 | public function rename($hash, $name) { |
||
1849 | if ($this->commandDisabled('rename')) { |
||
1850 | return $this->setError(elFinder::ERROR_PERM_DENIED); |
||
1851 | } |
||
1852 | |||
1853 | if (!$this->nameAccepted($name)) { |
||
1854 | return $this->setError(elFinder::ERROR_INVALID_NAME, $name); |
||
1855 | } |
||
1856 | |||
1857 | $mimeByName = elFinderVolumeDriver::mimetypeInternalDetect($name); |
||
1858 | if ($mimeByName && $mimeByName !== 'unknown' && !$this->allowPutMime($mimeByName)) { |
||
1859 | return $this->setError(elFinder::ERROR_UPLOAD_FILE_MIME, $name); |
||
1860 | } |
||
1861 | |||
1862 | if (!($file = $this->file($hash))) { |
||
1863 | return $this->setError(elFinder::ERROR_FILE_NOT_FOUND); |
||
1864 | } |
||
1865 | |||
1866 | if ($name === $file['name']) { |
||
1867 | return $file; |
||
1868 | } |
||
1869 | |||
1870 | if (!empty($file['locked'])) { |
||
1871 | return $this->setError(elFinder::ERROR_LOCKED, $file['name']); |
||
1872 | } |
||
1873 | |||
1874 | $path = $this->decode($hash); |
||
1875 | $dir = $this->dirnameCE($path); |
||
1876 | $stat = $this->stat($this->joinPathCE($dir, $name)); |
||
1877 | 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
Loading history...
|
|||
1878 | return $this->setError(elFinder::ERROR_EXISTS, $name); |
||
1879 | } |
||
1880 | |||
1881 | if (!$this->allowCreate($dir, $name, ($file['mime'] === 'directory'))) { |
||
1882 | return $this->setError(elFinder::ERROR_PERM_DENIED); |
||
1883 | } |
||
1884 | |||
1885 | $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);
Loading history...
|
|||
1886 | |||
1887 | |||
1888 | if ($path = $this->convEncOut($this->_move($this->convEncIn($path), $this->convEncIn($dir), $this->convEncIn($name)))) { |
||
1889 | $this->clearcache(); |
||
1890 | return $this->stat($path); |
||
1891 | } |
||
1892 | return false; |
||
1893 | } |
||
1894 | |||
1895 | /** |
||
1896 | * Create file copy with suffix "copy number" and return its info |
||
1897 | * |
||
1898 | * @param string $hash file hash |
||
1899 | * @param string $suffix suffix to add to file name |
||
1900 | * @return array|false |
||
1901 | * @author Dmitry (dio) Levashov |
||
1902 | **/ |
||
1903 | public function duplicate($hash, $suffix='copy') { |
||
1904 | if ($this->commandDisabled('duplicate')) { |
||
1905 | return $this->setError(elFinder::ERROR_COPY, '#'.$hash, elFinder::ERROR_PERM_DENIED); |
||
1906 | } |
||
1907 | |||
1908 | if (($file = $this->file($hash)) == false) { |
||
1909 | return $this->setError(elFinder::ERROR_COPY, elFinder::ERROR_FILE_NOT_FOUND); |
||
1910 | } |
||
1911 | |||
1912 | $path = $this->decode($hash); |
||
1913 | $dir = $this->dirnameCE($path); |
||
1914 | $name = $this->uniqueName($dir, $file['name'], sprintf($this->options['duplicateSuffix'], $suffix)); |
||
1915 | |||
1916 | if (!$this->allowCreate($dir, $name, ($file['mime'] === 'directory'))) { |
||
1917 | return $this->setError(elFinder::ERROR_PERM_DENIED); |
||
1918 | } |
||
1919 | |||
1920 | return ($path = $this->copy($path, $dir, $name)) == false |
||
1921 | ? false |
||
1922 | : $this->stat($path); |
||
0 ignored issues
–
show
It seems like
$path defined by $this->copy($path, $dir, $name) on line 1920 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.
Loading history...
|
|||
1923 | } |
||
1924 | |||
1925 | /** |
||
1926 | * Save uploaded file. |
||
1927 | * On success return array with new file stat and with removed file hash (if existed file was replaced) |
||
1928 | * |
||
1929 | * @param Resource $fp file pointer |
||
1930 | * @param string $dst destination folder hash |
||
1931 | * @param $name |
||
1932 | * @param string $tmpname file tmp name - required to detect mime type |
||
1933 | * @param array $hashes exists files hash array with filename as key |
||
1934 | * @return array|false |
||
1935 | * @internal param string $src file name |
||
1936 | * @author Dmitry (dio) Levashov |
||
1937 | */ |
||
1938 | public function upload($fp, $dst, $name, $tmpname, $hashes = array()) { |
||
0 ignored issues
–
show
upload 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);
}
}
Loading history...
|
|||
1939 | if ($this->commandDisabled('upload')) { |
||
1940 | return $this->setError(elFinder::ERROR_PERM_DENIED); |
||
1941 | } |
||
1942 | |||
1943 | if (($dir = $this->dir($dst)) == false) { |
||
1944 | return $this->setError(elFinder::ERROR_TRGDIR_NOT_FOUND, '#'.$dst); |
||
1945 | } |
||
1946 | |||
1947 | if (!$dir['write']) { |
||
1948 | return $this->setError(elFinder::ERROR_PERM_DENIED); |
||
1949 | } |
||
1950 | |||
1951 | if (!$this->nameAccepted($name)) { |
||
1952 | return $this->setError(elFinder::ERROR_INVALID_NAME); |
||
1953 | } |
||
1954 | |||
1955 | $mime = $this->mimetype($this->mimeDetect == 'internal' ? $name : $tmpname, $name); |
||
1956 | $mimeByName = ''; |
||
1957 | if ($this->mimeDetect !== 'internal') { |
||
1958 | $mimeByName = elFinderVolumeDriver::mimetypeInternalDetect($name); |
||
1959 | if ($mime == 'unknown') { |
||
1960 | $mime = $mimeByName; |
||
1961 | } |
||
1962 | } |
||
1963 | |||
1964 | if (!$this->allowPutMime($mime) || ($mimeByName && $mimeByName !== 'unknown' && !$this->allowPutMime($mimeByName))) { |
||
1965 | return $this->setError(elFinder::ERROR_UPLOAD_FILE_MIME); |
||
1966 | } |
||
1967 | |||
1968 | $tmpsize = sprintf('%u', filesize($tmpname)); |
||
1969 | if ($this->uploadMaxSize > 0 && $tmpsize > $this->uploadMaxSize) { |
||
1970 | return $this->setError(elFinder::ERROR_UPLOAD_FILE_SIZE); |
||
1971 | } |
||
1972 | |||
1973 | $dstpath = $this->decode($dst); |
||
1974 | if (isset($hashes[$name])) { |
||
1975 | $test = $this->decode($hashes[$name]); |
||
1976 | } else { |
||
1977 | $test = $this->joinPathCE($dstpath, $name); |
||
1978 | } |
||
1979 | |||
1980 | $file = $this->stat($test); |
||
1981 | $this->clearcache(); |
||
1982 | |||
1983 | 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
Loading history...
|
|||
1984 | // check POST data `overwrite` for 3rd party uploader |
||
1985 | $overwrite = isset($_POST['overwrite'])? (bool)$_POST['overwrite'] : $this->options['uploadOverwrite']; |
||
1986 | if ($overwrite) { |
||
1987 | if (!$file['write']) { |
||
1988 | return $this->setError(elFinder::ERROR_PERM_DENIED); |
||
1989 | } elseif ($file['mime'] == 'directory') { |
||
1990 | return $this->setError(elFinder::ERROR_NOT_REPLACE, $name); |
||
1991 | } |
||
1992 | $this->remove($test); |
||
1993 | } else { |
||
1994 | $name = $this->uniqueName($dstpath, $name, '-', false); |
||
1995 | } |
||
1996 | } |
||
1997 | |||
1998 | $stat = array( |
||
1999 | 'mime' => $mime, |
||
2000 | 'width' => 0, |
||
2001 | 'height' => 0, |
||
2002 | 'size' => $tmpsize); |
||
2003 | |||
2004 | // $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.
Loading history...
|
|||
2005 | if (strpos($mime, 'image') === 0 && ($s = getimagesize($tmpname))) { |
||
2006 | $stat['width'] = $s[0]; |
||
2007 | $stat['height'] = $s[1]; |
||
2008 | } |
||
2009 | // $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.
Loading history...
|
|||
2010 | if (($path = $this->saveCE($fp, $dstpath, $name, $stat)) == false) { |
||
2011 | return false; |
||
2012 | } |
||
2013 | |||
2014 | $stat = $this->stat($path); |
||
0 ignored issues
–
show
It seems like
$path defined by $this->saveCE($fp, $dstpath, $name, $stat) on line 2010 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.
Loading history...
|
|||
2015 | // Try get URL |
||
2016 | if (empty($stat['url']) && ($url = $this->getContentUrl($stat['hash']))) { |
||
2017 | $stat['url'] = $url; |
||
2018 | } |
||
2019 | |||
2020 | return $stat; |
||
2021 | } |
||
2022 | |||
2023 | /** |
||
2024 | * Paste files |
||
2025 | * |
||
2026 | * @param Object $volume source volume |
||
2027 | * @param $src |
||
2028 | * @param string $dst destination dir hash |
||
2029 | * @param bool $rmSrc remove source after copy? |
||
2030 | * @param array $hashes |
||
2031 | * @return array|false |
||
2032 | * @internal param string $source file hash |
||
2033 | * @author Dmitry (dio) Levashov |
||
2034 | */ |
||
2035 | public function paste($volume, $src, $dst, $rmSrc = false, $hashes = array()) { |
||
2036 | $err = $rmSrc ? elFinder::ERROR_MOVE : elFinder::ERROR_COPY; |
||
2037 | |||
2038 | if ($this->commandDisabled('paste')) { |
||
2039 | return $this->setError($err, '#'.$src, elFinder::ERROR_PERM_DENIED); |
||
2040 | } |
||
2041 | |||
2042 | if (($file = $volume->file($src, $rmSrc)) == false) { |
||
2043 | return $this->setError($err, '#'.$src, elFinder::ERROR_FILE_NOT_FOUND); |
||
2044 | } |
||
2045 | |||
2046 | $name = $file['name']; |
||
2047 | $errpath = $volume->path($file['hash']); |
||
2048 | |||
2049 | if (($dir = $this->dir($dst)) == false) { |
||
2050 | return $this->setError($err, $errpath, elFinder::ERROR_TRGDIR_NOT_FOUND, '#'.$dst); |
||
2051 | } |
||
2052 | |||
2053 | if (!$dir['write'] || !$file['read']) { |
||
2054 | return $this->setError($err, $errpath, elFinder::ERROR_PERM_DENIED); |
||
2055 | } |
||
2056 | |||
2057 | $destination = $this->decode($dst); |
||
2058 | |||
2059 | if (($test = $volume->closest($src, $rmSrc ? 'locked' : 'read', $rmSrc))) { |
||
2060 | return $rmSrc |
||
2061 | ? $this->setError($err, $errpath, elFinder::ERROR_LOCKED, $volume->path($test)) |
||
2062 | : $this->setError($err, $errpath, !empty($file['thash'])? elFinder::ERROR_PERM_DENIED : elFinder::ERROR_MKOUTLINK); |
||
2063 | } |
||
2064 | |||
2065 | if (isset($hashes[$name])) { |
||
2066 | $test = $this->decode($hashes[$name]); |
||
2067 | } else { |
||
2068 | $test = $this->joinPathCE($destination, $name); |
||
2069 | } |
||
2070 | $stat = $this->stat($test); |
||
2071 | $this->clearcache(); |
||
2072 | $dstDirExists = false; |
||
2073 | 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
Loading history...
|
|||
2074 | if ($this->options['copyOverwrite']) { |
||
2075 | // do not replace file with dir or dir with file |
||
2076 | if (!$this->isSameType($file['mime'], $stat['mime'])) { |
||
2077 | return $this->setError(elFinder::ERROR_NOT_REPLACE, $this->path($stat['hash'])); |
||
2078 | } |
||
2079 | // existed file is not writable |
||
2080 | if (!$stat['write']) { |
||
2081 | return $this->setError($err, $errpath, elFinder::ERROR_PERM_DENIED); |
||
2082 | } |
||
2083 | // existed file locked or has locked child |
||
2084 | if (($locked = $this->closestByAttr($test, 'locked', true))) { |
||
2085 | $stat = $this->stat($locked); |
||
2086 | return $this->setError(elFinder::ERROR_LOCKED, $this->path($stat['hash'])); |
||
2087 | } |
||
2088 | // target is entity file of alias |
||
2089 | if ($volume === $this && ((isset($file['target']) && $test == $file['target']) || $test == $this->decode($src))) { |
||
2090 | return $this->setError(elFinder::ERROR_REPLACE, $errpath); |
||
2091 | } |
||
2092 | // remove existed file |
||
2093 | if (! $this->options['copyJoin'] || $stat['mime'] !== 'directory') { |
||
2094 | if (! $this->remove($test)) { |
||
2095 | return $this->setError(elFinder::ERROR_REPLACE, $this->path($stat['hash'])); |
||
2096 | } |
||
2097 | } else if ($stat['mime'] === 'directory') { |
||
2098 | $dstDirExists = true; |
||
2099 | } |
||
2100 | } else { |
||
2101 | $name = $this->uniqueName($destination, $name, ' ', false); |
||
2102 | } |
||
2103 | } |
||
2104 | |||
2105 | // copy/move inside current volume |
||
2106 | if ($volume === $this) { // changing == operand to === fixes issue #1285 - Paul Canning 24/03/2016 |
||
2107 | $source = $this->decode($src); |
||
2108 | // do not copy into itself |
||
2109 | if ($this->inpathCE($destination, $source)) { |
||
2110 | return $this->setError(elFinder::ERROR_COPY_INTO_ITSELF, $errpath); |
||
2111 | } |
||
2112 | $rmDir = false; |
||
2113 | if ($rmSrc) { |
||
2114 | if ($dstDirExists) { |
||
2115 | $rmDir = true; |
||
2116 | $method = 'copy'; |
||
2117 | } else { |
||
2118 | $method = 'move'; |
||
2119 | } |
||
2120 | } else { |
||
2121 | $method = 'copy'; |
||
2122 | } |
||
2123 | $this->clearcache(); |
||
2124 | if ($res = ($path = $this->$method($source, $destination, $name)) ? $this->stat($path) : false) { |
||
2125 | if ($rmDir) { |
||
2126 | $this->remove($source); |
||
2127 | } |
||
2128 | } else { |
||
2129 | return false; |
||
2130 | } |
||
2131 | } else { |
||
2132 | // copy/move from another volume |
||
2133 | if (!$this->options['copyTo'] || !$volume->copyFromAllowed()) { |
||
2134 | return $this->setError(elFinder::ERROR_COPY, $errpath, elFinder::ERROR_PERM_DENIED); |
||
2135 | } |
||
2136 | |||
2137 | if (($path = $this->copyFrom($volume, $src, $destination, $name)) == false) { |
||
2138 | return false; |
||
2139 | } |
||
2140 | |||
2141 | if ($rmSrc) { |
||
2142 | if (!$volume->rm($src)) { |
||
2143 | return $this->setError(elFinder::ERROR_MOVE, $errpath, elFinder::ERROR_RM_SRC); |
||
2144 | } |
||
2145 | } |
||
2146 | $res = $this->stat($path); |
||
0 ignored issues
–
show
It seems like
$path defined by $this->copyFrom($volume,...c, $destination, $name) on line 2137 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.
Loading history...
|
|||
2147 | } |
||
2148 | return $res; |
||
2149 | } |
||
2150 | |||
2151 | /** |
||
2152 | * Return path to archive of target items |
||
2153 | * |
||
2154 | * @param array $hashes |
||
2155 | * @return string archive path |
||
2156 | * @author Naoki Sawada |
||
2157 | */ |
||
2158 | public function zipdl($hashes) { |
||
2159 | if ($this->commandDisabled('zipdl')) { |
||
2160 | return $this->setError(elFinder::ERROR_PERM_DENIED); |
||
2161 | } |
||
2162 | |||
2163 | $archivers = $this->getArchivers(); |
||
2164 | $cmd = null; |
||
2165 | 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
Loading history...
|
|||
2166 | return false; |
||
2167 | } |
||
2168 | $archivers = $archivers['create']; |
||
2169 | foreach(array('zip', 'tgz') as $ext) { |
||
2170 | $mime = self::$mimetypes[$ext]; |
||
2171 | if (isset($archivers[$mime])) { |
||
2172 | $cmd = $archivers[$mime]; |
||
2173 | break; |
||
2174 | } |
||
2175 | } |
||
2176 | if (!$cmd) { |
||
2177 | $cmd = $archivers[0]; |
||
2178 | $ext = $cmd['ext']; |
||
2179 | $mime = elFinderVolumeDriver::mimetypeInternalDetect('file.'.$ext); |
||
2180 | } |
||
2181 | $res = false; |
||
2182 | $mixed = false; |
||
2183 | $hashes = array_values($hashes); |
||
2184 | $dirname = dirname(str_replace($this->separator, DIRECTORY_SEPARATOR, $this->path($hashes[0]))); |
||
2185 | $cnt = count($hashes); |
||
2186 | if ($cnt > 1) { |
||
2187 | for($i = 1; $i < $cnt; $i++) { |
||
2188 | if ($dirname !== dirname(str_replace($this->separator, DIRECTORY_SEPARATOR, $this->path($hashes[$i])))) { |
||
2189 | $mixed = true; |
||
2190 | break; |
||
2191 | } |
||
2192 | } |
||
2193 | } |
||
2194 | if ($mixed || $this->root == $this->dirnameCE($this->decode($hashes[0]))) { |
||
2195 | $prefix = $this->rootName; |
||
2196 | } else { |
||
2197 | $prefix = basename($dirname); |
||
2198 | } |
||
2199 | if ($dir = $this->getItemsInHand($hashes)) { |
||
2200 | $tmppre = (substr(PHP_OS, 0, 3) === 'WIN')? 'zdl' : 'elfzdl'; |
||
2201 | $pdir = dirname($dir); |
||
2202 | // garbage collection |
||
2203 | $ttl = 7200; // expire 2h |
||
2204 | $time = time(); |
||
2205 | foreach(glob($pdir.DIRECTORY_SEPARATOR.$tmppre.'*') as $_file) { |
||
2206 | if (filemtime($_file) + $ttl < $time) { |
||
2207 | unlink($_file); |
||
2208 | } |
||
2209 | } |
||
2210 | $files = self::localScandir($dir); |
||
2211 | 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
Loading history...
|
|||
2212 | unlink($arc); |
||
2213 | $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
Loading history...
|
|||
2214 | $name = basename($arc); |
||
2215 | if ($arc = $this->makeArchive($dir, $files, $name, $cmd)) { |
||
2216 | $file = tempnam($pdir, $tmppre); |
||
2217 | unlink($file); |
||
2218 | $res = rename($arc, $file); |
||
2219 | $this->rmdirRecursive($dir); |
||
2220 | } |
||
2221 | } |
||
2222 | } |
||
2223 | return $res? array('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
Loading history...
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
Loading history...
|
|||
2224 | } |
||
2225 | |||
2226 | /** |
||
2227 | * Return file contents |
||
2228 | * |
||
2229 | * @param string $hash file hash |
||
2230 | * @return string|false |
||
2231 | * @author Dmitry (dio) Levashov |
||
2232 | **/ |
||
2233 | public function getContents($hash) { |
||
2234 | $file = $this->file($hash); |
||
2235 | |||
2236 | if (!$file) { |
||
2237 | return $this->setError(elFinder::ERROR_FILE_NOT_FOUND); |
||
2238 | } |
||
2239 | |||
2240 | if ($file['mime'] == 'directory') { |
||
2241 | return $this->setError(elFinder::ERROR_NOT_FILE); |
||
2242 | } |
||
2243 | |||
2244 | if (!$file['read']) { |
||
2245 | return $this->setError(elFinder::ERROR_PERM_DENIED); |
||
2246 | } |
||
2247 | |||
2248 | return $this->convEncOut($this->_getContents($this->convEncIn($this->decode($hash)))); |
||
2249 | } |
||
2250 | |||
2251 | /** |
||
2252 | * Put content in text file and return file info. |
||
2253 | * |
||
2254 | * @param string $hash file hash |
||
2255 | * @param string $content new file content |
||
2256 | * @return array |
||
2257 | * @author Dmitry (dio) Levashov |
||
2258 | **/ |
||
2259 | public function putContents($hash, $content) { |
||
2260 | if ($this->commandDisabled('edit')) { |
||
2261 | return $this->setError(elFinder::ERROR_PERM_DENIED); |
||
2262 | } |
||
2263 | |||
2264 | $path = $this->decode($hash); |
||
2265 | |||
2266 | if (!($file = $this->file($hash))) { |
||
2267 | return $this->setError(elFinder::ERROR_FILE_NOT_FOUND); |
||
2268 | } |
||
2269 | |||
2270 | if (!$file['write']) { |
||
2271 | return $this->setError(elFinder::ERROR_PERM_DENIED); |
||
2272 | } |
||
2273 | |||
2274 | // check MIME |
||
2275 | $name = $this->basenameCE($path); |
||
2276 | $mime = ''; |
||
2277 | $mimeByName = elFinderVolumeDriver::mimetypeInternalDetect($name); |
||
2278 | if ($this->mimeDetect !== 'internal') { |
||
2279 | if ($tp = tmpfile()) { |
||
2280 | fwrite($tp, $content); |
||
2281 | $info = stream_get_meta_data($tp); |
||
2282 | $filepath = $info['uri']; |
||
2283 | $mime = $this->mimetype($filepath, $name); |
||
2284 | fclose($tp); |
||
2285 | } |
||
2286 | } |
||
2287 | if (!$this->allowPutMime($mimeByName) || ($mime && $mime !== 'unknown' && !$this->allowPutMime($mime))) { |
||
2288 | return $this->setError(elFinder::ERROR_UPLOAD_FILE_MIME); |
||
2289 | } |
||
2290 | |||
2291 | $this->clearcache(); |
||
2292 | return $this->convEncOut($this->_filePutContents($this->convEncIn($path), $content)) ? $this->stat($path) : false; |
||
2293 | } |
||
2294 | |||
2295 | /** |
||
2296 | * Extract files from archive |
||
2297 | * |
||
2298 | * @param string $hash archive hash |
||
2299 | * @param null $makedir |
||
2300 | * @return array|bool |
||
2301 | * @author Dmitry (dio) Levashov, |
||
2302 | * @author Alexey Sukhotin |
||
2303 | */ |
||
2304 | public function extract($hash, $makedir = null) { |
||
2305 | if ($this->commandDisabled('extract')) { |
||
2306 | return $this->setError(elFinder::ERROR_PERM_DENIED); |
||
2307 | } |
||
2308 | |||
2309 | if (($file = $this->file($hash)) == false) { |
||
2310 | return $this->setError(elFinder::ERROR_FILE_NOT_FOUND); |
||
2311 | } |
||
2312 | |||
2313 | $archiver = isset($this->archivers['extract'][$file['mime']]) |
||
2314 | ? $this->archivers['extract'][$file['mime']] |
||
2315 | : false; |
||
2316 | |||
2317 | if (!$archiver) { |
||
2318 | return $this->setError(elFinder::ERROR_NOT_ARCHIVE); |
||
2319 | } |
||
2320 | |||
2321 | $path = $this->decode($hash); |
||
2322 | $parent = $this->stat($this->dirnameCE($path)); |
||
2323 | |||
2324 | if (!$file['read'] || !$parent['write']) { |
||
2325 | return $this->setError(elFinder::ERROR_PERM_DENIED); |
||
2326 | } |
||
2327 | $this->clearcache(); |
||
2328 | $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..
Loading history...
|
|||
2329 | |||
2330 | if ($path = $this->convEncOut($this->_extract($this->convEncIn($path), $archiver))) { |
||
2331 | if (is_array($path)) { |
||
2332 | foreach ($path as $_k => $_p) { |
||
2333 | $path[$_k] = $this->stat($_p); |
||
2334 | } |
||
2335 | } else { |
||
2336 | $path = $this->stat($path); |
||
2337 | } |
||
2338 | return $path; |
||
2339 | } else { |
||
2340 | return false; |
||
2341 | } |
||
2342 | } |
||
2343 | |||
2344 | /** |
||
2345 | * Add files to archive |
||
2346 | * |
||
2347 | * @param $hashes |
||
2348 | * @param $mime |
||
2349 | * @param string $name |
||
2350 | * @return array|bool |
||
2351 | */ |
||
2352 | public function archive($hashes, $mime, $name = '') { |
||
2353 | if ($this->commandDisabled('archive')) { |
||
2354 | return $this->setError(elFinder::ERROR_PERM_DENIED); |
||
2355 | } |
||
2356 | |||
2357 | if ($name !== '' && !$this->nameAccepted($name)) { |
||
2358 | return $this->setError(elFinder::ERROR_INVALID_NAME); |
||
2359 | } |
||
2360 | |||
2361 | $archiver = isset($this->archivers['create'][$mime]) |
||
2362 | ? $this->archivers['create'][$mime] |
||
2363 | : false; |
||
2364 | |||
2365 | if (!$archiver) { |
||
2366 | return $this->setError(elFinder::ERROR_ARCHIVE_TYPE); |
||
2367 | } |
||
2368 | |||
2369 | $files = array(); |
||
2370 | |||
2371 | foreach ($hashes as $hash) { |
||
2372 | if (($file = $this->file($hash)) == false) { |
||
2373 | return $this->setError(elFinder::ERROR_FILE_NOT_FOUND, '#'+$hash); |
||
2374 | } |
||
2375 | if (!$file['read']) { |
||
2376 | return $this->setError(elFinder::ERROR_PERM_DENIED); |
||
2377 | } |
||
2378 | $path = $this->decode($hash); |
||
2379 | if (!isset($dir)) { |
||
2380 | $dir = $this->dirnameCE($path); |
||
2381 | $stat = $this->stat($dir); |
||
2382 | if (!$stat['write']) { |
||
2383 | return $this->setError(elFinder::ERROR_PERM_DENIED); |
||
2384 | } |
||
2385 | } |
||
2386 | |||
2387 | $files[] = $this->basenameCE($path); |
||
2388 | } |
||
2389 | |||
2390 | if ($name === '') { |
||
2391 | $name = count($files) == 1 ? $files[0] : 'Archive'; |
||
2392 | } else { |
||
2393 | $name = str_replace(array('/', '\\'), '_', preg_replace('/\.' . preg_quote($archiver['ext'], '/') . '$/i', '', $name)); |
||
2394 | } |
||
2395 | $name .='.' . $archiver['ext']; |
||
2396 | $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
Loading history...
|
|||
2397 | $this->clearcache(); |
||
2398 | return ($path = $this->convEncOut($this->_archive($this->convEncIn($dir), $this->convEncIn($files), $this->convEncIn($name), $archiver))) ? $this->stat($path) : false; |
||
2399 | } |
||
2400 | |||
2401 | /** |
||
2402 | * Resize image |
||
2403 | * |
||
2404 | * @param string $hash image file |
||
2405 | * @param int $width new width |
||
2406 | * @param int $height new height |
||
2407 | * @param int $x X start poistion for crop |
||
2408 | * @param int $y Y start poistion for crop |
||
2409 | * @param string $mode action how to mainpulate image |
||
2410 | * @param string $bg background color |
||
2411 | * @param int $degree rotete degree |
||
2412 | * @param int $jpgQuality JEPG quality (1-100) |
||
2413 | * @return array|false |
||
2414 | * @author Dmitry (dio) Levashov |
||
2415 | * @author Alexey Sukhotin |
||
2416 | * @author nao-pon |
||
2417 | * @author Troex Nevelin |
||
2418 | **/ |
||
2419 | public function resize($hash, $width, $height, $x, $y, $mode = 'resize', $bg = '', $degree = 0, $jpgQuality = null) { |
||
2420 | if ($this->commandDisabled('resize')) { |
||
2421 | return $this->setError(elFinder::ERROR_PERM_DENIED); |
||
2422 | } |
||
2423 | |||
2424 | if (($file = $this->file($hash)) == false) { |
||
2425 | return $this->setError(elFinder::ERROR_FILE_NOT_FOUND); |
||
2426 | } |
||
2427 | |||
2428 | if (!$file['write'] || !$file['read']) { |
||
2429 | return $this->setError(elFinder::ERROR_PERM_DENIED); |
||
2430 | } |
||
2431 | |||
2432 | $path = $this->decode($hash); |
||
2433 | |||
2434 | $work_path = $this->getWorkFile($this->encoding? $this->convEncIn($path, true) : $path); |
||
2435 | |||
2436 | 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
Loading history...
|
|||
2437 | 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
Loading history...
|
|||
2438 | unlink($work_path); |
||
2439 | } |
||
2440 | return $this->setError(elFinder::ERROR_PERM_DENIED); |
||
2441 | } |
||
2442 | |||
2443 | if ($this->imgLib !== 'imagick' && $this->imgLib !== 'convert') { |
||
2444 | if (elFinder::isAnimationGif($work_path)) { |
||
2445 | return $this->setError(elFinder::ERROR_UNSUPPORT_TYPE); |
||
2446 | } |
||
2447 | } |
||
2448 | |||
2449 | switch($mode) { |
||
2450 | |||
2451 | case 'propresize': |
||
2452 | $result = $this->imgResize($work_path, $width, $height, true, true, null, $jpgQuality); |
||
2453 | break; |
||
2454 | |||
2455 | case 'crop': |
||
2456 | $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);
Loading history...
$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);
Loading history...
|
|||
2457 | break; |
||
2458 | |||
2459 | case 'fitsquare': |
||
2460 | $result = $this->imgSquareFit($work_path, $width, $height, 'center', 'middle', ($bg ? $bg : $this->options['tmbBgColor']), null, $jpgQuality); |
||
2461 | break; |
||
2462 | |||
2463 | case 'rotate': |
||
2464 | $result = $this->imgRotate($work_path, $degree, ($bg ? $bg : $this->options['bgColorFb']), null, $jpgQuality); |
||
2465 | break; |
||
2466 | |||
2467 | default: |
||
2468 | $result = $this->imgResize($work_path, $width, $height, false, true, null, $jpgQuality); |
||
2469 | break; |
||
2470 | } |
||
2471 | |||
2472 | $ret = false; |
||
2473 | 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
Loading history...
|
|||
2474 | $stat = $this->stat($path); |
||
2475 | clearstatcache(); |
||
2476 | $fstat = stat($work_path); |
||
2477 | $stat['size'] = $fstat['size']; |
||
2478 | $stat['ts'] = $fstat['mtime']; |
||
2479 | if ($imgsize = getimagesize($work_path)) { |
||
2480 | $stat['width'] = $imgsize[0]; |
||
2481 | $stat['height'] = $imgsize[1]; |
||
2482 | $stat['mime'] = $imgsize['mime']; |
||
2483 | } |
||
2484 | if ($path !== $work_path) { |
||
2485 | if ($fp = fopen($work_path, 'rb')) { |
||
2486 | $ret = $this->saveCE($fp, $this->dirnameCE($path), $this->basenameCE($path), $stat); |
||
2487 | fclose($fp); |
||
2488 | } |
||
2489 | } else { |
||
2490 | $ret = true; |
||
2491 | } |
||
2492 | if ($ret) { |
||
2493 | $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);
Loading history...
|
|||
2494 | $this->clearcache(); |
||
2495 | $ret = $this->stat($path); |
||
2496 | $ret['width'] = $stat['width']; |
||
2497 | $ret['height'] = $stat['height']; |
||
2498 | } |
||
2499 | } |
||
2500 | if ($path !== $work_path) { |
||
2501 | is_file($work_path) && unlink($work_path); |
||
2502 | } |
||
2503 | |||
2504 | return $ret; |
||
2505 | } |
||
2506 | |||
2507 | /** |
||
2508 | * Remove file/dir |
||
2509 | * |
||
2510 | * @param string $hash file hash |
||
2511 | * @return bool |
||
2512 | * @author Dmitry (dio) Levashov |
||
2513 | **/ |
||
2514 | public function rm($hash) { |
||
2515 | return $this->commandDisabled('rm') |
||
2516 | ? $this->setError(elFinder::ERROR_PERM_DENIED) |
||
2517 | : $this->remove($this->decode($hash)); |
||
2518 | } |
||
2519 | |||
2520 | /** |
||
2521 | * Search files |
||
2522 | * |
||
2523 | * @param string $q search string |
||
2524 | * @param array $mimes |
||
2525 | * @param null $hash |
||
2526 | * @return array |
||
2527 | * @author Dmitry (dio) Levashov |
||
2528 | */ |
||
2529 | public function search($q, $mimes, $hash = null) { |
||
2530 | $dir = null; |
||
2531 | if ($hash) { |
||
2532 | $dir = $this->decode($hash); |
||
2533 | $stat = $this->stat($dir); |
||
2534 | 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
Loading history...
|
|||
2535 | $q = ''; |
||
2536 | } |
||
2537 | } |
||
2538 | 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
Loading history...
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
Loading history...
|
|||
2539 | $mimes = array_intersect($mimes, $this->onlyMimes); |
||
2540 | 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
Loading history...
|
|||
2541 | $q = ''; |
||
2542 | } |
||
2543 | } |
||
2544 | $this->searchStart = time(); |
||
2545 | |||
2546 | $qs = preg_split('/"([^"]+)"| +/', $q, -1, PREG_SPLIT_NO_EMPTY|PREG_SPLIT_DELIM_CAPTURE); |
||
2547 | $query = $excludes = array(); |
||
2548 | foreach($qs as $_q) { |
||
2549 | $_q = trim($_q); |
||
2550 | if ($_q !== '') { |
||
2551 | if ($_q[0] === '-') { |
||
2552 | if (isset($_q[1])) { |
||
2553 | $excludes[] = substr($_q, 1); |
||
2554 | } |
||
2555 | } else { |
||
2556 | $query[] = $_q; |
||
2557 | } |
||
2558 | } |
||
2559 | } |
||
2560 | 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
Loading history...
|
|||
2561 | $q = ''; |
||
2562 | } else { |
||
2563 | $q = join(' ', $query); |
||
2564 | $this->doSearchCurrentQuery = array( |
||
0 ignored issues
–
show
It seems like
array('q' => $q, 'excludes' => $excludes) of type array<string,?,{"q":"?","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..
Loading history...
|
|||
2565 | 'q' => $q, |
||
2566 | 'excludes' => $excludes |
||
2567 | ); |
||
2568 | } |
||
2569 | |||
2570 | // 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.
Loading history...
|
|||
2571 | if ($this->options['searchExDirReg']) { |
||
2572 | if (false === preg_match($this->options['searchExDirReg'], '')) { |
||
2573 | $this->options['searchExDirReg'] = ''; |
||
2574 | } |
||
2575 | } |
||
2576 | |||
2577 | return ($q === '' || $this->commandDisabled('search')) |
||
2578 | ? array() |
||
2579 | : $this->doSearch(is_null($dir)? $this->root : $dir, $q, $mimes); |
||
2580 | } |
||
2581 | |||
2582 | /** |
||
2583 | * Return image dimensions |
||
2584 | * |
||
2585 | * @param string $hash file hash |
||
2586 | * @return array |
||
2587 | * @author Dmitry (dio) Levashov |
||
2588 | **/ |
||
2589 | public function dimensions($hash) { |
||
2590 | if (($file = $this->file($hash)) == false) { |
||
2591 | return false; |
||
2592 | } |
||
2593 | |||
2594 | return $this->convEncOut($this->_dimensions($this->convEncIn($this->decode($hash)), $file['mime'])); |
||
2595 | } |
||
2596 | |||
2597 | /** |
||
2598 | * Return content URL (for netmout volume driver) |
||
2599 | * If file.url == 1 requests from JavaScript client with XHR |
||
2600 | * |
||
2601 | * @param string $hash file hash |
||
2602 | * @param array $options options array |
||
2603 | * @return boolean|string |
||
2604 | * @author Naoki Sawada |
||
2605 | */ |
||
2606 | public function getContentUrl($hash, $options = array()) { |
||
0 ignored issues
–
show
|
|||
2607 | if (($file = $this->file($hash)) == false || (isset($file['url']) && $file['url'] == 1)) { |
||
2608 | return false; |
||
2609 | } |
||
2610 | if (empty($file['url'])) { |
||
2611 | if ($this->URL) { |
||
2612 | $path = str_replace($this->separator, '/', substr($this->decode($hash), strlen($this->root) + 1)); |
||
2613 | if ($this->encoding) { |
||
2614 | $path = str_replace('%2F', '/', rawurlencode($this->convEncIn($path, true))); |
||
2615 | } |
||
2616 | return $this->URL . $path; |
||
2617 | } |
||
2618 | return false; |
||
2619 | } else { |
||
2620 | return $file['url']; |
||
2621 | } |
||
2622 | } |
||
2623 | |||
2624 | /** |
||
2625 | * Return temp path |
||
2626 | * |
||
2627 | * @return string |
||
2628 | * @author Naoki Sawada |
||
2629 | */ |
||
2630 | public function getTempPath() { |
||
2631 | $tempPath = null; |
||
2632 | if (isset($this->tmpPath) && $this->tmpPath && is_writable($this->tmpPath)) { |
||
2633 | $tempPath = $this->tmpPath; |
||
2634 | } else if (isset($this->tmp) && $this->tmp && is_writable($this->tmp)) { |
||
2635 | $tempPath = $this->tmp; |
||
2636 | } else if (function_exists('sys_get_temp_dir')) { |
||
2637 | $tempPath = sys_get_temp_dir(); |
||
2638 | } else if (isset($this->tmbPath) && $this->tmbPath && is_writable($this->tmbPath)) { |
||
2639 | $tempPath = $this->tmbPath; |
||
2640 | } |
||
2641 | if ($tempPath && DIRECTORY_SEPARATOR !== '/') { |
||
2642 | $tempPath = str_replace('/', DIRECTORY_SEPARATOR, $tempPath); |
||
2643 | } |
||
2644 | return $tempPath; |
||
2645 | } |
||
2646 | |||
2647 | /** |
||
2648 | * (Make &) Get upload taget dirctory hash |
||
2649 | * |
||
2650 | * @param string $baseTargetHash |
||
2651 | * @param string $path |
||
2652 | * @param array $result |
||
2653 | * @return boolean|string |
||
2654 | * @author Naoki Sawada |
||
2655 | */ |
||
2656 | public function getUploadTaget($baseTargetHash, $path, & $result) { |
||
2657 | $base = $this->decode($baseTargetHash); |
||
2658 | $targetHash = $baseTargetHash; |
||
2659 | $path = ltrim($path, $this->separator); |
||
2660 | $dirs = explode($this->separator, $path); |
||
2661 | array_pop($dirs); |
||
2662 | foreach($dirs as $dir) { |
||
2663 | $targetPath = $this->joinPathCE($base, $dir); |
||
2664 | if (! $_realpath = $this->realpath($this->encode($targetPath))) { |
||
2665 | if ($stat = $this->mkdir($targetHash, $dir)) { |
||
2666 | $result['added'][] = $stat; |
||
2667 | $targetHash = $stat['hash']; |
||
2668 | $base = $this->decode($targetHash); |
||
2669 | } else { |
||
2670 | return false; |
||
2671 | } |
||
2672 | } else { |
||
2673 | $targetHash = $this->encode($_realpath); |
||
2674 | if ($this->dir($targetHash)) { |
||
2675 | $base = $this->decode($targetHash); |
||
2676 | } else { |
||
2677 | return false; |
||
2678 | } |
||
2679 | } |
||
2680 | } |
||
2681 | return $targetHash; |
||
2682 | } |
||
2683 | |||
2684 | /** |
||
2685 | * Return this uploadMaxSize value |
||
2686 | * |
||
2687 | * @return integer |
||
2688 | * @author Naoki Sawada |
||
2689 | */ |
||
2690 | public function getUploadMaxSize() { |
||
2691 | return $this->uploadMaxSize; |
||
2692 | } |
||
2693 | |||
2694 | /** |
||
2695 | * Image file utility |
||
2696 | * |
||
2697 | * @param string $mode 'resize', 'rotate', 'propresize', 'crop', 'fitsquare' |
||
2698 | * @param string $src Image file local path |
||
2699 | * @param array $options excute options |
||
2700 | * @return bool |
||
2701 | * @author Naoki Sawada |
||
2702 | */ |
||
2703 | public function imageUtil($mode, $src, $options = array()) { |
||
2704 | if (! isset($options['jpgQuality'])) { |
||
2705 | $options['jpgQuality'] = intval($this->options['jpgQuality']); |
||
2706 | } |
||
2707 | if (! isset($options['bgcolor'])) { |
||
2708 | $options['bgcolor'] = '#ffffff'; |
||
2709 | } |
||
2710 | if (! isset($options['bgColorFb'])) { |
||
2711 | $options['bgColorFb'] = $this->options['bgColorFb']; |
||
2712 | } |
||
2713 | switch($mode) { |
||
2714 | case 'rotate': |
||
2715 | if (empty($options['degree'])) { |
||
2716 | return true; |
||
2717 | } |
||
2718 | return (bool)$this->imgRotate($src, $options['degree'], $options['bgColorFb'], null, $options['jpgQuality']); |
||
2719 | |||
2720 | case 'resize': |
||
2721 | case 'propresize': |
||
2722 | case 'crop': |
||
2723 | case 'fitsquare': |
||
0 ignored issues
–
show
|
|||
2724 | if (empty($options['width']) || empty($options['height'])) { |
||
2725 | return false; |
||
2726 | } |
||
2727 | |||
2728 | case 'resize': |
||
2729 | return (bool)$this->imgResize($src, $options['width'], $options['height'], false, true, null, $options['jpgQuality'], $options); |
||
2730 | |||
2731 | case 'propresize': |
||
2732 | return (bool)$this->imgResize($src, $options['width'], $options['height'], true, true, null, $options['jpgQuality'], $options); |
||
2733 | |||
2734 | case 'crop': |
||
0 ignored issues
–
show
|
|||
2735 | if (isset($options['x']) && isset($options['y'])) { |
||
2736 | return (bool)$this->imgCrop($src, $options['width'], $options['height'], $options['x'], $options['y'], null, $options['jpgQuality']); |
||
2737 | } |
||
2738 | |||
2739 | case 'fitsquare': |
||
2740 | return (bool)$this->imgSquareFit($src, $options['width'], $options['height'], 'center', 'middle', $options['bgcolor'], null, $options['jpgQuality']); |
||
2741 | |||
2742 | } |
||
2743 | return false; |
||
2744 | } |
||
2745 | |||
2746 | /** |
||
2747 | * Convert Video To Image by ffmpeg |
||
2748 | * |
||
2749 | * @param $file video source file path |
||
2750 | * @param $stat file stat array |
||
2751 | * @return bool |
||
2752 | * @author Naoki Sawada |
||
2753 | */ |
||
2754 | 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);
}
}
Loading history...
|
|||
2755 | $name = basename($file); |
||
2756 | $path = dirname($file); |
||
2757 | $tmp = $path . DIRECTORY_SEPARATOR . md5($name); |
||
2758 | $GLOBALS['elFinderTempFiles'][] = $tmp; // regist to remove at the end |
||
2759 | if (rename($file, $tmp)) { |
||
2760 | // specific start time by file name (xxx^[sec].[extention] - video^3.mp4) |
||
2761 | if (preg_match('/\^(\d+(?:\.\d+)?)\.[^.]+$/', $stat['name'], $_m)) { |
||
2762 | $ss = $_m[1]; |
||
2763 | } else { |
||
2764 | $ss = $this->options['tmbVideoConvSec']; |
||
2765 | } |
||
2766 | $cmd = sprintf('ffmpeg -ss 00:00:%.3f -vframes 1 -i %s -f image2 %s', $ss, escapeshellarg($tmp), escapeshellarg($file)); |
||
2767 | $r = $this->procExec($cmd); |
||
2768 | unlink($tmp); |
||
2769 | return ($r === 0); |
||
2770 | } |
||
2771 | return false; |
||
2772 | } |
||
2773 | |||
2774 | /** |
||
2775 | * Save error message |
||
2776 | * |
||
2777 | * @param array error |
||
2778 | * @return false |
||
2779 | * @author Dmitry(dio) Levashov |
||
2780 | **/ |
||
2781 | protected function setError($error) { |
||
0 ignored issues
–
show
|
|||
2782 | |||
2783 | $this->error = array(); |
||
2784 | |||
2785 | foreach (func_get_args() as $err) { |
||
2786 | if (is_array($err)) { |
||
2787 | $this->error = array_merge($this->error, $err); |
||
2788 | } else { |
||
2789 | $this->error[] = $err; |
||
2790 | } |
||
2791 | } |
||
2792 | |||
2793 | // $this->error = is_array($error) ? $error : func_get_args(); |
||
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.
Loading history...
|
|||
2794 | return false; |
||
2795 | } |
||
2796 | |||
2797 | /*********************************************************************/ |
||
2798 | /* FS API */ |
||
2799 | /*********************************************************************/ |
||
2800 | |||
2801 | /***************** server encoding support *******************/ |
||
2802 | |||
2803 | /** |
||
2804 | * Return parent directory path (with convert encording) |
||
2805 | * |
||
2806 | * @param string $path file path |
||
2807 | * @return string |
||
2808 | * @author Naoki Sawada |
||
2809 | **/ |
||
2810 | protected function dirnameCE($path) { |
||
2811 | return (!$this->encoding)? $this->_dirname($path) : $this->convEncOut($this->_dirname($this->convEncIn($path))); |
||
2812 | } |
||
2813 | |||
2814 | /** |
||
2815 | * Return file name (with convert encording) |
||
2816 | * |
||
2817 | * @param string $path file path |
||
2818 | * @return string |
||
2819 | * @author Naoki Sawada |
||
2820 | **/ |
||
2821 | protected function basenameCE($path) { |
||
2822 | return (!$this->encoding)? $this->_basename($path) : $this->convEncOut($this->_basename($this->convEncIn($path))); |
||
2823 | } |
||
2824 | |||
2825 | /** |
||
2826 | * Join dir name and file name and return full path. (with convert encording) |
||
2827 | * Some drivers (db) use int as path - so we give to concat path to driver itself |
||
2828 | * |
||
2829 | * @param string $dir dir path |
||
2830 | * @param string $name file name |
||
2831 | * @return string |
||
2832 | * @author Naoki Sawada |
||
2833 | **/ |
||
2834 | protected function joinPathCE($dir, $name) { |
||
2835 | return (!$this->encoding)? $this->_joinPath($dir, $name) : $this->convEncOut($this->_joinPath($this->convEncIn($dir), $this->convEncIn($name))); |
||
2836 | } |
||
2837 | |||
2838 | /** |
||
2839 | * Return normalized path (with convert encording) |
||
2840 | * |
||
2841 | * @param string $path file path |
||
2842 | * @return string |
||
2843 | * @author Naoki Sawada |
||
2844 | **/ |
||
2845 | protected function normpathCE($path) { |
||
2846 | return (!$this->encoding)? $this->_normpath($path) : $this->convEncOut($this->_normpath($this->convEncIn($path))); |
||
2847 | } |
||
2848 | |||
2849 | /** |
||
2850 | * Return file path related to root dir (with convert encording) |
||
2851 | * |
||
2852 | * @param string $path file path |
||
2853 | * @return string |
||
2854 | * @author Naoki Sawada |
||
2855 | **/ |
||
2856 | protected function relpathCE($path) { |
||
2857 | return (!$this->encoding)? $this->_relpath($path) : $this->convEncOut($this->_relpath($this->convEncIn($path))); |
||
2858 | } |
||
2859 | |||
2860 | /** |
||
2861 | * Convert path related to root dir into real path (with convert encording) |
||
2862 | * |
||
2863 | * @param string $path rel file path |
||
2864 | * @return string |
||
2865 | * @author Naoki Sawada |
||
2866 | **/ |
||
2867 | protected function abspathCE($path) { |
||
2868 | return (!$this->encoding)? $this->_abspath($path): $this->convEncOut($this->_abspath($this->convEncIn($path))); |
||
2869 | } |
||
2870 | |||
2871 | /** |
||
2872 | * Return true if $path is children of $parent (with convert encording) |
||
2873 | * |
||
2874 | * @param string $path path to check |
||
2875 | * @param string $parent parent path |
||
2876 | * @return bool |
||
2877 | * @author Naoki Sawada |
||
2878 | **/ |
||
2879 | protected function inpathCE($path, $parent) { |
||
2880 | return (!$this->encoding)? $this->_inpath($path, $parent) : $this->convEncOut($this->_inpath($this->convEncIn($path), $this->convEncIn($parent))); |
||
2881 | } |
||
2882 | |||
2883 | /** |
||
2884 | * Open file and return file pointer (with convert encording) |
||
2885 | * |
||
2886 | * @param string $path file path |
||
2887 | * @param string $mode |
||
2888 | * @return false|resource |
||
2889 | * @internal param bool $write open file for writing |
||
2890 | * @author Naoki Sawada |
||
2891 | */ |
||
2892 | protected function fopenCE($path, $mode='rb') { |
||
2893 | return (!$this->encoding)? $this->_fopen($path, $mode) : $this->convEncOut($this->_fopen($this->convEncIn($path), $mode)); |
||
2894 | } |
||
2895 | |||
2896 | /** |
||
2897 | * Close opened file (with convert encording) |
||
2898 | * |
||
2899 | * @param resource $fp file pointer |
||
2900 | * @param string $path file path |
||
2901 | * @return bool |
||
2902 | * @author Naoki Sawada |
||
2903 | **/ |
||
2904 | protected function fcloseCE($fp, $path='') { |
||
2905 | return (!$this->encoding)? $this->_fclose($fp, $path) : $this->convEncOut($this->_fclose($fp, $this->convEncIn($path))); |
||
2906 | } |
||
2907 | |||
2908 | /** |
||
2909 | * Create new file and write into it from file pointer. (with convert encording) |
||
2910 | * Return new file path or false on error. |
||
2911 | * |
||
2912 | * @param resource $fp file pointer |
||
2913 | * @param string $dir target dir path |
||
2914 | * @param string $name file name |
||
2915 | * @param array $stat file stat (required by some virtual fs) |
||
2916 | * @return bool|string |
||
2917 | * @author Naoki Sawada |
||
2918 | **/ |
||
2919 | protected function saveCE($fp, $dir, $name, $stat) { |
||
2920 | return (!$this->encoding)? $this->_save($fp, $dir, $name, $stat) : $this->convEncOut($this->_save($fp, $this->convEncIn($dir), $this->convEncIn($name), $this->convEncIn($stat))); |
||
2921 | } |
||
2922 | |||
2923 | /** |
||
2924 | * Return true if path is dir and has at least one childs directory (with convert encording) |
||
2925 | * |
||
2926 | * @param string $path dir path |
||
2927 | * @return bool |
||
2928 | * @author Naoki Sawada |
||
2929 | **/ |
||
2930 | protected function subdirsCE($path) { |
||
2931 | if (!isset($this->subdirsCache[$path])) { |
||
2932 | $this->subdirsCache[$path] = (!$this->encoding)? $this->_subdirs($path) : $this->convEncOut($this->_subdirs($this->convEncIn($path))); |
||
2933 | } |
||
2934 | return $this->subdirsCache[$path]; |
||
2935 | } |
||
2936 | |||
2937 | /** |
||
2938 | * Return files list in directory (with convert encording) |
||
2939 | * |
||
2940 | * @param string $path dir path |
||
2941 | * @return array |
||
2942 | * @author Naoki Sawada |
||
2943 | **/ |
||
2944 | protected function scandirCE($path) { |
||
2945 | return (!$this->encoding)? $this->_scandir($path) : $this->convEncOut($this->_scandir($this->convEncIn($path))); |
||
2946 | } |
||
2947 | |||
2948 | /** |
||
2949 | * Create symlink (with convert encording) |
||
2950 | * |
||
2951 | * @param string $source file to link to |
||
2952 | * @param string $targetDir folder to create link in |
||
2953 | * @param string $name symlink name |
||
2954 | * @return bool |
||
2955 | * @author Naoki Sawada |
||
2956 | **/ |
||
2957 | protected function symlinkCE($source, $targetDir, $name) { |
||
2958 | return (!$this->encoding)? $this->_symlink($source, $targetDir, $name) : $this->convEncOut($this->_symlink($this->convEncIn($source), $this->convEncIn($targetDir), $this->convEncIn($name))); |
||
2959 | } |
||
2960 | |||
2961 | /***************** paths *******************/ |
||
2962 | |||
2963 | /** |
||
2964 | * Encode path into hash |
||
2965 | * |
||
2966 | * @param string file path |
||
2967 | * @return string |
||
2968 | * @author Dmitry (dio) Levashov |
||
2969 | * @author Troex Nevelin |
||
2970 | **/ |
||
2971 | protected function encode($path) { |
||
2972 | if ($path !== '') { |
||
2973 | |||
2974 | // cut ROOT from $path for security reason, even if hacker decodes the path he will not know the root |
||
2975 | $p = $this->relpathCE($path); |
||
2976 | // if reqesting root dir $path will be empty, then assign '/' as we cannot leave it blank for crypt |
||
2977 | if ($p === '') { |
||
2978 | $p = $this->separator; |
||
2979 | } |
||
2980 | |||
2981 | // TODO crypt path and return hash |
||
2982 | $hash = $this->crypt($p); |
||
2983 | // hash is used as id in HTML that means it must contain vaild chars |
||
2984 | // make base64 html safe and append prefix in begining |
||
2985 | $hash = strtr(base64_encode($hash), '+/=', '-_.'); |
||
2986 | // remove dots '.' at the end, before it was '=' in base64 |
||
2987 | $hash = rtrim($hash, '.'); |
||
2988 | // append volume id to make hash unique |
||
2989 | return $this->id.$hash; |
||
2990 | } |
||
2991 | //TODO: Add return statement here |
||
2992 | } |
||
2993 | |||
2994 | /** |
||
2995 | * Decode path from hash |
||
2996 | * |
||
2997 | * @param string file hash |
||
2998 | * @return string |
||
2999 | * @author Dmitry (dio) Levashov |
||
3000 | * @author Troex Nevelin |
||
3001 | **/ |
||
3002 | protected function decode($hash) { |
||
3003 | if (strpos($hash, $this->id) === 0) { |
||
3004 | // cut volume id after it was prepended in encode |
||
3005 | $h = substr($hash, strlen($this->id)); |
||
3006 | // replace HTML safe base64 to normal |
||
3007 | $h = base64_decode(strtr($h, '-_.', '+/=')); |
||
3008 | // TODO uncrypt hash and return path |
||
3009 | $path = $this->uncrypt($h); |
||
3010 | // append ROOT to path after it was cut in encode |
||
3011 | 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.
Loading history...
|
|||
3012 | } |
||
3013 | //TODO: Add return statement here |
||
3014 | } |
||
3015 | |||
3016 | /** |
||
3017 | * Return crypted path |
||
3018 | * Not implemented |
||
3019 | * |
||
3020 | * @param string path |
||
3021 | * @return mixed |
||
3022 | * @author Dmitry (dio) Levashov |
||
3023 | **/ |
||
3024 | protected function crypt($path) { |
||
3025 | return $path; |
||
3026 | } |
||
3027 | |||
3028 | /** |
||
3029 | * Return uncrypted path |
||
3030 | * Not implemented |
||
3031 | * |
||
3032 | * @param mixed hash |
||
3033 | * @return mixed |
||
3034 | * @author Dmitry (dio) Levashov |
||
3035 | **/ |
||
3036 | protected function uncrypt($hash) { |
||
3037 | return $hash; |
||
3038 | } |
||
3039 | |||
3040 | /** |
||
3041 | * Validate file name based on $this->options['acceptedName'] regexp or function |
||
3042 | * |
||
3043 | * @param string $name file name |
||
3044 | * @return bool |
||
3045 | * @author Dmitry (dio) Levashov |
||
3046 | **/ |
||
3047 | protected function nameAccepted($name) { |
||
3048 | if (json_encode($name)===false) { |
||
3049 | return false; |
||
3050 | } |
||
3051 | if ($this->nameValidator) { |
||
3052 | if (is_callable($this->nameValidator)) { |
||
3053 | $res = call_user_func($this->nameValidator, $name); |
||
3054 | return $res; |
||
3055 | } |
||
3056 | if (preg_match($this->nameValidator, '') !== false) { |
||
3057 | return preg_match($this->nameValidator, $name); |
||
3058 | } |
||
3059 | } |
||
3060 | return true; |
||
3061 | } |
||
3062 | |||
3063 | /** |
||
3064 | * Return new unique name based on file name and suffix |
||
3065 | * |
||
3066 | * @param $dir |
||
3067 | * @param $name |
||
3068 | * @param string $suffix suffix append to name |
||
3069 | * @param bool $checkNum |
||
3070 | * @param int $start |
||
3071 | * @return string |
||
3072 | * @internal param string $path file path |
||
3073 | * @author Dmitry (dio) Levashov |
||
3074 | */ |
||
3075 | public function uniqueName($dir, $name, $suffix = ' copy', $checkNum = true, $start = 1) { |
||
3076 | $ext = ''; |
||
3077 | |||
3078 | if (preg_match('/\.((tar\.(gz|bz|bz2|z|lzo))|cpio\.gz|ps\.gz|xcf\.(gz|bz2)|[a-z0-9]{1,4})$/i', $name, $m)) { |
||
3079 | $ext = '.'.$m[1]; |
||
3080 | $name = substr($name, 0, strlen($name)-strlen($m[0])); |
||
3081 | } |
||
3082 | |||
3083 | if ($checkNum && preg_match('/('.preg_quote($suffix, '/').')(\d*)$/i', $name, $m)) { |
||
3084 | $i = (int)$m[2]; |
||
3085 | $name = substr($name, 0, strlen($name)-strlen($m[2])); |
||
3086 | } else { |
||
3087 | $i = $start; |
||
3088 | $name .= $suffix; |
||
3089 | } |
||
3090 | $max = $i+100000; |
||
3091 | |||
3092 | while ($i <= $max) { |
||
3093 | $n = $name.($i > 0 ? sprintf($this->options['uniqueNumFormat'], $i) : '').$ext; |
||
3094 | |||
3095 | if (!$this->stat($this->joinPathCE($dir, $n))) { |
||
3096 | $this->clearcache(); |
||
3097 | return $n; |
||
3098 | } |
||
3099 | $i++; |
||
3100 | } |
||
3101 | return $name.md5($dir).$ext; |
||
3102 | } |
||
3103 | |||
3104 | /** |
||
3105 | * Converts character encoding from UTF-8 to server's one |
||
3106 | * |
||
3107 | * @param mixed $var target string or array var |
||
3108 | * @param bool $restoreLocale do retore global locale, default is false |
||
3109 | * @param string $unknown replaces character for unknown |
||
3110 | * @return mixed |
||
3111 | * @author Naoki Sawada |
||
3112 | */ |
||
3113 | public function convEncIn($var = null, $restoreLocale = false, $unknown = '_') { |
||
3114 | return (!$this->encoding)? $var : $this->convEnc($var, 'UTF-8', $this->encoding, $this->options['locale'], $restoreLocale, $unknown); |
||
3115 | } |
||
3116 | |||
3117 | /** |
||
3118 | * Converts character encoding from server's one to UTF-8 |
||
3119 | * |
||
3120 | * @param mixed $var target string or array var |
||
3121 | * @param bool $restoreLocale do retore global locale, default is true |
||
3122 | * @param string $unknown replaces character for unknown |
||
3123 | * @return mixed |
||
3124 | * @author Naoki Sawada |
||
3125 | */ |
||
3126 | public function convEncOut($var = null, $restoreLocale = true, $unknown = '_') { |
||
3127 | return (!$this->encoding)? $var : $this->convEnc($var, $this->encoding, 'UTF-8', $this->options['locale'], $restoreLocale, $unknown); |
||
3128 | } |
||
3129 | |||
3130 | /** |
||
3131 | * Converts character encoding (base function) |
||
3132 | * |
||
3133 | * @param mixed $var target string or array var |
||
3134 | * @param string $from from character encoding |
||
3135 | * @param string $to to character encoding |
||
3136 | * @param string $locale local locale |
||
3137 | * @param $restoreLocale |
||
3138 | * @param string $unknown replaces character for unknown |
||
3139 | * @return mixed |
||
3140 | */ |
||
3141 | protected function convEnc($var, $from, $to, $locale, $restoreLocale, $unknown = '_') { |
||
3142 | if (strtoupper($from) !== strtoupper($to)) { |
||
3143 | if ($locale) { |
||
3144 | setlocale(LC_ALL, $locale); |
||
3145 | } |
||
3146 | if (is_array($var)) { |
||
3147 | $_ret = array(); |
||
3148 | foreach($var as $_k => $_v) { |
||
3149 | $_ret[$_k] = $this->convEnc($_v, $from, $to, '', false, $unknown = '_'); |
||
3150 | } |
||
3151 | $var = $_ret; |
||
3152 | } else { |
||
3153 | $_var = false; |
||
3154 | if (is_string($var)) { |
||
3155 | $_var = $var; |
||
3156 | if (false !== ($_var = iconv($from, $to.'//TRANSLIT', $_var))) { |
||
3157 | $_var = str_replace('?', $unknown, $_var); |
||
3158 | } |
||
3159 | } |
||
3160 | if ($_var !== false) { |
||
3161 | $var = $_var; |
||
3162 | } |
||
3163 | } |
||
3164 | if ($restoreLocale) { |
||
3165 | setlocale(LC_ALL, elFinder::$locale); |
||
3166 | } |
||
3167 | } |
||
3168 | return $var; |
||
3169 | } |
||
3170 | |||
3171 | /*********************** util mainly for inheritance class *********************/ |
||
3172 | |||
3173 | /** |
||
3174 | * Get temporary filename. Tempfile will be removed when after script execution finishes or exit() is called. |
||
3175 | * When needing the unique file to a path, give $path to parameter. |
||
3176 | * |
||
3177 | * @param string $path for get unique file to a path |
||
3178 | * @return string|false |
||
3179 | * @author Naoki Sawada |
||
3180 | */ |
||
3181 | protected function getTempFile($path = '') { |
||
3182 | static $cache = array(); |
||
3183 | static $rmfunc; |
||
3184 | |||
3185 | $key = ''; |
||
3186 | if ($path !== '') { |
||
3187 | $key = $this->id . '#' . $path; |
||
3188 | if (isset($cache[$key])) { |
||
3189 | return $cache[$key]; |
||
3190 | } |
||
3191 | } |
||
3192 | |||
3193 | if ($tmpdir = $this->getTempPath()) { |
||
3194 | if (!$rmfunc) { |
||
3195 | $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; }
Loading history...
|
|||
3196 | } |
||
3197 | $name = tempnam($tmpdir, 'ELF'); |
||
3198 | if ($key) { |
||
3199 | $cache[$key] = $name; |
||
3200 | } |
||
3201 | register_shutdown_function($rmfunc, $name); |
||
3202 | return $name; |
||
3203 | } |
||
3204 | |||
3205 | return false; |
||
3206 | } |
||
3207 | |||
3208 | /** |
||
3209 | * File path of local server side work file path |
||
3210 | * |
||
3211 | * @param string $path path need convert encoding to server encoding |
||
3212 | * @return string |
||
3213 | * @author Naoki Sawada |
||
3214 | */ |
||
3215 | protected function getWorkFile($path) { |
||
3216 | if ($work = $this->getTempFile()) { |
||
3217 | if ($wfp = fopen($work, 'wb')) { |
||
3218 | if ($fp = $this->_fopen($path)) { |
||
3219 | while(!feof($fp)) { |
||
3220 | fwrite($wfp, fread($fp, 8192)); |
||
3221 | } |
||
3222 | $this->_fclose($fp, $path); |
||
3223 | fclose($wfp); |
||
3224 | return $work; |
||
3225 | } |
||
3226 | } |
||
3227 | } |
||
3228 | return false; |
||
3229 | } |
||
3230 | |||
3231 | /** |
||
3232 | * Get image size array with `dimensions` |
||
3233 | * |
||
3234 | * @param string $path path need convert encoding to server encoding |
||
3235 | * @param string $mime file mime type |
||
3236 | * @return array|false |
||
3237 | */ |
||
3238 | public function getImageSize($path, $mime = '') { |
||
3239 | $size = false; |
||
3240 | if ($mime === '' || strtolower(substr($mime, 0, 5)) === 'image') { |
||
3241 | if ($work = $this->getWorkFile($path)) { |
||
3242 | if ($size = getimagesize($work)) { |
||
3243 | $size['dimensions'] = $size[0].'x'.$size[1]; |
||
3244 | } |
||
3245 | } |
||
3246 | is_file($work) && unlink($work); |
||
3247 | } |
||
3248 | return $size; |
||
3249 | } |
||
3250 | |||
3251 | /** |
||
3252 | * Delete dirctory trees |
||
3253 | * |
||
3254 | * @param string $localpath path need convert encoding to server encoding |
||
3255 | * @return boolean |
||
3256 | * @author Naoki Sawada |
||
3257 | */ |
||
3258 | protected function delTree($localpath) { |
||
3259 | foreach ($this->_scandir($localpath) as $p) { |
||
3260 | elFinder::extendTimeLimit(); |
||
3261 | $stat = $this->stat($this->convEncOut($p)); |
||
3262 | $this->convEncIn(); |
||
3263 | ($stat['mime'] === 'directory')? $this->delTree($p) : $this->_unlink($p); |
||
3264 | } |
||
3265 | return $this->_rmdir($localpath); |
||
3266 | } |
||
3267 | |||
3268 | /** |
||
3269 | * Copy items to a new temporary directory on the local server |
||
3270 | * |
||
3271 | * @param array $hashes target hashes |
||
3272 | * @param string $dir destination directory (for recurcive) |
||
3273 | * @return string|false saved path name |
||
3274 | * @author Naoki Sawada |
||
3275 | */ |
||
3276 | protected function getItemsInHand($hashes, $dir = null) { |
||
3277 | static $totalSize = 0; |
||
3278 | if (is_null($dir)) { |
||
3279 | $totalSize = 0; |
||
3280 | if (! $tmpDir = $this->getTempPath()) { |
||
3281 | return false; |
||
3282 | } |
||
3283 | $dir = tempnam($tmpDir, 'elf'); |
||
3284 | if (!unlink($dir) || !mkdir($dir, 0700, true)) { |
||
3285 | return false; |
||
3286 | } |
||
3287 | register_shutdown_function(array($this, 'rmdirRecursive'), $dir); |
||
3288 | } |
||
3289 | $res = true; |
||
3290 | $files = array(); |
||
3291 | foreach ($hashes as $hash) { |
||
3292 | if (($file = $this->file($hash)) == false) { |
||
3293 | continue; |
||
3294 | } |
||
3295 | if (!$file['read']) { |
||
3296 | continue; |
||
3297 | } |
||
3298 | |||
3299 | $name = $file['name']; |
||
3300 | // for call from search results |
||
3301 | if (isset($files[$name])) { |
||
3302 | $name = preg_replace('/^(.*?)(\..*)?$/', '$1_'.$files[$name]++.'$2', $name); |
||
3303 | } else { |
||
3304 | $files[$name] = 1; |
||
3305 | } |
||
3306 | $target = $dir.DIRECTORY_SEPARATOR.$name; |
||
3307 | |||
3308 | if ($file['mime'] === 'directory') { |
||
3309 | $chashes = array(); |
||
3310 | $_files = $this->scandir($hash); |
||
3311 | 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.
Loading history...
|
|||
3312 | if ($file['read']) { |
||
3313 | $chashes[] = $_file['hash']; |
||
3314 | } |
||
3315 | } |
||
3316 | 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
Loading history...
|
|||
3317 | $res = $this->getItemsInHand($chashes, $target); |
||
3318 | } |
||
3319 | if (!$res) { |
||
3320 | break; |
||
3321 | } |
||
3322 | !empty($file['ts']) && touch($target, $file['ts']); |
||
3323 | } else { |
||
3324 | $path = $this->decode($hash); |
||
3325 | if ($fp = $this->fopenCE($path)) { |
||
3326 | if ($tfp = fopen($target, 'wb')) { |
||
3327 | $totalSize += stream_copy_to_stream($fp, $tfp); |
||
3328 | fclose($tfp); |
||
3329 | } |
||
3330 | !empty($file['ts']) && touch($target, $file['ts']); |
||
3331 | $this->fcloseCE($fp, $path); |
||
3332 | } |
||
3333 | if ($this->options['maxArcFilesSize'] > 0 && $this->options['maxArcFilesSize'] < $totalSize) { |
||
3334 | $res = $this->setError(elFinder::ERROR_ARC_MAXSIZE); |
||
3335 | } |
||
3336 | } |
||
3337 | } |
||
3338 | return $res? $dir : false; |
||
3339 | } |
||
3340 | |||
3341 | /*********************** file stat *********************/ |
||
3342 | |||
3343 | /** |
||
3344 | * Check file attribute |
||
3345 | * |
||
3346 | * @param string $path file path |
||
3347 | * @param string $name attribute name (read|write|locked|hidden) |
||
3348 | * @param bool $val attribute value returned by file system |
||
3349 | * @param bool $isDir path is directory (true: directory, false: file) |
||
3350 | * @return bool |
||
3351 | * @author Dmitry (dio) Levashov |
||
3352 | **/ |
||
3353 | protected function attr($path, $name, $val=null, $isDir=null) { |
||
3354 | if (!isset($this->defaults[$name])) { |
||
3355 | return false; |
||
3356 | } |
||
3357 | |||
3358 | |||
3359 | $perm = null; |
||
3360 | |||
3361 | if ($this->access) { |
||
3362 | $perm = call_user_func($this->access, $name, $path, $this->options['accessControlData'], $this, $isDir); |
||
3363 | |||
3364 | if ($perm !== null) { |
||
3365 | return !!$perm; |
||
3366 | } |
||
3367 | } |
||
3368 | |||
3369 | if ($this->separator != '/') { |
||
3370 | $path = str_replace($this->separator, '/', $this->relpathCE($path)); |
||
3371 | } else { |
||
3372 | $path = $this->relpathCE($path); |
||
3373 | } |
||
3374 | |||
3375 | $path = '/'.$path; |
||
3376 | |||
3377 | for ($i = 0, $c = count($this->attributes); $i < $c; $i++) { |
||
3378 | $attrs = $this->attributes[$i]; |
||
3379 | |||
3380 | if (isset($attrs[$name]) && isset($attrs['pattern']) && preg_match($attrs['pattern'], $path)) { |
||
3381 | $perm = $attrs[$name]; |
||
3382 | } |
||
3383 | } |
||
3384 | |||
3385 | return $perm === null ? (is_null($val)? $this->defaults[$name] : $val) : !!$perm; |
||
3386 | } |
||
3387 | |||
3388 | /** |
||
3389 | * Return true if file with given name can be created in given folder. |
||
3390 | * |
||
3391 | * @param string $dir parent dir path |
||
3392 | * @param string $name new file name |
||
3393 | * @param null $isDir |
||
3394 | * @return bool |
||
3395 | * @author Dmitry (dio) Levashov |
||
3396 | */ |
||
3397 | protected function allowCreate($dir, $name, $isDir = null) { |
||
3398 | $path = $this->joinPathCE($dir, $name); |
||
3399 | $perm = null; |
||
3400 | |||
3401 | if ($this->access) { |
||
3402 | $perm = call_user_func($this->access, 'write', $path, $this->options['accessControlData'], $this, $isDir); |
||
3403 | if ($perm !== null) { |
||
3404 | return !!$perm; |
||
3405 | } |
||
3406 | } |
||
3407 | |||
3408 | $testPath = $this->separator.$this->relpathCE($path); |
||
3409 | |||
3410 | for ($i = 0, $c = count($this->attributes); $i < $c; $i++) { |
||
3411 | $attrs = $this->attributes[$i]; |
||
3412 | |||
3413 | if (isset($attrs['write']) && isset($attrs['pattern']) && preg_match($attrs['pattern'], $testPath)) { |
||
3414 | $perm = $attrs['write']; |
||
3415 | } |
||
3416 | } |
||
3417 | |||
3418 | return $perm === null ? true : $perm; |
||
3419 | } |
||
3420 | |||
3421 | /** |
||
3422 | * Return true if file MIME type can save with check uploadOrder config. |
||
3423 | * |
||
3424 | * @param string $mime |
||
3425 | * @return boolean |
||
3426 | */ |
||
3427 | protected function allowPutMime($mime) { |
||
3428 | // logic based on http://httpd.apache.org/docs/2.2/mod/mod_authz_host.html#order |
||
3429 | $allow = $this->mimeAccepted($mime, $this->uploadAllow, null); |
||
3430 | $deny = $this->mimeAccepted($mime, $this->uploadDeny, null); |
||
3431 | $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
Loading history...
|
|||
3432 | 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.
Loading history...
|
|||
3433 | $res = false; // default is deny |
||
3434 | 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) { }
Loading history...
|
|||
3435 | $res = true; |
||
3436 | }// else (both match | no match | match only deny) { deny } |
||
3437 | } else { // array('deny', 'allow'), default is to 'allow' - this is the default rule |
||
3438 | $res = true; // default is allow |
||
3439 | 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) { }
Loading history...
|
|||
3440 | $res = false; |
||
3441 | } // else (both match | no match | match only allow) { allow } |
||
3442 | } |
||
3443 | return $res; |
||
3444 | } |
||
3445 | |||
3446 | /** |
||
3447 | * Return fileinfo |
||
3448 | * |
||
3449 | * @param string $path file cache |
||
3450 | * @return array |
||
3451 | * @author Dmitry (dio) Levashov |
||
3452 | **/ |
||
3453 | protected function stat($path) { |
||
3454 | if ($path === false || is_null($path)) { |
||
3455 | return false; |
||
3456 | } |
||
3457 | $is_root = ($path == $this->root); |
||
3458 | if ($is_root) { |
||
3459 | $rootKey = md5($path.(isset($this->options['alias'])? $this->options['alias'] : '')); |
||
3460 | if (!isset($this->sessionCache['rootstat'])) { |
||
3461 | $this->sessionCache['rootstat'] = array(); |
||
3462 | } |
||
3463 | if (! $this->isMyReload()) { |
||
3464 | // need $path as key for netmount/netunmount |
||
3465 | if (isset($this->sessionCache['rootstat'][$rootKey])) { |
||
3466 | if ($ret = $this->sessionCache['rootstat'][$rootKey]) { |
||
3467 | if ($this->options['rootRev'] === $ret['rootRev']) { |
||
3468 | if (isset($this->options['phash'])) { |
||
3469 | $ret['isroot'] = 1; |
||
3470 | $ret['phash'] = $this->options['phash']; |
||
3471 | } |
||
3472 | return $ret; |
||
3473 | } |
||
3474 | } |
||
3475 | } |
||
3476 | } |
||
3477 | } |
||
3478 | $ret = isset($this->cache[$path]) |
||
3479 | ? $this->cache[$path] |
||
3480 | : $this->updateCache($path, $this->convEncOut($this->_stat($this->convEncIn($path)))); |
||
3481 | if ($is_root) { |
||
3482 | $this->rootModified = false; |
||
3483 | $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
Loading history...
|
|||
3484 | $this->session->set($this->id, $this->sessionCache); |
||
3485 | if (isset($this->options['phash'])) { |
||
3486 | $ret['isroot'] = 1; |
||
3487 | $ret['phash'] = $this->options['phash']; |
||
3488 | } |
||
3489 | } |
||
3490 | return $ret; |
||
3491 | } |
||
3492 | |||
3493 | /** |
||
3494 | * Get root stat extra key values |
||
3495 | * |
||
3496 | * @return array stat extras |
||
3497 | * @author Naoki Sawada |
||
3498 | */ |
||
3499 | protected function getRootStatExtra() { |
||
3500 | $stat = array(); |
||
3501 | if ($this->rootName) { |
||
3502 | $stat['name'] = $this->rootName; |
||
3503 | } |
||
3504 | $stat['rootRev'] = $this->options['rootRev']; |
||
3505 | $stat['options'] = $this->options(null); |
||
3506 | return $stat; |
||
3507 | } |
||
3508 | |||
3509 | /** |
||
3510 | * Put file stat in cache and return it |
||
3511 | * |
||
3512 | * @param string $path file path |
||
3513 | * @param array $stat file stat |
||
3514 | * @return array |
||
3515 | * @author Dmitry (dio) Levashov |
||
3516 | **/ |
||
3517 | protected function updateCache($path, $stat) { |
||
3518 | if (empty($stat) || !is_array($stat)) { |
||
3519 | return $this->cache[$path] = array(); |
||
3520 | } |
||
3521 | |||
3522 | $stat['hash'] = $this->encode($path); |
||
3523 | |||
3524 | $root = $path == $this->root; |
||
3525 | $parent = ''; |
||
3526 | |||
3527 | if ($root) { |
||
3528 | $stat = array_merge($stat, $this->getRootStatExtra()); |
||
3529 | } else { |
||
3530 | if (!isset($stat['name']) || $stat['name'] === '') { |
||
3531 | $stat['name'] = $this->basenameCE($path); |
||
3532 | } |
||
3533 | if (empty($stat['phash'])) { |
||
3534 | $parent = $this->dirnameCE($path); |
||
3535 | $stat['phash'] = $this->encode($parent); |
||
3536 | } else { |
||
3537 | $parent = $this->getPath($stat['phash']); |
||
3538 | } |
||
3539 | } |
||
3540 | |||
3541 | // name check |
||
3542 | if (!$jeName = json_encode($stat['name'])) { |
||
3543 | return $this->cache[$path] = array(); |
||
3544 | } |
||
3545 | // fix name if required |
||
3546 | if ($this->options['utf8fix'] && $this->options['utf8patterns'] && $this->options['utf8replace']) { |
||
3547 | $stat['name'] = json_decode(str_replace($this->options['utf8patterns'], $this->options['utf8replace'], $jeName)); |
||
3548 | } |
||
3549 | |||
3550 | |||
3551 | if (empty($stat['mime'])) { |
||
3552 | $stat['mime'] = $this->mimetype($stat['name']); |
||
3553 | } |
||
3554 | |||
3555 | // @todo move dateformat to client |
||
3556 | // $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.
Loading history...
|
|||
3557 | // ? $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.
Loading history...
|
|||
3558 | // : 'unknown'; |
||
3559 | |||
3560 | if (!isset($stat['size'])) { |
||
3561 | $stat['size'] = 'unknown'; |
||
3562 | } |
||
3563 | |||
3564 | if ($isDir = ($stat['mime'] === 'directory')) { |
||
3565 | $stat['volumeid'] = $this->id; |
||
3566 | } |
||
3567 | |||
3568 | $stat['read'] = intval($this->attr($path, 'read', isset($stat['read']) ? !!$stat['read'] : null, $isDir)); |
||
3569 | $stat['write'] = intval($this->attr($path, 'write', isset($stat['write']) ? !!$stat['write'] : null, $isDir)); |
||
3570 | if ($root) { |
||
3571 | $stat['locked'] = 1; |
||
3572 | if ($this->options['type'] !== '') { |
||
3573 | $stat['type'] = $this->options['type']; |
||
3574 | } |
||
3575 | } else { |
||
3576 | // lock when parent directory is not writable |
||
3577 | if (!isset($stat['locked'])) { |
||
3578 | $pstat = $this->stat($parent); |
||
3579 | if (isset($pstat['write']) && !$pstat['write']) { |
||
3580 | $stat['locked'] = true; |
||
3581 | } |
||
3582 | } |
||
3583 | if ($this->attr($path, 'locked', isset($stat['locked']) ? !!$stat['locked'] : null, $isDir)) { |
||
3584 | $stat['locked'] = 1; |
||
3585 | } else { |
||
3586 | unset($stat['locked']); |
||
3587 | } |
||
3588 | } |
||
3589 | |||
3590 | if ($root) { |
||
3591 | unset($stat['hidden']); |
||
3592 | } elseif ($this->attr($path, 'hidden', isset($stat['hidden']) ? !!$stat['hidden'] : null, $isDir) |
||
3593 | || !$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) { }
Loading history...
|
|||
3594 | $stat['hidden'] = 1; |
||
3595 | } else { |
||
3596 | unset($stat['hidden']); |
||
3597 | } |
||
3598 | |||
3599 | if ($stat['read'] && empty($stat['hidden'])) { |
||
3600 | |||
3601 | if ($isDir) { |
||
3602 | // caching parent's subdirs |
||
3603 | 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
Loading history...
|
|||
3604 | $this->subdirsCache[$parent] = true; |
||
3605 | } |
||
3606 | // for dir - check for subdirs |
||
3607 | if ($this->options['checkSubfolders']) { |
||
3608 | if (isset($stat['dirs'])) { |
||
3609 | if ($stat['dirs']) { |
||
3610 | $stat['dirs'] = 1; |
||
3611 | } else { |
||
3612 | unset($stat['dirs']); |
||
3613 | } |
||
3614 | } elseif (!empty($stat['alias']) && !empty($stat['target'])) { |
||
3615 | $stat['dirs'] = isset($this->cache[$stat['target']]) |
||
3616 | ? intval(isset($this->cache[$stat['target']]['dirs'])) |
||
3617 | : $this->subdirsCE($stat['target']); |
||
3618 | |||
3619 | } elseif ($this->subdirsCE($path)) { |
||
3620 | $stat['dirs'] = 1; |
||
3621 | } |
||
3622 | } else { |
||
3623 | $stat['dirs'] = 1; |
||
3624 | } |
||
3625 | if ($this->options['dirUrlOwn'] === true) { |
||
3626 | $stat['url'] = '#elf_' . $stat['hash']; |
||
3627 | } |
||
3628 | } else { |
||
3629 | // for files - check for thumbnails |
||
3630 | $p = isset($stat['target']) ? $stat['target'] : $path; |
||
3631 | if ($this->tmbURL && !isset($stat['tmb']) && $this->canCreateTmb($p, $stat)) { |
||
3632 | $tmb = $this->gettmb($p, $stat); |
||
3633 | $stat['tmb'] = $tmb ? $tmb : 1; |
||
3634 | } |
||
3635 | |||
3636 | } |
||
3637 | if (!isset($stat['url']) && $this->URL && $this->encoding) { |
||
3638 | $_path = str_replace($this->separator, '/', substr($path, strlen($this->root) + 1)); |
||
3639 | $stat['url'] = rtrim($this->URL, '/') . '/' . str_replace('%2F', '/', rawurlencode((substr(PHP_OS, 0, 3) === 'WIN')? $_path : $this->convEncIn($_path, true))); |
||
3640 | } |
||
3641 | } else { |
||
3642 | if ($isDir) { |
||
3643 | unset($stat['dirs']); |
||
3644 | } |
||
3645 | } |
||
3646 | |||
3647 | if (!empty($stat['alias']) && !empty($stat['target'])) { |
||
3648 | $stat['thash'] = $this->encode($stat['target']); |
||
3649 | //$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.
Loading history...
|
|||
3650 | unset($stat['target']); |
||
3651 | } |
||
3652 | |||
3653 | return $this->cache[$path] = $stat; |
||
3654 | } |
||
3655 | |||
3656 | /** |
||
3657 | * Get stat for folder content and put in cache |
||
3658 | * |
||
3659 | * @param string $path |
||
3660 | * @return void |
||
3661 | * @author Dmitry (dio) Levashov |
||
3662 | **/ |
||
3663 | protected function cacheDir($path) { |
||
3664 | $this->dirsCache[$path] = array(); |
||
3665 | $this->subdirsCache[$path] = false; |
||
3666 | |||
3667 | foreach ($this->scandirCE($path) as $p) { |
||
3668 | if (($stat = $this->stat($p)) && empty($stat['hidden'])) { |
||
3669 | if ($stat['mime'] === 'directory') { |
||
3670 | $this->subdirsCache[$path] = true; |
||
3671 | } |
||
3672 | $this->dirsCache[$path][] = $p; |
||
3673 | } |
||
3674 | } |
||
3675 | } |
||
3676 | |||
3677 | /** |
||
3678 | * Clean cache |
||
3679 | * |
||
3680 | * @return void |
||
3681 | * @author Dmitry (dio) Levashov |
||
3682 | **/ |
||
3683 | protected function clearcache() { |
||
3684 | $this->cache = $this->dirsCache = $this->subdirsCache = array(); |
||
3685 | } |
||
3686 | |||
3687 | /** |
||
3688 | * Return file mimetype |
||
3689 | * |
||
3690 | * @param string $path file path |
||
3691 | * @param string $name |
||
3692 | * @return string |
||
3693 | * @author Dmitry (dio) Levashov |
||
3694 | */ |
||
3695 | protected function mimetype($path, $name = '') { |
||
3696 | $type = ''; |
||
3697 | |||
3698 | if ($name === '') { |
||
3699 | $name = $path; |
||
3700 | } |
||
3701 | $ext = (false === $pos = strrpos($name, '.')) ? '' : substr($name, $pos + 1); |
||
3702 | if (is_readable($path)) { |
||
3703 | if ($this->mimeDetect == 'finfo') { |
||
3704 | if ($type = finfo_file($this->finfo, $path)) { |
||
3705 | if ($ext && preg_match('~^application/(?:octet-stream|(?:x-)?zip)~', $type)) { |
||
3706 | if (isset(elFinderVolumeDriver::$mimetypes[$ext])) $type = elFinderVolumeDriver::$mimetypes[$ext]; |
||
3707 | } else if ($ext === 'js' && preg_match('~^text/~', $type)) { |
||
3708 | $type = 'text/javascript'; |
||
3709 | } |
||
3710 | } else { |
||
3711 | $type = 'unknown'; |
||
3712 | } |
||
3713 | } else if ($this->mimeDetect == 'mime_content_type') { |
||
3714 | $type = mime_content_type($path); |
||
3715 | } |
||
3716 | } |
||
3717 | if (! $type) { |
||
3718 | $type = elFinderVolumeDriver::mimetypeInternalDetect($path); |
||
3719 | } |
||
3720 | |||
3721 | $type = explode(';', $type); |
||
3722 | $type = trim($type[0]); |
||
3723 | |||
3724 | if (in_array($type, array('application/x-empty', 'inode/x-empty'))) { |
||
3725 | // finfo return this mime for empty files |
||
3726 | $type = 'text/plain'; |
||
3727 | } elseif ($type == 'application/x-zip') { |
||
3728 | // http://elrte.org/redmine/issues/163 |
||
3729 | $type = 'application/zip'; |
||
3730 | } |
||
3731 | |||
3732 | // mime type normalization |
||
3733 | $_checkKey = strtolower($ext.':'.$type); |
||
3734 | if (isset($this->options['mimeMap'][$_checkKey])) { |
||
3735 | $type = $this->options['mimeMap'][$_checkKey]; |
||
3736 | } |
||
3737 | |||
3738 | return $type == 'unknown' && $this->mimeDetect != 'internal' |
||
3739 | ? elFinderVolumeDriver::mimetypeInternalDetect($path) |
||
3740 | : $type; |
||
3741 | |||
3742 | } |
||
3743 | |||
3744 | /** |
||
3745 | * Detect file mimetype using "internal" method or Loading mime.types with $path = '' |
||
3746 | * |
||
3747 | * @param string $path file path |
||
3748 | * @return string |
||
3749 | * @author Dmitry (dio) Levashov |
||
3750 | **/ |
||
3751 | static protected function mimetypeInternalDetect($path = '') { |
||
0 ignored issues
–
show
|
|||
3752 | // load default MIME table file "mime.types" |
||
3753 | if (!elFinderVolumeDriver::$mimetypesLoaded) { |
||
3754 | elFinderVolumeDriver::$mimetypesLoaded = true; |
||
3755 | $file = elFinder::$defaultMimefile; |
||
3756 | if ($file === '' || ! is_readable($file)) { |
||
3757 | $file = dirname(__FILE__).DIRECTORY_SEPARATOR.'mime.types'; |
||
3758 | } |
||
3759 | if (is_readable($file)) { |
||
3760 | $mimecf = file($file); |
||
3761 | foreach ($mimecf as $line_num => $line) { |
||
3762 | if (!preg_match('/^\s*#/', $line)) { |
||
3763 | $mime = preg_split('/\s+/', $line, -1, PREG_SPLIT_NO_EMPTY); |
||
3764 | for ($i = 1, $size = count($mime); $i < $size ; $i++) { |
||
3765 | if (!isset(elFinderVolumeDriver::$mimetypes[$mime[$i]])) { |
||
3766 | elFinderVolumeDriver::$mimetypes[$mime[$i]] = $mime[0]; |
||
3767 | } |
||
3768 | } |
||
3769 | } |
||
3770 | } |
||
3771 | } |
||
3772 | } |
||
3773 | $ext = ''; |
||
3774 | if ($path) { |
||
3775 | $pinfo = pathinfo($path); |
||
3776 | $ext = isset($pinfo['extension']) ? strtolower($pinfo['extension']) : ''; |
||
3777 | } |
||
3778 | return ($ext && isset(elFinderVolumeDriver::$mimetypes[$ext])) ? elFinderVolumeDriver::$mimetypes[$ext] : 'unknown'; |
||
3779 | } |
||
3780 | |||
3781 | /** |
||
3782 | * Return file/total directory size |
||
3783 | * |
||
3784 | * @param string $path file path |
||
3785 | * @return int |
||
3786 | * @author Dmitry (dio) Levashov |
||
3787 | **/ |
||
3788 | protected function countSize($path) { |
||
3789 | |||
3790 | elFinder::extendTimeLimit(); |
||
3791 | |||
3792 | $stat = $this->stat($path); |
||
3793 | |||
3794 | if (empty($stat) || !$stat['read'] || !empty($stat['hidden'])) { |
||
3795 | return 'unknown'; |
||
3796 | } |
||
3797 | |||
3798 | if ($stat['mime'] != 'directory') { |
||
3799 | return $stat['size']; |
||
3800 | } |
||
3801 | |||
3802 | $subdirs = $this->options['checkSubfolders']; |
||
3803 | $this->options['checkSubfolders'] = true; |
||
3804 | $result = 0; |
||
3805 | foreach ($this->getScandir($path) as $stat) { |
||
3806 | $size = $stat['mime'] == 'directory' && $stat['read'] |
||
3807 | ? $this->countSize($this->joinPathCE($path, $stat['name'])) |
||
3808 | : (isset($stat['size']) ? intval($stat['size']) : 0); |
||
3809 | if ($size > 0) { |
||
3810 | $result += $size; |
||
3811 | } |
||
3812 | } |
||
3813 | $this->options['checkSubfolders'] = $subdirs; |
||
3814 | return $result; |
||
3815 | } |
||
3816 | |||
3817 | /** |
||
3818 | * Return true if all mimes is directory or files |
||
3819 | * |
||
3820 | * @param string $mime1 mimetype |
||
3821 | * @param string $mime2 mimetype |
||
3822 | * @return bool |
||
3823 | * @author Dmitry (dio) Levashov |
||
3824 | **/ |
||
3825 | protected function isSameType($mime1, $mime2) { |
||
3826 | return ($mime1 == 'directory' && $mime1 == $mime2) || ($mime1 != 'directory' && $mime2 != 'directory'); |
||
3827 | } |
||
3828 | |||
3829 | /** |
||
3830 | * If file has required attr == $val - return file path, |
||
3831 | * If dir has child with has required attr == $val - return child path |
||
3832 | * |
||
3833 | * @param string $path file path |
||
3834 | * @param string $attr attribute name |
||
3835 | * @param bool $val attribute value |
||
3836 | * @return string|false |
||
3837 | * @author Dmitry (dio) Levashov |
||
3838 | **/ |
||
3839 | protected function closestByAttr($path, $attr, $val) { |
||
3840 | $stat = $this->stat($path); |
||
3841 | |||
3842 | if (empty($stat)) { |
||
3843 | return false; |
||
3844 | } |
||
3845 | |||
3846 | $v = isset($stat[$attr]) ? $stat[$attr] : false; |
||
3847 | |||
3848 | if ($v == $val) { |
||
3849 | return $path; |
||
3850 | } |
||
3851 | |||
3852 | return $stat['mime'] == 'directory' |
||
3853 | ? $this->childsByAttr($path, $attr, $val) |
||
3854 | : false; |
||
3855 | } |
||
3856 | |||
3857 | /** |
||
3858 | * Return first found children with required attr == $val |
||
3859 | * |
||
3860 | * @param string $path file path |
||
3861 | * @param string $attr attribute name |
||
3862 | * @param bool $val attribute value |
||
3863 | * @return string|false |
||
3864 | * @author Dmitry (dio) Levashov |
||
3865 | **/ |
||
3866 | protected function childsByAttr($path, $attr, $val) { |
||
3867 | foreach ($this->scandirCE($path) as $p) { |
||
3868 | if (($_p = $this->closestByAttr($p, $attr, $val)) != false) { |
||
0 ignored issues
–
show
|
|||
3869 | return $_p; |
||
3870 | } |
||
3871 | } |
||
3872 | return false; |
||
3873 | } |
||
3874 | |||
3875 | protected function isMyReload($target = '', $ARGtarget = '') { |
||
3876 | if ($this->rootModified || (! empty($this->ARGS['cmd']) && $this->ARGS['cmd'] === 'parents')) { |
||
3877 | return true; |
||
3878 | } |
||
3879 | if (! empty($this->ARGS['reload'])) { |
||
3880 | if ($ARGtarget === '') { |
||
3881 | $ARGtarget = isset($this->ARGS['target'])? $this->ARGS['target'] |
||
3882 | : ((isset($this->ARGS['targets']) && is_array($this->ARGS['targets']) && count($this->ARGS['targets']) === 1)? |
||
3883 | $this->ARGS['targets'][0] : ''); |
||
3884 | } |
||
3885 | if ($ARGtarget !== '') { |
||
3886 | $ARGtarget = strval($ARGtarget); |
||
3887 | if ($target === '') { |
||
3888 | return (strpos($ARGtarget, $this->id) === 0); |
||
3889 | } else { |
||
3890 | $target = strval($target); |
||
3891 | return ($target === $ARGtarget); |
||
3892 | } |
||
3893 | } |
||
3894 | } |
||
3895 | return false; |
||
3896 | } |
||
3897 | |||
3898 | /***************** get content *******************/ |
||
3899 | |||
3900 | /** |
||
3901 | * Return required dir's files info. |
||
3902 | * If onlyMimes is set - return only dirs and files of required mimes |
||
3903 | * |
||
3904 | * @param string $path dir path |
||
3905 | * @return array |
||
3906 | * @author Dmitry (dio) Levashov |
||
3907 | **/ |
||
3908 | protected function getScandir($path) { |
||
3909 | $files = array(); |
||
3910 | |||
3911 | !isset($this->dirsCache[$path]) && $this->cacheDir($path); |
||
3912 | |||
3913 | foreach ($this->dirsCache[$path] as $p) { |
||
3914 | if (($stat = $this->stat($p)) && empty($stat['hidden'])) { |
||
3915 | $files[] = $stat; |
||
3916 | } |
||
3917 | } |
||
3918 | |||
3919 | return $files; |
||
3920 | } |
||
3921 | |||
3922 | |||
3923 | /** |
||
3924 | * Return subdirs tree |
||
3925 | * |
||
3926 | * @param string $path parent dir path |
||
3927 | * @param int $deep tree deep |
||
3928 | * @param string $exclude |
||
3929 | * @return array |
||
3930 | * @author Dmitry (dio) Levashov |
||
3931 | */ |
||
3932 | protected function gettree($path, $deep, $exclude='') { |
||
3933 | $dirs = array(); |
||
3934 | |||
3935 | !isset($this->dirsCache[$path]) && $this->cacheDir($path); |
||
3936 | |||
3937 | foreach ($this->dirsCache[$path] as $p) { |
||
3938 | $stat = $this->stat($p); |
||
3939 | |||
3940 | 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
Loading history...
|
|||
3941 | $dirs[] = $stat; |
||
3942 | if ($deep > 0 && !empty($stat['dirs'])) { |
||
3943 | $dirs = array_merge($dirs, $this->gettree($p, $deep-1)); |
||
3944 | } |
||
3945 | } |
||
3946 | } |
||
3947 | |||
3948 | return $dirs; |
||
3949 | } |
||
3950 | |||
3951 | /** |
||
3952 | * Recursive files search |
||
3953 | * |
||
3954 | * @param string $path dir path |
||
3955 | * @param string $q search string |
||
3956 | * @param array $mimes |
||
3957 | * @return array |
||
3958 | * @author Dmitry (dio) Levashov |
||
3959 | **/ |
||
3960 | protected function doSearch($path, $q, $mimes) { |
||
3961 | $result = array(); |
||
3962 | |||
3963 | $timeout = $this->options['searchTimeout']? $this->searchStart + $this->options['searchTimeout'] : 0; |
||
3964 | if ($timeout && $timeout < time()) { |
||
3965 | $this->setError(elFinder::ERROR_SEARCH_TIMEOUT, $this->path($this->encode($path))); |
||
3966 | return $result; |
||
3967 | } |
||
3968 | |||
3969 | foreach($this->scandirCE($path) as $p) { |
||
3970 | elFinder::extendTimeLimit($this->options['searchTimeout'] + 30); |
||
3971 | |||
3972 | 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
Loading history...
|
|||
3973 | !$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
Loading history...
|
|||
3974 | break; |
||
3975 | } |
||
3976 | |||
3977 | |||
3978 | $stat = $this->stat($p); |
||
3979 | |||
3980 | 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
Loading history...
|
|||
3981 | continue; |
||
3982 | } |
||
3983 | |||
3984 | if (!empty($stat['hidden']) || !$this->mimeAccepted($stat['mime'], $mimes)) { |
||
3985 | continue; |
||
3986 | } |
||
3987 | |||
3988 | $name = $stat['name']; |
||
3989 | |||
3990 | if ($this->doSearchCurrentQuery['excludes']) { |
||
3991 | foreach($this->doSearchCurrentQuery['excludes'] as $exclude) { |
||
0 ignored issues
–
show
|
|||
3992 | if ($this->stripos($name, $exclude) !== false) { |
||
3993 | continue 2; |
||
3994 | } |
||
3995 | } |
||
3996 | } |
||
3997 | |||
3998 | 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
Loading history...
|
|||
3999 | $stat['path'] = $this->path($stat['hash']); |
||
4000 | if ($this->URL && !isset($stat['url'])) { |
||
4001 | $path = str_replace($this->separator, '/', substr($p, strlen($this->root) + 1)); |
||
4002 | if ($this->encoding) { |
||
4003 | $path = str_replace('%2F', '/', rawurlencode($this->convEncIn($path, true))); |
||
4004 | } |
||
4005 | $stat['url'] = $this->URL . $path; |
||
4006 | } |
||
4007 | |||
4008 | $result[] = $stat; |
||
4009 | } |
||
4010 | if ($stat['mime'] == 'directory' && $stat['read'] && !isset($stat['alias'])) { |
||
4011 | if (! $this->options['searchExDirReg'] || ! preg_match($this->options['searchExDirReg'], $p)) { |
||
4012 | $result = array_merge($result, $this->doSearch($p, $q, $mimes)); |
||
4013 | } |
||
4014 | } |
||
4015 | } |
||
4016 | |||
4017 | return $result; |
||
4018 | } |
||
4019 | |||
4020 | /********************** manuipulations ******************/ |
||
4021 | |||
4022 | /** |
||
4023 | * Copy file/recursive copy dir only in current volume. |
||
4024 | * Return new file path or false. |
||
4025 | * |
||
4026 | * @param string $src source path |
||
4027 | * @param string $dst destination dir path |
||
4028 | * @param string $name new file name (optionaly) |
||
4029 | * @return string|false |
||
4030 | * @author Dmitry (dio) Levashov |
||
4031 | **/ |
||
4032 | protected function copy($src, $dst, $name) { |
||
4033 | |||
4034 | elFinder::extendTimeLimit(); |
||
4035 | |||
4036 | $srcStat = $this->stat($src); |
||
4037 | $this->clearcache(); |
||
4038 | |||
4039 | if (!empty($srcStat['thash'])) { |
||
4040 | $target = $this->decode($srcStat['thash']); |
||
4041 | if (!$this->inpathCE($target, $this->root)) { |
||
4042 | return $this->setError(elFinder::ERROR_COPY, $this->path($srcStat['hash']), elFinder::ERROR_MKOUTLINK); |
||
4043 | } |
||
4044 | $stat = $this->stat($target); |
||
4045 | $this->clearcache(); |
||
4046 | 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
Loading history...
|
|||
4047 | ? $this->joinPathCE($dst, $name) |
||
4048 | : $this->setError(elFinder::ERROR_COPY, $this->path($srcStat['hash'])); |
||
4049 | } |
||
4050 | |||
4051 | if ($srcStat['mime'] === 'directory') { |
||
4052 | $testStat = $this->stat($this->joinPathCE($dst, $name)); |
||
4053 | $this->clearcache(); |
||
4054 | |||
4055 | 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
Loading history...
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
Loading history...
|
|||
4056 | return $this->setError(elFinder::ERROR_COPY, $this->path($srcStat['hash'])); |
||
4057 | } |
||
4058 | |||
4059 | $dst = $this->decode($testStat['hash']); |
||
4060 | |||
4061 | foreach ($this->getScandir($src) as $stat) { |
||
4062 | if (empty($stat['hidden'])) { |
||
4063 | $name = $stat['name']; |
||
4064 | $_src = $this->decode($stat['hash']); |
||
4065 | if (! $this->copy($_src, $dst, $name)) { |
||
4066 | $this->remove($dst, true); // fall back |
||
4067 | return $this->setError($this->error, elFinder::ERROR_COPY, $this->_path($src)); |
||
4068 | } |
||
4069 | } |
||
4070 | } |
||
4071 | |||
4072 | $this->added[] = $testStat; |
||
4073 | |||
4074 | return $dst; |
||
4075 | } |
||
4076 | |||
4077 | if ($this->options['copyJoin']) { |
||
4078 | $test = $this->joinPathCE($dst, $name); |
||
4079 | if ($testStat = $this->stat($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
Loading history...
|
|||
4080 | $this->remove($test); |
||
4081 | } |
||
4082 | } else { |
||
4083 | $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
Loading history...
|
|||
4084 | } |
||
4085 | if ($res = $this->convEncOut($this->_copy($this->convEncIn($src), $this->convEncIn($dst), $this->convEncIn($name)))) { |
||
4086 | $path = is_string($res)? $res : $this->joinPathCE($dst, $name); |
||
4087 | $this->clearcache(); |
||
4088 | $this->added[] = $this->stat($path); |
||
4089 | return $path; |
||
4090 | } |
||
4091 | |||
4092 | return $this->setError(elFinder::ERROR_COPY, $this->path($srcStat['hash'])); |
||
4093 | } |
||
4094 | |||
4095 | /** |
||
4096 | * Move file |
||
4097 | * Return new file path or false. |
||
4098 | * |
||
4099 | * @param string $src source path |
||
4100 | * @param string $dst destination dir path |
||
4101 | * @param string $name new file name |
||
4102 | * @return string|false |
||
4103 | * @author Dmitry (dio) Levashov |
||
4104 | **/ |
||
4105 | protected function move($src, $dst, $name) { |
||
4106 | $stat = $this->stat($src); |
||
4107 | $stat['realpath'] = $src; |
||
4108 | $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);
Loading history...
|
|||
4109 | $this->clearcache(); |
||
4110 | |||
4111 | if ($res = $this->convEncOut($this->_move($this->convEncIn($src), $this->convEncIn($dst), $this->convEncIn($name)))) { |
||
4112 | $this->removed[] = $stat; |
||
4113 | return is_string($res)? $res : $this->joinPathCE($dst, $name); |
||
4114 | } |
||
4115 | |||
4116 | return $this->setError(elFinder::ERROR_MOVE, $this->path($stat['hash'])); |
||
4117 | } |
||
4118 | |||
4119 | /** |
||
4120 | * Copy file from another volume. |
||
4121 | * Return new file path or false. |
||
4122 | * |
||
4123 | * @param Object $volume source volume |
||
4124 | * @param string $src source file hash |
||
4125 | * @param string $destination destination dir path |
||
4126 | * @param string $name file name |
||
4127 | * @return string|false |
||
4128 | * @author Dmitry (dio) Levashov |
||
4129 | **/ |
||
4130 | protected function copyFrom($volume, $src, $destination, $name) { |
||
4131 | |||
4132 | elFinder::extendTimeLimit(); |
||
4133 | |||
4134 | if (($source = $volume->file($src)) == false) { |
||
4135 | return $this->setError(elFinder::ERROR_COPY, '#'.$src, $volume->error()); |
||
4136 | } |
||
4137 | |||
4138 | $errpath = $volume->path($source['hash']); |
||
4139 | |||
4140 | if (!$this->nameAccepted($source['name'])) { |
||
4141 | return $this->setError(elFinder::ERROR_COPY, $errpath, elFinder::ERROR_INVALID_NAME); |
||
4142 | } |
||
4143 | |||
4144 | if (!$source['read']) { |
||
4145 | return $this->setError(elFinder::ERROR_COPY, $errpath, elFinder::ERROR_PERM_DENIED); |
||
4146 | } |
||
4147 | |||
4148 | if ($source['mime'] == 'directory') { |
||
4149 | $test = $this->stat($this->joinPathCE($destination, $name)); |
||
4150 | $this->clearcache(); |
||
4151 | |||
4152 | 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
Loading history...
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
Loading history...
|
|||
4153 | return $this->setError(elFinder::ERROR_COPY, $errpath); |
||
4154 | } |
||
4155 | |||
4156 | $path = $this->joinPathCE($destination, $name); |
||
0 ignored issues
–
show
$path 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
Loading history...
|
|||
4157 | $path = $this->decode($test['hash']); |
||
4158 | |||
4159 | foreach ($volume->scandir($src) as $entr) { |
||
4160 | if (!$this->copyFrom($volume, $entr['hash'], $path, $entr['name'])) { |
||
4161 | $this->remove($path, true); // fall back |
||
4162 | return $this->setError($this->error, elFinder::ERROR_COPY, $errpath); |
||
4163 | } |
||
4164 | } |
||
4165 | |||
4166 | $this->added[] = $test; |
||
4167 | } else { |
||
4168 | // $mime = $source['mime']; |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
60% 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.
Loading history...
|
|||
4169 | // $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.
Loading history...
|
|||
4170 | if (($dim = $volume->dimensions($src))) { |
||
4171 | $s = explode('x', $dim); |
||
4172 | $source['width'] = $s[0]; |
||
4173 | $source['height'] = $s[1]; |
||
4174 | } |
||
4175 | |||
4176 | if (($fp = $volume->open($src)) == false |
||
4177 | || ($path = $this->saveCE($fp, $destination, $name, $source)) == false) { |
||
4178 | $fp && $volume->close($fp, $src); |
||
4179 | return $this->setError(elFinder::ERROR_COPY, $errpath); |
||
4180 | } |
||
4181 | $volume->close($fp, $src); |
||
4182 | |||
4183 | // MIME check |
||
4184 | $stat = $this->stat($path); |
||
0 ignored issues
–
show
It seems like
$path defined by $this->saveCE($fp, $destination, $name, $source) on line 4177 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.
Loading history...
|
|||
4185 | $mimeByName = elFinderVolumeDriver::mimetypeInternalDetect($stat['name']); |
||
4186 | if ($stat['mime'] === $mimeByName) { |
||
4187 | $mimeByName = ''; |
||
4188 | } |
||
4189 | if (!$this->allowPutMime($stat['mime']) || ($mimeByName && $mimeByName !== 'unknown' && !$this->allowPutMime($mimeByName))) { |
||
4190 | $this->remove($path, true); |
||
0 ignored issues
–
show
It seems like
$path defined by $this->saveCE($fp, $destination, $name, $source) on line 4177 can also be of type boolean ; however, elFinderVolumeDriver::remove() 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.
Loading history...
|
|||
4191 | return $this->setError(elFinder::ERROR_UPLOAD_FILE_MIME, $errpath); |
||
4192 | } |
||
4193 | |||
4194 | $this->added[] = $stat; |
||
4195 | } |
||
4196 | |||
4197 | return $path; |
||
4198 | } |
||
4199 | |||
4200 | /** |
||
4201 | * Remove file/ recursive remove dir |
||
4202 | * |
||
4203 | * @param string $path file path |
||
4204 | * @param bool $force try to remove even if file locked |
||
4205 | * @return bool |
||
4206 | * @author Dmitry (dio) Levashov |
||
4207 | **/ |
||
4208 | protected function remove($path, $force = false) { |
||
4209 | $stat = $this->stat($path); |
||
4210 | |||
4211 | if (empty($stat)) { |
||
4212 | return $this->setError(elFinder::ERROR_RM, $path, elFinder::ERROR_FILE_NOT_FOUND); |
||
4213 | } |
||
4214 | |||
4215 | $stat['realpath'] = $path; |
||
4216 | $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);
Loading history...
|
|||
4217 | $this->clearcache(); |
||
4218 | |||
4219 | if (!$force && !empty($stat['locked'])) { |
||
4220 | return $this->setError(elFinder::ERROR_LOCKED, $this->path($stat['hash'])); |
||
4221 | } |
||
4222 | |||
4223 | if ($stat['mime'] == 'directory' && empty($stat['thash'])) { |
||
4224 | $ret = $this->delTree($this->convEncIn($path)); |
||
4225 | $this->convEncOut(); |
||
4226 | if (!$ret) { |
||
4227 | return $this->setError(elFinder::ERROR_RM, $this->path($stat['hash'])); |
||
4228 | } |
||
4229 | } else { |
||
4230 | if ($this->convEncOut(!$this->_unlink($this->convEncIn($path)))) { |
||
4231 | return $this->setError(elFinder::ERROR_RM, $this->path($stat['hash'])); |
||
4232 | } |
||
4233 | } |
||
4234 | |||
4235 | $this->removed[] = $stat; |
||
4236 | return true; |
||
4237 | } |
||
4238 | |||
4239 | |||
4240 | /************************* thumbnails **************************/ |
||
4241 | |||
4242 | /** |
||
4243 | * Return thumbnail file name for required file |
||
4244 | * |
||
4245 | * @param array $stat file stat |
||
4246 | * @return string |
||
4247 | * @author Dmitry (dio) Levashov |
||
4248 | **/ |
||
4249 | protected function tmbname($stat) { |
||
4250 | return $stat['hash'].$stat['ts'].'.png'; |
||
4251 | } |
||
4252 | |||
4253 | /** |
||
4254 | * Return thumnbnail name if exists |
||
4255 | * |
||
4256 | * @param string $path file path |
||
4257 | * @param array $stat file stat |
||
4258 | * @return string|false |
||
4259 | * @author Dmitry (dio) Levashov |
||
4260 | **/ |
||
4261 | protected function gettmb($path, $stat) { |
||
4262 | if ($this->tmbURL && $this->tmbPath) { |
||
4263 | // file itself thumnbnail |
||
4264 | if (strpos($path, $this->tmbPath) === 0) { |
||
4265 | return basename($path); |
||
4266 | } |
||
4267 | |||
4268 | $name = $this->tmbname($stat); |
||
4269 | if (file_exists($this->tmbPath.DIRECTORY_SEPARATOR.$name)) { |
||
4270 | return $name; |
||
4271 | } |
||
4272 | } |
||
4273 | return false; |
||
4274 | } |
||
4275 | |||
4276 | /** |
||
4277 | * Return true if thumnbnail for required file can be created |
||
4278 | * |
||
4279 | * @param string $path thumnbnail path |
||
4280 | * @param array $stat file stat |
||
4281 | * @param bool $checkTmbPath |
||
4282 | * @return string|bool |
||
4283 | * @author Dmitry (dio) Levashov |
||
4284 | **/ |
||
4285 | protected function canCreateTmb($path, $stat, $checkTmbPath = true) { |
||
4286 | if ((! $checkTmbPath || $this->tmbPathWritable) |
||
4287 | && (! $this->tmbPath || strpos($path, $this->tmbPath) === false) // do not create thumnbnail for thumnbnail |
||
4288 | ) { |
||
4289 | $mime = strtolower($stat['mime']); |
||
4290 | list($type) = explode('/', $mime); |
||
4291 | if (! empty($this->imgConverter)) { |
||
4292 | if (isset($this->imgConverter[$mime])) { |
||
4293 | return true; |
||
4294 | } |
||
4295 | if (isset($this->imgConverter[$type])) { |
||
4296 | return true; |
||
4297 | } |
||
4298 | } |
||
4299 | return $this->imgLib |
||
4300 | && ($type === 'image') |
||
4301 | && ($this->imgLib == 'gd' ? in_array($stat['mime'], array('image/jpeg', 'image/png', 'image/gif', 'image/x-ms-bmp')) : true); |
||
4302 | } |
||
4303 | return false; |
||
4304 | } |
||
4305 | |||
4306 | /** |
||
4307 | * Return true if required file can be resized. |
||
4308 | * By default - the same as canCreateTmb |
||
4309 | * |
||
4310 | * @param string $path thumnbnail path |
||
4311 | * @param array $stat file stat |
||
4312 | * @return string|bool |
||
4313 | * @author Dmitry (dio) Levashov |
||
4314 | **/ |
||
4315 | protected function canResize($path, $stat) { |
||
4316 | return $this->canCreateTmb($path, $stat, false); |
||
4317 | } |
||
4318 | |||
4319 | /** |
||
4320 | * Create thumnbnail and return it's URL on success |
||
4321 | * |
||
4322 | * @param string $path file path |
||
4323 | * @param $stat |
||
4324 | * @return false|string |
||
4325 | * @internal param string $mime file mime type |
||
4326 | * @author Dmitry (dio) Levashov |
||
4327 | */ |
||
4328 | protected function createTmb($path, $stat) { |
||
4329 | if (!$stat || !$this->canCreateTmb($path, $stat)) { |
||
4330 | return false; |
||
4331 | } |
||
4332 | |||
4333 | $name = $this->tmbname($stat); |
||
4334 | $tmb = $this->tmbPath.DIRECTORY_SEPARATOR.$name; |
||
4335 | |||
4336 | $maxlength = -1; |
||
4337 | $imgConverter = null; |
||
4338 | |||
4339 | // check imgConverter |
||
4340 | $mime = strtolower($stat['mime']); |
||
4341 | list($type) = explode('/', $mime); |
||
4342 | if (isset($this->imgConverter[$mime])) { |
||
4343 | $imgConverter = $this->imgConverter[$mime]['func']; |
||
4344 | if (! empty($this->imgConverter[$mime]['maxlen'])) { |
||
4345 | $maxlength = intval($this->imgConverter[$mime]['maxlen']); |
||
4346 | } |
||
4347 | } else if (isset($this->imgConverter[$type])) { |
||
4348 | $imgConverter = $this->imgConverter[$type]['func']; |
||
4349 | if (! empty($this->imgConverter[$type]['maxlen'])) { |
||
4350 | $maxlength = intval($this->imgConverter[$type]['maxlen']); |
||
4351 | } |
||
4352 | } |
||
4353 | if ($imgConverter && ! is_callable($imgConverter)) { |
||
4354 | return false; |
||
4355 | } |
||
4356 | |||
4357 | // copy image into tmbPath so some drivers does not store files on local fs |
||
4358 | if (($src = $this->fopenCE($path, 'rb')) == false) { |
||
4359 | return false; |
||
4360 | } |
||
4361 | |||
4362 | if (($trg = fopen($tmb, 'wb')) == false) { |
||
4363 | $this->fcloseCE($src, $path); |
||
4364 | return false; |
||
4365 | } |
||
4366 | |||
4367 | stream_copy_to_stream($src, $trg, $maxlength); |
||
4368 | |||
4369 | $this->fcloseCE($src, $path); |
||
4370 | fclose($trg); |
||
4371 | |||
4372 | // call imgConverter |
||
4373 | if ($imgConverter) { |
||
4374 | if (! call_user_func_array($imgConverter, array($tmb, $stat, $this))) { |
||
4375 | file_exists($tmb) && unlink($tmb); |
||
4376 | return false; |
||
4377 | } |
||
4378 | } |
||
4379 | |||
4380 | $result = false; |
||
4381 | |||
4382 | $tmbSize = $this->tmbSize; |
||
4383 | |||
4384 | if ($this->imgLib === 'imagick') { |
||
4385 | try { |
||
4386 | $imagickTest = new imagick($tmb); |
||
4387 | $imagickTest->clear(); |
||
4388 | $imagickTest = true; |
||
4389 | } catch (Exception $e) { |
||
4390 | $imagickTest = false; |
||
4391 | } |
||
4392 | } |
||
4393 | |||
4394 | 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
Loading history...
|
|||
4395 | if ($this->imgLib === 'imagick') { |
||
4396 | $bgcolor = $this->options['tmbBgColor']; |
||
4397 | if ($bgcolor === 'transparent') { |
||
4398 | $bgcolor = 'rgba(255, 255, 255, 0.0)'; |
||
4399 | } |
||
4400 | try { |
||
4401 | $imagick = new imagick(); |
||
4402 | $imagick->setBackgroundColor(new ImagickPixel($bgcolor)); |
||
4403 | $imagick->readImage($this->getExtentionByMime($stat['mime'], ':') . $tmb); |
||
4404 | $imagick->setImageFormat('png'); |
||
4405 | $imagick->writeImage($tmb); |
||
4406 | $imagick->clear(); |
||
4407 | if (($s = getimagesize($tmb)) !== false) { |
||
4408 | $result = true; |
||
4409 | } |
||
4410 | } catch (Exception $e) {} |
||
0 ignored issues
–
show
Coding Style
Comprehensibility
introduced
by
|
|||
4411 | } |
||
4412 | if (! $result) { |
||
4413 | file_exists($tmb) && unlink($tmb); |
||
4414 | return false; |
||
4415 | } |
||
4416 | $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
Loading history...
|
|||
4417 | } |
||
4418 | |||
4419 | /* If image smaller or equal thumbnail size - just fitting to thumbnail square */ |
||
4420 | if ($s[0] <= $tmbSize && $s[1] <= $tmbSize) { |
||
4421 | $result = $this->imgSquareFit($tmb, $tmbSize, $tmbSize, 'center', 'middle', $this->options['tmbBgColor'], 'png' ); |
||
4422 | } else { |
||
4423 | |||
4424 | if ($this->options['tmbCrop']) { |
||
4425 | |||
4426 | $result = $tmb; |
||
4427 | /* Resize and crop if image bigger than thumbnail */ |
||
4428 | 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
Loading history...
|
|||
4429 | $result = $this->imgResize($tmb, $tmbSize, $tmbSize, true, false, 'png'); |
||
4430 | } |
||
4431 | |||
4432 | 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
Loading history...
|
|||
4433 | $x = $s[0] > $tmbSize ? intval(($s[0] - $tmbSize)/2) : 0; |
||
4434 | $y = $s[1] > $tmbSize ? intval(($s[1] - $tmbSize)/2) : 0; |
||
4435 | $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);
Loading history...
$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);
Loading history...
|
|||
4436 | } else { |
||
4437 | $result = false; |
||
4438 | } |
||
4439 | |||
4440 | } else { |
||
4441 | $result = $this->imgResize($tmb, $tmbSize, $tmbSize, true, true, 'png'); |
||
4442 | } |
||
4443 | |||
4444 | 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
Loading history...
|
|||
4445 | if ($s = getimagesize($tmb)) { |
||
4446 | if ($s[0] !== $tmbSize || $s[1] !== $tmbSize) { |
||
4447 | $result = $this->imgSquareFit($result, $tmbSize, $tmbSize, 'center', 'middle', $this->options['tmbBgColor'], 'png' ); |
||
4448 | } |
||
4449 | } |
||
4450 | } |
||
4451 | } |
||
4452 | |||
4453 | 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
Loading history...
|
|||
4454 | unlink($tmb); |
||
4455 | return false; |
||
4456 | } |
||
4457 | |||
4458 | return $name; |
||
4459 | } |
||
4460 | |||
4461 | /** |
||
4462 | * Resize image |
||
4463 | * |
||
4464 | * @param string $path image file |
||
4465 | * @param int $width new width |
||
4466 | * @param int $height new height |
||
4467 | * @param bool $keepProportions crop image |
||
4468 | * @param bool $resizeByBiggerSide resize image based on bigger side if true |
||
4469 | * @param string $destformat image destination format |
||
4470 | * @param int $jpgQuality JEPG quality (1-100) |
||
4471 | * @param array $options Other extra options |
||
4472 | * @return string|false |
||
4473 | * @author Dmitry (dio) Levashov |
||
4474 | * @author Alexey Sukhotin |
||
4475 | **/ |
||
4476 | protected function imgResize($path, $width, $height, $keepProportions = false, $resizeByBiggerSide = true, $destformat = null, $jpgQuality = null, $options = array()) { |
||
4477 | if (($s = getimagesize($path)) == false) { |
||
4478 | return false; |
||
4479 | } |
||
4480 | |||
4481 | $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
Loading history...
|
|||
4482 | |||
4483 | list($size_w, $size_h) = array($width, $height); |
||
4484 | |||
4485 | 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
Loading history...
|
|||
4486 | $jpgQuality = $this->options['jpgQuality']; |
||
4487 | } |
||
4488 | |||
4489 | if ($keepProportions == true) { |
||
0 ignored issues
–
show
|
|||
4490 | |||
4491 | list($orig_w, $orig_h) = array($s[0], $s[1]); |
||
4492 | |||
4493 | /* Resizing by biggest side */ |
||
4494 | if ($resizeByBiggerSide) { |
||
4495 | if ($orig_w > $orig_h) { |
||
4496 | $size_h = round($orig_h * $width / $orig_w); |
||
4497 | $size_w = $width; |
||
4498 | } else { |
||
4499 | $size_w = round($orig_w * $height / $orig_h); |
||
4500 | $size_h = $height; |
||
4501 | } |
||
4502 | } else { |
||
4503 | if ($orig_w > $orig_h) { |
||
4504 | $size_w = round($orig_w * $height / $orig_h); |
||
4505 | $size_h = $height; |
||
4506 | } else { |
||
4507 | $size_h = round($orig_h * $width / $orig_w); |
||
4508 | $size_w = $width; |
||
4509 | } |
||
4510 | } |
||
4511 | } |
||
4512 | |||
4513 | elFinder::extendTimeLimit(300); |
||
4514 | switch ($this->imgLib) { |
||
4515 | 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.
Loading history...
|
|||
4516 | |||
4517 | try { |
||
4518 | $img = new imagick($path); |
||
4519 | } catch (Exception $e) { |
||
4520 | return false; |
||
4521 | } |
||
4522 | |||
4523 | // Imagick::FILTER_BOX faster than FILTER_LANCZOS so use for createTmb |
||
4524 | // resize bench: http://app-mgng.rhcloud.com/9 |
||
4525 | // resize sample: http://www.dylanbeattie.net/magick/filters/result.html |
||
4526 | $filter = ($destformat === 'png' /* createTmb */)? Imagick::FILTER_BOX : Imagick::FILTER_LANCZOS; |
||
4527 | |||
4528 | $ani = ($img->getNumberImages() > 1); |
||
4529 | if ($ani && is_null($destformat)) { |
||
4530 | $img = $img->coalesceImages(); |
||
4531 | do { |
||
4532 | $img->resizeImage($size_w, $size_h, $filter, 1); |
||
4533 | } while ($img->nextImage()); |
||
4534 | $img = $img->optimizeImageLayers(); |
||
4535 | $result = $img->writeImages($path, true); |
||
0 ignored issues
–
show
|
|||
4536 | } else { |
||
4537 | if ($ani) { |
||
4538 | $img->setFirstIterator(); |
||
4539 | } |
||
4540 | if (strtoupper($img->getImageFormat()) === 'JPEG') { |
||
4541 | $img->setImageCompression(imagick::COMPRESSION_JPEG); |
||
4542 | $img->setImageCompressionQuality($jpgQuality); |
||
4543 | if (isset($options['preserveExif']) && ! $options['preserveExif']) { |
||
4544 | try { |
||
4545 | $orientation = $img->getImageOrientation(); |
||
4546 | } catch (ImagickException $e) { |
||
4547 | $orientation = 0; |
||
4548 | } |
||
4549 | $img->stripImage(); |
||
4550 | if ($orientation) { |
||
4551 | $img->setImageOrientation($orientation); |
||
4552 | } |
||
4553 | } |
||
4554 | } |
||
4555 | $img->resizeImage($size_w, $size_h, $filter, true); |
||
4556 | 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
Loading history...
|
|||
4557 | $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);
Loading history...
|
|||
4558 | } else { |
||
4559 | $result = $img->writeImage($path); |
||
4560 | } |
||
4561 | } |
||
4562 | |||
4563 | $img->clear(); |
||
4564 | |||
4565 | return $result ? $path : false; |
||
4566 | |||
4567 | 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.
Loading history...
|
|||
4568 | |||
4569 | case 'convert': |
||
4570 | extract($this->imageMagickConvertPrepare($path, $destformat, $jpgQuality, $s)); |
||
0 ignored issues
–
show
|
|||
4571 | $filter = ($destformat === 'png' /* createTmb */)? '-filter Box' : '-filter Lanczos'; |
||
4572 | $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
Loading history...
|
|||
4573 | //$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.
Loading history...
|
|||
4574 | $cmd = sprintf('convert %s%s%s %s -geometry %dx%d! %s %s', $quotedPath, $coalesce, $jpgQuality, $filter, $size_w, $size_h, $deconstruct, $quotedDstPath); |
||
4575 | |||
4576 | $result = false; |
||
4577 | if ($this->procExec($cmd) === 0) { |
||
4578 | $result = true; |
||
4579 | } |
||
4580 | return $result ? $path : false; |
||
4581 | |||
4582 | 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.
Loading history...
|
|||
4583 | |||
4584 | case 'gd': |
||
4585 | $img = $this->gdImageCreate($path,$s['mime']); |
||
4586 | |||
4587 | if ($img && false != ($tmp = imagecreatetruecolor($size_w, $size_h))) { |
||
4588 | |||
4589 | $bgNum = false; |
||
4590 | 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
Loading history...
|
|||
4591 | $bgIdx = imagecolortransparent($img); |
||
4592 | if ($bgIdx !== -1) { |
||
4593 | $c = imagecolorsforindex($img, $bgIdx); |
||
4594 | $bgNum = imagecolorallocate($tmp, $c['red'], $c['green'], $c['blue']); |
||
4595 | imagefill($tmp, 0, 0, $bgNum); |
||
4596 | imagecolortransparent($tmp, $bgNum); |
||
4597 | } |
||
4598 | } |
||
4599 | if ($bgNum === false) { |
||
4600 | $this->gdImageBackground($tmp, 'transparent'); |
||
4601 | } |
||
4602 | |||
4603 | if (!imagecopyresampled($tmp, $img, 0, 0, 0, 0, $size_w, $size_h, $s[0], $s[1])) { |
||
4604 | return false; |
||
4605 | } |
||
4606 | |||
4607 | $result = $this->gdImage($tmp, $path, $destformat, $s['mime'], $jpgQuality); |
||
4608 | |||
4609 | imagedestroy($img); |
||
4610 | imagedestroy($tmp); |
||
4611 | |||
4612 | return $result ? $path : false; |
||
4613 | |||
4614 | } |
||
4615 | break; |
||
4616 | } |
||
4617 | |||
4618 | return false; |
||
4619 | } |
||
4620 | |||
4621 | /** |
||
4622 | * Crop image |
||
4623 | * |
||
4624 | * @param string $path image file |
||
4625 | * @param int $width crop width |
||
4626 | * @param int $height crop height |
||
4627 | * @param bool $x crop left offset |
||
4628 | * @param bool $y crop top offset |
||
4629 | * @param string $destformat image destination format |
||
4630 | * @param int $jpgQuality JEPG quality (1-100) |
||
4631 | * @return string|false |
||
4632 | * @author Dmitry (dio) Levashov |
||
4633 | * @author Alexey Sukhotin |
||
4634 | **/ |
||
4635 | protected function imgCrop($path, $width, $height, $x, $y, $destformat = null, $jpgQuality = null) { |
||
4636 | if (($s = getimagesize($path)) == false) { |
||
4637 | return false; |
||
4638 | } |
||
4639 | |||
4640 | $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
Loading history...
|
|||
4641 | |||
4642 | 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
Loading history...
|
|||
4643 | $jpgQuality = $this->options['jpgQuality']; |
||
4644 | } |
||
4645 | |||
4646 | elFinder::extendTimeLimit(300); |
||
4647 | switch ($this->imgLib) { |
||
4648 | 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.
Loading history...
|
|||
4649 | |||
4650 | try { |
||
4651 | $img = new imagick($path); |
||
4652 | } catch (Exception $e) { |
||
4653 | return false; |
||
4654 | } |
||
4655 | |||
4656 | $ani = ($img->getNumberImages() > 1); |
||
4657 | if ($ani && is_null($destformat)) { |
||
4658 | $img = $img->coalesceImages(); |
||
4659 | do { |
||
4660 | $img->setImagePage($s[0], $s[1], 0, 0); |
||
4661 | $img->cropImage($width, $height, $x, $y); |
||
4662 | $img->setImagePage($width, $height, 0, 0); |
||
4663 | } while ($img->nextImage()); |
||
4664 | $img = $img->optimizeImageLayers(); |
||
4665 | $result = $img->writeImages($path, true); |
||
0 ignored issues
–
show
|
|||
4666 | } else { |
||
4667 | if ($ani) { |
||
4668 | $img->setFirstIterator(); |
||
4669 | } |
||
4670 | $img->setImagePage($s[0], $s[1], 0, 0); |
||
4671 | $img->cropImage($width, $height, $x, $y); |
||
4672 | $img->setImagePage($width, $height, 0, 0); |
||
4673 | $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);
Loading history...
|
|||
4674 | } |
||
4675 | |||
4676 | $img->clear(); |
||
4677 | |||
4678 | return $result ? $path : false; |
||
4679 | |||
4680 | 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.
Loading history...
|
|||
4681 | |||
4682 | case 'convert': |
||
4683 | extract($this->imageMagickConvertPrepare($path, $destformat, $jpgQuality, $s)); |
||
0 ignored issues
–
show
|
|||
4684 | $cmd = sprintf('convert %s%s%s -crop %dx%d+%d+%d%s %s', $quotedPath, $coalesce, $jpgQuality, $width, $height, $x, $y, $deconstruct, $quotedDstPath); |
||
4685 | |||
4686 | $result = false; |
||
4687 | if ($this->procExec($cmd) === 0) { |
||
4688 | $result = true; |
||
4689 | } |
||
4690 | return $result ? $path : false; |
||
4691 | |||
4692 | 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.
Loading history...
|
|||
4693 | |||
4694 | case 'gd': |
||
4695 | $img = $this->gdImageCreate($path,$s['mime']); |
||
4696 | |||
4697 | if ($img && false != ($tmp = imagecreatetruecolor($width, $height))) { |
||
4698 | |||
4699 | $bgNum = false; |
||
4700 | 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
Loading history...
|
|||
4701 | $bgIdx = imagecolortransparent($img); |
||
4702 | if ($bgIdx !== -1) { |
||
4703 | $c = imagecolorsforindex($img, $bgIdx); |
||
4704 | $bgNum = imagecolorallocate($tmp, $c['red'], $c['green'], $c['blue']); |
||
4705 | imagefill($tmp, 0, 0, $bgNum); |
||
4706 | imagecolortransparent($tmp, $bgNum); |
||
4707 | } |
||
4708 | } |
||
4709 | if ($bgNum === false) { |
||
4710 | $this->gdImageBackground($tmp, 'transparent'); |
||
4711 | } |
||
4712 | |||
4713 | $size_w = $width; |
||
4714 | $size_h = $height; |
||
4715 | |||
4716 | if ($s[0] < $width || $s[1] < $height) { |
||
4717 | $size_w = $s[0]; |
||
4718 | $size_h = $s[1]; |
||
4719 | } |
||
4720 | |||
4721 | if (!imagecopy($tmp, $img, 0, 0, $x, $y, $size_w, $size_h)) { |
||
4722 | return false; |
||
4723 | } |
||
4724 | |||
4725 | $result = $this->gdImage($tmp, $path, $destformat, $s['mime'], $jpgQuality); |
||
4726 | |||
4727 | imagedestroy($img); |
||
4728 | imagedestroy($tmp); |
||
4729 | |||
4730 | return $result ? $path : false; |
||
4731 | |||
4732 | } |
||
4733 | break; |
||
4734 | } |
||
4735 | |||
4736 | return false; |
||
4737 | } |
||
4738 | |||
4739 | /** |
||
4740 | * Put image to square |
||
4741 | * |
||
4742 | * @param string $path image file |
||
4743 | * @param int $width square width |
||
4744 | * @param int $height square height |
||
4745 | * @param int|string $align reserved |
||
4746 | * @param int|string $valign reserved |
||
4747 | * @param string $bgcolor square background color in #rrggbb format |
||
4748 | * @param string $destformat image destination format |
||
4749 | * @param int $jpgQuality JEPG quality (1-100) |
||
4750 | * @return false|string |
||
4751 | * @author Dmitry (dio) Levashov |
||
4752 | * @author Alexey Sukhotin |
||
4753 | */ |
||
4754 | protected function imgSquareFit($path, $width, $height, $align = 'center', $valign = 'middle', $bgcolor = '#0000ff', $destformat = null, $jpgQuality = null) { |
||
0 ignored issues
–
show
|
|||
4755 | if (($s = getimagesize($path)) == false) { |
||
4756 | return false; |
||
4757 | } |
||
4758 | |||
4759 | $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
Loading history...
|
|||
4760 | |||
4761 | /* Coordinates for image over square aligning */ |
||
4762 | $y = ceil(abs($height - $s[1]) / 2); |
||
4763 | $x = ceil(abs($width - $s[0]) / 2); |
||
4764 | |||
4765 | 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
Loading history...
|
|||
4766 | $jpgQuality = $this->options['jpgQuality']; |
||
4767 | } |
||
4768 | |||
4769 | elFinder::extendTimeLimit(300); |
||
4770 | switch ($this->imgLib) { |
||
4771 | case 'imagick': |
||
4772 | try { |
||
4773 | $img = new imagick($path); |
||
4774 | } catch (Exception $e) { |
||
4775 | return false; |
||
4776 | } |
||
4777 | |||
4778 | if ($bgcolor === 'transparent') { |
||
4779 | $bgcolor = 'rgba(255, 255, 255, 0.0)'; |
||
4780 | } |
||
4781 | $ani = ($img->getNumberImages() > 1); |
||
4782 | if ($ani && is_null($destformat)) { |
||
4783 | $img1 = new Imagick(); |
||
4784 | $img1->setFormat('gif'); |
||
4785 | $img = $img->coalesceImages(); |
||
4786 | do { |
||
4787 | $gif = new Imagick(); |
||
4788 | $gif->newImage($width, $height, new ImagickPixel($bgcolor)); |
||
4789 | $gif->setImageColorspace($img->getImageColorspace()); |
||
4790 | $gif->setImageFormat('gif'); |
||
4791 | $gif->compositeImage( $img, imagick::COMPOSITE_OVER, $x, $y ); |
||
4792 | $gif->setImageDelay($img->getImageDelay()); |
||
4793 | $gif->setImageIterations($img->getImageIterations()); |
||
4794 | $img1->addImage($gif); |
||
4795 | $gif->clear(); |
||
4796 | } while ($img->nextImage()); |
||
4797 | $img1 = $img1->optimizeImageLayers(); |
||
4798 | $result = $img1->writeImages($path, true); |
||
0 ignored issues
–
show
|
|||
4799 | } else { |
||
4800 | if ($ani) { |
||
4801 | $img->setFirstIterator(); |
||
4802 | } |
||
4803 | $img1 = new Imagick(); |
||
4804 | $img1->newImage($width, $height, new ImagickPixel($bgcolor)); |
||
4805 | $img1->setImageColorspace($img->getImageColorspace()); |
||
4806 | $img1->compositeImage( $img, imagick::COMPOSITE_OVER, $x, $y ); |
||
4807 | $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);
Loading history...
|
|||
4808 | } |
||
4809 | |||
4810 | $img1->clear(); |
||
4811 | $img->clear(); |
||
4812 | return $result ? $path : false; |
||
4813 | |||
4814 | 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.
Loading history...
|
|||
4815 | |||
4816 | case 'convert': |
||
4817 | extract($this->imageMagickConvertPrepare($path, $destformat, $jpgQuality, $s)); |
||
0 ignored issues
–
show
|
|||
4818 | if ($bgcolor === 'transparent') { |
||
4819 | $bgcolor = 'rgba(255, 255, 255, 0.0)'; |
||
4820 | } |
||
4821 | $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); |
||
4822 | |||
4823 | $result = false; |
||
4824 | if ($this->procExec($cmd) === 0) { |
||
4825 | $result = true; |
||
4826 | } |
||
4827 | return $result ? $path : false; |
||
4828 | |||
4829 | 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.
Loading history...
|
|||
4830 | |||
4831 | case 'gd': |
||
4832 | $img = $this->gdImageCreate($path,$s['mime']); |
||
4833 | |||
4834 | if ($img && false != ($tmp = imagecreatetruecolor($width, $height))) { |
||
4835 | |||
4836 | $this->gdImageBackground($tmp, $bgcolor); |
||
4837 | if ($bgcolor === 'transparent' && ($destformat === 'png' || $s[2] === IMAGETYPE_PNG)) { |
||
4838 | $bgNum = imagecolorallocatealpha($tmp, 255, 255, 255, 127); |
||
4839 | imagefill($tmp, 0, 0, $bgNum); |
||
4840 | } |
||
4841 | |||
4842 | if (!imagecopy($tmp, $img, $x, $y, 0, 0, $s[0], $s[1])) { |
||
4843 | return false; |
||
4844 | } |
||
4845 | |||
4846 | $result = $this->gdImage($tmp, $path, $destformat, $s['mime'], $jpgQuality); |
||
4847 | |||
4848 | imagedestroy($img); |
||
4849 | imagedestroy($tmp); |
||
4850 | |||
4851 | return $result ? $path : false; |
||
4852 | } |
||
4853 | break; |
||
4854 | } |
||
4855 | |||
4856 | return false; |
||
4857 | } |
||
4858 | |||
4859 | /** |
||
4860 | * Rotate image |
||
4861 | * |
||
4862 | * @param string $path image file |
||
4863 | * @param int $degree rotete degrees |
||
4864 | * @param string $bgcolor square background color in #rrggbb format |
||
4865 | * @param string $destformat image destination format |
||
4866 | * @param int $jpgQuality JEPG quality (1-100) |
||
4867 | * @return string|false |
||
4868 | * @author nao-pon |
||
4869 | * @author Troex Nevelin |
||
4870 | **/ |
||
4871 | protected function imgRotate($path, $degree, $bgcolor = '#ffffff', $destformat = null, $jpgQuality = null) { |
||
4872 | if (($s = getimagesize($path)) == false || $degree % 360 === 0) { |
||
4873 | return false; |
||
4874 | } |
||
4875 | |||
4876 | $result = false; |
||
4877 | |||
4878 | // try lossless rotate |
||
4879 | if ($degree % 90 === 0 && in_array($s[2], array(IMAGETYPE_JPEG, IMAGETYPE_JPEG2000))) { |
||
4880 | $count = ($degree / 90) % 4; |
||
4881 | $exiftran = array( |
||
4882 | 1 => '-9', |
||
4883 | 2 => '-1', |
||
4884 | 3 => '-2' |
||
4885 | ); |
||
4886 | $jpegtran = array( |
||
4887 | 1 => '90', |
||
4888 | 2 => '180', |
||
4889 | 3 => '270' |
||
4890 | ); |
||
4891 | $quotedPath = escapeshellarg($path); |
||
4892 | $cmds = array( |
||
4893 | 'exiftran -i '.$exiftran[$count].' '.$path, |
||
4894 | 'jpegtran -rotate '.$jpegtran[$count].' -copy all -outfile '.$quotedPath.' '.$quotedPath |
||
4895 | ); |
||
4896 | foreach($cmds as $cmd) { |
||
4897 | if ($this->procExec($cmd) === 0) { |
||
4898 | $result = true; |
||
4899 | break; |
||
4900 | } |
||
4901 | } |
||
4902 | if ($result) { |
||
4903 | return $path; |
||
4904 | } |
||
4905 | } |
||
4906 | |||
4907 | 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
Loading history...
|
|||
4908 | $jpgQuality = $this->options['jpgQuality']; |
||
4909 | } |
||
4910 | |||
4911 | elFinder::extendTimeLimit(300); |
||
4912 | switch ($this->imgLib) { |
||
4913 | case 'imagick': |
||
4914 | try { |
||
4915 | $img = new imagick($path); |
||
4916 | } catch (Exception $e) { |
||
4917 | return false; |
||
4918 | } |
||
4919 | |||
4920 | if ($s[2] === IMAGETYPE_GIF || $s[2] === IMAGETYPE_PNG) { |
||
4921 | $bgcolor = 'rgba(255, 255, 255, 0.0)'; |
||
4922 | } |
||
4923 | if ($img->getNumberImages() > 1) { |
||
4924 | $img = $img->coalesceImages(); |
||
4925 | do { |
||
4926 | $img->rotateImage(new ImagickPixel($bgcolor), $degree); |
||
4927 | } while ($img->nextImage()); |
||
4928 | $img = $img->optimizeImageLayers(); |
||
4929 | $result = $img->writeImages($path, true); |
||
0 ignored issues
–
show
|
|||
4930 | } else { |
||
4931 | $img->rotateImage(new ImagickPixel($bgcolor), $degree); |
||
4932 | $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);
Loading history...
|
|||
4933 | } |
||
4934 | $img->clear(); |
||
4935 | return $result ? $path : false; |
||
4936 | |||
4937 | 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.
Loading history...
|
|||
4938 | |||
4939 | case 'convert': |
||
4940 | extract($this->imageMagickConvertPrepare($path, $destformat, $jpgQuality, $s)); |
||
0 ignored issues
–
show
|
|||
4941 | if ($s[2] === IMAGETYPE_GIF || $s[2] === IMAGETYPE_PNG) { |
||
4942 | $bgcolor = 'rgba(255, 255, 255, 0.0)'; |
||
4943 | } |
||
4944 | $cmd = sprintf('convert %s%s%s -background "%s" -rotate %d%s %s', $quotedPath, $coalesce, $jpgQuality, $bgcolor, $degree, $deconstruct, $quotedDstPath); |
||
4945 | |||
4946 | $result = false; |
||
4947 | if ($this->procExec($cmd) === 0) { |
||
4948 | $result = true; |
||
4949 | } |
||
4950 | return $result ? $path : false; |
||
4951 | |||
4952 | 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.
Loading history...
|
|||
4953 | |||
4954 | case 'gd': |
||
4955 | $img = $this->gdImageCreate($path,$s['mime']); |
||
4956 | |||
4957 | $degree = 360 - $degree; |
||
4958 | |||
4959 | $bgNum = -1; |
||
4960 | $bgIdx = false; |
||
4961 | if ($s[2] === IMAGETYPE_GIF) { |
||
4962 | $bgIdx = imagecolortransparent($img); |
||
4963 | if ($bgIdx !== -1) { |
||
4964 | $c = imagecolorsforindex($img, $bgIdx); |
||
4965 | $w = imagesx($img); |
||
4966 | $h = imagesy($img); |
||
4967 | $newImg = imagecreatetruecolor($w, $h); |
||
4968 | imagepalettecopy($newImg, $img); |
||
4969 | $bgNum = imagecolorallocate($newImg, $c['red'], $c['green'], $c['blue']); |
||
4970 | imagefill($newImg, 0, 0, $bgNum); |
||
4971 | imagecolortransparent($newImg, $bgNum); |
||
4972 | imagecopy($newImg, $img, 0, 0, 0, 0, $w, $h); |
||
4973 | imagedestroy($img); |
||
4974 | $img = $newImg; |
||
4975 | $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
Loading history...
|
|||
4976 | } |
||
4977 | } else if ($s[2] === IMAGETYPE_PNG) { |
||
4978 | $bgNum = imagecolorallocatealpha($img, 255, 255, 255, 127); |
||
4979 | } |
||
4980 | if ($bgNum === -1) { |
||
4981 | list($r, $g, $b) = sscanf($bgcolor, "#%02x%02x%02x"); |
||
4982 | $bgNum = imagecolorallocate($img, $r, $g, $b); |
||
4983 | } |
||
4984 | |||
4985 | $tmp = imageRotate($img, $degree, $bgNum); |
||
4986 | if ($bgIdx !== -1) { |
||
4987 | imagecolortransparent($tmp, $bgNum); |
||
4988 | } |
||
4989 | |||
4990 | $result = $this->gdImage($tmp, $path, $destformat, $s['mime'], $jpgQuality); |
||
4991 | |||
4992 | imageDestroy($img); |
||
4993 | imageDestroy($tmp); |
||
4994 | |||
4995 | return $result ? $path : false; |
||
4996 | |||
4997 | 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.
Loading history...
|
|||
4998 | } |
||
4999 | |||
5000 | return false; |
||
5001 | } |
||
5002 | |||
5003 | /** |
||
5004 | * Execute shell command |
||
5005 | * |
||
5006 | * @param string $command command line |
||
5007 | * @param array $output stdout strings |
||
5008 | * @param array|int $return_var process exit code |
||
5009 | * @param array $error_output stderr strings |
||
5010 | * @return int exit code |
||
5011 | * @author Alexey Sukhotin |
||
5012 | */ |
||
5013 | protected function procExec($command , array &$output = null, &$return_var = -1, array &$error_output = null) { |
||
5014 | |||
5015 | static $allowed = null; |
||
5016 | |||
5017 | if ($allowed === null) { |
||
5018 | if ($allowed = function_exists('proc_open')) { |
||
5019 | if ($disabled = ini_get('disable_functions')) { |
||
5020 | $funcs = array_map('trim', explode(',', $disabled)); |
||
5021 | $allowed = ! in_array('proc_open', $funcs); |
||
5022 | } |
||
5023 | } |
||
5024 | } |
||
5025 | |||
5026 | 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) { }
Loading history...
|
|||
5027 | $return_var = -1; |
||
5028 | return $return_var; |
||
5029 | } |
||
5030 | |||
5031 | if (! $command) { |
||
5032 | $return_var = 0; |
||
5033 | return $return_var; |
||
5034 | } |
||
5035 | |||
5036 | $descriptorspec = array( |
||
5037 | 0 => array("pipe", "r"), // stdin |
||
5038 | 1 => array("pipe", "w"), // stdout |
||
5039 | 2 => array("pipe", "w") // stderr |
||
5040 | ); |
||
5041 | |||
5042 | $process = proc_open($command, $descriptorspec, $pipes, null, null); |
||
5043 | |||
5044 | if (is_resource($process)) { |
||
5045 | |||
5046 | fclose($pipes[0]); |
||
5047 | |||
5048 | $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
Loading history...
|
|||
5049 | $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
Loading history...
|
|||
5050 | |||
5051 | $output = stream_get_contents($pipes[1]); |
||
5052 | $error_output = stream_get_contents($pipes[2]); |
||
5053 | |||
5054 | fclose($pipes[1]); |
||
5055 | fclose($pipes[2]); |
||
5056 | $return_var = proc_close($process); |
||
5057 | |||
5058 | } else { |
||
5059 | $return_var = -1; |
||
5060 | } |
||
5061 | |||
5062 | return $return_var; |
||
5063 | |||
5064 | } |
||
5065 | |||
5066 | /** |
||
5067 | * Remove thumbnail, also remove recursively if stat is directory |
||
5068 | * |
||
5069 | * @param string $stat file stat |
||
5070 | * @return void |
||
5071 | * @author Dmitry (dio) Levashov |
||
5072 | * @author Naoki Sawada |
||
5073 | * @author Troex Nevelin |
||
5074 | **/ |
||
5075 | protected function rmTmb($stat) { |
||
5076 | if ($stat['mime'] === 'directory') { |
||
5077 | foreach ($this->scandirCE($this->decode($stat['hash'])) as $p) { |
||
5078 | elFinder::extendTimeLimit(30); |
||
5079 | $name = $this->basenameCE($p); |
||
5080 | $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);
Loading history...
|
|||
5081 | } |
||
5082 | } else if (!empty($stat['tmb']) && $stat['tmb'] != "1") { |
||
5083 | $tmb = $this->tmbPath.DIRECTORY_SEPARATOR.$stat['tmb']; |
||
5084 | file_exists($tmb) && unlink($tmb); |
||
5085 | clearstatcache(); |
||
5086 | } |
||
5087 | } |
||
5088 | |||
5089 | /** |
||
5090 | * Create an gd image according to the specified mime type |
||
5091 | * |
||
5092 | * @param string $path image file |
||
5093 | * @param string $mime |
||
5094 | * @return gd image resource identifier |
||
5095 | */ |
||
5096 | protected function gdImageCreate($path,$mime){ |
||
5097 | switch($mime){ |
||
5098 | case 'image/jpeg': |
||
5099 | return imagecreatefromjpeg($path); |
||
5100 | |||
5101 | case 'image/png': |
||
5102 | return imagecreatefrompng($path); |
||
5103 | |||
5104 | case 'image/gif': |
||
5105 | return imagecreatefromgif($path); |
||
5106 | |||
5107 | case 'image/x-ms-bmp': |
||
5108 | if (!function_exists('imagecreatefrombmp')) { |
||
5109 | include_once dirname(__FILE__).'/libs/GdBmp.php'; |
||
5110 | } |
||
5111 | return imagecreatefrombmp($path); |
||
5112 | |||
5113 | case 'image/xbm': |
||
5114 | return imagecreatefromxbm($path); |
||
5115 | |||
5116 | case 'image/xpm': |
||
5117 | return imagecreatefromxpm($path); |
||
5118 | } |
||
5119 | return false; |
||
5120 | } |
||
5121 | |||
5122 | /** |
||
5123 | * Output gd image to file |
||
5124 | * |
||
5125 | * @param resource $image gd image resource |
||
5126 | * @param string $filename The path to save the file to. |
||
5127 | * @param string $destformat The Image type to use for $filename |
||
5128 | * @param string $mime The original image mime type |
||
5129 | * @param int $jpgQuality JEPG quality (1-100) |
||
5130 | * @return bool |
||
5131 | */ |
||
5132 | protected function gdImage($image, $filename, $destformat, $mime, $jpgQuality = null ){ |
||
5133 | |||
5134 | 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
Loading history...
|
|||
5135 | $jpgQuality = $this->options['jpgQuality']; |
||
5136 | } |
||
5137 | if ($destformat) { |
||
5138 | switch ($destformat) { |
||
5139 | case 'jpg': |
||
5140 | $mime = 'image/jpeg'; |
||
5141 | break; |
||
5142 | case 'gif': |
||
5143 | $mime = 'image/gif'; |
||
5144 | break; |
||
5145 | case 'png': |
||
5146 | default: |
||
5147 | $mime = 'image/png'; |
||
5148 | break; |
||
5149 | } |
||
5150 | } |
||
5151 | switch ($mime) { |
||
5152 | case 'image/gif': |
||
5153 | return imagegif($image, $filename); |
||
5154 | case 'image/jpeg': |
||
5155 | return imagejpeg($image, $filename, $jpgQuality); |
||
5156 | case 'image/wbmp': |
||
5157 | return imagewbmp($image, $filename); |
||
5158 | case 'image/png': |
||
5159 | default: |
||
5160 | return imagepng($image, $filename); |
||
5161 | } |
||
5162 | } |
||
5163 | |||
5164 | /** |
||
5165 | * Output imagick image to file |
||
5166 | * |
||
5167 | * @param resource $img imagick image resource |
||
5168 | * @param string $filename The path to save the file to. |
||
5169 | * @param string $destformat The Image type to use for $filename |
||
5170 | * @param int $jpgQuality JEPG quality (1-100) |
||
5171 | * @return bool |
||
5172 | */ |
||
5173 | protected function imagickImage($img, $filename, $destformat, $jpgQuality = null ){ |
||
5174 | |||
5175 | 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
Loading history...
|
|||
5176 | $jpgQuality = $this->options['jpgQuality']; |
||
5177 | } |
||
5178 | |||
5179 | try { |
||
5180 | if ($destformat) { |
||
5181 | if ($destformat === 'gif') { |
||
5182 | $img->setImageFormat('gif'); |
||
0 ignored issues
–
show
|
|||
5183 | } else if ($destformat === 'png') { |
||
5184 | $img->setImageFormat('png'); |
||
0 ignored issues
–
show
|
|||
5185 | } else if ($destformat === 'jpg') { |
||
5186 | $img->setImageFormat('jpeg'); |
||
0 ignored issues
–
show
|
|||
5187 | } |
||
5188 | } |
||
5189 | if (strtoupper($img->getImageFormat()) === 'JPEG') { |
||
0 ignored issues
–
show
|
|||
5190 | $img->setImageCompression(imagick::COMPRESSION_JPEG); |
||
0 ignored issues
–
show
|
|||
5191 | $img->setImageCompressionQuality($jpgQuality); |
||
0 ignored issues
–
show
|
|||
5192 | try { |
||
5193 | $orientation = $img->getImageOrientation(); |
||
0 ignored issues
–
show
|
|||
5194 | } catch (ImagickException $e) { |
||
5195 | $orientation = 0; |
||
5196 | } |
||
5197 | $img->stripImage(); |
||
0 ignored issues
–
show
|
|||
5198 | if ($orientation) { |
||
5199 | $img->setImageOrientation($orientation); |
||
0 ignored issues
–
show
|
|||
5200 | } |
||
5201 | } |
||
5202 | $result = $img->writeImage($filename); |
||
0 ignored issues
–
show
|
|||
5203 | } catch (Exception $e) { |
||
5204 | $result = false; |
||
5205 | } |
||
5206 | |||
5207 | return $result; |
||
5208 | } |
||
5209 | |||
5210 | /** |
||
5211 | * Assign the proper background to a gd image |
||
5212 | * |
||
5213 | * @param resource $image gd image resource |
||
5214 | * @param string $bgcolor background color in #rrggbb format |
||
5215 | */ |
||
5216 | protected function gdImageBackground($image, $bgcolor){ |
||
5217 | |||
5218 | if ($bgcolor === 'transparent'){ |
||
5219 | imagealphablending($image, false); |
||
5220 | imagesavealpha($image, true); |
||
5221 | } else { |
||
5222 | list($r, $g, $b) = sscanf($bgcolor, "#%02x%02x%02x"); |
||
5223 | $bgcolor1 = imagecolorallocate($image, $r, $g, $b); |
||
5224 | imagefill($image, 0, 0, $bgcolor1); |
||
5225 | } |
||
5226 | } |
||
5227 | |||
5228 | /** |
||
5229 | * Prepare variables for exec convert of ImageMagick |
||
5230 | * |
||
5231 | * @param string $path |
||
5232 | * @param string $destformat |
||
5233 | * @param int $jpgQuality |
||
5234 | * @param array $imageSize |
||
5235 | * @return array |
||
5236 | */ |
||
5237 | protected function imageMagickConvertPrepare($path, $destformat, $jpgQuality, $imageSize = null) { |
||
5238 | if (is_null($imageSize)) { |
||
5239 | $imageSize = getimagesize($path); |
||
5240 | } |
||
5241 | 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
Loading history...
|
|||
5242 | return array(); |
||
5243 | } |
||
5244 | $srcType = $this->getExtentionByMime($imageSize['mime'], ':'); |
||
5245 | $ani = false; |
||
5246 | $cmd = 'identify ' . escapeshellarg($srcType . $path); |
||
5247 | if ($this->procExec($cmd, $o) === 0) { |
||
5248 | $ani = preg_split('/(?:\r\n|\n|\r)/', trim($o)); |
||
5249 | if (count($ani) < 2) { |
||
5250 | $ani = false; |
||
5251 | } |
||
5252 | } |
||
5253 | $coalesce = $index = ''; |
||
5254 | $deconstruct = ' +repage'; |
||
5255 | if ($ani) { |
||
5256 | if (is_null($destformat)) { |
||
5257 | $coalesce = ' -coalesce -repage 0x0'; |
||
5258 | $deconstruct = ' +repage -deconstruct -layers optimize'; |
||
5259 | } else { |
||
5260 | $index = '[0]'; |
||
5261 | if ($srcType === 'ico:') { |
||
5262 | foreach($ani as $_i => $_info) { |
||
5263 | if (preg_match('/ (\d+)x(\d+) /', $_info, $m)) { |
||
5264 | if ($m[1] == $imageSize[0] && $m[2] == $imageSize[1]) { |
||
5265 | $index = '[' . $_i . ']'; |
||
5266 | break; |
||
5267 | } |
||
5268 | } |
||
5269 | } |
||
5270 | } |
||
5271 | } |
||
5272 | } |
||
5273 | if ($imageSize[2] === IMAGETYPE_JPEG || $imageSize[2] === IMAGETYPE_JPEG2000) { |
||
5274 | $jpgQuality = ' -quality ' . $jpgQuality; |
||
5275 | } else { |
||
5276 | $jpgQuality = ''; |
||
5277 | } |
||
5278 | $quotedPath = escapeshellarg($srcType . $path . $index); |
||
5279 | $quotedDstPath = escapeshellarg(($destformat? ($destformat . ':') : $srcType) . $path); |
||
5280 | return compact('ani', 'index', 'coalesce', 'deconstruct', 'jpgQuality', 'quotedPath', 'quotedDstPath'); |
||
5281 | } |
||
5282 | |||
5283 | /*********************** misc *************************/ |
||
5284 | |||
5285 | /** |
||
5286 | * Return smart formatted date |
||
5287 | * |
||
5288 | * @param int $ts file timestamp |
||
5289 | * @return string |
||
5290 | * @author Dmitry (dio) Levashov |
||
5291 | **/ |
||
5292 | // 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.
Loading history...
|
|||
5293 | // 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.
Loading history...
|
|||
5294 | // 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.
Loading history...
|
|||
5295 | // } |
||
5296 | // |
||
5297 | // 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.
Loading history...
|
|||
5298 | // 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.
Loading history...
|
|||
5299 | // } |
||
5300 | // |
||
5301 | // 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.
Loading history...
|
|||
5302 | // } |
||
5303 | |||
5304 | /** |
||
5305 | * Find position of first occurrence of string in a string with multibyte support |
||
5306 | * |
||
5307 | * @param string $haystack The string being checked. |
||
5308 | * @param string $needle The string to find in haystack. |
||
5309 | * @param int $offset The search offset. If it is not specified, 0 is used. |
||
5310 | * @return int|bool |
||
5311 | * @author Alexey Sukhotin |
||
5312 | **/ |
||
5313 | protected function stripos($haystack , $needle , $offset = 0) { |
||
5314 | if (function_exists('mb_stripos')) { |
||
5315 | return mb_stripos($haystack , $needle , $offset, 'UTF-8'); |
||
5316 | } else if (function_exists('mb_strtolower') && function_exists('mb_strpos')) { |
||
5317 | return mb_strpos(mb_strtolower($haystack, 'UTF-8'), mb_strtolower($needle, 'UTF-8'), $offset); |
||
5318 | } |
||
5319 | return stripos($haystack , $needle , $offset); |
||
5320 | } |
||
5321 | |||
5322 | /** |
||
5323 | * Get server side available archivers |
||
5324 | * |
||
5325 | * @param bool $use_cache |
||
5326 | * @return array |
||
5327 | */ |
||
5328 | protected function getArchivers($use_cache = true) { |
||
5329 | |||
5330 | $sessionKey = 'ARCHIVERS_CACHE'; |
||
5331 | if ($use_cache && isset($this->sessionCache[$sessionKey]) && is_array($this->sessionCache[$sessionKey])) { |
||
5332 | return $this->sessionCache[$sessionKey]; |
||
5333 | } |
||
5334 | |||
5335 | $arcs = array( |
||
5336 | 'create' => array(), |
||
5337 | 'extract' => array() |
||
5338 | ); |
||
5339 | |||
5340 | if ($this->procExec('') === 0) { |
||
5341 | |||
5342 | $this->procExec('tar --version', $o, $ctar); |
||
5343 | |||
5344 | if ($ctar == 0) { |
||
5345 | $arcs['create']['application/x-tar'] = array('cmd' => 'tar', 'argc' => '-cf', 'ext' => 'tar'); |
||
5346 | $arcs['extract']['application/x-tar'] = array('cmd' => 'tar', 'argc' => '-xf', 'ext' => 'tar'); |
||
5347 | unset($o); |
||
5348 | $test = $this->procExec('gzip --version', $o, $c); |
||
0 ignored issues
–
show
$test 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
Loading history...
|
|||
5349 | if ($c == 0) { |
||
5350 | $arcs['create']['application/x-gzip'] = array('cmd' => 'tar', 'argc' => '-czf', 'ext' => 'tgz'); |
||
5351 | $arcs['extract']['application/x-gzip'] = array('cmd' => 'tar', 'argc' => '-xzf', 'ext' => 'tgz'); |
||
5352 | } |
||
5353 | unset($o); |
||
5354 | $test = $this->procExec('bzip2 --version', $o, $c); |
||
0 ignored issues
–
show
$test 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
Loading history...
|
|||
5355 | if ($c == 0) { |
||
5356 | $arcs['create']['application/x-bzip2'] = array('cmd' => 'tar', 'argc' => '-cjf', 'ext' => 'tbz'); |
||
5357 | $arcs['extract']['application/x-bzip2'] = array('cmd' => 'tar', 'argc' => '-xjf', 'ext' => 'tbz'); |
||
5358 | } |
||
5359 | unset($o); |
||
5360 | $test = $this->procExec('xz --version', $o, $c); |
||
0 ignored issues
–
show
$test 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
Loading history...
|
|||
5361 | if ($c == 0) { |
||
5362 | $arcs['create']['application/x-xz'] = array('cmd' => 'tar', 'argc' => '-cJf', 'ext' => 'xz'); |
||
5363 | $arcs['extract']['application/x-xz'] = array('cmd' => 'tar', 'argc' => '-xJf', 'ext' => 'xz'); |
||
5364 | } |
||
5365 | } |
||
5366 | unset($o); |
||
5367 | $this->procExec('zip -v', $o, $c); |
||
5368 | if ($c == 0) { |
||
5369 | $arcs['create']['application/zip'] = array('cmd' => 'zip', 'argc' => '-r9', 'ext' => 'zip'); |
||
5370 | } |
||
5371 | unset($o); |
||
5372 | $this->procExec('unzip --help', $o, $c); |
||
5373 | if ($c == 0) { |
||
5374 | $arcs['extract']['application/zip'] = array('cmd' => 'unzip', 'argc' => '', 'ext' => 'zip'); |
||
5375 | } |
||
5376 | unset($o); |
||
5377 | $this->procExec('rar --version', $o, $c); |
||
5378 | if ($c == 0 || $c == 7) { |
||
5379 | $arcs['create']['application/x-rar'] = array('cmd' => 'rar', 'argc' => 'a -inul', 'ext' => 'rar'); |
||
5380 | $arcs['extract']['application/x-rar'] = array('cmd' => 'rar', 'argc' => 'x -y', 'ext' => 'rar'); |
||
5381 | } else { |
||
5382 | unset($o); |
||
5383 | $test = $this->procExec('unrar', $o, $c); |
||
0 ignored issues
–
show
$test 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
Loading history...
|
|||
5384 | if ($c==0 || $c == 7) { |
||
5385 | $arcs['extract']['application/x-rar'] = array('cmd' => 'unrar', 'argc' => 'x -y', 'ext' => 'rar'); |
||
5386 | } |
||
5387 | } |
||
5388 | unset($o); |
||
5389 | $this->procExec('7za --help', $o, $c); |
||
5390 | if ($c == 0) { |
||
5391 | $arcs['create']['application/x-7z-compressed'] = array('cmd' => '7za', 'argc' => 'a', 'ext' => '7z'); |
||
5392 | $arcs['extract']['application/x-7z-compressed'] = array('cmd' => '7za', 'argc' => 'x -y', 'ext' => '7z'); |
||
5393 | |||
5394 | if (empty($arcs['create']['application/zip'])) { |
||
5395 | $arcs['create']['application/zip'] = array('cmd' => '7za', 'argc' => 'a -tzip', 'ext' => 'zip'); |
||
5396 | } |
||
5397 | if (empty($arcs['extract']['application/zip'])) { |
||
5398 | $arcs['extract']['application/zip'] = array('cmd' => '7za', 'argc' => 'x -tzip -y', 'ext' => 'zip'); |
||
5399 | } |
||
5400 | if (empty($arcs['create']['application/x-tar'])) { |
||
5401 | $arcs['create']['application/x-tar'] = array('cmd' => '7za', 'argc' => 'a -ttar', 'ext' => 'tar'); |
||
5402 | } |
||
5403 | if (empty($arcs['extract']['application/x-tar'])) { |
||
5404 | $arcs['extract']['application/x-tar'] = array('cmd' => '7za', 'argc' => 'x -ttar -y', 'ext' => 'tar'); |
||
5405 | } |
||
5406 | } else if (substr(PHP_OS,0,3) === 'WIN') { |
||
5407 | // check `7z` for Windows server. |
||
5408 | unset($o); |
||
5409 | $this->procExec('7z', $o, $c); |
||
5410 | if ($c == 0) { |
||
5411 | $arcs['create']['application/x-7z-compressed'] = array('cmd' => '7z', 'argc' => 'a', 'ext' => '7z'); |
||
5412 | $arcs['extract']['application/x-7z-compressed'] = array('cmd' => '7z', 'argc' => 'x -y', 'ext' => '7z'); |
||
5413 | |||
5414 | if (empty($arcs['create']['application/zip'])) { |
||
5415 | $arcs['create']['application/zip'] = array('cmd' => '7z', 'argc' => 'a -tzip', 'ext' => 'zip'); |
||
5416 | } |
||
5417 | if (empty($arcs['extract']['application/zip'])) { |
||
5418 | $arcs['extract']['application/zip'] = array('cmd' => '7z', 'argc' => 'x -tzip -y', 'ext' => 'zip'); |
||
5419 | } |
||
5420 | if (empty($arcs['create']['application/x-tar'])) { |
||
5421 | $arcs['create']['application/x-tar'] = array('cmd' => '7z', 'argc' => 'a -ttar', 'ext' => 'tar'); |
||
5422 | } |
||
5423 | if (empty($arcs['extract']['application/x-tar'])) { |
||
5424 | $arcs['extract']['application/x-tar'] = array('cmd' => '7z', 'argc' => 'x -ttar -y', 'ext' => 'tar'); |
||
5425 | } |
||
5426 | } |
||
5427 | } |
||
5428 | |||
5429 | } |
||
5430 | |||
5431 | // Use PHP ZipArchive Class |
||
5432 | if (class_exists('ZipArchive', false)) { |
||
5433 | if (empty($arcs['create']['application/zip'])) { |
||
5434 | $arcs['create']['application/zip'] = array('cmd' => 'phpfunction', 'argc' => array('self', 'zipArchiveZip'), 'ext' => 'zip'); |
||
5435 | } |
||
5436 | if (empty($arcs['extract']['application/zip'])) { |
||
5437 | $arcs['extract']['application/zip'] = array('cmd' => 'phpfunction', 'argc' => array('self', 'zipArchiveUnzip'), 'ext' => 'zip'); |
||
5438 | } |
||
5439 | } |
||
5440 | |||
5441 | $this->sessionCache[$sessionKey] = $arcs; |
||
5442 | $this->session->set($this->id, $this->sessionCache); |
||
5443 | return $arcs; |
||
5444 | } |
||
5445 | |||
5446 | /** |
||
5447 | * Resolve relative / (Unix-like)absolute path |
||
5448 | * |
||
5449 | * @param string $path target path |
||
5450 | * @param string $base base path |
||
5451 | * @return string |
||
5452 | */ |
||
5453 | protected function getFullPath($path, $base) { |
||
5454 | $separator = $this->separator; |
||
5455 | $systemroot = $this->systemRoot; |
||
5456 | |||
5457 | if ($base[0] === $separator && strpos($base, 0, strlen($systemroot)) !== $systemroot) { |
||
0 ignored issues
–
show
|
|||
5458 | $base = $systemroot . substr($base, 1); |
||
5459 | } |
||
5460 | |||
5461 | // 'Here' |
||
5462 | if ($path === '' || $path === '.' . $separator) return $base; |
||
5463 | |||
5464 | $sepquoted = preg_quote($separator, '#'); |
||
5465 | |||
5466 | if (substr($path, 0, 3) === '..' . $separator) { |
||
5467 | $path = $base . $separator . $path; |
||
5468 | } |
||
5469 | // normalize `/../` |
||
5470 | $normreg = '#('.$sepquoted.')[^'.$sepquoted.']+'.$sepquoted.'\.\.'.$sepquoted.'#'; // '#(/)[^\/]+/\.\./#' |
||
5471 | while(preg_match($normreg, $path)) { |
||
5472 | $path = preg_replace($normreg, '$1', $path, 1); |
||
5473 | } |
||
5474 | |||
5475 | // Absolute path |
||
5476 | if ($path[0] === $separator || strpos($path, $systemroot) === 0) { |
||
5477 | return $path; |
||
5478 | } |
||
5479 | |||
5480 | $preg_separator = '#' . $sepquoted . '#'; |
||
5481 | |||
5482 | // Relative path from 'Here' |
||
5483 | if (substr($path, 0, 2) === '.' . $separator || $path[0] !== '.') { |
||
5484 | $arrn = preg_split($preg_separator, $path, -1, PREG_SPLIT_NO_EMPTY); |
||
5485 | if ($arrn[0] !== '.') { |
||
5486 | array_unshift($arrn, '.'); |
||
5487 | } |
||
5488 | $arrn[0] = $base; |
||
5489 | return join($separator, $arrn); |
||
5490 | } |
||
5491 | |||
5492 | return $path; |
||
5493 | } |
||
5494 | |||
5495 | /** |
||
5496 | * Remove directory recursive on local file system |
||
5497 | * |
||
5498 | * @param string $dir Target dirctory path |
||
5499 | * @return boolean |
||
5500 | * @author Naoki Sawada |
||
5501 | */ |
||
5502 | public function rmdirRecursive($dir) { |
||
5503 | if (!is_link($dir) && is_dir($dir)) { |
||
5504 | chmod($dir, 0777); |
||
5505 | if ($handle = opendir($dir)) { |
||
5506 | while (false !== ($file = readdir($handle))) { |
||
5507 | if ($file === '.' || $file === '..') { |
||
5508 | continue; |
||
5509 | } |
||
5510 | elFinder::extendTimeLimit(30); |
||
5511 | $path = $dir . DIRECTORY_SEPARATOR . $file; |
||
5512 | if (!is_link($dir) && is_dir($path)) { |
||
5513 | $this->rmdirRecursive($path); |
||
5514 | } else { |
||
5515 | chmod($path, 0666); |
||
5516 | unlink($path); |
||
5517 | } |
||
5518 | } |
||
5519 | closedir($handle); |
||
5520 | } |
||
5521 | return rmdir($dir); |
||
5522 | } elseif (is_file($dir) || is_link($dir)) { |
||
5523 | chmod($dir, 0666); |
||
5524 | return unlink($dir); |
||
5525 | } |
||
5526 | return false; |
||
5527 | } |
||
5528 | |||
5529 | /** |
||
5530 | * Create archive and return its path |
||
5531 | * |
||
5532 | * @param string $dir target dir |
||
5533 | * @param array $files files names list |
||
5534 | * @param string $name archive name |
||
5535 | * @param array $arc archiver options |
||
5536 | * @return string|bool |
||
5537 | * @author Dmitry (dio) Levashov, |
||
5538 | * @author Alexey Sukhotin |
||
5539 | * @author Naoki Sawada |
||
5540 | **/ |
||
5541 | protected function makeArchive($dir, $files, $name, $arc) { |
||
5542 | if ($arc['cmd'] === 'phpfunction') { |
||
5543 | if (is_callable($arc['argc'])) { |
||
5544 | call_user_func_array($arc['argc'], array($dir, $files, $name)); |
||
5545 | } |
||
5546 | } else { |
||
5547 | $cwd = getcwd(); |
||
5548 | chdir($dir); |
||
5549 | |||
5550 | foreach($files as $i => $file) { |
||
5551 | $files[$i] = '.'.DIRECTORY_SEPARATOR.$file; |
||
5552 | } |
||
5553 | $files = array_map('escapeshellarg', $files); |
||
5554 | |||
5555 | $cmd = $arc['cmd'].' '.$arc['argc'].' '.escapeshellarg($name).' '.implode(' ', $files); |
||
5556 | $this->procExec($cmd, $o, $c); |
||
5557 | chdir($cwd); |
||
5558 | } |
||
5559 | $path = $dir.DIRECTORY_SEPARATOR.$name; |
||
5560 | return file_exists($path) ? $path : false; |
||
5561 | } |
||
5562 | |||
5563 | /** |
||
5564 | * Unpack archive |
||
5565 | * |
||
5566 | * @param string $path archive path |
||
5567 | * @param array $arc archiver command and arguments (same as in $this->archivers) |
||
5568 | * @param bool $remove remove archive ( unlink($path) ) |
||
5569 | * @return void |
||
5570 | * @author Dmitry (dio) Levashov |
||
5571 | * @author Alexey Sukhotin |
||
5572 | * @author Naoki Sawada |
||
5573 | **/ |
||
5574 | protected function unpackArchive($path, $arc, $remove = true) { |
||
5575 | $dir = dirname($path); |
||
5576 | if ($arc['cmd'] === 'phpfunction') { |
||
5577 | if (is_callable($arc['argc'])) { |
||
5578 | call_user_func_array($arc['argc'], array($path, $dir)); |
||
5579 | } |
||
5580 | } else { |
||
5581 | $cwd = getcwd(); |
||
5582 | chdir($dir); |
||
5583 | $cmd = $arc['cmd'].' '.$arc['argc'].' '.escapeshellarg(basename($path)); |
||
5584 | $this->procExec($cmd, $o, $c); |
||
5585 | chdir($cwd); |
||
5586 | } |
||
5587 | $remove && unlink($path); |
||
5588 | } |
||
5589 | |||
5590 | /** |
||
5591 | * Return files of target directory that is dotfiles excludes. |
||
5592 | * |
||
5593 | * @param string $dir target directory path |
||
5594 | * @return array |
||
5595 | * @throws Exception |
||
5596 | * @author Naoki Sawada |
||
5597 | */ |
||
5598 | protected static function localScandir($dir) { |
||
5599 | // PHP function scandir() is not work well in specific environment. I dont know why. |
||
5600 | // ref. https://github.com/Studio-42/elFinder/issues/1248 |
||
5601 | $files = array(); |
||
5602 | if ($dh = opendir($dir)) { |
||
5603 | while (false !== ($file = readdir($dh))) { |
||
5604 | if ($file !== '.' && $file !== '..') { |
||
5605 | $files[] = $file; |
||
5606 | } |
||
5607 | } |
||
5608 | closedir($dh); |
||
5609 | } else { |
||
5610 | throw new Exception('Can not open local directory.'); |
||
5611 | } |
||
5612 | return $files; |
||
5613 | } |
||
5614 | |||
5615 | /** |
||
5616 | * Create Zip archive using PHP class ZipArchive |
||
5617 | * |
||
5618 | * @param string $dir target dir |
||
5619 | * @param array $files files names list |
||
5620 | * @param string|object $zipPath Zip archive name |
||
5621 | * @return bool |
||
5622 | * @author Naoki Sawada |
||
5623 | */ |
||
5624 | protected static function zipArchiveZip($dir, $files, $zipPath) { |
||
5625 | try { |
||
5626 | if ($start = is_string($zipPath)) { |
||
5627 | $zip = new ZipArchive(); |
||
5628 | if ($zip->open($dir . DIRECTORY_SEPARATOR . $zipPath, ZipArchive::CREATE) !== true) { |
||
5629 | $zip = false; |
||
5630 | } |
||
5631 | } else { |
||
5632 | $zip = $zipPath; |
||
5633 | } |
||
5634 | if ($zip) { |
||
5635 | foreach($files as $file) { |
||
5636 | $path = $dir . DIRECTORY_SEPARATOR . $file; |
||
5637 | if (is_dir($path)) { |
||
5638 | $zip->addEmptyDir($file); |
||
5639 | $_files = array(); |
||
5640 | if ($handle = opendir($path)) { |
||
5641 | while (false !== ($entry = readdir($handle))) { |
||
5642 | if ($entry !== "." && $entry !== "..") { |
||
5643 | $_files[] = $file . DIRECTORY_SEPARATOR . $entry; |
||
5644 | } |
||
5645 | } |
||
5646 | closedir($handle); |
||
5647 | } |
||
5648 | 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
Loading history...
|
|||
5649 | self::zipArchiveZip($dir, $_files, $zip); |
||
5650 | } |
||
5651 | } else { |
||
5652 | $zip->addFile($path, $file); |
||
5653 | } |
||
5654 | } |
||
5655 | $start && $zip->close(); |
||
5656 | } |
||
5657 | } catch (Exception $e) { |
||
5658 | return false; |
||
5659 | } |
||
5660 | return true; |
||
5661 | } |
||
5662 | |||
5663 | /** |
||
5664 | * Unpack Zip archive using PHP class ZipArchive |
||
5665 | * |
||
5666 | * @param string $zipPath Zip archive name |
||
5667 | * @param string $toDir Extract to path |
||
5668 | * @return bool |
||
5669 | * @author Naoki Sawada |
||
5670 | */ |
||
5671 | protected static function zipArchiveUnzip($zipPath, $toDir) { |
||
5672 | try { |
||
5673 | $zip = new ZipArchive(); |
||
5674 | if ($zip->open($zipPath) === true) { |
||
5675 | $zip->extractTo($toDir); |
||
5676 | $zip->close(); |
||
5677 | } |
||
5678 | } catch (Exception $e) { |
||
5679 | return false; |
||
5680 | } |
||
5681 | return true; |
||
5682 | } |
||
5683 | |||
5684 | /**==================================* abstract methods *====================================**/ |
||
5685 | |||
5686 | /*********************** paths/urls *************************/ |
||
5687 | |||
5688 | /** |
||
5689 | * Return parent directory path |
||
5690 | * |
||
5691 | * @param string $path file path |
||
5692 | * @return string |
||
5693 | * @author Dmitry (dio) Levashov |
||
5694 | **/ |
||
5695 | abstract protected function _dirname($path); |
||
5696 | |||
5697 | /** |
||
5698 | * Return file name |
||
5699 | * |
||
5700 | * @param string $path file path |
||
5701 | * @return string |
||
5702 | * @author Dmitry (dio) Levashov |
||
5703 | **/ |
||
5704 | abstract protected function _basename($path); |
||
5705 | |||
5706 | /** |
||
5707 | * Join dir name and file name and return full path. |
||
5708 | * Some drivers (db) use int as path - so we give to concat path to driver itself |
||
5709 | * |
||
5710 | * @param string $dir dir path |
||
5711 | * @param string $name file name |
||
5712 | * @return string |
||
5713 | * @author Dmitry (dio) Levashov |
||
5714 | **/ |
||
5715 | abstract protected function _joinPath($dir, $name); |
||
5716 | |||
5717 | /** |
||
5718 | * Return normalized path |
||
5719 | * |
||
5720 | * @param string $path file path |
||
5721 | * @return string |
||
5722 | * @author Dmitry (dio) Levashov |
||
5723 | **/ |
||
5724 | abstract protected function _normpath($path); |
||
5725 | |||
5726 | /** |
||
5727 | * Return file path related to root dir |
||
5728 | * |
||
5729 | * @param string $path file path |
||
5730 | * @return string |
||
5731 | * @author Dmitry (dio) Levashov |
||
5732 | **/ |
||
5733 | abstract protected function _relpath($path); |
||
5734 | |||
5735 | /** |
||
5736 | * Convert path related to root dir into real path |
||
5737 | * |
||
5738 | * @param string $path rel file path |
||
5739 | * @return string |
||
5740 | * @author Dmitry (dio) Levashov |
||
5741 | **/ |
||
5742 | abstract protected function _abspath($path); |
||
5743 | |||
5744 | /** |
||
5745 | * Return fake path started from root dir. |
||
5746 | * Required to show path on client side. |
||
5747 | * |
||
5748 | * @param string $path file path |
||
5749 | * @return string |
||
5750 | * @author Dmitry (dio) Levashov |
||
5751 | **/ |
||
5752 | abstract protected function _path($path); |
||
5753 | |||
5754 | /** |
||
5755 | * Return true if $path is children of $parent |
||
5756 | * |
||
5757 | * @param string $path path to check |
||
5758 | * @param string $parent parent path |
||
5759 | * @return bool |
||
5760 | * @author Dmitry (dio) Levashov |
||
5761 | **/ |
||
5762 | abstract protected function _inpath($path, $parent); |
||
5763 | |||
5764 | /** |
||
5765 | * Return stat for given path. |
||
5766 | * Stat contains following fields: |
||
5767 | * - (int) size file size in b. required |
||
5768 | * - (int) ts file modification time in unix time. required |
||
5769 | * - (string) mime mimetype. required for folders, others - optionally |
||
5770 | * - (bool) read read permissions. required |
||
5771 | * - (bool) write write permissions. required |
||
5772 | * - (bool) locked is object locked. optionally |
||
5773 | * - (bool) hidden is object hidden. optionally |
||
5774 | * - (string) alias for symlinks - link target path relative to root path. optionally |
||
5775 | * - (string) target for symlinks - link target path. optionally |
||
5776 | * |
||
5777 | * If file does not exists - returns empty array or false. |
||
5778 | * |
||
5779 | * @param string $path file path |
||
5780 | * @return array|false |
||
5781 | * @author Dmitry (dio) Levashov |
||
5782 | **/ |
||
5783 | abstract protected function _stat($path); |
||
5784 | |||
5785 | |||
5786 | /***************** file stat ********************/ |
||
5787 | |||
5788 | |||
5789 | /** |
||
5790 | * Return true if path is dir and has at least one childs directory |
||
5791 | * |
||
5792 | * @param string $path dir path |
||
5793 | * @return bool |
||
5794 | * @author Dmitry (dio) Levashov |
||
5795 | **/ |
||
5796 | abstract protected function _subdirs($path); |
||
5797 | |||
5798 | /** |
||
5799 | * Return object width and height |
||
5800 | * Ususaly used for images, but can be realize for video etc... |
||
5801 | * |
||
5802 | * @param string $path file path |
||
5803 | * @param string $mime file mime type |
||
5804 | * @return string |
||
5805 | * @author Dmitry (dio) Levashov |
||
5806 | **/ |
||
5807 | abstract protected function _dimensions($path, $mime); |
||
5808 | |||
5809 | /******************** file/dir content *********************/ |
||
5810 | |||
5811 | /** |
||
5812 | * Return files list in directory |
||
5813 | * |
||
5814 | * @param string $path dir path |
||
5815 | * @return array |
||
5816 | * @author Dmitry (dio) Levashov |
||
5817 | **/ |
||
5818 | abstract protected function _scandir($path); |
||
5819 | |||
5820 | /** |
||
5821 | * Open file and return file pointer |
||
5822 | * |
||
5823 | * @param string $path file path |
||
5824 | * @param string $mode open mode |
||
5825 | * @return resource|false |
||
5826 | * @author Dmitry (dio) Levashov |
||
5827 | **/ |
||
5828 | abstract protected function _fopen($path, $mode="rb"); |
||
5829 | |||
5830 | /** |
||
5831 | * Close opened file |
||
5832 | * |
||
5833 | * @param resource $fp file pointer |
||
5834 | * @param string $path file path |
||
5835 | * @return bool |
||
5836 | * @author Dmitry (dio) Levashov |
||
5837 | **/ |
||
5838 | abstract protected function _fclose($fp, $path=''); |
||
5839 | |||
5840 | /******************** file/dir manipulations *************************/ |
||
5841 | |||
5842 | /** |
||
5843 | * Create dir and return created dir path or false on failed |
||
5844 | * |
||
5845 | * @param string $path parent dir path |
||
5846 | * @param string $name new directory name |
||
5847 | * @return string|bool |
||
5848 | * @author Dmitry (dio) Levashov |
||
5849 | **/ |
||
5850 | abstract protected function _mkdir($path, $name); |
||
5851 | |||
5852 | /** |
||
5853 | * Create file and return it's path or false on failed |
||
5854 | * |
||
5855 | * @param string $path parent dir path |
||
5856 | * @param string $name new file name |
||
5857 | * @return string|bool |
||
5858 | * @author Dmitry (dio) Levashov |
||
5859 | **/ |
||
5860 | abstract protected function _mkfile($path, $name); |
||
5861 | |||
5862 | /** |
||
5863 | * Create symlink |
||
5864 | * |
||
5865 | * @param string $source file to link to |
||
5866 | * @param string $targetDir folder to create link in |
||
5867 | * @param string $name symlink name |
||
5868 | * @return bool |
||
5869 | * @author Dmitry (dio) Levashov |
||
5870 | **/ |
||
5871 | abstract protected function _symlink($source, $targetDir, $name); |
||
5872 | |||
5873 | /** |
||
5874 | * Copy file into another file (only inside one volume) |
||
5875 | * |
||
5876 | * @param string $source source file path |
||
5877 | * @param $targetDir |
||
5878 | * @param string $name file name |
||
5879 | * @return bool|string |
||
5880 | * @internal param string $target target dir path |
||
5881 | * @author Dmitry (dio) Levashov |
||
5882 | */ |
||
5883 | abstract protected function _copy($source, $targetDir, $name); |
||
5884 | |||
5885 | /** |
||
5886 | * Move file into another parent dir. |
||
5887 | * Return new file path or false. |
||
5888 | * |
||
5889 | * @param string $source source file path |
||
5890 | * @param $targetDir |
||
5891 | * @param string $name file name |
||
5892 | * @return bool|string |
||
5893 | * @internal param string $target target dir path |
||
5894 | * @author Dmitry (dio) Levashov |
||
5895 | */ |
||
5896 | abstract protected function _move($source, $targetDir, $name); |
||
5897 | |||
5898 | /** |
||
5899 | * Remove file |
||
5900 | * |
||
5901 | * @param string $path file path |
||
5902 | * @return bool |
||
5903 | * @author Dmitry (dio) Levashov |
||
5904 | **/ |
||
5905 | abstract protected function _unlink($path); |
||
5906 | |||
5907 | /** |
||
5908 | * Remove dir |
||
5909 | * |
||
5910 | * @param string $path dir path |
||
5911 | * @return bool |
||
5912 | * @author Dmitry (dio) Levashov |
||
5913 | **/ |
||
5914 | abstract protected function _rmdir($path); |
||
5915 | |||
5916 | /** |
||
5917 | * Create new file and write into it from file pointer. |
||
5918 | * Return new file path or false on error. |
||
5919 | * |
||
5920 | * @param resource $fp file pointer |
||
5921 | * @param string $dir target dir path |
||
5922 | * @param string $name file name |
||
5923 | * @param array $stat file stat (required by some virtual fs) |
||
5924 | * @return bool|string |
||
5925 | * @author Dmitry (dio) Levashov |
||
5926 | **/ |
||
5927 | abstract protected function _save($fp, $dir, $name, $stat); |
||
5928 | |||
5929 | /** |
||
5930 | * Get file contents |
||
5931 | * |
||
5932 | * @param string $path file path |
||
5933 | * @return string|false |
||
5934 | * @author Dmitry (dio) Levashov |
||
5935 | **/ |
||
5936 | abstract protected function _getContents($path); |
||
5937 | |||
5938 | /** |
||
5939 | * Write a string to a file |
||
5940 | * |
||
5941 | * @param string $path file path |
||
5942 | * @param string $content new file content |
||
5943 | * @return bool |
||
5944 | * @author Dmitry (dio) Levashov |
||
5945 | **/ |
||
5946 | abstract protected function _filePutContents($path, $content); |
||
5947 | |||
5948 | /** |
||
5949 | * Extract files from archive |
||
5950 | * |
||
5951 | * @param string $path file path |
||
5952 | * @param array $arc archiver options |
||
5953 | * @return bool |
||
5954 | * @author Dmitry (dio) Levashov, |
||
5955 | * @author Alexey Sukhotin |
||
5956 | **/ |
||
5957 | abstract protected function _extract($path, $arc); |
||
5958 | |||
5959 | /** |
||
5960 | * Create archive and return its path |
||
5961 | * |
||
5962 | * @param string $dir target dir |
||
5963 | * @param array $files files names list |
||
5964 | * @param string $name archive name |
||
5965 | * @param array $arc archiver options |
||
5966 | * @return string|bool |
||
5967 | * @author Dmitry (dio) Levashov, |
||
5968 | * @author Alexey Sukhotin |
||
5969 | **/ |
||
5970 | abstract protected function _archive($dir, $files, $name, $arc); |
||
5971 | |||
5972 | /** |
||
5973 | * Detect available archivers |
||
5974 | * |
||
5975 | * @return void |
||
5976 | * @author Dmitry (dio) Levashov, |
||
5977 | * @author Alexey Sukhotin |
||
5978 | **/ |
||
5979 | abstract protected function _checkArchivers(); |
||
5980 | |||
5981 | /** |
||
5982 | * Change file mode (chmod) |
||
5983 | * |
||
5984 | * @param string $path file path |
||
5985 | * @param string $mode octal string such as '0755' |
||
5986 | * @return bool |
||
5987 | * @author David Bartle, |
||
5988 | **/ |
||
5989 | abstract protected function _chmod($path, $mode); |
||
5990 | |||
5991 | |||
5992 | } // END class |
||
5993 |
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.