This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
|||||||||||
2 | ||||||||||||
3 | /** |
|||||||||||
4 | * elFinder - file manager for web. |
|||||||||||
5 | * Core class. |
|||||||||||
6 | * |
|||||||||||
7 | * @author Dmitry (dio) Levashov |
|||||||||||
8 | * @author Troex Nevelin |
|||||||||||
9 | * @author Alexey Sukhotin |
|||||||||||
10 | **/ |
|||||||||||
11 | class elFinder |
|||||||||||
0 ignored issues
–
show
|
||||||||||||
12 | { |
|||||||||||
13 | // Errors messages |
|||||||||||
14 | const ERROR_UNKNOWN = 'errUnknown'; |
|||||||||||
15 | const ERROR_UNKNOWN_CMD = 'errUnknownCmd'; |
|||||||||||
16 | const ERROR_CONF = 'errConf'; |
|||||||||||
17 | const ERROR_CONF_NO_JSON = 'errJSON'; |
|||||||||||
18 | const ERROR_CONF_NO_VOL = 'errNoVolumes'; |
|||||||||||
19 | const ERROR_INV_PARAMS = 'errCmdParams'; |
|||||||||||
20 | const ERROR_OPEN = 'errOpen'; |
|||||||||||
21 | const ERROR_DIR_NOT_FOUND = 'errFolderNotFound'; |
|||||||||||
22 | const ERROR_FILE_NOT_FOUND = 'errFileNotFound'; // 'File not found.' |
|||||||||||
23 | const ERROR_TRGDIR_NOT_FOUND = 'errTrgFolderNotFound'; // 'Target folder "$1" not found.' |
|||||||||||
24 | const ERROR_NOT_DIR = 'errNotFolder'; |
|||||||||||
25 | const ERROR_NOT_FILE = 'errNotFile'; |
|||||||||||
26 | const ERROR_PERM_DENIED = 'errPerm'; |
|||||||||||
27 | const ERROR_LOCKED = 'errLocked'; // '"$1" is locked and can not be renamed, moved or removed.' |
|||||||||||
28 | const ERROR_EXISTS = 'errExists'; // 'File named "$1" already exists.' |
|||||||||||
29 | const ERROR_INVALID_NAME = 'errInvName'; // 'Invalid file name.' |
|||||||||||
30 | const ERROR_INVALID_DIRNAME = 'errInvDirname'; // 'Invalid folder name.' |
|||||||||||
31 | const ERROR_MKDIR = 'errMkdir'; |
|||||||||||
32 | const ERROR_MKFILE = 'errMkfile'; |
|||||||||||
33 | const ERROR_RENAME = 'errRename'; |
|||||||||||
34 | const ERROR_COPY = 'errCopy'; |
|||||||||||
35 | const ERROR_MOVE = 'errMove'; |
|||||||||||
36 | const ERROR_COPY_FROM = 'errCopyFrom'; |
|||||||||||
37 | const ERROR_COPY_TO = 'errCopyTo'; |
|||||||||||
38 | const ERROR_COPY_ITSELF = 'errCopyInItself'; |
|||||||||||
39 | const ERROR_REPLACE = 'errReplace'; // 'Unable to replace "$1".' |
|||||||||||
40 | const ERROR_RM = 'errRm'; // 'Unable to remove "$1".' |
|||||||||||
41 | const ERROR_RM_SRC = 'errRmSrc'; // 'Unable remove source file(s)' |
|||||||||||
42 | const ERROR_MKOUTLINK = 'errMkOutLink'; // 'Unable to create a link to outside the volume root.' |
|||||||||||
43 | const ERROR_UPLOAD = 'errUpload'; // 'Upload error.' |
|||||||||||
44 | const ERROR_UPLOAD_FILE = 'errUploadFile'; // 'Unable to upload "$1".' |
|||||||||||
45 | const ERROR_UPLOAD_NO_FILES = 'errUploadNoFiles'; // 'No files found for upload.' |
|||||||||||
46 | const ERROR_UPLOAD_TOTAL_SIZE = 'errUploadTotalSize'; // 'Data exceeds the maximum allowed size.' |
|||||||||||
47 | const ERROR_UPLOAD_FILE_SIZE = 'errUploadFileSize'; // 'File exceeds maximum allowed size.' |
|||||||||||
48 | const ERROR_UPLOAD_FILE_MIME = 'errUploadMime'; // 'File type not allowed.' |
|||||||||||
49 | const ERROR_UPLOAD_TRANSFER = 'errUploadTransfer'; // '"$1" transfer error.' |
|||||||||||
50 | const ERROR_UPLOAD_TEMP = 'errUploadTemp'; // 'Unable to make temporary file for upload.' |
|||||||||||
51 | const ERROR_ACCESS_DENIED = 'errAccess'; |
|||||||||||
52 | const ERROR_NOT_REPLACE = 'errNotReplace'; // Object "$1" already exists at this location and can not be replaced with object of another type. |
|||||||||||
53 | const ERROR_SAVE = 'errSave'; |
|||||||||||
54 | const ERROR_EXTRACT = 'errExtract'; |
|||||||||||
55 | const ERROR_ARCHIVE = 'errArchive'; |
|||||||||||
56 | const ERROR_NOT_ARCHIVE = 'errNoArchive'; |
|||||||||||
57 | const ERROR_ARCHIVE_TYPE = 'errArcType'; |
|||||||||||
58 | const ERROR_ARC_SYMLINKS = 'errArcSymlinks'; |
|||||||||||
59 | const ERROR_ARC_MAXSIZE = 'errArcMaxSize'; |
|||||||||||
60 | const ERROR_RESIZE = 'errResize'; |
|||||||||||
61 | const ERROR_RESIZESIZE = 'errResizeSize'; |
|||||||||||
62 | const ERROR_UNSUPPORT_TYPE = 'errUsupportType'; |
|||||||||||
63 | const ERROR_CONV_UTF8 = 'errConvUTF8'; |
|||||||||||
64 | const ERROR_NOT_UTF8_CONTENT = 'errNotUTF8Content'; |
|||||||||||
65 | const ERROR_NETMOUNT = 'errNetMount'; |
|||||||||||
66 | const ERROR_NETUNMOUNT = 'errNetUnMount'; |
|||||||||||
67 | const ERROR_NETMOUNT_NO_DRIVER = 'errNetMountNoDriver'; |
|||||||||||
68 | const ERROR_NETMOUNT_FAILED = 'errNetMountFailed'; |
|||||||||||
69 | const ERROR_SESSION_EXPIRES = 'errSessionExpires'; |
|||||||||||
70 | const ERROR_CREATING_TEMP_DIR = 'errCreatingTempDir'; |
|||||||||||
71 | const ERROR_FTP_DOWNLOAD_FILE = 'errFtpDownloadFile'; |
|||||||||||
72 | const ERROR_FTP_UPLOAD_FILE = 'errFtpUploadFile'; |
|||||||||||
73 | const ERROR_FTP_MKDIR = 'errFtpMkdir'; |
|||||||||||
74 | const ERROR_ARCHIVE_EXEC = 'errArchiveExec'; |
|||||||||||
75 | const ERROR_EXTRACT_EXEC = 'errExtractExec'; |
|||||||||||
76 | const ERROR_SEARCH_TIMEOUT = 'errSearchTimeout'; // 'Timed out while searching "$1". Search result is partial.' |
|||||||||||
77 | const ERROR_REAUTH_REQUIRE = 'errReauthRequire'; // 'Re-authorization is required.' |
|||||||||||
78 | const ERROR_MAX_TARGTES = 'errMaxTargets'; // 'Max number of selectable items is $1.' |
|||||||||||
79 | ||||||||||||
80 | /** |
|||||||||||
81 | * elFinder instance. |
|||||||||||
82 | * |
|||||||||||
83 | * @var object |
|||||||||||
84 | */ |
|||||||||||
85 | public static $instance = null; |
|||||||||||
86 | ||||||||||||
87 | /** |
|||||||||||
88 | * Network mount drivers. |
|||||||||||
89 | * |
|||||||||||
90 | * @var array |
|||||||||||
91 | */ |
|||||||||||
92 | public static $netDrivers = []; |
|||||||||||
93 | ||||||||||||
94 | /** |
|||||||||||
95 | * elFinder global locale. |
|||||||||||
96 | * |
|||||||||||
97 | * @var string |
|||||||||||
98 | */ |
|||||||||||
99 | public static $locale = ''; |
|||||||||||
100 | ||||||||||||
101 | /** |
|||||||||||
102 | * elFinderVolumeDriver default mime.type file path. |
|||||||||||
103 | * |
|||||||||||
104 | * @var string |
|||||||||||
105 | */ |
|||||||||||
106 | public static $defaultMimefile = ''; |
|||||||||||
107 | ||||||||||||
108 | /** |
|||||||||||
109 | * A file save destination path when a temporary content URL is required |
|||||||||||
110 | * on a network volume or the like |
|||||||||||
111 | * It can be overwritten by volume route setting. |
|||||||||||
112 | * |
|||||||||||
113 | * @var string |
|||||||||||
114 | */ |
|||||||||||
115 | public static $tmpLinkPath = ''; |
|||||||||||
116 | ||||||||||||
117 | /** |
|||||||||||
118 | * A file save destination URL when a temporary content URL is required |
|||||||||||
119 | * on a network volume or the like |
|||||||||||
120 | * It can be overwritten by volume route setting. |
|||||||||||
121 | * |
|||||||||||
122 | * @var string |
|||||||||||
123 | */ |
|||||||||||
124 | public static $tmpLinkUrl = ''; |
|||||||||||
125 | ||||||||||||
126 | /** |
|||||||||||
127 | * Temporary content URL lifetime (seconds). |
|||||||||||
128 | * |
|||||||||||
129 | * @var int |
|||||||||||
130 | */ |
|||||||||||
131 | public static $tmpLinkLifeTime = 3600; |
|||||||||||
132 | ||||||||||||
133 | /** |
|||||||||||
134 | * elFinder global sessionCacheKey. |
|||||||||||
135 | * |
|||||||||||
136 | * @deprecated |
|||||||||||
137 | * @var string |
|||||||||||
138 | */ |
|||||||||||
139 | public static $sessionCacheKey = ''; |
|||||||||||
140 | ||||||||||||
141 | /** |
|||||||||||
142 | * Mounted volumes count |
|||||||||||
143 | * Required to create unique volume id. |
|||||||||||
144 | * |
|||||||||||
145 | * @var int |
|||||||||||
146 | **/ |
|||||||||||
147 | public static $volumesCnt = 1; |
|||||||||||
148 | ||||||||||||
149 | /** |
|||||||||||
150 | * Max allowed numbar of @var targets (0 - no limit). |
|||||||||||
151 | * |
|||||||||||
152 | * @var int |
|||||||||||
153 | */ |
|||||||||||
154 | public $maxTargets = 1000; |
|||||||||||
155 | ||||||||||||
156 | /** |
|||||||||||
157 | * Errors from PHP. |
|||||||||||
158 | * |
|||||||||||
159 | * @var array |
|||||||||||
160 | **/ |
|||||||||||
161 | public static $phpErrors = []; |
|||||||||||
162 | ||||||||||||
163 | /** |
|||||||||||
164 | * Errors from not mounted volumes. |
|||||||||||
165 | * |
|||||||||||
166 | * @var array |
|||||||||||
167 | **/ |
|||||||||||
168 | public $mountErrors = []; |
|||||||||||
169 | ||||||||||||
170 | /** |
|||||||||||
171 | * API version number. |
|||||||||||
172 | * |
|||||||||||
173 | * @var string |
|||||||||||
174 | **/ |
|||||||||||
175 | protected $version = '2.1'; |
|||||||||||
176 | ||||||||||||
177 | /** |
|||||||||||
178 | * Storages (root dirs). |
|||||||||||
179 | * |
|||||||||||
180 | * @var array |
|||||||||||
181 | **/ |
|||||||||||
182 | protected $volumes = []; |
|||||||||||
183 | /** |
|||||||||||
184 | * elFinder session wrapper object. |
|||||||||||
185 | * |
|||||||||||
186 | * @var elFinderSessionInterface |
|||||||||||
187 | */ |
|||||||||||
188 | protected $session; |
|||||||||||
189 | ||||||||||||
190 | /** |
|||||||||||
191 | * elFinder base64encodeSessionData |
|||||||||||
192 | * elFinder save session data as `UTF-8` |
|||||||||||
193 | * If the session storage mechanism of the system does not allow `UTF-8` |
|||||||||||
194 | * And it must be `true` option 'base64encodeSessionData' of elFinder. |
|||||||||||
195 | * |
|||||||||||
196 | * @var bool |
|||||||||||
197 | */ |
|||||||||||
198 | protected static $base64encodeSessionData = false; |
|||||||||||
199 | ||||||||||||
200 | /** |
|||||||||||
201 | * elFinder common tempraly path. |
|||||||||||
202 | * |
|||||||||||
203 | * @var string |
|||||||||||
204 | **/ |
|||||||||||
205 | protected static $commonTempPath = ''; |
|||||||||||
206 | ||||||||||||
207 | /** |
|||||||||||
208 | * Additional volume root options for network mounting volume. |
|||||||||||
209 | * |
|||||||||||
210 | * @var array |
|||||||||||
211 | */ |
|||||||||||
212 | protected $optionsNetVolumes = []; |
|||||||||||
213 | ||||||||||||
214 | /** |
|||||||||||
215 | * Session key of net mount volumes. |
|||||||||||
216 | * |
|||||||||||
217 | * @deprecated |
|||||||||||
218 | * @var string |
|||||||||||
219 | */ |
|||||||||||
220 | protected $netVolumesSessionKey = ''; |
|||||||||||
221 | ||||||||||||
222 | /** |
|||||||||||
223 | * Default root (storage). |
|||||||||||
224 | * |
|||||||||||
225 | * @var elFinderStorageDriver |
|||||||||||
226 | **/ |
|||||||||||
227 | protected $default = null; |
|||||||||||
228 | ||||||||||||
229 | /** |
|||||||||||
230 | * Commands and required arguments list. |
|||||||||||
231 | * |
|||||||||||
232 | * @var array |
|||||||||||
233 | **/ |
|||||||||||
234 | protected $commands = [ |
|||||||||||
235 | 'open' => ['target' => false, 'tree' => false, 'init' => false, 'mimes' => false, 'compare' => false], |
|||||||||||
236 | 'ls' => ['target' => true, 'mimes' => false, 'intersect' => false], |
|||||||||||
237 | 'tree' => ['target' => true], |
|||||||||||
238 | 'parents' => ['target' => true, 'until' => false], |
|||||||||||
239 | 'tmb' => ['targets' => true], |
|||||||||||
240 | 'file' => ['target' => true, 'download' => false], |
|||||||||||
241 | 'zipdl' => ['targets' => true, 'download' => false], |
|||||||||||
242 | 'size' => ['targets' => true], |
|||||||||||
243 | 'mkdir' => ['target' => true, 'name' => false, 'dirs' => false], |
|||||||||||
244 | 'mkfile' => ['target' => true, 'name' => true, 'mimes' => false], |
|||||||||||
245 | 'rm' => ['targets' => true], |
|||||||||||
246 | 'rename' => ['target' => true, 'name' => true, 'mimes' => false], |
|||||||||||
247 | 'duplicate' => ['targets' => true, 'suffix' => false], |
|||||||||||
248 | 'paste' => ['dst' => true, 'targets' => true, 'cut' => false, 'mimes' => false, 'renames' => false, 'hashes' => false, 'suffix' => false], |
|||||||||||
249 | 'upload' => ['target' => true, 'FILES' => true, 'mimes' => false, 'html' => false, 'upload' => false, 'name' => false, 'upload_path' => false, 'chunk' => false, 'cid' => false, 'node' => false, 'renames' => false, 'hashes' => false, 'suffix' => false, 'mtime' => false, 'overwrite' => false], |
|||||||||||
250 | 'get' => ['target' => true, 'conv' => false], |
|||||||||||
251 | 'put' => ['target' => true, 'content' => '', 'mimes' => false, 'encoding' => false], |
|||||||||||
252 | 'archive' => ['targets' => true, 'type' => true, 'mimes' => false, 'name' => false], |
|||||||||||
253 | 'extract' => ['target' => true, 'mimes' => false, 'makedir' => false], |
|||||||||||
254 | 'search' => ['q' => true, 'mimes' => false, 'target' => false], |
|||||||||||
255 | 'info' => ['targets' => true, 'compare' => false], |
|||||||||||
256 | 'dim' => ['target' => true], |
|||||||||||
257 | 'resize' => ['target' => true, 'width' => false, 'height' => false, 'mode' => false, 'x' => false, 'y' => false, 'degree' => false, 'quality' => false, 'bg' => false], |
|||||||||||
258 | 'netmount' => ['protocol' => true, 'host' => true, 'path' => false, 'port' => false, 'user' => false, 'pass' => false, 'alias' => false, 'options' => false], |
|||||||||||
259 | 'url' => ['target' => true, 'options' => false], |
|||||||||||
260 | 'callback' => ['node' => true, 'json' => false, 'bind' => false, 'done' => false], |
|||||||||||
261 | 'chmod' => ['targets' => true, 'mode' => true], |
|||||||||||
262 | 'subdirs' => ['targets' => true], |
|||||||||||
263 | ]; |
|||||||||||
264 | ||||||||||||
265 | /** |
|||||||||||
266 | * Plugins instance. |
|||||||||||
267 | * |
|||||||||||
268 | * @var array |
|||||||||||
269 | **/ |
|||||||||||
270 | protected $plugins = []; |
|||||||||||
271 | ||||||||||||
272 | /** |
|||||||||||
273 | * Commands listeners. |
|||||||||||
274 | * |
|||||||||||
275 | * @var array |
|||||||||||
276 | **/ |
|||||||||||
277 | protected $listeners = []; |
|||||||||||
278 | ||||||||||||
279 | /** |
|||||||||||
280 | * script work time for debug. |
|||||||||||
281 | * |
|||||||||||
282 | * @var string |
|||||||||||
283 | **/ |
|||||||||||
284 | protected $time = 0; |
|||||||||||
285 | /** |
|||||||||||
286 | * Is elFinder init correctly? |
|||||||||||
287 | * |
|||||||||||
288 | * @var bool |
|||||||||||
289 | **/ |
|||||||||||
290 | protected $loaded = false; |
|||||||||||
291 | /** |
|||||||||||
292 | * Send debug to client? |
|||||||||||
293 | * |
|||||||||||
294 | * @var string |
|||||||||||
295 | **/ |
|||||||||||
296 | protected $debug = false; |
|||||||||||
297 | ||||||||||||
298 | /** |
|||||||||||
299 | * Call `session_write_close()` before exec command? |
|||||||||||
300 | * |
|||||||||||
301 | * @var bool |
|||||||||||
302 | */ |
|||||||||||
303 | protected $sessionCloseEarlier = true; |
|||||||||||
304 | ||||||||||||
305 | /** |
|||||||||||
306 | * SESSION use commands @see __construct(). |
|||||||||||
307 | * |
|||||||||||
308 | * @var array |
|||||||||||
309 | */ |
|||||||||||
310 | protected $sessionUseCmds = []; |
|||||||||||
311 | ||||||||||||
312 | /** |
|||||||||||
313 | * session expires timeout. |
|||||||||||
314 | * |
|||||||||||
315 | * @var int |
|||||||||||
316 | **/ |
|||||||||||
317 | protected $timeout = 0; |
|||||||||||
318 | ||||||||||||
319 | /** |
|||||||||||
320 | * Temp dir path for Upload. |
|||||||||||
321 | * |
|||||||||||
322 | * @var string |
|||||||||||
323 | */ |
|||||||||||
324 | protected $uploadTempPath = ''; |
|||||||||||
325 | ||||||||||||
326 | /** |
|||||||||||
327 | * Max allowed archive files size (0 - no limit). |
|||||||||||
328 | * |
|||||||||||
329 | * @var int |
|||||||||||
330 | */ |
|||||||||||
331 | protected $maxArcFilesSize = 0; |
|||||||||||
332 | ||||||||||||
333 | /** |
|||||||||||
334 | * undocumented class variable. |
|||||||||||
335 | * |
|||||||||||
336 | * @var string |
|||||||||||
337 | **/ |
|||||||||||
338 | protected $uploadDebug = ''; |
|||||||||||
339 | ||||||||||||
340 | /** |
|||||||||||
341 | * URL for callback output window for CORS |
|||||||||||
342 | * redirect to this URL when callback output. |
|||||||||||
343 | * |
|||||||||||
344 | * @var string URL |
|||||||||||
345 | */ |
|||||||||||
346 | protected $callbackWindowURL = ''; |
|||||||||||
347 | ||||||||||||
348 | /** |
|||||||||||
349 | * hash of items to unlock on command completion. |
|||||||||||
350 | * |
|||||||||||
351 | * @var array hashes |
|||||||||||
352 | */ |
|||||||||||
353 | protected $autoUnlocks = []; |
|||||||||||
354 | ||||||||||||
355 | /** |
|||||||||||
356 | * Item locking expiration (seconds) |
|||||||||||
357 | * Default: 3600 secs. |
|||||||||||
358 | * |
|||||||||||
359 | * @var int |
|||||||||||
360 | */ |
|||||||||||
361 | protected $itemLockExpire = 3600; |
|||||||||||
362 | ||||||||||||
363 | /** |
|||||||||||
364 | * Is session closed. |
|||||||||||
365 | * |
|||||||||||
366 | * @deprecated |
|||||||||||
367 | * @var bool |
|||||||||||
368 | */ |
|||||||||||
369 | private static $sessionClosed = false; |
|||||||||||
370 | ||||||||||||
371 | /** |
|||||||||||
372 | * Constructor. |
|||||||||||
373 | * |
|||||||||||
374 | * @param array elFinder and roots configurations |
|||||||||||
375 | * @author Dmitry (dio) Levashov |
|||||||||||
376 | */ |
|||||||||||
377 | public function __construct($opts) |
|||||||||||
0 ignored issues
–
show
__construct 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);
}
}
![]() __construct 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);
}
}
![]() __construct 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);
}
}
![]() |
||||||||||||
378 | { |
|||||||||||
379 | // set error handler of WARNING, NOTICE |
|||||||||||
380 | $errLevel = E_WARNING | E_NOTICE | E_USER_WARNING | E_USER_NOTICE | E_STRICT | E_RECOVERABLE_ERROR; |
|||||||||||
381 | if (defined('E_DEPRECATED')) { |
|||||||||||
382 | $errLevel |= E_DEPRECATED | E_USER_DEPRECATED; |
|||||||||||
383 | } |
|||||||||||
384 | set_error_handler('elFinder::phpErrorHandler', $errLevel); |
|||||||||||
385 | ||||||||||||
386 | // convert PATH_INFO to GET query |
|||||||||||
387 | if (! empty($_SERVER['PATH_INFO'])) { |
|||||||||||
388 | $_ps = explode('/', trim($_SERVER['PATH_INFO'], '/')); |
|||||||||||
389 | if (! isset($_GET['cmd'])) { |
|||||||||||
390 | $_cmd = $_ps[0]; |
|||||||||||
391 | if (isset($this->commands[$_cmd])) { |
|||||||||||
392 | $_GET['cmd'] = $_cmd; |
|||||||||||
393 | $_i = 1; |
|||||||||||
394 | foreach (array_keys($this->commands[$_cmd]) as $_k) { |
|||||||||||
395 | if (isset($_ps[$_i])) { |
|||||||||||
396 | if (! isset($_GET[$_k])) { |
|||||||||||
397 | $_GET[$_k] = $_ps[$_i]; |
|||||||||||
398 | } |
|||||||||||
399 | } else { |
|||||||||||
400 | break; |
|||||||||||
401 | } |
|||||||||||
402 | } |
|||||||||||
403 | } |
|||||||||||
404 | } |
|||||||||||
405 | } |
|||||||||||
406 | ||||||||||||
407 | // set elFinder instance |
|||||||||||
408 | self::$instance = $this; |
|||||||||||
409 | ||||||||||||
410 | // setup debug mode |
|||||||||||
411 | $this->debug = (isset($opts['debug']) && $opts['debug'] ? true : false); |
|||||||||||
0 ignored issues
–
show
The property
$debug was declared of type string , but isset($opts['debug']) &&...'debug'] ? true : false is of type boolean . Maybe add a type cast?
This check looks for assignments to scalar types that may be of the wrong type. To ensure the code behaves as expected, it may be a good idea to add an explicit type cast. $answer = 42;
$correct = false;
$correct = (bool) $answer;
![]() |
||||||||||||
412 | if ($this->debug) { |
|||||||||||
413 | error_reporting(defined('ELFINDER_DEBUG_ERRORLEVEL') ? ELFINDER_DEBUG_ERRORLEVEL : -1); |
|||||||||||
414 | ini_set('diaplay_errors', '1'); |
|||||||||||
415 | } |
|||||||||||
416 | ||||||||||||
417 | if (! interface_exists('elFinderSessionInterface')) { |
|||||||||||
418 | include_once dirname(__FILE__).'/elFinderSessionInterface.php'; |
|||||||||||
419 | } |
|||||||||||
420 | ||||||||||||
421 | // session handler |
|||||||||||
422 | if (! empty($opts['session']) && $opts['session'] instanceof elFinderSessionInterface) { |
|||||||||||
423 | $this->session = $opts['session']; |
|||||||||||
424 | } else { |
|||||||||||
425 | $sessionOpts = [ |
|||||||||||
426 | 'base64encode' => ! empty($opts['base64encodeSessionData']), |
|||||||||||
427 | 'keys' => [ |
|||||||||||
428 | 'default' => ! empty($opts['sessionCacheKey']) ? $opts['sessionCacheKey'] : 'elFinderCaches', |
|||||||||||
429 | 'netvolume' => ! empty($opts['netVolumesSessionKey']) ? $opts['netVolumesSessionKey'] : 'elFinderNetVolumes', |
|||||||||||
430 | ], |
|||||||||||
431 | ]; |
|||||||||||
432 | if (! class_exists('elFinderSession')) { |
|||||||||||
433 | include_once dirname(__FILE__).'/elFinderSession.php'; |
|||||||||||
434 | } |
|||||||||||
435 | $this->session = new elFinderSession($sessionOpts); |
|||||||||||
436 | } |
|||||||||||
437 | // try session start | restart |
|||||||||||
438 | $this->session->start(); |
|||||||||||
439 | ||||||||||||
440 | $sessionUseCmds = []; |
|||||||||||
441 | if (isset($opts['sessionUseCmds']) && is_array($opts['sessionUseCmds'])) { |
|||||||||||
442 | $sessionUseCmds = $opts['sessionUseCmds']; |
|||||||||||
443 | } |
|||||||||||
444 | ||||||||||||
445 | // set self::$volumesCnt by HTTP header "X-elFinder-VolumesCntStart" |
|||||||||||
446 | if (isset($_SERVER['HTTP_X_ELFINDER_VOLUMESCNTSTART']) && ($volumesCntStart = intval($_SERVER['HTTP_X_ELFINDER_VOLUMESCNTSTART']))) { |
|||||||||||
447 | self::$volumesCnt = $volumesCntStart; |
|||||||||||
448 | } |
|||||||||||
449 | ||||||||||||
450 | $this->time = $this->utime(); |
|||||||||||
0 ignored issues
–
show
The property
$time was declared of type string , but $this->utime() is of type double . Maybe add a type cast?
This check looks for assignments to scalar types that may be of the wrong type. To ensure the code behaves as expected, it may be a good idea to add an explicit type cast. $answer = 42;
$correct = false;
$correct = (bool) $answer;
![]() |
||||||||||||
451 | $this->sessionCloseEarlier = isset($opts['sessionCloseEarlier']) ? (bool) $opts['sessionCloseEarlier'] : true; |
|||||||||||
452 | $this->sessionUseCmds = array_flip($sessionUseCmds); |
|||||||||||
453 | $this->timeout = (isset($opts['timeout']) ? $opts['timeout'] : 0); |
|||||||||||
454 | $this->uploadTempPath = (isset($opts['uploadTempPath']) ? $opts['uploadTempPath'] : ''); |
|||||||||||
455 | $this->callbackWindowURL = (isset($opts['callbackWindowURL']) ? $opts['callbackWindowURL'] : ''); |
|||||||||||
456 | $this->maxTargets = (isset($opts['maxTargets']) ? intval($opts['maxTargets']) : $this->maxTargets); |
|||||||||||
0 ignored issues
–
show
It seems like
isset($opts['maxTargets'...']) : $this->maxTargets can also be of type integer . However, the property $maxTargets is declared as type object<targets> . Maybe add an additional type check?
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly. For example, imagine you have a variable Either this assignment is in error or a type check should be added for that assignment. class Id
{
public $id;
public function __construct($id)
{
$this->id = $id;
}
}
class Account
{
/** @var Id $id */
public $id;
}
$account_id = false;
if (starsAreRight()) {
$account_id = new Id(42);
}
$account = new Account();
if ($account instanceof Id)
{
$account->id = $account_id;
}
![]() |
||||||||||||
457 | self::$commonTempPath = (isset($opts['commonTempPath']) ? $opts['commonTempPath'] : './.tmp'); |
|||||||||||
458 | if (! is_writable(self::$commonTempPath)) { |
|||||||||||
459 | self::$commonTempPath = sys_get_temp_dir(); |
|||||||||||
460 | if (! is_writable(self::$commonTempPath)) { |
|||||||||||
461 | self::$commonTempPath = ''; |
|||||||||||
462 | } |
|||||||||||
463 | } |
|||||||||||
464 | if (! empty($opts['tmpLinkPath'])) { |
|||||||||||
465 | self::$tmpLinkPath = $opts['tmpLinkPath']; |
|||||||||||
466 | } |
|||||||||||
467 | if (! empty($opts['tmpLinkUrl'])) { |
|||||||||||
468 | self::$tmpLinkUrl = $opts['tmpLinkUrl']; |
|||||||||||
469 | } |
|||||||||||
470 | if (! empty($opts['tmpLinkLifeTime'])) { |
|||||||||||
471 | self::$tmpLinkLifeTime = $opts['tmpLinkLifeTime']; |
|||||||||||
472 | } |
|||||||||||
473 | $this->maxArcFilesSize = isset($opts['maxArcFilesSize']) ? intval($opts['maxArcFilesSize']) : 0; |
|||||||||||
474 | $this->optionsNetVolumes = (isset($opts['optionsNetVolumes']) && is_array($opts['optionsNetVolumes'])) ? $opts['optionsNetVolumes'] : []; |
|||||||||||
475 | if (isset($opts['itemLockExpire'])) { |
|||||||||||
476 | $this->itemLockExpire = intval($opts['itemLockExpire']); |
|||||||||||
477 | } |
|||||||||||
478 | ||||||||||||
479 | // deprecated settings |
|||||||||||
480 | $this->netVolumesSessionKey = ! empty($opts['netVolumesSessionKey']) ? $opts['netVolumesSessionKey'] : 'elFinderNetVolumes'; |
|||||||||||
0 ignored issues
–
show
The property
elFinder::$netVolumesSessionKey has been deprecated.
This property has been deprecated. The supplier of the class has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead. ![]() |
||||||||||||
481 | self::$sessionCacheKey = ! empty($opts['sessionCacheKey']) ? $opts['sessionCacheKey'] : 'elFinderCaches'; |
|||||||||||
0 ignored issues
–
show
The property
elFinder::$sessionCacheKey has been deprecated.
This property has been deprecated. The supplier of the class has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead. ![]() |
||||||||||||
482 | ||||||||||||
483 | // check session cache |
|||||||||||
484 | $_optsMD5 = md5(json_encode($opts['roots'])); |
|||||||||||
485 | if ($this->session->get('_optsMD5') !== $_optsMD5) { |
|||||||||||
486 | $this->session->set('_optsMD5', $_optsMD5); |
|||||||||||
487 | } |
|||||||||||
488 | ||||||||||||
489 | // setlocale and global locale regists to elFinder::locale |
|||||||||||
490 | self::$locale = ! empty($opts['locale']) ? $opts['locale'] : 'en_US.UTF-8'; |
|||||||||||
491 | if (false === setlocale(LC_ALL, self::$locale)) { |
|||||||||||
492 | self::$locale = setlocale(LC_ALL, ''); |
|||||||||||
493 | } |
|||||||||||
494 | ||||||||||||
495 | // set defaultMimefile |
|||||||||||
496 | self::$defaultMimefile = (isset($opts['defaultMimefile']) ? $opts['defaultMimefile'] : ''); |
|||||||||||
497 | ||||||||||||
498 | // bind events listeners |
|||||||||||
499 | if (! empty($opts['bind']) && is_array($opts['bind'])) { |
|||||||||||
500 | $_req = $_SERVER['REQUEST_METHOD'] == 'POST' ? $_POST : $_GET; |
|||||||||||
501 | $_reqCmd = isset($_req['cmd']) ? $_req['cmd'] : ''; |
|||||||||||
502 | foreach ($opts['bind'] as $cmd => $handlers) { |
|||||||||||
503 | $doRegist = (strpos($cmd, '*') !== false); |
|||||||||||
504 | if (! $doRegist) { |
|||||||||||
505 | $_getcmd = create_function('$cmd', 'list($ret) = explode(\'.\', $cmd);return trim($ret);'); |
|||||||||||
0 ignored issues
–
show
The use of
create_function is highly discouraged, better use a closure.
// Instead of
$function = create_function('$a, $b', 'return $a + $b');
// Better use
$function = function($a, $b) { return $a + $b; }
![]() |
||||||||||||
506 | $doRegist = ($_reqCmd && in_array($_reqCmd, array_map($_getcmd, explode(' ', $cmd)))); |
|||||||||||
507 | } |
|||||||||||
508 | if ($doRegist) { |
|||||||||||
509 | // for backward compatibility |
|||||||||||
510 | if (! is_array($handlers)) { |
|||||||||||
511 | $handlers = [$handlers]; |
|||||||||||
512 | } else { |
|||||||||||
513 | if (count($handlers) === 2 && is_object($handlers[0])) { |
|||||||||||
514 | $handlers = [$handlers]; |
|||||||||||
515 | } |
|||||||||||
516 | } |
|||||||||||
517 | foreach ($handlers as $handler) { |
|||||||||||
518 | if ($handler) { |
|||||||||||
519 | if (is_string($handler) && strpos($handler, '.')) { |
|||||||||||
520 | list($_domain, $_name, $_method) = array_pad(explode('.', $handler), 3, ''); |
|||||||||||
521 | if (strcasecmp($_domain, 'plugin') === 0) { |
|||||||||||
522 | if ($plugin = $this->getPluginInstance($_name, isset($opts['plugin'][$_name]) ? $opts['plugin'][$_name] : []) |
|||||||||||
523 | and method_exists($plugin, $_method)) { |
|||||||||||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
Using logical operators such as
and instead of && is generally not recommended.
PHP has two types of connecting operators (logical operators, and boolean operators):
The difference between these is the order in which they are executed. In most cases,
you would want to use a boolean operator like Let’s take a look at a few examples: // Logical operators have lower precedence:
$f = false or true;
// is executed like this:
($f = false) or true;
// Boolean operators have higher precedence:
$f = false || true;
// is executed like this:
$f = (false || true);
Logical Operators are used for Control-FlowOne case where you explicitly want to use logical operators is for control-flow such as this: $x === 5
or die('$x must be 5.');
// Instead of
if ($x !== 5) {
die('$x must be 5.');
}
Since // The following is currently a parse error.
$x === 5
or throw new RuntimeException('$x must be 5.');
These limitations lead to logical operators rarely being of use in current PHP code. ![]() |
||||||||||||
524 | $this->bind($cmd, [$plugin, $_method]); |
|||||||||||
525 | } |
|||||||||||
526 | } |
|||||||||||
527 | } else { |
|||||||||||
528 | $this->bind($cmd, $handler); |
|||||||||||
529 | } |
|||||||||||
530 | } |
|||||||||||
531 | } |
|||||||||||
532 | } |
|||||||||||
533 | } |
|||||||||||
534 | } |
|||||||||||
535 | ||||||||||||
536 | if (! isset($opts['roots']) || ! is_array($opts['roots'])) { |
|||||||||||
537 | $opts['roots'] = []; |
|||||||||||
538 | } |
|||||||||||
539 | ||||||||||||
540 | // check for net volumes stored in session |
|||||||||||
541 | $netVolumes = $this->getNetVolumes(); |
|||||||||||
542 | foreach ($netVolumes as $key => $root) { |
|||||||||||
543 | if (! isset($root['id'])) { |
|||||||||||
544 | // given fixed unique id |
|||||||||||
545 | if (! $root['id'] = $this->getNetVolumeUniqueId($netVolumes)) { |
|||||||||||
546 | $this->mountErrors[] = 'Netmount Driver "'.$root['driver'].'" : Could\'t given volume id.'; |
|||||||||||
547 | continue; |
|||||||||||
548 | } |
|||||||||||
549 | } |
|||||||||||
550 | $opts['roots'][$key] = $root; |
|||||||||||
551 | } |
|||||||||||
552 | ||||||||||||
553 | // "mount" volumes |
|||||||||||
554 | foreach ($opts['roots'] as $i => $o) { |
|||||||||||
555 | $class = 'elFinderVolume'.(isset($o['driver']) ? $o['driver'] : ''); |
|||||||||||
556 | ||||||||||||
557 | if (class_exists($class)) { |
|||||||||||
558 | $volume = new $class(); |
|||||||||||
559 | ||||||||||||
560 | try { |
|||||||||||
561 | if ($this->maxArcFilesSize && (empty($o['maxArcFilesSize']) || $this->maxArcFilesSize < $o['maxArcFilesSize'])) { |
|||||||||||
562 | $o['maxArcFilesSize'] = $this->maxArcFilesSize; |
|||||||||||
563 | } |
|||||||||||
564 | // pass session handler |
|||||||||||
565 | $volume->setSession($this->session); |
|||||||||||
566 | if ($volume->mount($o)) { |
|||||||||||
567 | // unique volume id (ends on "_") - used as prefix to files hash |
|||||||||||
568 | $id = $volume->id(); |
|||||||||||
569 | ||||||||||||
570 | $this->volumes[$id] = $volume; |
|||||||||||
571 | if ((! $this->default || $volume->root() !== $volume->defaultPath()) && $volume->isReadable()) { |
|||||||||||
572 | $this->default = $this->volumes[$id]; |
|||||||||||
573 | } |
|||||||||||
574 | } else { |
|||||||||||
575 | $this->removeNetVolume($i, $volume); |
|||||||||||
576 | $this->mountErrors[] = 'Driver "'.$class.'" : '.implode(' ', $volume->error()); |
|||||||||||
577 | } |
|||||||||||
578 | } catch (Exception $e) { |
|||||||||||
579 | $this->removeNetVolume($i, $volume); |
|||||||||||
580 | $this->mountErrors[] = 'Driver "'.$class.'" : '.$e->getMessage(); |
|||||||||||
581 | } |
|||||||||||
582 | } else { |
|||||||||||
583 | $this->removeNetVolume($i, $volume); |
|||||||||||
0 ignored issues
–
show
The variable
$volume 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
![]() |
||||||||||||
584 | $this->mountErrors[] = 'Driver "'.$class.'" does not exist'; |
|||||||||||
585 | } |
|||||||||||
586 | } |
|||||||||||
587 | ||||||||||||
588 | // if at least one readable volume - ii desu >_< |
|||||||||||
589 | $this->loaded = ! empty($this->default); |
|||||||||||
590 | ||||||||||||
591 | // restore error handler for now |
|||||||||||
592 | restore_error_handler(); |
|||||||||||
593 | } |
|||||||||||
594 | ||||||||||||
595 | /** |
|||||||||||
596 | * Return elFinder session wrapper instance. |
|||||||||||
597 | * |
|||||||||||
598 | * @return object elFinderSessionInterface |
|||||||||||
599 | **/ |
|||||||||||
600 | public function getSession() |
|||||||||||
601 | { |
|||||||||||
602 | return $this->session; |
|||||||||||
603 | } |
|||||||||||
604 | ||||||||||||
605 | /** |
|||||||||||
606 | * Return true if fm init correctly. |
|||||||||||
607 | * |
|||||||||||
608 | * @return bool |
|||||||||||
609 | * @author Dmitry (dio) Levashov |
|||||||||||
610 | **/ |
|||||||||||
611 | public function loaded() |
|||||||||||
612 | { |
|||||||||||
613 | return $this->loaded; |
|||||||||||
614 | } |
|||||||||||
615 | ||||||||||||
616 | /** |
|||||||||||
617 | * Return version (api) number. |
|||||||||||
618 | * |
|||||||||||
619 | * @return string |
|||||||||||
620 | * @author Dmitry (dio) Levashov |
|||||||||||
621 | **/ |
|||||||||||
622 | public function version() |
|||||||||||
623 | { |
|||||||||||
624 | return $this->version; |
|||||||||||
625 | } |
|||||||||||
626 | ||||||||||||
627 | /** |
|||||||||||
628 | * Add handler to elFinder command. |
|||||||||||
629 | * |
|||||||||||
630 | * @param string command name |
|||||||||||
631 | * @param string|array callback name or array(object, method) |
|||||||||||
632 | * @return elFinder |
|||||||||||
633 | * @author Dmitry (dio) Levashov |
|||||||||||
634 | **/ |
|||||||||||
635 | public function bind($cmd, $handler) |
|||||||||||
636 | { |
|||||||||||
637 | $allCmds = array_keys($this->commands); |
|||||||||||
638 | $cmds = []; |
|||||||||||
639 | foreach (explode(' ', $cmd) as $_cmd) { |
|||||||||||
640 | if ($_cmd !== '') { |
|||||||||||
641 | if ($all = strpos($_cmd, '*') !== false) { |
|||||||||||
0 ignored issues
–
show
$all is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
||||||||||||
642 | list(, $sub) = array_pad(explode('.', $_cmd), 2, ''); |
|||||||||||
643 | if ($sub) { |
|||||||||||
644 | $sub = str_replace('\'', '\\\'', $sub); |
|||||||||||
645 | $addSub = create_function('$cmd', 'return $cmd . \'.\' . trim(\''.$sub.'\');'); |
|||||||||||
0 ignored issues
–
show
The use of
create_function is highly discouraged, better use a closure.
// Instead of
$function = create_function('$a, $b', 'return $a + $b');
// Better use
$function = function($a, $b) { return $a + $b; }
![]() |
||||||||||||
646 | $cmds = array_merge($cmds, array_map($addSub, $allCmds)); |
|||||||||||
647 | } else { |
|||||||||||
648 | $cmds = array_merge($cmds, $allCmds); |
|||||||||||
649 | } |
|||||||||||
650 | } else { |
|||||||||||
651 | $cmds[] = $_cmd; |
|||||||||||
652 | } |
|||||||||||
653 | } |
|||||||||||
654 | } |
|||||||||||
655 | $cmds = array_unique($cmds); |
|||||||||||
656 | ||||||||||||
657 | foreach ($cmds as $cmd) { |
|||||||||||
658 | if (! isset($this->listeners[$cmd])) { |
|||||||||||
659 | $this->listeners[$cmd] = []; |
|||||||||||
660 | } |
|||||||||||
661 | ||||||||||||
662 | if (is_callable($handler)) { |
|||||||||||
663 | $this->listeners[$cmd][] = $handler; |
|||||||||||
664 | } |
|||||||||||
665 | } |
|||||||||||
666 | ||||||||||||
667 | return $this; |
|||||||||||
668 | } |
|||||||||||
669 | ||||||||||||
670 | /** |
|||||||||||
671 | * Remove event (command exec) handler. |
|||||||||||
672 | * |
|||||||||||
673 | * @param string command name |
|||||||||||
674 | * @param string|array callback name or array(object, method) |
|||||||||||
675 | * @return elFinder |
|||||||||||
676 | * @author Dmitry (dio) Levashov |
|||||||||||
677 | **/ |
|||||||||||
678 | public function unbind($cmd, $handler) |
|||||||||||
679 | { |
|||||||||||
680 | if (! empty($this->listeners[$cmd])) { |
|||||||||||
681 | foreach ($this->listeners[$cmd] as $i => $h) { |
|||||||||||
682 | if ($h === $handler) { |
|||||||||||
683 | unset($this->listeners[$cmd][$i]); |
|||||||||||
684 | ||||||||||||
685 | return $this; |
|||||||||||
686 | } |
|||||||||||
687 | } |
|||||||||||
688 | } |
|||||||||||
689 | ||||||||||||
690 | return $this; |
|||||||||||
691 | } |
|||||||||||
692 | ||||||||||||
693 | /** |
|||||||||||
694 | * Return true if command exists. |
|||||||||||
695 | * |
|||||||||||
696 | * @param string command name |
|||||||||||
697 | * @return bool |
|||||||||||
698 | * @author Dmitry (dio) Levashov |
|||||||||||
699 | **/ |
|||||||||||
700 | public function commandExists($cmd) |
|||||||||||
701 | { |
|||||||||||
702 | return $this->loaded && isset($this->commands[$cmd]) && method_exists($this, $cmd); |
|||||||||||
703 | } |
|||||||||||
704 | ||||||||||||
705 | /** |
|||||||||||
706 | * Return root - file's owner (public func of volume()). |
|||||||||||
707 | * |
|||||||||||
708 | * @param string file hash |
|||||||||||
709 | * @return elFinderStorageDriver |
|||||||||||
710 | * @author Naoki Sawada |
|||||||||||
711 | */ |
|||||||||||
712 | public function getVolume($hash) |
|||||||||||
713 | { |
|||||||||||
714 | return $this->volume($hash); |
|||||||||||
715 | } |
|||||||||||
716 | ||||||||||||
717 | /** |
|||||||||||
718 | * Return command required arguments info. |
|||||||||||
719 | * |
|||||||||||
720 | * @param string command name |
|||||||||||
721 | * @return array |
|||||||||||
722 | * @author Dmitry (dio) Levashov |
|||||||||||
723 | **/ |
|||||||||||
724 | public function commandArgsList($cmd) |
|||||||||||
725 | { |
|||||||||||
726 | return $this->commandExists($cmd) ? $this->commands[$cmd] : []; |
|||||||||||
727 | } |
|||||||||||
728 | ||||||||||||
729 | /** |
|||||||||||
730 | * Exec command and return result. |
|||||||||||
731 | * |
|||||||||||
732 | * @param string $cmd command name |
|||||||||||
733 | * @param array $args command arguments |
|||||||||||
734 | * @return array |
|||||||||||
735 | * @author Dmitry (dio) Levashov |
|||||||||||
736 | **/ |
|||||||||||
737 | public function exec($cmd, $args) |
|||||||||||
738 | { |
|||||||||||
739 | // set error handler of WARNING, NOTICE |
|||||||||||
740 | set_error_handler('elFinder::phpErrorHandler', E_WARNING | E_NOTICE | E_USER_WARNING | E_USER_NOTICE); |
|||||||||||
741 | ||||||||||||
742 | if (! $this->loaded) { |
|||||||||||
743 | return ['error' => $this->error(self::ERROR_CONF, self::ERROR_CONF_NO_VOL)]; |
|||||||||||
744 | } |
|||||||||||
745 | ||||||||||||
746 | if ($this->session_expires()) { |
|||||||||||
747 | return ['error' => $this->error(self::ERROR_SESSION_EXPIRES)]; |
|||||||||||
748 | } |
|||||||||||
749 | ||||||||||||
750 | if (! $this->commandExists($cmd)) { |
|||||||||||
751 | return ['error' => $this->error(self::ERROR_UNKNOWN_CMD)]; |
|||||||||||
752 | } |
|||||||||||
753 | ||||||||||||
754 | if (! empty($args['mimes']) && is_array($args['mimes'])) { |
|||||||||||
755 | foreach ($this->volumes as $id => $v) { |
|||||||||||
756 | $this->volumes[$id]->setMimesFilter($args['mimes']); |
|||||||||||
757 | } |
|||||||||||
758 | } |
|||||||||||
759 | ||||||||||||
760 | // regist shutdown function as fallback |
|||||||||||
761 | register_shutdown_function([$this, 'itemAutoUnlock']); |
|||||||||||
762 | ||||||||||||
763 | // detect destination dirHash and volume |
|||||||||||
764 | $dstVolume = false; |
|||||||||||
765 | $dst = ! empty($args['target']) ? $args['target'] : (! empty($args['dst']) ? $args['dst'] : ''); |
|||||||||||
766 | if ($dst) { |
|||||||||||
767 | $dstVolume = $this->volume($dst); |
|||||||||||
768 | } elseif (isset($args['targets']) && is_array($args['targets']) && isset($args['targets'][0])) { |
|||||||||||
769 | $dst = $args['targets'][0]; |
|||||||||||
770 | $dstVolume = $this->volume($dst); |
|||||||||||
771 | if ($dstVolume && ($_stat = $dstVolume->file($dst)) && ! empty($_stat['phash'])) { |
|||||||||||
772 | $dst = $_stat['phash']; |
|||||||||||
773 | } else { |
|||||||||||
774 | $dst = ''; |
|||||||||||
775 | } |
|||||||||||
776 | } elseif ($cmd === 'open') { |
|||||||||||
777 | // for initial open without args `target` |
|||||||||||
778 | $dstVolume = $this->default; |
|||||||||||
779 | $dst = $dstVolume->defaultPath(); |
|||||||||||
780 | } |
|||||||||||
781 | ||||||||||||
782 | $result = null; |
|||||||||||
783 | ||||||||||||
784 | // call pre handlers for this command |
|||||||||||
785 | $args['sessionCloseEarlier'] = isset($this->sessionUseCmds[$cmd]) ? false : $this->sessionCloseEarlier; |
|||||||||||
786 | if (! empty($this->listeners[$cmd.'.pre'])) { |
|||||||||||
787 | foreach ($this->listeners[$cmd.'.pre'] as $handler) { |
|||||||||||
788 | $_res = call_user_func_array($handler, [$cmd, &$args, $this, $dstVolume]); |
|||||||||||
789 | if (is_array($_res)) { |
|||||||||||
790 | if (! empty($_res['preventexec'])) { |
|||||||||||
791 | $result = ['error' => true]; |
|||||||||||
792 | View Code Duplication | if ($cmd === 'upload' & ! empty($args['node'])) { |
||||||||||
0 ignored issues
–
show
Consider adding parentheses for clarity. Current Interpretation:
($cmd === 'upload') & !empty($args['node']) , Probably Intended Meaning: $cmd === ('upload' & !empty($args['node']))
When comparing the result of a bit operation, we suggest to add explicit parenthesis and not to rely on PHP’s built-in operator precedence to ensure the code behaves as intended and to make it more readable. Let’s take a look at these examples: // Returns always int(0).
return 0 === $foo & 4;
return (0 === $foo) & 4;
// More likely intended return: true/false
return 0 === ($foo & 4);
![]() This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
||||||||||||
793 | $result['callback'] = [ |
|||||||||||
794 | 'node' => $args['node'], |
|||||||||||
795 | 'bind' => $cmd, |
|||||||||||
796 | ]; |
|||||||||||
797 | } |
|||||||||||
798 | if (! empty($_res['results']) && is_array($_res['results'])) { |
|||||||||||
799 | $result = array_merge($result, $_res['results']); |
|||||||||||
800 | } |
|||||||||||
801 | break; |
|||||||||||
802 | } |
|||||||||||
803 | } |
|||||||||||
804 | } |
|||||||||||
805 | } |
|||||||||||
806 | ||||||||||||
807 | // unlock session data for multiple access |
|||||||||||
808 | if ($this->sessionCloseEarlier && $args['sessionCloseEarlier']) { |
|||||||||||
809 | $this->session->close(); |
|||||||||||
810 | // deprecated property |
|||||||||||
811 | self::$sessionClosed = true; |
|||||||||||
0 ignored issues
–
show
The property
elFinder::$sessionClosed has been deprecated.
This property has been deprecated. The supplier of the class has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead. ![]() |
||||||||||||
812 | } |
|||||||||||
813 | ||||||||||||
814 | if (substr(PHP_OS, 0, 3) === 'WIN') { |
|||||||||||
815 | // set time out |
|||||||||||
816 | self::extendTimeLimit(300); |
|||||||||||
817 | } |
|||||||||||
818 | ||||||||||||
819 | if (! is_array($result)) { |
|||||||||||
820 | try { |
|||||||||||
821 | $result = $this->$cmd($args); |
|||||||||||
822 | } catch (Exception $e) { |
|||||||||||
823 | $result = [ |
|||||||||||
824 | 'error' => htmlspecialchars($e->getMessage()), |
|||||||||||
825 | 'sync' => true, |
|||||||||||
826 | ]; |
|||||||||||
827 | } |
|||||||||||
828 | } |
|||||||||||
829 | ||||||||||||
830 | // check change dstDir |
|||||||||||
831 | $changeDst = false; |
|||||||||||
832 | if ($dst && $dstVolume && (! empty($result['added']) || ! empty($result['removed']))) { |
|||||||||||
833 | $changeDst = true; |
|||||||||||
834 | } |
|||||||||||
835 | ||||||||||||
836 | foreach ($this->volumes as $volume) { |
|||||||||||
837 | $removed = $volume->removed(); |
|||||||||||
838 | View Code Duplication | if (! empty($removed)) { |
||||||||||
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
||||||||||||
839 | if (! isset($result['removed'])) { |
|||||||||||
840 | $result['removed'] = []; |
|||||||||||
841 | } |
|||||||||||
842 | $result['removed'] = array_merge($result['removed'], $removed); |
|||||||||||
843 | if (! $changeDst && $dst && $dstVolume && $volume === $dstVolume) { |
|||||||||||
844 | $changeDst = true; |
|||||||||||
845 | } |
|||||||||||
846 | } |
|||||||||||
847 | $added = $volume->added(); |
|||||||||||
848 | View Code Duplication | if (! empty($added)) { |
||||||||||
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
||||||||||||
849 | if (! isset($result['added'])) { |
|||||||||||
850 | $result['added'] = []; |
|||||||||||
851 | } |
|||||||||||
852 | $result['added'] = array_merge($result['added'], $added); |
|||||||||||
853 | if (! $changeDst && $dst && $dstVolume && $volume === $dstVolume) { |
|||||||||||
854 | $changeDst = true; |
|||||||||||
855 | } |
|||||||||||
856 | } |
|||||||||||
857 | $volume->resetResultStat(); |
|||||||||||
858 | } |
|||||||||||
859 | ||||||||||||
860 | // dstDir is changed |
|||||||||||
861 | if ($changeDst) { |
|||||||||||
862 | if ($dstDir = $dstVolume->dir($dst)) { |
|||||||||||
863 | if (! isset($result['changed'])) { |
|||||||||||
864 | $result['changed'] = []; |
|||||||||||
865 | } |
|||||||||||
866 | $result['changed'][] = $dstDir; |
|||||||||||
867 | } |
|||||||||||
868 | } |
|||||||||||
869 | ||||||||||||
870 | // call handlers for this command |
|||||||||||
871 | if (! empty($this->listeners[$cmd])) { |
|||||||||||
872 | foreach ($this->listeners[$cmd] as $handler) { |
|||||||||||
873 | if (call_user_func_array($handler, [$cmd, &$result, $args, $this, $dstVolume])) { |
|||||||||||
874 | // handler return true to force sync client after command completed |
|||||||||||
875 | $result['sync'] = true; |
|||||||||||
876 | } |
|||||||||||
877 | } |
|||||||||||
878 | } |
|||||||||||
879 | ||||||||||||
880 | // replace removed files info with removed files hashes |
|||||||||||
881 | if (! empty($result['removed'])) { |
|||||||||||
882 | $removed = []; |
|||||||||||
883 | foreach ($result['removed'] as $file) { |
|||||||||||
884 | $removed[] = $file['hash']; |
|||||||||||
885 | } |
|||||||||||
886 | $result['removed'] = array_unique($removed); |
|||||||||||
887 | } |
|||||||||||
888 | // remove hidden files and filter files by mimetypes |
|||||||||||
889 | if (! empty($result['added'])) { |
|||||||||||
890 | $result['added'] = $this->filter($result['added']); |
|||||||||||
891 | } |
|||||||||||
892 | // remove hidden files and filter files by mimetypes |
|||||||||||
893 | if (! empty($result['changed'])) { |
|||||||||||
894 | $result['changed'] = $this->filter($result['changed']); |
|||||||||||
895 | } |
|||||||||||
896 | ||||||||||||
897 | if ($this->debug || ! empty($args['debug'])) { |
|||||||||||
898 | $result['debug'] = [ |
|||||||||||
899 | 'connector' => 'php', |
|||||||||||
900 | 'phpver' => PHP_VERSION, |
|||||||||||
901 | 'time' => $this->utime() - $this->time, |
|||||||||||
902 | 'memory' => (function_exists('memory_get_peak_usage') ? ceil(memory_get_peak_usage() / 1024).'Kb / ' : '').ceil(memory_get_usage() / 1024).'Kb / '.ini_get('memory_limit'), |
|||||||||||
903 | 'upload' => $this->uploadDebug, |
|||||||||||
904 | 'volumes' => [], |
|||||||||||
905 | 'mountErrors' => $this->mountErrors, |
|||||||||||
906 | 'phpErrors' => self::$phpErrors, |
|||||||||||
907 | ]; |
|||||||||||
908 | self::$phpErrors = []; |
|||||||||||
909 | ||||||||||||
910 | foreach ($this->volumes as $id => $volume) { |
|||||||||||
911 | $result['debug']['volumes'][] = $volume->debug(); |
|||||||||||
912 | } |
|||||||||||
913 | } |
|||||||||||
914 | ||||||||||||
915 | foreach ($this->volumes as $volume) { |
|||||||||||
916 | $volume->saveSessionCache(); |
|||||||||||
917 | $volume->umount(); |
|||||||||||
918 | } |
|||||||||||
919 | ||||||||||||
920 | // unlock locked items |
|||||||||||
921 | $this->itemAutoUnlock(); |
|||||||||||
922 | ||||||||||||
923 | if (! empty($result['callback'])) { |
|||||||||||
924 | $result['callback']['json'] = json_encode($result); |
|||||||||||
925 | $this->callback($result['callback']); |
|||||||||||
926 | } else { |
|||||||||||
927 | return $result; |
|||||||||||
928 | } |
|||||||||||
929 | //TODO: Add return statement here |
|||||||||||
930 | } |
|||||||||||
931 | ||||||||||||
932 | /** |
|||||||||||
933 | * Return file real path. |
|||||||||||
934 | * |
|||||||||||
935 | * @param string $hash file hash |
|||||||||||
936 | * @return string |
|||||||||||
937 | * @author Dmitry (dio) Levashov |
|||||||||||
938 | **/ |
|||||||||||
939 | public function realpath($hash) |
|||||||||||
940 | { |
|||||||||||
941 | if (($volume = $this->volume($hash)) == false) { |
|||||||||||
942 | return false; |
|||||||||||
943 | } |
|||||||||||
944 | ||||||||||||
945 | return $volume->realpath($hash); |
|||||||||||
946 | } |
|||||||||||
947 | ||||||||||||
948 | /** |
|||||||||||
949 | * Update sesstion value of a NetVolume option. |
|||||||||||
950 | * |
|||||||||||
951 | * @param string $netKey |
|||||||||||
952 | * @param string $optionKey |
|||||||||||
953 | * @param mixed $val |
|||||||||||
954 | */ |
|||||||||||
955 | public function updateNetVolumeOption($netKey, $optionKey, $val) |
|||||||||||
956 | { |
|||||||||||
957 | $netVolumes = $this->getNetVolumes(); |
|||||||||||
958 | if (is_string($netKey) && isset($netVolumes[$netKey]) && is_string($optionKey)) { |
|||||||||||
959 | $netVolumes[$netKey][$optionKey] = $val; |
|||||||||||
960 | $this->saveNetVolumes($netVolumes); |
|||||||||||
961 | } |
|||||||||||
962 | } |
|||||||||||
963 | ||||||||||||
964 | /***************************************************************************/ |
|||||||||||
965 | /* commands */ |
|||||||||||
966 | /***************************************************************************/ |
|||||||||||
967 | ||||||||||||
968 | /** |
|||||||||||
969 | * Normalize error messages. |
|||||||||||
970 | * |
|||||||||||
971 | * @return array |
|||||||||||
972 | * @author Dmitry (dio) Levashov |
|||||||||||
973 | **/ |
|||||||||||
974 | public function error() |
|||||||||||
975 | { |
|||||||||||
976 | $errors = []; |
|||||||||||
977 | ||||||||||||
978 | foreach (func_get_args() as $msg) { |
|||||||||||
979 | if (is_array($msg)) { |
|||||||||||
980 | $errors = array_merge($errors, $msg); |
|||||||||||
981 | } else { |
|||||||||||
982 | $errors[] = $msg; |
|||||||||||
983 | } |
|||||||||||
984 | } |
|||||||||||
985 | ||||||||||||
986 | return count($errors) ? $errors : [self::ERROR_UNKNOWN]; |
|||||||||||
987 | } |
|||||||||||
988 | ||||||||||||
989 | /** |
|||||||||||
990 | * PHP error handler, catch error types only E_WARNING | E_NOTICE | E_USER_WARNING | E_USER_NOTICE. |
|||||||||||
991 | * |
|||||||||||
992 | * @param int $errno |
|||||||||||
993 | * @param string $errstr |
|||||||||||
994 | * @param string $errfile |
|||||||||||
995 | * @param int $errline |
|||||||||||
996 | * @return void|bool |
|||||||||||
997 | */ |
|||||||||||
998 | public static function phpErrorHandler($errno, $errstr, $errfile, $errline) |
|||||||||||
999 | { |
|||||||||||
1000 | static $base = null; |
|||||||||||
1001 | ||||||||||||
1002 | if (is_null($base)) { |
|||||||||||
1003 | $base = dirname(__FILE__).DIRECTORY_SEPARATOR; |
|||||||||||
1004 | } |
|||||||||||
1005 | ||||||||||||
1006 | if (! (error_reporting() & $errno)) { |
|||||||||||
1007 | return; |
|||||||||||
1008 | } |
|||||||||||
1009 | ||||||||||||
1010 | $errfile = str_replace($base, '', $errfile); |
|||||||||||
1011 | ||||||||||||
1012 | $proc = false; |
|||||||||||
1013 | switch ($errno) { |
|||||||||||
1014 | case E_WARNING: |
|||||||||||
1015 | View Code Duplication | case E_USER_WARNING: |
||||||||||
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
||||||||||||
1016 | self::$phpErrors[] = "WARNING: $errstr in $errfile line $errline."; |
|||||||||||
1017 | $proc = true; |
|||||||||||
1018 | break; |
|||||||||||
1019 | ||||||||||||
1020 | case E_NOTICE: |
|||||||||||
1021 | View Code Duplication | case E_USER_NOTICE: |
||||||||||
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
||||||||||||
1022 | self::$phpErrors[] = "NOTICE: $errstr in $errfile line $errline."; |
|||||||||||
1023 | $proc = true; |
|||||||||||
1024 | break; |
|||||||||||
1025 | } |
|||||||||||
1026 | ||||||||||||
1027 | return $proc; |
|||||||||||
1028 | } |
|||||||||||
1029 | ||||||||||||
1030 | /** |
|||||||||||
1031 | * unlock locked items on command completion. |
|||||||||||
1032 | * |
|||||||||||
1033 | * @return void |
|||||||||||
1034 | */ |
|||||||||||
1035 | public function itemAutoUnlock() |
|||||||||||
1036 | { |
|||||||||||
1037 | if ($this->autoUnlocks) { |
|||||||||||
0 ignored issues
–
show
The expression
$this->autoUnlocks 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 ![]() |
||||||||||||
1038 | foreach ($this->autoUnlocks as $hash) { |
|||||||||||
1039 | $this->itemUnlock($hash); |
|||||||||||
1040 | } |
|||||||||||
1041 | $this->autoUnlocks = []; |
|||||||||||
1042 | } |
|||||||||||
1043 | } |
|||||||||||
1044 | ||||||||||||
1045 | /***************************************************************************/ |
|||||||||||
1046 | /* static utils */ |
|||||||||||
1047 | /***************************************************************************/ |
|||||||||||
1048 | ||||||||||||
1049 | /** |
|||||||||||
1050 | * Return Is Animation Gif. |
|||||||||||
1051 | * |
|||||||||||
1052 | * @param string $path server local path of target image |
|||||||||||
1053 | * @return bool |
|||||||||||
1054 | */ |
|||||||||||
1055 | public static function isAnimationGif($path) |
|||||||||||
1056 | { |
|||||||||||
1057 | list($width, $height, $type, $attr) = getimagesize($path); |
|||||||||||
0 ignored issues
–
show
The assignment to
$width is unused. Consider omitting it like so list($first,,$third) .
This checks looks for assignemnts to variables using the Consider the following code example. <?php
function returnThreeValues() {
return array('a', 'b', 'c');
}
list($a, $b, $c) = returnThreeValues();
print $a . " - " . $c;
Only the variables Instead, the list call could have been. list($a,, $c) = returnThreeValues();
![]() The assignment to
$height is unused. Consider omitting it like so list($first,,$third) .
This checks looks for assignemnts to variables using the Consider the following code example. <?php
function returnThreeValues() {
return array('a', 'b', 'c');
}
list($a, $b, $c) = returnThreeValues();
print $a . " - " . $c;
Only the variables Instead, the list call could have been. list($a,, $c) = returnThreeValues();
![]() The assignment to
$attr is unused. Consider omitting it like so list($first,,$third) .
This checks looks for assignemnts to variables using the Consider the following code example. <?php
function returnThreeValues() {
return array('a', 'b', 'c');
}
list($a, $b, $c) = returnThreeValues();
print $a . " - " . $c;
Only the variables Instead, the list call could have been. list($a,, $c) = returnThreeValues();
![]() |
||||||||||||
1058 | switch ($type) { |
|||||||||||
1059 | case IMAGETYPE_GIF: |
|||||||||||
1060 | break; |
|||||||||||
1061 | default: |
|||||||||||
1062 | return false; |
|||||||||||
1063 | } |
|||||||||||
1064 | ||||||||||||
1065 | $imgcnt = 0; |
|||||||||||
1066 | $fp = fopen($path, 'rb'); |
|||||||||||
1067 | fread($fp, 4); |
|||||||||||
1068 | $c = fread($fp, 1); |
|||||||||||
1069 | if (ord($c) != 0x39) { // GIF89a |
|||||||||||
1070 | return false; |
|||||||||||
1071 | } |
|||||||||||
1072 | ||||||||||||
1073 | while (! feof($fp)) { |
|||||||||||
1074 | do { |
|||||||||||
1075 | $c = fread($fp, 1); |
|||||||||||
1076 | } while (ord($c) != 0x21 && ! feof($fp)); |
|||||||||||
1077 | ||||||||||||
1078 | if (feof($fp)) { |
|||||||||||
1079 | break; |
|||||||||||
1080 | } |
|||||||||||
1081 | ||||||||||||
1082 | $c2 = fread($fp, 2); |
|||||||||||
1083 | if (bin2hex($c2) == 'f904') { |
|||||||||||
1084 | $imgcnt++; |
|||||||||||
1085 | } |
|||||||||||
1086 | ||||||||||||
1087 | if (feof($fp)) { |
|||||||||||
1088 | break; |
|||||||||||
1089 | } |
|||||||||||
1090 | } |
|||||||||||
1091 | ||||||||||||
1092 | if ($imgcnt > 1) { |
|||||||||||
1093 | return true; |
|||||||||||
1094 | } else { |
|||||||||||
1095 | return false; |
|||||||||||
1096 | } |
|||||||||||
1097 | } |
|||||||||||
1098 | ||||||||||||
1099 | /** |
|||||||||||
1100 | * Return Is seekable stream resource. |
|||||||||||
1101 | * |
|||||||||||
1102 | * @param resource $resource |
|||||||||||
1103 | * @return bool |
|||||||||||
1104 | */ |
|||||||||||
1105 | public static function isSeekableStream($resource) |
|||||||||||
1106 | { |
|||||||||||
1107 | $metadata = stream_get_meta_data($resource); |
|||||||||||
1108 | ||||||||||||
1109 | return $metadata['seekable']; |
|||||||||||
1110 | } |
|||||||||||
1111 | ||||||||||||
1112 | /** |
|||||||||||
1113 | * Rewind stream resource. |
|||||||||||
1114 | * |
|||||||||||
1115 | * @param resource $resource |
|||||||||||
1116 | * @return void |
|||||||||||
1117 | */ |
|||||||||||
1118 | public static function rewind($resource) |
|||||||||||
1119 | { |
|||||||||||
1120 | self::isSeekableStream($resource) && rewind($resource); |
|||||||||||
1121 | } |
|||||||||||
1122 | ||||||||||||
1123 | /** |
|||||||||||
1124 | * serialize and base64_encode of session data (If needed). |
|||||||||||
1125 | * |
|||||||||||
1126 | * @deprecated |
|||||||||||
1127 | * @param mixed $var target variable |
|||||||||||
1128 | * @author Naoki Sawada |
|||||||||||
1129 | * @return mixed|string |
|||||||||||
1130 | */ |
|||||||||||
1131 | public static function sessionDataEncode($var) |
|||||||||||
1132 | { |
|||||||||||
1133 | if (self::$base64encodeSessionData) { |
|||||||||||
1134 | $var = base64_encode(serialize($var)); |
|||||||||||
1135 | } |
|||||||||||
1136 | ||||||||||||
1137 | return $var; |
|||||||||||
1138 | } |
|||||||||||
1139 | ||||||||||||
1140 | /** |
|||||||||||
1141 | * base64_decode and unserialize of session data (If needed). |
|||||||||||
1142 | * |
|||||||||||
1143 | * @deprecated |
|||||||||||
1144 | * @param mixed $var target variable |
|||||||||||
1145 | * @param bool $checkIs data type for check (array|string|object|int) |
|||||||||||
1146 | * @author Naoki Sawada |
|||||||||||
1147 | * @return bool|mixed |
|||||||||||
1148 | */ |
|||||||||||
1149 | public static function sessionDataDecode(&$var, $checkIs = null) |
|||||||||||
1150 | { |
|||||||||||
1151 | if (self::$base64encodeSessionData) { |
|||||||||||
1152 | $data = unserialize(base64_decode($var)); |
|||||||||||
1153 | } else { |
|||||||||||
1154 | $data = $var; |
|||||||||||
1155 | } |
|||||||||||
1156 | $chk = true; |
|||||||||||
1157 | if ($checkIs) { |
|||||||||||
1158 | switch ($checkIs) { |
|||||||||||
1159 | case 'array': |
|||||||||||
1160 | $chk = is_array($data); |
|||||||||||
1161 | break; |
|||||||||||
1162 | case 'string': |
|||||||||||
1163 | $chk = is_string($data); |
|||||||||||
1164 | break; |
|||||||||||
1165 | case 'object': |
|||||||||||
1166 | $chk = is_object($data); |
|||||||||||
1167 | break; |
|||||||||||
1168 | case 'int': |
|||||||||||
1169 | $chk = is_int($data); |
|||||||||||
1170 | break; |
|||||||||||
1171 | } |
|||||||||||
1172 | } |
|||||||||||
1173 | if (! $chk) { |
|||||||||||
1174 | unset($var); |
|||||||||||
1175 | ||||||||||||
1176 | return false; |
|||||||||||
1177 | } |
|||||||||||
1178 | ||||||||||||
1179 | return $data; |
|||||||||||
1180 | } |
|||||||||||
1181 | ||||||||||||
1182 | /** |
|||||||||||
1183 | * Call session_write_close() if session is restarted. |
|||||||||||
1184 | * |
|||||||||||
1185 | * @deprecated |
|||||||||||
1186 | * @return void |
|||||||||||
1187 | */ |
|||||||||||
1188 | public static function sessionWrite() |
|||||||||||
1189 | { |
|||||||||||
1190 | if (session_id()) { |
|||||||||||
1191 | session_write_close(); |
|||||||||||
1192 | } |
|||||||||||
1193 | } |
|||||||||||
1194 | ||||||||||||
1195 | /** |
|||||||||||
1196 | * Return elFinder static variable. |
|||||||||||
1197 | * |
|||||||||||
1198 | * @param $key |
|||||||||||
1199 | * @return mixed|null |
|||||||||||
1200 | */ |
|||||||||||
1201 | public static function getStaticVar($key) |
|||||||||||
1202 | { |
|||||||||||
1203 | return isset(self::$$key) ? self::$$key : null; |
|||||||||||
1204 | } |
|||||||||||
1205 | ||||||||||||
1206 | /** |
|||||||||||
1207 | * Extend PHP execution time limit. |
|||||||||||
1208 | * |
|||||||||||
1209 | * @param int $time |
|||||||||||
1210 | * @return void |
|||||||||||
1211 | */ |
|||||||||||
1212 | public static function extendTimeLimit($time = null) |
|||||||||||
1213 | { |
|||||||||||
1214 | static $defLimit = null; |
|||||||||||
1215 | if (is_null($defLimit)) { |
|||||||||||
1216 | $defLimit = ini_get('max_execution_time'); |
|||||||||||
1217 | } |
|||||||||||
1218 | if ($defLimit != 0) { |
|||||||||||
1219 | $time = is_null($time) ? $defLimit : max($defLimit, $time); |
|||||||||||
1220 | set_time_limit($time); |
|||||||||||
1221 | } |
|||||||||||
1222 | } |
|||||||||||
1223 | ||||||||||||
1224 | /** |
|||||||||||
1225 | * Return bytes from php.ini value. |
|||||||||||
1226 | * |
|||||||||||
1227 | * @param string $iniName |
|||||||||||
1228 | * @param string $val |
|||||||||||
1229 | * @return number |
|||||||||||
1230 | */ |
|||||||||||
1231 | public static function getIniBytes($iniName = '', $val = '') |
|||||||||||
1232 | { |
|||||||||||
1233 | if ($iniName !== '') { |
|||||||||||
1234 | $val = ini_get($iniName); |
|||||||||||
1235 | if ($val === false) { |
|||||||||||
1236 | return 0; |
|||||||||||
1237 | } |
|||||||||||
1238 | } |
|||||||||||
1239 | $val = trim($val, "bB \t\n\r\0\x0B"); |
|||||||||||
1240 | $last = strtolower($val[strlen($val) - 1]); |
|||||||||||
1241 | switch ($last) { |
|||||||||||
1242 | case 't': |
|||||||||||
0 ignored issues
–
show
|
||||||||||||
1243 | $val *= 1024; |
|||||||||||
1244 | case 'g': |
|||||||||||
0 ignored issues
–
show
|
||||||||||||
1245 | $val *= 1024; |
|||||||||||
1246 | case 'm': |
|||||||||||
0 ignored issues
–
show
|
||||||||||||
1247 | $val *= 1024; |
|||||||||||
1248 | case 'k': |
|||||||||||
1249 | $val *= 1024; |
|||||||||||
1250 | } |
|||||||||||
1251 | ||||||||||||
1252 | return (int) $val; |
|||||||||||
1253 | } |
|||||||||||
1254 | ||||||||||||
1255 | /** |
|||||||||||
1256 | * Get script url. |
|||||||||||
1257 | * |
|||||||||||
1258 | * @return string full URL |
|||||||||||
1259 | * |
|||||||||||
1260 | * @author Naoki Sawada |
|||||||||||
1261 | */ |
|||||||||||
1262 | public static function getConnectorUrl() |
|||||||||||
0 ignored issues
–
show
getConnectorUrl 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);
}
}
![]() |
||||||||||||
1263 | { |
|||||||||||
1264 | $https = (isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off'); |
|||||||||||
1265 | $url = ($https ? 'https://' : 'http://') |
|||||||||||
1266 | .$_SERVER['SERVER_NAME'] // host |
|||||||||||
1267 | .(((! $https && $_SERVER['SERVER_PORT'] == 80) || ($https && $_SERVER['SERVER_PORT'] == 443)) ? '' : (':'.$_SERVER['SERVER_PORT'])) // port |
|||||||||||
1268 | .$_SERVER['REQUEST_URI']; // path & query |
|||||||||||
1269 | list($url) = explode('?', $url); |
|||||||||||
1270 | ||||||||||||
1271 | return $url; |
|||||||||||
1272 | } |
|||||||||||
1273 | ||||||||||||
1274 | /** |
|||||||||||
1275 | * Get stream resource pointer by URL. |
|||||||||||
1276 | * |
|||||||||||
1277 | * @param array $data array('target'=>'URL', 'headers' => array()) |
|||||||||||
1278 | * @param number $redirectLimit |
|||||||||||
1279 | * @return resource|bool |
|||||||||||
1280 | * |
|||||||||||
1281 | * @author Naoki Sawada |
|||||||||||
1282 | */ |
|||||||||||
1283 | public static function getStreamByUrl($data, $redirectLimit = 5) |
|||||||||||
1284 | { |
|||||||||||
1285 | if (isset($data['target'])) { |
|||||||||||
1286 | $data = [ |
|||||||||||
1287 | 'cnt' => 0, |
|||||||||||
1288 | 'url' => $data['target'], |
|||||||||||
1289 | 'headers' => isset($data['headers']) ? $data['headers'] : [], |
|||||||||||
1290 | 'cookies' => [], |
|||||||||||
1291 | ]; |
|||||||||||
1292 | } |
|||||||||||
1293 | if ($data['cnt'] > $redirectLimit) { |
|||||||||||
1294 | return false; |
|||||||||||
1295 | } |
|||||||||||
1296 | $dlurl = $data['url']; |
|||||||||||
1297 | $data['url'] = ''; |
|||||||||||
1298 | $headers = $data['headers']; |
|||||||||||
1299 | ||||||||||||
1300 | if ($dlurl) { |
|||||||||||
1301 | $url = parse_url($dlurl); |
|||||||||||
1302 | $ports = [ |
|||||||||||
1303 | 'http' => '80', |
|||||||||||
1304 | 'ssl' => '443', |
|||||||||||
1305 | 'ftp' => '21', |
|||||||||||
1306 | ]; |
|||||||||||
1307 | $url['scheme'] = strtolower($url['scheme']); |
|||||||||||
1308 | if ($url['scheme'] === 'https') { |
|||||||||||
1309 | $url['scheme'] = 'ssl'; |
|||||||||||
1310 | } |
|||||||||||
1311 | if (! isset($url['port']) && isset($ports[$url['scheme']])) { |
|||||||||||
1312 | $url['port'] = $ports[$url['scheme']]; |
|||||||||||
1313 | } |
|||||||||||
1314 | if (! isset($url['port'])) { |
|||||||||||
1315 | return false; |
|||||||||||
1316 | } |
|||||||||||
1317 | $cookies = []; |
|||||||||||
1318 | if ($data['cookies']) { |
|||||||||||
1319 | foreach ($data['cookies'] as $d => $c) { |
|||||||||||
1320 | if (strpos($url['host'], $d) !== false) { |
|||||||||||
1321 | $cookies[] = $c; |
|||||||||||
1322 | } |
|||||||||||
1323 | } |
|||||||||||
1324 | } |
|||||||||||
1325 | ||||||||||||
1326 | $query = isset($url['query']) ? '?'.$url['query'] : ''; |
|||||||||||
1327 | $stream = stream_socket_client($url['scheme'].'://'.$url['host'].':'.$url['port']); |
|||||||||||
1328 | stream_set_timeout($stream, 300); |
|||||||||||
1329 | fwrite($stream, "GET {$url['path']}{$query} HTTP/1.1\r\n"); |
|||||||||||
1330 | fwrite($stream, "Host: {$url['host']}\r\n"); |
|||||||||||
1331 | foreach ($headers as $header) { |
|||||||||||
1332 | fwrite($stream, trim($header, "\r\n")."\r\n"); |
|||||||||||
1333 | } |
|||||||||||
1334 | fwrite($stream, "Connection: Close\r\n"); |
|||||||||||
1335 | if ($cookies) { |
|||||||||||
0 ignored issues
–
show
The expression
$cookies 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 ![]() |
||||||||||||
1336 | fwrite($stream, 'Cookie: '.implode('; ', $cookies)."\r\n"); |
|||||||||||
1337 | } |
|||||||||||
1338 | fwrite($stream, "\r\n"); |
|||||||||||
1339 | while (($res = trim(fgets($stream))) !== '') { |
|||||||||||
1340 | // find redirect |
|||||||||||
1341 | if (preg_match('/^Location: (.+)$/', $res, $m)) { |
|||||||||||
1342 | $data['url'] = $m[1]; |
|||||||||||
1343 | } |
|||||||||||
1344 | // fetch cookie |
|||||||||||
1345 | if (strpos($res, 'Set-Cookie:') === 0) { |
|||||||||||
1346 | $domain = $url['host']; |
|||||||||||
1347 | if (preg_match('/^Set-Cookie:(.+)(?:domain=\s*([^ ;]+))?/i', $res, $c1)) { |
|||||||||||
1348 | if (! empty($c1[2])) { |
|||||||||||
1349 | $domain = trim($c1[2]); |
|||||||||||
1350 | } |
|||||||||||
1351 | if (preg_match('/([^ ]+=[^;]+)/', $c1[1], $c2)) { |
|||||||||||
1352 | $data['cookies'][$domain] = $c2[1]; |
|||||||||||
1353 | } |
|||||||||||
1354 | } |
|||||||||||
1355 | } |
|||||||||||
1356 | } |
|||||||||||
1357 | if ($data['url']) { |
|||||||||||
1358 | $data['cnt']++; |
|||||||||||
1359 | fclose($stream); |
|||||||||||
1360 | ||||||||||||
1361 | return self::getStreamByUrl($data, $redirectLimit); |
|||||||||||
1362 | } |
|||||||||||
1363 | ||||||||||||
1364 | return $stream; |
|||||||||||
1365 | } |
|||||||||||
1366 | ||||||||||||
1367 | return false; |
|||||||||||
1368 | } |
|||||||||||
1369 | ||||||||||||
1370 | /** |
|||||||||||
1371 | * Call curl_exec() with supported redirect on `safe_mode` or `open_basedir`. |
|||||||||||
1372 | * |
|||||||||||
1373 | * @param resource $curl |
|||||||||||
1374 | * @param array $options |
|||||||||||
1375 | * @param array $headers |
|||||||||||
1376 | * |
|||||||||||
1377 | * @throws \Exception |
|||||||||||
1378 | * |
|||||||||||
1379 | * @return mixed |
|||||||||||
1380 | * |
|||||||||||
1381 | * @author Naoki Sawada |
|||||||||||
1382 | */ |
|||||||||||
1383 | public static function curlExec($curl, $options = [], $headers = []) |
|||||||||||
1384 | { |
|||||||||||
1385 | if ($followLocation = (! ini_get('safe_mode') && ! ini_get('open_basedir'))) { |
|||||||||||
1386 | curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); |
|||||||||||
1387 | } |
|||||||||||
1388 | ||||||||||||
1389 | if ($options) { |
|||||||||||
0 ignored issues
–
show
The expression
$options 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 ![]() |
||||||||||||
1390 | curl_setopt_array($curl, $options); |
|||||||||||
1391 | } |
|||||||||||
1392 | ||||||||||||
1393 | if ($headers) { |
|||||||||||
0 ignored issues
–
show
The expression
$headers 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 ![]() |
||||||||||||
1394 | curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); |
|||||||||||
1395 | } |
|||||||||||
1396 | ||||||||||||
1397 | $result = curl_exec($curl); |
|||||||||||
1398 | ||||||||||||
1399 | if (! $followLocation && $redirect = curl_getinfo($curl, CURLINFO_REDIRECT_URL)) { |
|||||||||||
1400 | if ($stream = self::getStreamByUrl(['target' => $redirect, 'headers' => $headers])) { |
|||||||||||
1401 | $result = stream_get_contents($stream); |
|||||||||||
1402 | } |
|||||||||||
1403 | } |
|||||||||||
1404 | ||||||||||||
1405 | View Code Duplication | if ($result === false) { |
||||||||||
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
||||||||||||
1406 | if (curl_errno($curl)) { |
|||||||||||
1407 | throw new \Exception('curl_exec() failed: '.curl_error($curl)); |
|||||||||||
1408 | } else { |
|||||||||||
1409 | throw new \Exception('curl_exec(): empty response'); |
|||||||||||
1410 | } |
|||||||||||
1411 | } |
|||||||||||
1412 | ||||||||||||
1413 | curl_close($curl); |
|||||||||||
1414 | ||||||||||||
1415 | return $result; |
|||||||||||
1416 | } |
|||||||||||
1417 | ||||||||||||
1418 | /** |
|||||||||||
1419 | * Return network volumes config. |
|||||||||||
1420 | * |
|||||||||||
1421 | * @return array |
|||||||||||
1422 | * @author Dmitry (dio) Levashov |
|||||||||||
1423 | */ |
|||||||||||
1424 | protected function getNetVolumes() |
|||||||||||
1425 | { |
|||||||||||
1426 | if ($data = $this->session->get('netvolume', [])) { |
|||||||||||
1427 | return $data; |
|||||||||||
1428 | } |
|||||||||||
1429 | ||||||||||||
1430 | return []; |
|||||||||||
1431 | } |
|||||||||||
1432 | ||||||||||||
1433 | /** |
|||||||||||
1434 | * Save network volumes config. |
|||||||||||
1435 | * |
|||||||||||
1436 | * @param array $volumes volumes config |
|||||||||||
1437 | * @return void |
|||||||||||
1438 | * @author Dmitry (dio) Levashov |
|||||||||||
1439 | */ |
|||||||||||
1440 | protected function saveNetVolumes($volumes) |
|||||||||||
1441 | { |
|||||||||||
1442 | $this->session->set('netvolume', $volumes); |
|||||||||||
1443 | } |
|||||||||||
1444 | ||||||||||||
1445 | /** |
|||||||||||
1446 | * Remove netmount volume. |
|||||||||||
1447 | * |
|||||||||||
1448 | * @param string $key netvolume key |
|||||||||||
1449 | * @param object $volume volume driver instance |
|||||||||||
1450 | * @return bool |
|||||||||||
1451 | */ |
|||||||||||
1452 | protected function removeNetVolume($key, $volume) |
|||||||||||
1453 | { |
|||||||||||
1454 | $netVolumes = $this->getNetVolumes(); |
|||||||||||
1455 | $res = true; |
|||||||||||
1456 | if (is_object($volume) && method_exists($volume, 'netunmount')) { |
|||||||||||
1457 | $res = $volume->netunmount($netVolumes, $key); |
|||||||||||
1458 | $volume->clearSessionCache(); |
|||||||||||
1459 | } |
|||||||||||
1460 | if ($res) { |
|||||||||||
1461 | if (is_string($key) && isset($netVolumes[$key])) { |
|||||||||||
1462 | unset($netVolumes[$key]); |
|||||||||||
1463 | $this->saveNetVolumes($netVolumes); |
|||||||||||
1464 | ||||||||||||
1465 | return true; |
|||||||||||
1466 | } |
|||||||||||
1467 | } |
|||||||||||
1468 | ||||||||||||
1469 | return false; |
|||||||||||
1470 | } |
|||||||||||
1471 | ||||||||||||
1472 | /** |
|||||||||||
1473 | * Get plugin instance & set to $this->plugins. |
|||||||||||
1474 | * |
|||||||||||
1475 | * @param string $name Plugin name (dirctory name) |
|||||||||||
1476 | * @param array $opts Plugin options (optional) |
|||||||||||
1477 | * @return object | bool Plugin object instance Or false |
|||||||||||
1478 | * @author Naoki Sawada |
|||||||||||
1479 | */ |
|||||||||||
1480 | protected function getPluginInstance($name, $opts = []) |
|||||||||||
1481 | { |
|||||||||||
1482 | $key = strtolower($name); |
|||||||||||
1483 | if (! isset($this->plugins[$key])) { |
|||||||||||
1484 | $class = 'elFinderPlugin'.$name; |
|||||||||||
1485 | // to try auto load |
|||||||||||
1486 | if (! class_exists($class)) { |
|||||||||||
1487 | $p_file = dirname(__FILE__).DIRECTORY_SEPARATOR.'plugins'.DIRECTORY_SEPARATOR.$name.DIRECTORY_SEPARATOR.'plugin.php'; |
|||||||||||
1488 | if (is_file($p_file)) { |
|||||||||||
1489 | include_once $p_file; |
|||||||||||
1490 | } |
|||||||||||
1491 | } |
|||||||||||
1492 | if (class_exists($class, false)) { |
|||||||||||
1493 | $this->plugins[$key] = new $class($opts); |
|||||||||||
1494 | } else { |
|||||||||||
1495 | $this->plugins[$key] = false; |
|||||||||||
1496 | } |
|||||||||||
1497 | } |
|||||||||||
1498 | ||||||||||||
1499 | return $this->plugins[$key]; |
|||||||||||
1500 | } |
|||||||||||
1501 | ||||||||||||
1502 | protected function netmount($args) |
|||||||||||
1503 | { |
|||||||||||
1504 | $options = []; |
|||||||||||
1505 | $protocol = $args['protocol']; |
|||||||||||
1506 | ||||||||||||
1507 | if ($protocol === 'netunmount') { |
|||||||||||
1508 | if (! empty($args['user']) && $volume = $this->volume($args['user'])) { |
|||||||||||
1509 | if ($this->removeNetVolume($args['host'], $volume)) { |
|||||||||||
1510 | return ['removed' => [['hash' => $volume->root()]]]; |
|||||||||||
1511 | } |
|||||||||||
1512 | } |
|||||||||||
1513 | ||||||||||||
1514 | return ['sync' => true, 'error' => $this->error(self::ERROR_NETUNMOUNT)]; |
|||||||||||
1515 | } |
|||||||||||
1516 | ||||||||||||
1517 | $driver = isset(self::$netDrivers[$protocol]) ? self::$netDrivers[$protocol] : ''; |
|||||||||||
1518 | $class = 'elFinderVolume'.$driver; |
|||||||||||
1519 | ||||||||||||
1520 | if (! class_exists($class)) { |
|||||||||||
1521 | return ['error' => $this->error(self::ERROR_NETMOUNT, $args['host'], self::ERROR_NETMOUNT_NO_DRIVER)]; |
|||||||||||
1522 | } |
|||||||||||
1523 | ||||||||||||
1524 | if (! $args['path']) { |
|||||||||||
1525 | $args['path'] = '/'; |
|||||||||||
1526 | } |
|||||||||||
1527 | ||||||||||||
1528 | foreach ($args as $k => $v) { |
|||||||||||
1529 | if ($k != 'options' && $k != 'protocol' && $v) { |
|||||||||||
1530 | $options[$k] = $v; |
|||||||||||
1531 | } |
|||||||||||
1532 | } |
|||||||||||
1533 | ||||||||||||
1534 | if (is_array($args['options'])) { |
|||||||||||
1535 | foreach ($args['options'] as $key => $value) { |
|||||||||||
1536 | $options[$key] = $value; |
|||||||||||
1537 | } |
|||||||||||
1538 | } |
|||||||||||
1539 | ||||||||||||
1540 | $volume = new $class(); |
|||||||||||
1541 | ||||||||||||
1542 | // pass session handler |
|||||||||||
1543 | $volume->setSession($this->session); |
|||||||||||
1544 | ||||||||||||
1545 | if (method_exists($volume, 'netmountPrepare')) { |
|||||||||||
1546 | $options = $volume->netmountPrepare($options); |
|||||||||||
1547 | if (isset($options['exit'])) { |
|||||||||||
1548 | if ($options['exit'] === 'callback') { |
|||||||||||
1549 | $this->callback($options['out']); |
|||||||||||
1550 | } |
|||||||||||
1551 | ||||||||||||
1552 | return $options; |
|||||||||||
1553 | } |
|||||||||||
1554 | } |
|||||||||||
1555 | ||||||||||||
1556 | $netVolumes = $this->getNetVolumes(); |
|||||||||||
1557 | ||||||||||||
1558 | if (! isset($options['id'])) { |
|||||||||||
1559 | // given fixed unique id |
|||||||||||
1560 | if (! $options['id'] = $this->getNetVolumeUniqueId($netVolumes)) { |
|||||||||||
1561 | return ['error' => $this->error(self::ERROR_NETMOUNT, $args['host'], 'Could\'t given volume id.')]; |
|||||||||||
1562 | } |
|||||||||||
1563 | } |
|||||||||||
1564 | ||||||||||||
1565 | // load additional volume root options |
|||||||||||
1566 | View Code Duplication | if (! empty($this->optionsNetVolumes['*'])) { |
||||||||||
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
||||||||||||
1567 | $options = array_merge($options, $this->optionsNetVolumes['*']); |
|||||||||||
1568 | } |
|||||||||||
1569 | View Code Duplication | if (! empty($this->optionsNetVolumes[$protocol])) { |
||||||||||
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
||||||||||||
1570 | $options = array_merge($options, $this->optionsNetVolumes[$protocol]); |
|||||||||||
1571 | } |
|||||||||||
1572 | ||||||||||||
1573 | if (! $key = $volume->netMountKey) { |
|||||||||||
1574 | $key = md5($protocol.'-'.serialize($options)); |
|||||||||||
1575 | } |
|||||||||||
1576 | $options['netkey'] = $key; |
|||||||||||
1577 | ||||||||||||
1578 | if ($volume->mount($options)) { |
|||||||||||
1579 | $options['driver'] = $driver; |
|||||||||||
1580 | $netVolumes[$key] = $options; |
|||||||||||
1581 | $this->saveNetVolumes($netVolumes); |
|||||||||||
1582 | $rootstat = $volume->file($volume->root()); |
|||||||||||
1583 | ||||||||||||
1584 | return ['added' => [$rootstat]]; |
|||||||||||
1585 | } else { |
|||||||||||
1586 | $this->removeNetVolume(null, $volume); |
|||||||||||
1587 | ||||||||||||
1588 | return ['error' => $this->error(self::ERROR_NETMOUNT, $args['host'], implode(' ', $volume->error()))]; |
|||||||||||
1589 | } |
|||||||||||
1590 | } |
|||||||||||
1591 | ||||||||||||
1592 | /** |
|||||||||||
1593 | * "Open" directory |
|||||||||||
1594 | * Return array with following elements |
|||||||||||
1595 | * - cwd - opened dir info |
|||||||||||
1596 | * - files - opened dir content [and dirs tree if $args[tree]] |
|||||||||||
1597 | * - api - api version (if $args[init]) |
|||||||||||
1598 | * - uplMaxSize - if $args[init] |
|||||||||||
1599 | * - error - on failed. |
|||||||||||
1600 | * |
|||||||||||
1601 | * @param array command arguments |
|||||||||||
1602 | * @return array |
|||||||||||
1603 | * @author Dmitry (dio) Levashov |
|||||||||||
1604 | **/ |
|||||||||||
1605 | protected function open($args) |
|||||||||||
1606 | { |
|||||||||||
1607 | $target = $args['target']; |
|||||||||||
1608 | $init = ! empty($args['init']); |
|||||||||||
1609 | $tree = ! empty($args['tree']); |
|||||||||||
1610 | $volume = $this->volume($target); |
|||||||||||
1611 | $cwd = $volume ? $volume->dir($target) : false; |
|||||||||||
1612 | $hash = $init ? 'default folder' : '#'.$target; |
|||||||||||
1613 | $sleep = 0; |
|||||||||||
0 ignored issues
–
show
$sleep is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
||||||||||||
1614 | $compare = ''; |
|||||||||||
1615 | ||||||||||||
1616 | // on init request we can get invalid dir hash - |
|||||||||||
1617 | // dir which can not be opened now, but remembered by client, |
|||||||||||
1618 | // so open default dir |
|||||||||||
1619 | if ((! $cwd || ! $cwd['read']) && $init) { |
|||||||||||
1620 | $volume = $this->default; |
|||||||||||
1621 | $target = $volume->defaultPath(); |
|||||||||||
1622 | $cwd = $volume->dir($target); |
|||||||||||
1623 | } |
|||||||||||
1624 | ||||||||||||
1625 | if (! $cwd) { |
|||||||||||
1626 | return ['error' => $this->error(self::ERROR_OPEN, $hash, self::ERROR_DIR_NOT_FOUND)]; |
|||||||||||
1627 | } |
|||||||||||
1628 | if (! $cwd['read']) { |
|||||||||||
1629 | return ['error' => $this->error(self::ERROR_OPEN, $hash, self::ERROR_PERM_DENIED)]; |
|||||||||||
1630 | } |
|||||||||||
1631 | ||||||||||||
1632 | $files = []; |
|||||||||||
1633 | ||||||||||||
1634 | // get current working directory files list |
|||||||||||
1635 | View Code Duplication | if (($ls = $volume->scandir($cwd['hash'])) === false) { |
||||||||||
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
||||||||||||
1636 | return ['error' => $this->error(self::ERROR_OPEN, $cwd['name'], $volume->error())]; |
|||||||||||
1637 | } |
|||||||||||
1638 | ||||||||||||
1639 | if (isset($cwd['dirs']) && $cwd['dirs'] != 1) { |
|||||||||||
1640 | $cwd = $volume->dir($target); |
|||||||||||
1641 | } |
|||||||||||
1642 | ||||||||||||
1643 | // get other volume root |
|||||||||||
1644 | if ($tree) { |
|||||||||||
1645 | foreach ($this->volumes as $id => $v) { |
|||||||||||
1646 | $files[] = $v->file($v->root()); |
|||||||||||
1647 | } |
|||||||||||
1648 | } |
|||||||||||
1649 | ||||||||||||
1650 | // long polling mode |
|||||||||||
1651 | if ($args['compare']) { |
|||||||||||
1652 | $sleep = max(1, (int) $volume->getOption('lsPlSleep')); |
|||||||||||
1653 | $standby = (int) $volume->getOption('plStandby'); |
|||||||||||
1654 | if ($standby > 0 && $sleep > $standby) { |
|||||||||||
1655 | $standby = $sleep; |
|||||||||||
1656 | } |
|||||||||||
1657 | $limit = max(0, floor($standby / $sleep)) + 1; |
|||||||||||
1658 | do { |
|||||||||||
1659 | self::extendTimeLimit(30 + $sleep); |
|||||||||||
1660 | $_mtime = 0; |
|||||||||||
1661 | foreach ($ls as $_f) { |
|||||||||||
1662 | $_mtime = max($_mtime, $_f['ts']); |
|||||||||||
1663 | } |
|||||||||||
1664 | $compare = strval(count($ls)).':'.strval($_mtime); |
|||||||||||
1665 | if ($compare !== $args['compare']) { |
|||||||||||
1666 | break; |
|||||||||||
1667 | } |
|||||||||||
1668 | if (--$limit) { |
|||||||||||
1669 | sleep($sleep); |
|||||||||||
1670 | $volume->clearstatcache(); |
|||||||||||
1671 | if (($ls = $volume->scandir($cwd['hash'])) === false) { |
|||||||||||
1672 | break; |
|||||||||||
1673 | } |
|||||||||||
1674 | } |
|||||||||||
1675 | } while ($limit); |
|||||||||||
1676 | View Code Duplication | if ($ls === false) { |
||||||||||
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
||||||||||||
1677 | return ['error' => $this->error(self::ERROR_OPEN, $cwd['name'], $volume->error())]; |
|||||||||||
1678 | } |
|||||||||||
1679 | } |
|||||||||||
1680 | ||||||||||||
1681 | if ($ls) { |
|||||||||||
1682 | 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 ![]() |
||||||||||||
1683 | $files = array_merge($files, $ls); |
|||||||||||
1684 | } else { |
|||||||||||
1685 | $files = $ls; |
|||||||||||
1686 | } |
|||||||||||
1687 | } |
|||||||||||
1688 | ||||||||||||
1689 | $result = [ |
|||||||||||
1690 | 'cwd' => $cwd, |
|||||||||||
1691 | 'options' => $volume->options($cwd['hash']), |
|||||||||||
1692 | 'files' => $files, |
|||||||||||
1693 | ]; |
|||||||||||
1694 | ||||||||||||
1695 | if ($compare) { |
|||||||||||
1696 | $result['cwd']['compare'] = $compare; |
|||||||||||
1697 | } |
|||||||||||
1698 | ||||||||||||
1699 | if (! empty($args['init'])) { |
|||||||||||
1700 | $result['api'] = $this->version; |
|||||||||||
1701 | $result['uplMaxSize'] = ini_get('upload_max_filesize'); |
|||||||||||
1702 | $result['uplMaxFile'] = ini_get('max_file_uploads'); |
|||||||||||
1703 | $result['netDrivers'] = array_keys(self::$netDrivers); |
|||||||||||
1704 | $result['maxTargets'] = $this->maxTargets; |
|||||||||||
1705 | if ($volume) { |
|||||||||||
1706 | $result['cwd']['root'] = $volume->root(); |
|||||||||||
1707 | } |
|||||||||||
1708 | } |
|||||||||||
1709 | ||||||||||||
1710 | return $result; |
|||||||||||
1711 | } |
|||||||||||
1712 | ||||||||||||
1713 | /** |
|||||||||||
1714 | * Return dir files names list. |
|||||||||||
1715 | * |
|||||||||||
1716 | * @param array command arguments |
|||||||||||
1717 | * @return array |
|||||||||||
1718 | * @author Dmitry (dio) Levashov |
|||||||||||
1719 | **/ |
|||||||||||
1720 | protected function ls($args) |
|||||||||||
1721 | { |
|||||||||||
1722 | $target = $args['target']; |
|||||||||||
1723 | $intersect = isset($args['intersect']) ? $args['intersect'] : []; |
|||||||||||
1724 | ||||||||||||
1725 | if (($volume = $this->volume($target)) == false |
|||||||||||
1726 | || ($list = $volume->ls($target, $intersect)) === false) { |
|||||||||||
1727 | return ['error' => $this->error(self::ERROR_OPEN, '#'.$target)]; |
|||||||||||
1728 | } |
|||||||||||
1729 | ||||||||||||
1730 | return ['list' => $list]; |
|||||||||||
1731 | } |
|||||||||||
1732 | ||||||||||||
1733 | /** |
|||||||||||
1734 | * Return subdirs for required directory. |
|||||||||||
1735 | * |
|||||||||||
1736 | * @param array command arguments |
|||||||||||
1737 | * @return array |
|||||||||||
1738 | * @author Dmitry (dio) Levashov |
|||||||||||
1739 | **/ |
|||||||||||
1740 | protected function tree($args) |
|||||||||||
1741 | { |
|||||||||||
1742 | $target = $args['target']; |
|||||||||||
1743 | ||||||||||||
1744 | if (($volume = $this->volume($target)) == false |
|||||||||||
1745 | || ($tree = $volume->tree($target)) == false) { |
|||||||||||
1746 | return ['error' => $this->error(self::ERROR_OPEN, '#'.$target)]; |
|||||||||||
1747 | } |
|||||||||||
1748 | ||||||||||||
1749 | return ['tree' => $tree]; |
|||||||||||
1750 | } |
|||||||||||
1751 | ||||||||||||
1752 | /** |
|||||||||||
1753 | * Return parents dir for required directory. |
|||||||||||
1754 | * |
|||||||||||
1755 | * @param array command arguments |
|||||||||||
1756 | * @return array |
|||||||||||
1757 | * @author Dmitry (dio) Levashov |
|||||||||||
1758 | **/ |
|||||||||||
1759 | protected function parents($args) |
|||||||||||
1760 | { |
|||||||||||
1761 | $target = $args['target']; |
|||||||||||
1762 | $until = $args['until']; |
|||||||||||
1763 | ||||||||||||
1764 | if (($volume = $this->volume($target)) == false |
|||||||||||
1765 | || ($tree = $volume->parents($target, false, $until)) == false) { |
|||||||||||
1766 | return ['error' => $this->error(self::ERROR_OPEN, '#'.$target)]; |
|||||||||||
1767 | } |
|||||||||||
1768 | ||||||||||||
1769 | return ['tree' => $tree]; |
|||||||||||
1770 | } |
|||||||||||
1771 | ||||||||||||
1772 | /** |
|||||||||||
1773 | * Return new created thumbnails list. |
|||||||||||
1774 | * |
|||||||||||
1775 | * @param array command arguments |
|||||||||||
1776 | * @return array |
|||||||||||
1777 | * @author Dmitry (dio) Levashov |
|||||||||||
1778 | **/ |
|||||||||||
1779 | protected function tmb($args) |
|||||||||||
1780 | { |
|||||||||||
1781 | $result = ['images' => []]; |
|||||||||||
1782 | $targets = $args['targets']; |
|||||||||||
1783 | ||||||||||||
1784 | foreach ($targets as $target) { |
|||||||||||
1785 | self::extendTimeLimit(); |
|||||||||||
1786 | ||||||||||||
1787 | if (($volume = $this->volume($target)) != false |
|||||||||||
1788 | && (($tmb = $volume->tmb($target)) != false)) { |
|||||||||||
1789 | $result['images'][$target] = $tmb; |
|||||||||||
1790 | } |
|||||||||||
1791 | } |
|||||||||||
1792 | ||||||||||||
1793 | return $result; |
|||||||||||
1794 | } |
|||||||||||
1795 | ||||||||||||
1796 | /** |
|||||||||||
1797 | * Download files/folders as an archive file. |
|||||||||||
1798 | * |
|||||||||||
1799 | * 1st: Return srrsy contains download archive file info |
|||||||||||
1800 | * 2nd: Return array contains opened file pointer, root itself and required headers |
|||||||||||
1801 | * |
|||||||||||
1802 | * @param array command arguments |
|||||||||||
1803 | * @return array |
|||||||||||
1804 | * @author Naoki Sawada |
|||||||||||
1805 | **/ |
|||||||||||
1806 | protected function zipdl($args) |
|||||||||||
0 ignored issues
–
show
zipdl 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);
}
}
![]() |
||||||||||||
1807 | { |
|||||||||||
1808 | $targets = $args['targets']; |
|||||||||||
1809 | $download = ! empty($args['download']); |
|||||||||||
1810 | $h404 = 'HTTP/1.x 404 Not Found'; |
|||||||||||
1811 | ||||||||||||
1812 | if (! $download) { |
|||||||||||
1813 | //1st: Return srrsy contains download archive file info |
|||||||||||
1814 | $error = [self::ERROR_ARCHIVE]; |
|||||||||||
1815 | if (($volume = $this->volume($targets[0])) !== false) { |
|||||||||||
1816 | if ($dlres = $volume->zipdl($targets)) { |
|||||||||||
1817 | $path = $dlres['path']; |
|||||||||||
1818 | register_shutdown_function(create_function('$f', 'connection_status() && is_file($f) && unlink($f);'), $path); |
|||||||||||
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; }
![]() |
||||||||||||
1819 | if (count($targets) === 1) { |
|||||||||||
1820 | $name = basename($volume->path($targets[0])); |
|||||||||||
1821 | } else { |
|||||||||||
1822 | $name = $dlres['prefix'].'_Files'; |
|||||||||||
1823 | } |
|||||||||||
1824 | $name .= '.'.$dlres['ext']; |
|||||||||||
1825 | $result = [ |
|||||||||||
1826 | 'zipdl' => [ |
|||||||||||
1827 | 'file' => basename($path), |
|||||||||||
1828 | 'name' => $name, |
|||||||||||
1829 | 'mime' => $dlres['mime'], |
|||||||||||
1830 | ], |
|||||||||||
1831 | ]; |
|||||||||||
1832 | ||||||||||||
1833 | return $result; |
|||||||||||
1834 | } |
|||||||||||
1835 | $error = array_merge($error, $volume->error()); |
|||||||||||
1836 | } |
|||||||||||
1837 | ||||||||||||
1838 | return ['error' => $error]; |
|||||||||||
1839 | } else { |
|||||||||||
1840 | // 2nd: Return array contains opened file pointer, root itself and required headers |
|||||||||||
1841 | if (count($targets) !== 4 || ($volume = $this->volume($targets[0])) == false) { |
|||||||||||
1842 | return ['error' => 'File not found', 'header' => $h404, 'raw' => true]; |
|||||||||||
1843 | } |
|||||||||||
1844 | $file = $targets[1]; |
|||||||||||
1845 | $path = $volume->getTempPath().DIRECTORY_SEPARATOR.$file; |
|||||||||||
1846 | register_shutdown_function(create_function('$f', 'is_file($f) && unlink($f);'), $path); |
|||||||||||
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; }
![]() |
||||||||||||
1847 | if (! is_readable($path)) { |
|||||||||||
1848 | return ['error' => 'File not found', 'header' => $h404, 'raw' => true]; |
|||||||||||
1849 | } |
|||||||||||
1850 | $name = $targets[2]; |
|||||||||||
1851 | $mime = $targets[3]; |
|||||||||||
1852 | ||||||||||||
1853 | $filenameEncoded = rawurlencode($name); |
|||||||||||
1854 | View Code Duplication | if (strpos($filenameEncoded, '%') === false) { // ASCII only |
||||||||||
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
||||||||||||
1855 | $filename = 'filename="'.$name.'"'; |
|||||||||||
1856 | } else { |
|||||||||||
1857 | $ua = $_SERVER['HTTP_USER_AGENT']; |
|||||||||||
1858 | if (preg_match('/MSIE [4-8]/', $ua)) { // IE < 9 do not support RFC 6266 (RFC 2231/RFC 5987) |
|||||||||||
1859 | $filename = 'filename="'.$filenameEncoded.'"'; |
|||||||||||
1860 | } elseif (strpos($ua, 'Chrome') === false && strpos($ua, 'Safari') !== false && preg_match('#Version/[3-5]#', $ua)) { // Safari < 6 |
|||||||||||
1861 | $filename = 'filename="'.str_replace('"', '', $name).'"'; |
|||||||||||
1862 | } else { // RFC 6266 (RFC 2231/RFC 5987) |
|||||||||||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
36% 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. ![]() |
||||||||||||
1863 | $filename = 'filename*=UTF-8\'\''.$filenameEncoded; |
|||||||||||
1864 | } |
|||||||||||
1865 | } |
|||||||||||
1866 | ||||||||||||
1867 | $fp = fopen($path, 'rb'); |
|||||||||||
1868 | $file = fstat($fp); |
|||||||||||
1869 | $result = [ |
|||||||||||
1870 | 'pointer' => $fp, |
|||||||||||
1871 | 'header' => [ |
|||||||||||
1872 | 'Content-Type: '.$mime, |
|||||||||||
1873 | 'Content-Disposition: attachment; '.$filename, |
|||||||||||
1874 | 'Content-Transfer-Encoding: binary', |
|||||||||||
1875 | 'Content-Length: '.$file['size'], |
|||||||||||
1876 | 'Accept-Ranges: none', |
|||||||||||
1877 | 'Connection: close', |
|||||||||||
1878 | ], |
|||||||||||
1879 | ]; |
|||||||||||
1880 | ||||||||||||
1881 | return $result; |
|||||||||||
1882 | } |
|||||||||||
1883 | } |
|||||||||||
1884 | ||||||||||||
1885 | /** |
|||||||||||
1886 | * Required to output file in browser when volume URL is not set |
|||||||||||
1887 | * Return array contains opened file pointer, root itself and required headers. |
|||||||||||
1888 | * |
|||||||||||
1889 | * @param array command arguments |
|||||||||||
1890 | * @return array |
|||||||||||
1891 | * @author Dmitry (dio) Levashov |
|||||||||||
1892 | **/ |
|||||||||||
1893 | protected function file($args) |
|||||||||||
0 ignored issues
–
show
file 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);
}
}
![]() |
||||||||||||
1894 | { |
|||||||||||
1895 | $target = $args['target']; |
|||||||||||
1896 | $download = ! empty($args['download']); |
|||||||||||
1897 | $h403 = 'HTTP/1.x 403 Access Denied'; |
|||||||||||
1898 | $h404 = 'HTTP/1.x 404 Not Found'; |
|||||||||||
1899 | ||||||||||||
1900 | View Code Duplication | if (($volume = $this->volume($target)) == false) { |
||||||||||
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
||||||||||||
1901 | return ['error' => 'File not found', 'header' => $h404, 'raw' => true]; |
|||||||||||
1902 | } |
|||||||||||
1903 | ||||||||||||
1904 | View Code Duplication | if (($file = $volume->file($target)) == false) { |
||||||||||
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
||||||||||||
1905 | return ['error' => 'File not found', 'header' => $h404, 'raw' => true]; |
|||||||||||
1906 | } |
|||||||||||
1907 | ||||||||||||
1908 | if (! $file['read']) { |
|||||||||||
1909 | return ['error' => 'Access denied', 'header' => $h403, 'raw' => true]; |
|||||||||||
1910 | } |
|||||||||||
1911 | ||||||||||||
1912 | View Code Duplication | if (($fp = $volume->open($target)) == false) { |
||||||||||
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
||||||||||||
1913 | return ['error' => 'File not found', 'header' => $h404, 'raw' => true]; |
|||||||||||
1914 | } |
|||||||||||
1915 | ||||||||||||
1916 | // allow change MIME type by 'file.pre' callback functions |
|||||||||||
1917 | $mime = isset($args['mime']) ? $args['mime'] : $file['mime']; |
|||||||||||
1918 | if ($download) { |
|||||||||||
1919 | $disp = 'attachment'; |
|||||||||||
1920 | } else { |
|||||||||||
1921 | $dispInlineRegex = $volume->getOption('dispInlineRegex'); |
|||||||||||
1922 | $inlineRegex = false; |
|||||||||||
1923 | if ($dispInlineRegex) { |
|||||||||||
1924 | $inlineRegex = '#'.str_replace('#', '\\#', $dispInlineRegex).'#'; |
|||||||||||
1925 | try { |
|||||||||||
1926 | preg_match($inlineRegex, ''); |
|||||||||||
1927 | } catch (Exception $e) { |
|||||||||||
1928 | $inlineRegex = false; |
|||||||||||
1929 | } |
|||||||||||
1930 | } |
|||||||||||
1931 | if (! $inlineRegex) { |
|||||||||||
0 ignored issues
–
show
The expression
$inlineRegex of type string|false is loosely compared to false ; this is ambiguous if the string can be empty. You might want to explicitly use === false instead.
In PHP, under loose comparison (like For '' == false // true
'' == null // true
'ab' == false // false
'ab' == null // false
// It is often better to use strict comparison
'' === false // false
'' === null // false
![]() |
||||||||||||
1932 | $inlineRegex = '#^(?:(?:image|text)|application/x-shockwave-flash$)#'; |
|||||||||||
1933 | } |
|||||||||||
1934 | $disp = preg_match($inlineRegex, $mime) ? 'inline' : 'attachment'; |
|||||||||||
1935 | } |
|||||||||||
1936 | ||||||||||||
1937 | $filenameEncoded = rawurlencode($file['name']); |
|||||||||||
1938 | View Code Duplication | if (strpos($filenameEncoded, '%') === false) { // ASCII only |
||||||||||
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
||||||||||||
1939 | $filename = 'filename="'.$file['name'].'"'; |
|||||||||||
1940 | } else { |
|||||||||||
1941 | $ua = $_SERVER['HTTP_USER_AGENT']; |
|||||||||||
1942 | if (preg_match('/MSIE [4-8]/', $ua)) { // IE < 9 do not support RFC 6266 (RFC 2231/RFC 5987) |
|||||||||||
1943 | $filename = 'filename="'.$filenameEncoded.'"'; |
|||||||||||
1944 | } elseif (strpos($ua, 'Chrome') === false && strpos($ua, 'Safari') !== false && preg_match('#Version/[3-5]#', $ua)) { // Safari < 6 |
|||||||||||
1945 | $filename = 'filename="'.str_replace('"', '', $file['name']).'"'; |
|||||||||||
1946 | } else { // RFC 6266 (RFC 2231/RFC 5987) |
|||||||||||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
36% 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. ![]() |
||||||||||||
1947 | $filename = 'filename*=UTF-8\'\''.$filenameEncoded; |
|||||||||||
1948 | } |
|||||||||||
1949 | } |
|||||||||||
1950 | ||||||||||||
1951 | $result = [ |
|||||||||||
1952 | 'volume' => $volume, |
|||||||||||
1953 | 'pointer' => $fp, |
|||||||||||
1954 | 'info' => $file, |
|||||||||||
1955 | 'header' => [ |
|||||||||||
1956 | 'Content-Type: '.$mime, |
|||||||||||
1957 | 'Content-Disposition: '.$disp.'; '.$filename, |
|||||||||||
1958 | 'Content-Transfer-Encoding: binary', |
|||||||||||
1959 | 'Content-Length: '.$file['size'], |
|||||||||||
1960 | 'Connection: close', |
|||||||||||
1961 | ], |
|||||||||||
1962 | ]; |
|||||||||||
1963 | if (isset($file['url']) && $file['url'] && $file['url'] != 1) { |
|||||||||||
1964 | $result['header'][] = 'Content-Location: '.$file['url']; |
|||||||||||
1965 | } |
|||||||||||
1966 | ||||||||||||
1967 | return $result; |
|||||||||||
1968 | } |
|||||||||||
1969 | ||||||||||||
1970 | /** |
|||||||||||
1971 | * Count total files size. |
|||||||||||
1972 | * |
|||||||||||
1973 | * @param array command arguments |
|||||||||||
1974 | * @return array |
|||||||||||
1975 | * @author Dmitry (dio) Levashov |
|||||||||||
1976 | **/ |
|||||||||||
1977 | protected function size($args) |
|||||||||||
1978 | { |
|||||||||||
1979 | $size = 0; |
|||||||||||
1980 | $files = 0; |
|||||||||||
1981 | $dirs = 0; |
|||||||||||
1982 | $itemCount = true; |
|||||||||||
1983 | ||||||||||||
1984 | foreach ($args['targets'] as $target) { |
|||||||||||
1985 | if (($volume = $this->volume($target)) == false |
|||||||||||
1986 | || ($file = $volume->file($target)) == false |
|||||||||||
1987 | || ! $file['read']) { |
|||||||||||
1988 | return ['error' => $this->error(self::ERROR_OPEN, '#'.$target)]; |
|||||||||||
1989 | } |
|||||||||||
1990 | ||||||||||||
1991 | $volRes = $volume->size($target); |
|||||||||||
1992 | if (is_array($volRes)) { |
|||||||||||
1993 | if (! empty($volRes['size'])) { |
|||||||||||
1994 | $size += $volRes['size']; |
|||||||||||
1995 | } |
|||||||||||
1996 | if ($itemCount) { |
|||||||||||
1997 | if (! empty($volRes['files'])) { |
|||||||||||
1998 | $files += $volRes['files']; |
|||||||||||
1999 | } |
|||||||||||
2000 | if (! empty($volRes['dirs'])) { |
|||||||||||
2001 | $dirs += $volRes['dirs']; |
|||||||||||
2002 | } |
|||||||||||
2003 | } |
|||||||||||
2004 | } elseif (is_numeric($volRes)) { |
|||||||||||
2005 | $size += $volRes; |
|||||||||||
2006 | $files = $dirs = 'unknown'; |
|||||||||||
2007 | $itemCount = false; |
|||||||||||
2008 | } |
|||||||||||
2009 | } |
|||||||||||
2010 | ||||||||||||
2011 | return ['size' => $size, 'fileCnt' => $files, 'dirCnt' => $dirs]; |
|||||||||||
2012 | } |
|||||||||||
2013 | ||||||||||||
2014 | /** |
|||||||||||
2015 | * Create directory. |
|||||||||||
2016 | * |
|||||||||||
2017 | * @param array command arguments |
|||||||||||
2018 | * @return array |
|||||||||||
2019 | * @author Dmitry (dio) Levashov |
|||||||||||
2020 | **/ |
|||||||||||
2021 | protected function mkdir($args) |
|||||||||||
2022 | { |
|||||||||||
2023 | $target = $args['target']; |
|||||||||||
2024 | $name = $args['name']; |
|||||||||||
2025 | $dirs = $args['dirs']; |
|||||||||||
2026 | if ($name === '' && ! $dirs) { |
|||||||||||
2027 | return ['error' => $this->error(self::ERROR_INV_PARAMS, 'mkdir')]; |
|||||||||||
2028 | } |
|||||||||||
2029 | ||||||||||||
2030 | View Code Duplication | if (($volume = $this->volume($target)) == false) { |
||||||||||
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
||||||||||||
2031 | return ['error' => $this->error(self::ERROR_MKDIR, $name, self::ERROR_TRGDIR_NOT_FOUND, '#'.$target)]; |
|||||||||||
2032 | } |
|||||||||||
2033 | if ($dirs) { |
|||||||||||
2034 | sort($dirs); |
|||||||||||
2035 | $reset = null; |
|||||||||||
2036 | $mkdirs = []; |
|||||||||||
2037 | foreach ($dirs as $dir) { |
|||||||||||
2038 | $tgt = &$mkdirs; |
|||||||||||
2039 | $_names = explode('/', trim($dir, '/')); |
|||||||||||
2040 | foreach ($_names as $_key => $_name) { |
|||||||||||
2041 | if (! isset($tgt[$_name])) { |
|||||||||||
2042 | $tgt[$_name] = []; |
|||||||||||
2043 | } |
|||||||||||
2044 | $tgt = &$tgt[$_name]; |
|||||||||||
2045 | } |
|||||||||||
2046 | $tgt = &$reset; |
|||||||||||
2047 | } |
|||||||||||
2048 | $res = $this->ensureDirsRecursively($volume, $target, $mkdirs); |
|||||||||||
0 ignored issues
–
show
$mkdirs 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);
![]() |
||||||||||||
2049 | if ($res['error']) { |
|||||||||||
2050 | $errors = $volume->error(); |
|||||||||||
2051 | if ($res['makes']) { |
|||||||||||
2052 | $this->rm(['targets' => $res['makes']]); |
|||||||||||
2053 | } |
|||||||||||
2054 | ||||||||||||
2055 | return ['error' => $this->error(self::ERROR_MKDIR, $res['error'][0], $errors)]; |
|||||||||||
2056 | } else { |
|||||||||||
2057 | return ['added' => $res['stats'], 'hashes' => $res['hashes']]; |
|||||||||||
2058 | } |
|||||||||||
2059 | } else { |
|||||||||||
2060 | return ($dir = $volume->mkdir($target, $name)) == false |
|||||||||||
2061 | ? ['error' => $this->error(self::ERROR_MKDIR, $name, $volume->error())] |
|||||||||||
2062 | : ['added' => [$dir]]; |
|||||||||||
2063 | } |
|||||||||||
2064 | } |
|||||||||||
2065 | ||||||||||||
2066 | /** |
|||||||||||
2067 | * Create empty file. |
|||||||||||
2068 | * |
|||||||||||
2069 | * @param array command arguments |
|||||||||||
2070 | * @return array |
|||||||||||
2071 | * @author Dmitry (dio) Levashov |
|||||||||||
2072 | **/ |
|||||||||||
2073 | protected function mkfile($args) |
|||||||||||
2074 | { |
|||||||||||
2075 | $target = $args['target']; |
|||||||||||
2076 | $name = $args['name']; |
|||||||||||
2077 | ||||||||||||
2078 | View Code Duplication | if (($volume = $this->volume($target)) == false) { |
||||||||||
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
||||||||||||
2079 | return ['error' => $this->error(self::ERROR_MKFILE, $name, self::ERROR_TRGDIR_NOT_FOUND, '#'.$target)]; |
|||||||||||
2080 | } |
|||||||||||
2081 | ||||||||||||
2082 | return ($file = $volume->mkfile($target, $args['name'])) == false |
|||||||||||
2083 | ? ['error' => $this->error(self::ERROR_MKFILE, $name, $volume->error())] |
|||||||||||
2084 | : ['added' => [$file]]; |
|||||||||||
2085 | } |
|||||||||||
2086 | ||||||||||||
2087 | /** |
|||||||||||
2088 | * Rename file. |
|||||||||||
2089 | * |
|||||||||||
2090 | * @param array $args |
|||||||||||
2091 | * @return array |
|||||||||||
2092 | * @author Dmitry (dio) Levashov |
|||||||||||
2093 | **/ |
|||||||||||
2094 | protected function rename($args) |
|||||||||||
2095 | { |
|||||||||||
2096 | $target = $args['target']; |
|||||||||||
2097 | $name = $args['name']; |
|||||||||||
2098 | ||||||||||||
2099 | View Code Duplication | if (($volume = $this->volume($target)) == false |
||||||||||
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
||||||||||||
2100 | || ($rm = $volume->file($target)) == false) { |
|||||||||||
2101 | return ['error' => $this->error(self::ERROR_RENAME, '#'.$target, self::ERROR_FILE_NOT_FOUND)]; |
|||||||||||
2102 | } |
|||||||||||
2103 | $rm['realpath'] = $volume->realpath($target); |
|||||||||||
2104 | ||||||||||||
2105 | if ($this->itemLocked($target)) { |
|||||||||||
2106 | return ['error' => $this->error(self::ERROR_LOCKED, $rm['name'])]; |
|||||||||||
2107 | } |
|||||||||||
2108 | ||||||||||||
2109 | return ($file = $volume->rename($target, $name)) == false |
|||||||||||
2110 | ? ['error' => $this->error(self::ERROR_RENAME, $rm['name'], $volume->error())] |
|||||||||||
2111 | : ['added' => [$file], 'removed' => [$rm]]; |
|||||||||||
2112 | } |
|||||||||||
2113 | ||||||||||||
2114 | /** |
|||||||||||
2115 | * Duplicate file - create copy with "copy %d" suffix. |
|||||||||||
2116 | * |
|||||||||||
2117 | * @param array $args command arguments |
|||||||||||
2118 | * @return array |
|||||||||||
2119 | * @author Dmitry (dio) Levashov |
|||||||||||
2120 | **/ |
|||||||||||
2121 | protected function duplicate($args) |
|||||||||||
2122 | { |
|||||||||||
2123 | $targets = is_array($args['targets']) ? $args['targets'] : []; |
|||||||||||
2124 | $result = ['added' => []]; |
|||||||||||
2125 | $suffix = empty($args['suffix']) ? 'copy' : $args['suffix']; |
|||||||||||
2126 | ||||||||||||
2127 | $this->itemLock($targets); |
|||||||||||
2128 | ||||||||||||
2129 | foreach ($targets as $target) { |
|||||||||||
2130 | self::extendTimeLimit(); |
|||||||||||
2131 | ||||||||||||
2132 | View Code Duplication | if (($volume = $this->volume($target)) == false |
||||||||||
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
||||||||||||
2133 | || ($src = $volume->file($target)) == false) { |
|||||||||||
2134 | $result['warning'] = $this->error(self::ERROR_COPY, '#'.$target, self::ERROR_FILE_NOT_FOUND); |
|||||||||||
2135 | break; |
|||||||||||
2136 | } |
|||||||||||
2137 | ||||||||||||
2138 | if (($file = $volume->duplicate($target, $suffix)) == false) { |
|||||||||||
2139 | $result['warning'] = $this->error($volume->error()); |
|||||||||||
2140 | break; |
|||||||||||
2141 | } |
|||||||||||
2142 | ||||||||||||
2143 | $result['added'][] = $file; |
|||||||||||
2144 | } |
|||||||||||
2145 | ||||||||||||
2146 | return $result; |
|||||||||||
2147 | } |
|||||||||||
2148 | ||||||||||||
2149 | /** |
|||||||||||
2150 | * Remove dirs/files. |
|||||||||||
2151 | * |
|||||||||||
2152 | * @param array command arguments |
|||||||||||
2153 | * @return array |
|||||||||||
2154 | * @author Dmitry (dio) Levashov |
|||||||||||
2155 | **/ |
|||||||||||
2156 | protected function rm($args) |
|||||||||||
2157 | { |
|||||||||||
2158 | $targets = is_array($args['targets']) ? $args['targets'] : []; |
|||||||||||
2159 | $result = ['removed' => []]; |
|||||||||||
2160 | ||||||||||||
2161 | foreach ($targets as $target) { |
|||||||||||
2162 | self::extendTimeLimit(); |
|||||||||||
2163 | ||||||||||||
2164 | View Code Duplication | if (($volume = $this->volume($target)) == false) { |
||||||||||
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
||||||||||||
2165 | $result['warning'] = $this->error(self::ERROR_RM, '#'.$target, self::ERROR_FILE_NOT_FOUND); |
|||||||||||
2166 | break; |
|||||||||||
2167 | } |
|||||||||||
2168 | ||||||||||||
2169 | View Code Duplication | if ($this->itemLocked($target)) { |
||||||||||
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
||||||||||||
2170 | $rm = $volume->file($target); |
|||||||||||
2171 | $result['warning'] = $this->error(self::ERROR_LOCKED, $rm['name']); |
|||||||||||
2172 | break; |
|||||||||||
2173 | } |
|||||||||||
2174 | ||||||||||||
2175 | if (! $volume->rm($target)) { |
|||||||||||
2176 | $result['warning'] = $this->error($volume->error()); |
|||||||||||
2177 | break; |
|||||||||||
2178 | } |
|||||||||||
2179 | } |
|||||||||||
2180 | ||||||||||||
2181 | return $result; |
|||||||||||
2182 | } |
|||||||||||
2183 | ||||||||||||
2184 | /** |
|||||||||||
2185 | * Return has subdirs. |
|||||||||||
2186 | * |
|||||||||||
2187 | * @param array command arguments |
|||||||||||
2188 | * @return array |
|||||||||||
2189 | * @author Dmitry Naoki Sawada |
|||||||||||
2190 | **/ |
|||||||||||
2191 | protected function subdirs($args) |
|||||||||||
2192 | { |
|||||||||||
2193 | $result = ['subdirs' => []]; |
|||||||||||
2194 | $targets = $args['targets']; |
|||||||||||
2195 | ||||||||||||
2196 | foreach ($targets as $target) { |
|||||||||||
2197 | View Code Duplication | if (($volume = $this->volume($target)) !== false) { |
||||||||||
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
||||||||||||
2198 | $result['subdirs'][$target] = $volume->subdirs($target) ? 1 : 0; |
|||||||||||
2199 | } |
|||||||||||
2200 | } |
|||||||||||
2201 | ||||||||||||
2202 | return $result; |
|||||||||||
2203 | } |
|||||||||||
2204 | ||||||||||||
2205 | /** |
|||||||||||
2206 | * Get remote contents. |
|||||||||||
2207 | * |
|||||||||||
2208 | * @param string $url target url |
|||||||||||
2209 | * @param int $timeout timeout (sec) |
|||||||||||
2210 | * @param int $redirect_max redirect max count |
|||||||||||
2211 | * @param string $ua |
|||||||||||
2212 | * @param resource $fp |
|||||||||||
2213 | * @return string or bool(false) |
|||||||||||
2214 | * @retval string contents |
|||||||||||
2215 | * @rettval false error |
|||||||||||
2216 | * @author Naoki Sawada |
|||||||||||
2217 | **/ |
|||||||||||
2218 | protected function get_remote_contents(&$url, $timeout = 30, $redirect_max = 5, $ua = 'Mozilla/5.0', $fp = null) |
|||||||||||
2219 | { |
|||||||||||
2220 | $method = (function_exists('curl_exec') && ! ini_get('safe_mode') && ! ini_get('open_basedir')) ? 'curl_get_contents' : 'fsock_get_contents'; |
|||||||||||
2221 | ||||||||||||
2222 | return $this->$method($url, $timeout, $redirect_max, $ua, $fp); |
|||||||||||
2223 | } |
|||||||||||
2224 | ||||||||||||
2225 | /** |
|||||||||||
2226 | * Get remote contents with cURL. |
|||||||||||
2227 | * |
|||||||||||
2228 | * @param string $url target url |
|||||||||||
2229 | * @param int $timeout timeout (sec) |
|||||||||||
2230 | * @param int $redirect_max redirect max count |
|||||||||||
2231 | * @param string $ua |
|||||||||||
2232 | * @param resource $outfp |
|||||||||||
2233 | * @return string or bool(false) |
|||||||||||
2234 | * @retval string contents |
|||||||||||
2235 | * @retval false error |
|||||||||||
2236 | * @author Naoki Sawada |
|||||||||||
2237 | **/ |
|||||||||||
2238 | protected function curl_get_contents(&$url, $timeout, $redirect_max, $ua, $outfp) |
|||||||||||
2239 | { |
|||||||||||
2240 | $ch = curl_init(); |
|||||||||||
2241 | curl_setopt($ch, CURLOPT_URL, $url); |
|||||||||||
2242 | curl_setopt($ch, CURLOPT_HEADER, false); |
|||||||||||
2243 | if ($outfp) { |
|||||||||||
2244 | curl_setopt($ch, CURLOPT_FILE, $outfp); |
|||||||||||
2245 | } else { |
|||||||||||
2246 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); |
|||||||||||
2247 | curl_setopt($ch, CURLOPT_BINARYTRANSFER, true); |
|||||||||||
2248 | } |
|||||||||||
2249 | curl_setopt($ch, CURLOPT_LOW_SPEED_LIMIT, 1); |
|||||||||||
2250 | curl_setopt($ch, CURLOPT_LOW_SPEED_TIME, $timeout); |
|||||||||||
2251 | curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); |
|||||||||||
2252 | curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); |
|||||||||||
2253 | curl_setopt($ch, CURLOPT_MAXREDIRS, $redirect_max); |
|||||||||||
2254 | curl_setopt($ch, CURLOPT_USERAGENT, $ua); |
|||||||||||
2255 | $result = curl_exec($ch); |
|||||||||||
2256 | $url = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL); |
|||||||||||
2257 | curl_close($ch); |
|||||||||||
2258 | ||||||||||||
2259 | return $outfp ? $outfp : $result; |
|||||||||||
2260 | } |
|||||||||||
2261 | ||||||||||||
2262 | /** |
|||||||||||
2263 | * Get remote contents with fsockopen(). |
|||||||||||
2264 | * |
|||||||||||
2265 | * @param string $url url |
|||||||||||
2266 | * @param int $timeout timeout (sec) |
|||||||||||
2267 | * @param int $redirect_max redirect max count |
|||||||||||
2268 | * @param string $ua |
|||||||||||
2269 | * @param resource $outfp |
|||||||||||
2270 | * @return string or bool(false) |
|||||||||||
2271 | * @retval string contents |
|||||||||||
2272 | * @retval false error |
|||||||||||
2273 | * @author Naoki Sawada |
|||||||||||
2274 | */ |
|||||||||||
2275 | protected function fsock_get_contents(&$url, $timeout, $redirect_max, $ua, $outfp) |
|||||||||||
2276 | { |
|||||||||||
2277 | $connect_timeout = 3; |
|||||||||||
2278 | $connect_try = 3; |
|||||||||||
2279 | $method = 'GET'; |
|||||||||||
2280 | $readsize = 4096; |
|||||||||||
2281 | $ssl = ''; |
|||||||||||
2282 | ||||||||||||
2283 | $getSize = null; |
|||||||||||
2284 | $headers = ''; |
|||||||||||
2285 | ||||||||||||
2286 | $arr = parse_url($url); |
|||||||||||
2287 | if (! $arr) { |
|||||||||||
2288 | // Bad request |
|||||||||||
2289 | return false; |
|||||||||||
2290 | } |
|||||||||||
2291 | if ($arr['scheme'] === 'https') { |
|||||||||||
2292 | $ssl = 'ssl://'; |
|||||||||||
2293 | } |
|||||||||||
2294 | ||||||||||||
2295 | // query |
|||||||||||
2296 | $arr['query'] = isset($arr['query']) ? '?'.$arr['query'] : ''; |
|||||||||||
2297 | // port |
|||||||||||
2298 | $arr['port'] = isset($arr['port']) ? $arr['port'] : ($ssl ? 443 : 80); |
|||||||||||
2299 | ||||||||||||
2300 | $url_base = $arr['scheme'].'://'.$arr['host'].':'.$arr['port']; |
|||||||||||
2301 | $url_path = isset($arr['path']) ? $arr['path'] : '/'; |
|||||||||||
2302 | $uri = $url_path.$arr['query']; |
|||||||||||
2303 | ||||||||||||
2304 | $query = $method.' '.$uri." HTTP/1.0\r\n"; |
|||||||||||
2305 | $query .= 'Host: '.$arr['host']."\r\n"; |
|||||||||||
2306 | $query .= "Accept: */*\r\n"; |
|||||||||||
2307 | $query .= "Connection: close\r\n"; |
|||||||||||
2308 | if (! empty($ua)) { |
|||||||||||
2309 | $query .= 'User-Agent: '.$ua."\r\n"; |
|||||||||||
2310 | } |
|||||||||||
2311 | if (! is_null($getSize)) { |
|||||||||||
2312 | $query .= 'Range: bytes=0-'.($getSize - 1)."\r\n"; |
|||||||||||
2313 | } |
|||||||||||
2314 | ||||||||||||
2315 | $query .= $headers; |
|||||||||||
2316 | ||||||||||||
2317 | $query .= "\r\n"; |
|||||||||||
2318 | ||||||||||||
2319 | $fp = $connect_try_count = 0; |
|||||||||||
2320 | while (! $fp && $connect_try_count < $connect_try) { |
|||||||||||
2321 | $errno = 0; |
|||||||||||
2322 | $errstr = ''; |
|||||||||||
2323 | $fp = fsockopen( |
|||||||||||
2324 | $ssl.$arr['host'], |
|||||||||||
2325 | $arr['port'], |
|||||||||||
2326 | $errno, $errstr, $connect_timeout); |
|||||||||||
2327 | if ($fp) { |
|||||||||||
2328 | break; |
|||||||||||
2329 | } |
|||||||||||
2330 | $connect_try_count++; |
|||||||||||
2331 | if (connection_aborted()) { |
|||||||||||
2332 | exit(); |
|||||||||||
0 ignored issues
–
show
The method
fsock_get_contents() contains an exit expression.
An exit expression should only be used in rare cases. For example, if you write a short command line script. In most cases however, using an ![]() |
||||||||||||
2333 | } |
|||||||||||
2334 | sleep(1); // wait 1sec |
|||||||||||
2335 | } |
|||||||||||
2336 | ||||||||||||
2337 | $fwrite = 0; |
|||||||||||
0 ignored issues
–
show
$fwrite is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
||||||||||||
2338 | for ($written = 0; $written < strlen($query); $written += $fwrite) { |
|||||||||||
2339 | $fwrite = fwrite($fp, substr($query, $written)); |
|||||||||||
2340 | if (! $fwrite) { |
|||||||||||
2341 | break; |
|||||||||||
2342 | } |
|||||||||||
2343 | } |
|||||||||||
2344 | ||||||||||||
2345 | $response = ''; |
|||||||||||
0 ignored issues
–
show
$response is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
||||||||||||
2346 | ||||||||||||
2347 | if ($timeout) { |
|||||||||||
2348 | socket_set_timeout($fp, $timeout); |
|||||||||||
2349 | } |
|||||||||||
2350 | ||||||||||||
2351 | $_response = ''; |
|||||||||||
2352 | $header = ''; |
|||||||||||
2353 | while ($_response !== "\r\n") { |
|||||||||||
2354 | $_response = fgets($fp, $readsize); |
|||||||||||
2355 | $header .= $_response; |
|||||||||||
2356 | } |
|||||||||||
2357 | ||||||||||||
2358 | $rccd = array_pad(explode(' ', $header, 2), 2, ''); // array('HTTP/1.1','200') |
|||||||||||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
86% 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. ![]() |
||||||||||||
2359 | $rc = (int) $rccd[1]; |
|||||||||||
2360 | ||||||||||||
2361 | $ret = false; |
|||||||||||
2362 | // Redirect |
|||||||||||
2363 | switch ($rc) { |
|||||||||||
2364 | case 307: // Temporary Redirect |
|||||||||||
2365 | case 303: // See Other |
|||||||||||
2366 | case 302: // Moved Temporarily |
|||||||||||
2367 | case 301: // Moved Permanently |
|||||||||||
2368 | $matches = []; |
|||||||||||
2369 | if (preg_match('/^Location: (.+?)(#.+)?$/im', $header, $matches) && --$redirect_max > 0) { |
|||||||||||
2370 | $_url = $url; |
|||||||||||
2371 | $url = trim($matches[1]); |
|||||||||||
2372 | $hash = isset($matches[2]) ? trim($matches[2]) : ''; |
|||||||||||
0 ignored issues
–
show
$hash is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
||||||||||||
2373 | if (! preg_match('/^https?:\//', $url)) { // no scheme |
|||||||||||
2374 | if ($url[0] != '/') { // Relative path |
|||||||||||
2375 | // to Absolute path |
|||||||||||
2376 | $url = substr($url_path, 0, strrpos($url_path, '/')).'/'.$url; |
|||||||||||
2377 | } |
|||||||||||
2378 | // add sheme,host |
|||||||||||
2379 | $url = $url_base.$url; |
|||||||||||
2380 | } |
|||||||||||
2381 | if ($_url !== $url) { |
|||||||||||
2382 | fclose($fp); |
|||||||||||
2383 | ||||||||||||
2384 | return $this->fsock_get_contents($url, $timeout, $redirect_max, $ua, $outfp); |
|||||||||||
2385 | } |
|||||||||||
2386 | } |
|||||||||||
2387 | break; |
|||||||||||
2388 | case 200: |
|||||||||||
2389 | $ret = true; |
|||||||||||
2390 | } |
|||||||||||
2391 | if (! $ret) { |
|||||||||||
2392 | fclose($fp); |
|||||||||||
2393 | ||||||||||||
2394 | return false; |
|||||||||||
2395 | } |
|||||||||||
2396 | ||||||||||||
2397 | $body = ''; |
|||||||||||
2398 | if (! $outfp) { |
|||||||||||
2399 | $outfp = fopen('php://temp', 'rwb'); |
|||||||||||
2400 | $body = true; |
|||||||||||
2401 | } |
|||||||||||
2402 | while (fwrite($outfp, fread($fp, $readsize))) { |
|||||||||||
2403 | if ($timeout) { |
|||||||||||
2404 | $_status = socket_get_status($fp); |
|||||||||||
2405 | if ($_status['timed_out']) { |
|||||||||||
2406 | fclose($outfp); |
|||||||||||
2407 | fclose($fp); |
|||||||||||
2408 | ||||||||||||
2409 | return false; // Request Time-out |
|||||||||||
2410 | } |
|||||||||||
2411 | } |
|||||||||||
2412 | } |
|||||||||||
2413 | if ($body) { |
|||||||||||
2414 | rewind($outfp); |
|||||||||||
2415 | $body = stream_get_contents($outfp); |
|||||||||||
2416 | fclose($outfp); |
|||||||||||
2417 | $outfp = null; |
|||||||||||
2418 | } |
|||||||||||
2419 | ||||||||||||
2420 | fclose($fp); |
|||||||||||
2421 | ||||||||||||
2422 | return $outfp ? $outfp : $body; // Data |
|||||||||||
2423 | } |
|||||||||||
2424 | ||||||||||||
2425 | /** |
|||||||||||
2426 | * Parse Data URI scheme. |
|||||||||||
2427 | * |
|||||||||||
2428 | * @param string $str |
|||||||||||
2429 | * @param array $extTable |
|||||||||||
2430 | * @param array $args |
|||||||||||
2431 | * @return array |
|||||||||||
2432 | * @author Naoki Sawada |
|||||||||||
2433 | */ |
|||||||||||
2434 | protected function parse_data_scheme($str, $extTable, $args = null) |
|||||||||||
2435 | { |
|||||||||||
2436 | $data = $name = ''; |
|||||||||||
2437 | if ($fp = fopen('data://'.substr($str, 5), 'rb')) { |
|||||||||||
2438 | if ($data = stream_get_contents($fp)) { |
|||||||||||
2439 | $meta = stream_get_meta_data($fp); |
|||||||||||
2440 | $ext = isset($extTable[$meta['mediatype']]) ? '.'.$extTable[$meta['mediatype']] : ''; |
|||||||||||
2441 | // Set name if name eq 'image.png' and $args has 'name' array, e.g. clipboard data |
|||||||||||
2442 | if (is_array($args['name']) && isset($args['name'][0])) { |
|||||||||||
2443 | $name = $args['name'][0]; |
|||||||||||
2444 | if ($ext) { |
|||||||||||
2445 | $name = preg_replace('/\.[^.]*$/', '', $name); |
|||||||||||
2446 | } |
|||||||||||
2447 | } else { |
|||||||||||
2448 | $name = substr(md5($data), 0, 8); |
|||||||||||
2449 | } |
|||||||||||
2450 | $name .= $ext; |
|||||||||||
2451 | } |
|||||||||||
2452 | fclose($fp); |
|||||||||||
2453 | } |
|||||||||||
2454 | ||||||||||||
2455 | return [$data, $name]; |
|||||||||||
2456 | } |
|||||||||||
2457 | ||||||||||||
2458 | /** |
|||||||||||
2459 | * Detect file MIME Type by local path. |
|||||||||||
2460 | * |
|||||||||||
2461 | * @param string $path Local path |
|||||||||||
2462 | * @return string file MIME Type |
|||||||||||
2463 | * @author Naoki Sawada |
|||||||||||
2464 | */ |
|||||||||||
2465 | protected function detectMimeType($path) |
|||||||||||
2466 | { |
|||||||||||
2467 | static $type, $finfo, $volume; |
|||||||||||
2468 | if (! $type) { |
|||||||||||
2469 | $keys = array_keys($this->volumes); |
|||||||||||
2470 | $volume = $this->volumes[$keys[0]]; |
|||||||||||
2471 | ||||||||||||
2472 | if (class_exists('finfo', false)) { |
|||||||||||
2473 | $tmpFileInfo = explode(';', finfo_file(finfo_open(FILEINFO_MIME), __FILE__)); |
|||||||||||
2474 | } else { |
|||||||||||
2475 | $tmpFileInfo = false; |
|||||||||||
2476 | } |
|||||||||||
2477 | $regexp = '/text\/x\-(php|c\+\+)/'; |
|||||||||||
2478 | if ($tmpFileInfo && preg_match($regexp, array_shift($tmpFileInfo))) { |
|||||||||||
2479 | $type = 'finfo'; |
|||||||||||
2480 | $finfo = finfo_open(FILEINFO_MIME); |
|||||||||||
2481 | } elseif (function_exists('mime_content_type') |
|||||||||||
2482 | && preg_match($regexp, array_shift(explode(';', mime_content_type(__FILE__))))) { |
|||||||||||
0 ignored issues
–
show
|
||||||||||||
2483 | $type = 'mime_content_type'; |
|||||||||||
2484 | } elseif (function_exists('getimagesize')) { |
|||||||||||
2485 | $type = 'getimagesize'; |
|||||||||||
2486 | } else { |
|||||||||||
2487 | $type = 'none'; |
|||||||||||
2488 | } |
|||||||||||
2489 | } |
|||||||||||
2490 | ||||||||||||
2491 | $mime = ''; |
|||||||||||
2492 | if ($type === 'finfo') { |
|||||||||||
2493 | $mime = finfo_file($finfo, $path); |
|||||||||||
2494 | } elseif ($type === 'mime_content_type') { |
|||||||||||
2495 | $mime = mime_content_type($path); |
|||||||||||
2496 | } elseif ($type === 'getimagesize') { |
|||||||||||
2497 | if ($img = getimagesize($path)) { |
|||||||||||
2498 | $mime = $img['mime']; |
|||||||||||
2499 | } |
|||||||||||
2500 | } |
|||||||||||
2501 | ||||||||||||
2502 | if ($mime) { |
|||||||||||
2503 | $mime = explode(';', $mime); |
|||||||||||
2504 | $mime = trim($mime[0]); |
|||||||||||
2505 | ||||||||||||
2506 | if (in_array($mime, ['application/x-empty', 'inode/x-empty'])) { |
|||||||||||
2507 | // finfo return this mime for empty files |
|||||||||||
2508 | $mime = 'text/plain'; |
|||||||||||
2509 | } elseif ($mime == 'application/x-zip') { |
|||||||||||
2510 | // http://elrte.org/redmine/issues/163 |
|||||||||||
2511 | $mime = 'application/zip'; |
|||||||||||
2512 | } |
|||||||||||
2513 | } |
|||||||||||
2514 | ||||||||||||
2515 | return $mime ? $mime : 'unknown'; |
|||||||||||
2516 | } |
|||||||||||
2517 | ||||||||||||
2518 | /** |
|||||||||||
2519 | * Detect file type extension by local path. |
|||||||||||
2520 | * |
|||||||||||
2521 | * @param object $volume elFinderVolumeDriver instance |
|||||||||||
2522 | * @param string $path Local path |
|||||||||||
2523 | * @return string file type extension with dot |
|||||||||||
2524 | * @author Naoki Sawada |
|||||||||||
2525 | */ |
|||||||||||
2526 | protected function detectFileExtension($volume, $path) |
|||||||||||
2527 | { |
|||||||||||
2528 | $mime = $this->detectMimeType($path); |
|||||||||||
2529 | $ext = $mime !== 'unknown' ? $volume->getExtentionByMime($mime) : ''; |
|||||||||||
2530 | ||||||||||||
2531 | return $ext ? ('.'.$ext) : ''; |
|||||||||||
2532 | } |
|||||||||||
2533 | ||||||||||||
2534 | /** |
|||||||||||
2535 | * chmod. |
|||||||||||
2536 | * |
|||||||||||
2537 | * @param array command arguments |
|||||||||||
2538 | * @return array |
|||||||||||
2539 | * @author David Bartle |
|||||||||||
2540 | **/ |
|||||||||||
2541 | protected function chmod($args) |
|||||||||||
2542 | { |
|||||||||||
2543 | $targets = $args['targets']; |
|||||||||||
2544 | $mode = intval((string) $args['mode'], 8); |
|||||||||||
2545 | ||||||||||||
2546 | if (! is_array($targets)) { |
|||||||||||
2547 | $targets = [$targets]; |
|||||||||||
2548 | } |
|||||||||||
2549 | ||||||||||||
2550 | $result = []; |
|||||||||||
2551 | ||||||||||||
2552 | View Code Duplication | if (($volume = $this->volume($targets[0])) == false) { |
||||||||||
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
||||||||||||
2553 | $result['error'] = $this->error(self::ERROR_CONF_NO_VOL); |
|||||||||||
2554 | ||||||||||||
2555 | return $result; |
|||||||||||
2556 | } |
|||||||||||
2557 | ||||||||||||
2558 | $this->itemLock($targets); |
|||||||||||
2559 | ||||||||||||
2560 | $files = []; |
|||||||||||
2561 | $errors = []; |
|||||||||||
2562 | foreach ($targets as $target) { |
|||||||||||
2563 | self::extendTimeLimit(); |
|||||||||||
2564 | ||||||||||||
2565 | $file = $volume->chmod($target, $mode); |
|||||||||||
2566 | if ($file) { |
|||||||||||
2567 | $files = array_merge($files, is_array($file) ? $file : [$file]); |
|||||||||||
2568 | } else { |
|||||||||||
2569 | $errors = array_merge($errors, $volume->error()); |
|||||||||||
2570 | } |
|||||||||||
2571 | } |
|||||||||||
2572 | ||||||||||||
2573 | 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 ![]() |
||||||||||||
2574 | $result['changed'] = $files; |
|||||||||||
2575 | if ($errors) { |
|||||||||||
0 ignored issues
–
show
The expression
$errors of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using ![]() |
||||||||||||
2576 | $result['warning'] = $this->error($errors); |
|||||||||||
2577 | } |
|||||||||||
2578 | } else { |
|||||||||||
2579 | $result['error'] = $this->error($errors); |
|||||||||||
2580 | } |
|||||||||||
2581 | ||||||||||||
2582 | return $result; |
|||||||||||
2583 | } |
|||||||||||
2584 | ||||||||||||
2585 | /** |
|||||||||||
2586 | * Save uploaded files. |
|||||||||||
2587 | * |
|||||||||||
2588 | * @param array |
|||||||||||
2589 | * @return array |
|||||||||||
2590 | * @author Dmitry (dio) Levashov |
|||||||||||
2591 | **/ |
|||||||||||
2592 | protected function upload($args) |
|||||||||||
0 ignored issues
–
show
upload 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);
}
}
![]() |
||||||||||||
2593 | { |
|||||||||||
2594 | $ngReg = '/[\/\\?*:|"<>]/'; |
|||||||||||
2595 | $target = $args['target']; |
|||||||||||
2596 | $volume = $this->volume($target); |
|||||||||||
2597 | $files = isset($args['FILES']['upload']) && is_array($args['FILES']['upload']) ? $args['FILES']['upload'] : []; |
|||||||||||
2598 | $header = empty($args['html']) ? [] : ['header' => 'Content-Type: text/html; charset=utf-8']; |
|||||||||||
2599 | $result = array_merge(['added' => []], $header); |
|||||||||||
2600 | $paths = $args['upload_path'] ? $args['upload_path'] : []; |
|||||||||||
2601 | $chunk = $args['chunk'] ? $args['chunk'] : ''; |
|||||||||||
2602 | $cid = $args['cid'] ? (int) $args['cid'] : ''; |
|||||||||||
2603 | $mtimes = $args['mtime'] ? $args['mtime'] : []; |
|||||||||||
2604 | ||||||||||||
2605 | if (! $volume) { |
|||||||||||
2606 | return array_merge(['error' => $this->error(self::ERROR_UPLOAD, self::ERROR_TRGDIR_NOT_FOUND, '#'.$target)], $header); |
|||||||||||
2607 | } |
|||||||||||
2608 | ||||||||||||
2609 | // check $chunk |
|||||||||||
2610 | if (strpos($chunk, '/') !== false || strpos($chunk, '\\') !== false) { |
|||||||||||
2611 | return ['error' => $this->error(self::ERROR_UPLOAD)]; |
|||||||||||
2612 | } |
|||||||||||
2613 | ||||||||||||
2614 | if ($args['overwrite'] !== '') { |
|||||||||||
2615 | $volume->setUploadOverwrite($args['overwrite']); |
|||||||||||
2616 | } |
|||||||||||
2617 | ||||||||||||
2618 | $renames = $hashes = []; |
|||||||||||
2619 | $suffix = '~'; |
|||||||||||
2620 | if ($args['renames'] && is_array($args['renames'])) { |
|||||||||||
2621 | $renames = array_flip($args['renames']); |
|||||||||||
2622 | View Code Duplication | if (is_string($args['suffix']) && ! preg_match($ngReg, $args['suffix'])) { |
||||||||||
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
||||||||||||
2623 | $suffix = $args['suffix']; |
|||||||||||
2624 | } |
|||||||||||
2625 | } |
|||||||||||
2626 | if ($args['hashes'] && is_array($args['hashes'])) { |
|||||||||||
2627 | $hashes = array_flip($args['hashes']); |
|||||||||||
2628 | } |
|||||||||||
2629 | ||||||||||||
2630 | $this->itemLock($target); |
|||||||||||
2631 | ||||||||||||
2632 | // regist Shutdown function |
|||||||||||
2633 | $GLOBALS['elFinderTempFiles'] = []; |
|||||||||||
2634 | // if (version_compare(PHP_VERSION, '5.3.0', '>=')) { |
|||||||||||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
59% 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. ![]() |
||||||||||||
2635 | // $shutdownfunc = function(){ // <- Parse error on PHP < 5.3 ;-( |
|||||||||||
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. ![]() |
||||||||||||
2636 | // foreach(array_keys($GLOBALS['elFinderTempFiles']) as $f){ |
|||||||||||
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. ![]() |
||||||||||||
2637 | // unlink($f); |
|||||||||||
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. ![]() |
||||||||||||
2638 | // } |
|||||||||||
2639 | // }; |
|||||||||||
2640 | // } else { |
|||||||||||
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. ![]() |
||||||||||||
2641 | $shutdownfunc = create_function('', ' |
|||||||||||
0 ignored issues
–
show
The use of
create_function is highly discouraged, better use a closure.
// Instead of
$function = create_function('$a, $b', 'return $a + $b');
// Better use
$function = function($a, $b) { return $a + $b; }
![]() |
||||||||||||
2642 | foreach(array_keys($GLOBALS[\'elFinderTempFiles\']) as $f){ |
|||||||||||
2643 | is_file($f) && unlink($f); |
|||||||||||
2644 | } |
|||||||||||
2645 | '); |
|||||||||||
2646 | // } |
|||||||||||
2647 | register_shutdown_function($shutdownfunc); |
|||||||||||
2648 | ||||||||||||
2649 | // file extentions table by MIME |
|||||||||||
2650 | $extTable = array_flip(array_unique($volume->getMimeTable())); |
|||||||||||
2651 | ||||||||||||
2652 | if (empty($files)) { |
|||||||||||
2653 | if (isset($args['upload']) && is_array($args['upload']) && ($tempDir = $this->getTempDir($volume->getTempPath()))) { |
|||||||||||
2654 | $names = []; |
|||||||||||
2655 | foreach ($args['upload'] as $i => $url) { |
|||||||||||
2656 | // check chunked file upload commit |
|||||||||||
2657 | if ($chunk) { |
|||||||||||
2658 | if ($url === 'chunkfail' && $args['mimes'] === 'chunkfail') { |
|||||||||||
2659 | $this->checkChunkedFile(null, $chunk, $cid, $tempDir); |
|||||||||||
2660 | if (preg_match('/^(.+)(\.\d+_(\d+))\.part$/s', $chunk, $m)) { |
|||||||||||
2661 | $result['warning'] = $this->error(self::ERROR_UPLOAD_FILE, $m[1], self::ERROR_UPLOAD_TRANSFER); |
|||||||||||
2662 | } |
|||||||||||
2663 | ||||||||||||
2664 | return $result; |
|||||||||||
2665 | } else { |
|||||||||||
2666 | $tmpfname = $tempDir.'/'.$chunk; |
|||||||||||
2667 | $files['tmp_name'][$i] = $tmpfname; |
|||||||||||
2668 | $files['name'][$i] = $url; |
|||||||||||
2669 | $files['error'][$i] = 0; |
|||||||||||
2670 | $GLOBALS['elFinderTempFiles'][$tmpfname] = true; |
|||||||||||
2671 | break; |
|||||||||||
2672 | } |
|||||||||||
2673 | } |
|||||||||||
2674 | ||||||||||||
2675 | $tmpfname = $tempDir.DIRECTORY_SEPARATOR.'ELF_FATCH_'.md5($url.microtime(true)); |
|||||||||||
2676 | ||||||||||||
2677 | $_name = ''; |
|||||||||||
2678 | // check is data: |
|||||||||||
2679 | if (substr($url, 0, 5) === 'data:') { |
|||||||||||
2680 | list($data, $args['name'][$i]) = $this->parse_data_scheme($url, $extTable, $args); |
|||||||||||
2681 | } else { |
|||||||||||
2682 | $fp = fopen($tmpfname, 'wb'); |
|||||||||||
2683 | $data = $this->get_remote_contents($url, 30, 5, 'Mozilla/5.0', $fp); |
|||||||||||
2684 | $_name = preg_replace('~^.*?([^/#?]+)(?:\?.*)?(?:#.*)?$~', '$1', rawurldecode($url)); |
|||||||||||
2685 | // Check `Content-Disposition` response header |
|||||||||||
2686 | if ($data && ($headers = get_headers($url, true)) && ! empty($headers['Content-Disposition'])) { |
|||||||||||
2687 | if (preg_match('/filename\*?=(?:([a-zA-Z0-9_-]+?)\'\')?"?([a-z0-9_.~%-]+)"?/i', $headers['Content-Disposition'], $m)) { |
|||||||||||
2688 | $_name = rawurldecode($m[2]); |
|||||||||||
2689 | if ($m[1] && strtoupper($m[1]) !== 'UTF-8' && function_exists('mb_convert_encoding')) { |
|||||||||||
2690 | $_name = mb_convert_encoding($_name, 'UTF-8', $m[1]); |
|||||||||||
2691 | } |
|||||||||||
2692 | } |
|||||||||||
2693 | } |
|||||||||||
2694 | } |
|||||||||||
2695 | if ($data) { |
|||||||||||
2696 | if (isset($args['name'][$i])) { |
|||||||||||
2697 | $_name = $args['name'][$i]; |
|||||||||||
2698 | } |
|||||||||||
2699 | if ($_name) { |
|||||||||||
2700 | $_ext = ''; |
|||||||||||
2701 | if (preg_match('/(\.[a-z0-9]{1,7})$/', $_name, $_match)) { |
|||||||||||
2702 | $_ext = $_match[1]; |
|||||||||||
2703 | } |
|||||||||||
2704 | if ((is_resource($data) && fclose($data)) || file_put_contents($tmpfname, $data)) { |
|||||||||||
2705 | $GLOBALS['elFinderTempFiles'][$tmpfname] = true; |
|||||||||||
2706 | $_name = preg_replace($ngReg, '_', $_name); |
|||||||||||
2707 | list($_a, $_b) = array_pad(explode('.', $_name, 2), 2, ''); |
|||||||||||
2708 | if ($_b === '') { |
|||||||||||
2709 | if ($_ext) { |
|||||||||||
2710 | rename($tmpfname, $tmpfname.$_ext); |
|||||||||||
2711 | $tmpfname = $tmpfname.$_ext; |
|||||||||||
2712 | } |
|||||||||||
2713 | $_b = $this->detectFileExtension($volume, $tmpfname); |
|||||||||||
2714 | $_name = $_a.$_b; |
|||||||||||
2715 | } else { |
|||||||||||
2716 | $_b = '.'.$_b; |
|||||||||||
2717 | } |
|||||||||||
2718 | if (isset($names[$_name])) { |
|||||||||||
2719 | $_name = $_a.'_'.$names[$_name]++.$_b; |
|||||||||||
2720 | } else { |
|||||||||||
2721 | $names[$_name] = 1; |
|||||||||||
2722 | } |
|||||||||||
2723 | $files['tmp_name'][$i] = $tmpfname; |
|||||||||||
2724 | $files['name'][$i] = $_name; |
|||||||||||
2725 | $files['error'][$i] = 0; |
|||||||||||
2726 | // set to auto rename |
|||||||||||
2727 | $volume->setUploadOverwrite(false); |
|||||||||||
2728 | } else { |
|||||||||||
2729 | unlink($tmpfname); |
|||||||||||
2730 | } |
|||||||||||
2731 | } |
|||||||||||
2732 | } |
|||||||||||
2733 | } |
|||||||||||
2734 | } |
|||||||||||
2735 | if (empty($files)) { |
|||||||||||
2736 | return array_merge(['error' => $this->error(self::ERROR_UPLOAD, self::ERROR_UPLOAD_NO_FILES)], $header); |
|||||||||||
2737 | } |
|||||||||||
2738 | } |
|||||||||||
2739 | ||||||||||||
2740 | $addedDirs = []; |
|||||||||||
2741 | foreach ($files['name'] as $i => $name) { |
|||||||||||
2742 | if (($error = $files['error'][$i]) > 0) { |
|||||||||||
2743 | $result['warning'] = $this->error(self::ERROR_UPLOAD_FILE, $name, $error == UPLOAD_ERR_INI_SIZE || $error == UPLOAD_ERR_FORM_SIZE ? self::ERROR_UPLOAD_FILE_SIZE : self::ERROR_UPLOAD_TRANSFER); |
|||||||||||
2744 | $this->uploadDebug = 'Upload error code: '.$error; |
|||||||||||
2745 | break; |
|||||||||||
2746 | } |
|||||||||||
2747 | ||||||||||||
2748 | $tmpname = $files['tmp_name'][$i]; |
|||||||||||
2749 | $thash = ($paths && isset($paths[$i])) ? $paths[$i] : ''; |
|||||||||||
2750 | $mtime = isset($mtimes[$i]) ? $mtimes[$i] : 0; |
|||||||||||
2751 | if ($name === 'blob') { |
|||||||||||
2752 | if ($chunk) { |
|||||||||||
2753 | if ($tempDir = $this->getTempDir($volume->getTempPath())) { |
|||||||||||
2754 | list($tmpname, $name) = $this->checkChunkedFile($tmpname, $chunk, $cid, $tempDir, $volume); |
|||||||||||
2755 | if ($tmpname) { |
|||||||||||
2756 | if ($name === false) { |
|||||||||||
2757 | preg_match('/^(.+)(\.\d+_(\d+))\.part$/s', $chunk, $m); |
|||||||||||
2758 | $result['error'] = $this->error(self::ERROR_UPLOAD_FILE, $m[1], $tmpname); |
|||||||||||
2759 | $result['_chunkfailure'] = true; |
|||||||||||
2760 | $this->uploadDebug = 'Upload error: '.$tmpname; |
|||||||||||
2761 | } elseif ($name) { |
|||||||||||
2762 | $result['_chunkmerged'] = basename($tmpname); |
|||||||||||
2763 | $result['_name'] = $name; |
|||||||||||
2764 | $result['_mtime'] = $mtime; |
|||||||||||
2765 | } |
|||||||||||
2766 | } |
|||||||||||
2767 | } else { |
|||||||||||
2768 | $result['error'] = $this->error(self::ERROR_UPLOAD_FILE, $chunk, self::ERROR_UPLOAD_TRANSFER); |
|||||||||||
2769 | $this->uploadDebug = 'Upload error: unable open tmp file'; |
|||||||||||
2770 | } |
|||||||||||
2771 | ||||||||||||
2772 | return $result; |
|||||||||||
2773 | } else { |
|||||||||||
2774 | // for form clipboard with Google Chrome or Opera |
|||||||||||
2775 | $name = 'image.png'; |
|||||||||||
2776 | } |
|||||||||||
2777 | } |
|||||||||||
2778 | ||||||||||||
2779 | // Set name if name eq 'image.png' and $args has 'name' array, e.g. clipboard data |
|||||||||||
2780 | if (strtolower(substr($name, 0, 5)) === 'image' && is_array($args['name']) && isset($args['name'][$i])) { |
|||||||||||
2781 | $type = $files['type'][$i]; |
|||||||||||
2782 | $name = $args['name'][$i]; |
|||||||||||
2783 | $ext = isset($extTable[$type]) ? '.'.$extTable[$type] : ''; |
|||||||||||
2784 | if ($ext) { |
|||||||||||
2785 | $name = preg_replace('/\.[^.]*$/', '', $name); |
|||||||||||
2786 | } |
|||||||||||
2787 | $name .= $ext; |
|||||||||||
2788 | } |
|||||||||||
2789 | ||||||||||||
2790 | // do hook function 'upload.presave' |
|||||||||||
2791 | if (! empty($this->listeners['upload.presave'])) { |
|||||||||||
2792 | foreach ($this->listeners['upload.presave'] as $handler) { |
|||||||||||
2793 | call_user_func_array($handler, [&$thash, &$name, $tmpname, $this, $volume]); |
|||||||||||
2794 | } |
|||||||||||
2795 | } |
|||||||||||
2796 | ||||||||||||
2797 | if ($mtime) { |
|||||||||||
2798 | // for keep timestamp option in the LocalFileSystem volume |
|||||||||||
2799 | touch($tmpname, $mtime); |
|||||||||||
2800 | } |
|||||||||||
2801 | ||||||||||||
2802 | if (($fp = fopen($tmpname, 'rb')) == false) { |
|||||||||||
2803 | $result['warning'] = $this->error(self::ERROR_UPLOAD_FILE, $name, self::ERROR_UPLOAD_TRANSFER); |
|||||||||||
2804 | $this->uploadDebug = 'Upload error: unable open tmp file'; |
|||||||||||
2805 | View Code Duplication | if (! is_uploaded_file($tmpname)) { |
||||||||||
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
||||||||||||
2806 | if (unlink($tmpname)) { |
|||||||||||
2807 | unset($GLOBALS['elFinderTempFiles'][$tmpfname]); |
|||||||||||
2808 | } |
|||||||||||
2809 | continue; |
|||||||||||
2810 | } |
|||||||||||
2811 | break; |
|||||||||||
2812 | } |
|||||||||||
2813 | $rnres = []; |
|||||||||||
2814 | if ($thash !== '' && $thash !== $target) { |
|||||||||||
2815 | if ($dir = $volume->dir($thash)) { |
|||||||||||
2816 | $_target = $thash; |
|||||||||||
2817 | if (! isset($addedDirs[$thash])) { |
|||||||||||
2818 | $addedDirs[$thash] = true; |
|||||||||||
2819 | $result['added'][] = $dir; |
|||||||||||
2820 | } |
|||||||||||
2821 | } else { |
|||||||||||
2822 | $result['error'] = $this->error(self::ERROR_UPLOAD, self::ERROR_TRGDIR_NOT_FOUND, 'hash@'.$thash); |
|||||||||||
2823 | break; |
|||||||||||
2824 | } |
|||||||||||
2825 | } else { |
|||||||||||
2826 | $_target = $target; |
|||||||||||
2827 | // file rename for backup |
|||||||||||
2828 | if (isset($renames[$name])) { |
|||||||||||
2829 | $dir = $volume->realpath($_target); |
|||||||||||
2830 | if (isset($hashes[$name])) { |
|||||||||||
2831 | $hash = $hashes[$name]; |
|||||||||||
2832 | } else { |
|||||||||||
2833 | $hash = $volume->getHash($dir, $name); |
|||||||||||
2834 | } |
|||||||||||
2835 | $rnres = $this->rename(['target' => $hash, 'name' => $volume->uniqueName($dir, $name, $suffix, true, 0)]); |
|||||||||||
2836 | if (! empty($rnres['error'])) { |
|||||||||||
2837 | $result['warning'] = $rnres['error']; |
|||||||||||
2838 | break; |
|||||||||||
2839 | } |
|||||||||||
2840 | } |
|||||||||||
2841 | } |
|||||||||||
2842 | if (! $_target || ($file = $volume->upload($fp, $_target, $name, $tmpname, $hashes)) === false) { |
|||||||||||
2843 | $result['warning'] = $this->error(self::ERROR_UPLOAD_FILE, $name, $volume->error()); |
|||||||||||
2844 | fclose($fp); |
|||||||||||
2845 | View Code Duplication | if (! is_uploaded_file($tmpname)) { |
||||||||||
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
||||||||||||
2846 | if (unlink($tmpname)) { |
|||||||||||
2847 | unset($GLOBALS['elFinderTempFiles'][$tmpname]); |
|||||||||||
2848 | } |
|||||||||||
2849 | continue; |
|||||||||||
2850 | } |
|||||||||||
2851 | break; |
|||||||||||
2852 | } |
|||||||||||
2853 | ||||||||||||
2854 | is_resource($fp) && fclose($fp); |
|||||||||||
2855 | if (! is_uploaded_file($tmpname)) { |
|||||||||||
2856 | clearstatcache(); |
|||||||||||
2857 | if (! is_file($tmpname) || unlink($tmpname)) { |
|||||||||||
2858 | unset($GLOBALS['elFinderTempFiles'][$tmpname]); |
|||||||||||
2859 | } |
|||||||||||
2860 | } |
|||||||||||
2861 | $result['added'][] = $file; |
|||||||||||
2862 | if ($rnres) { |
|||||||||||
0 ignored issues
–
show
The expression
$rnres of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using ![]() |
||||||||||||
2863 | $result = array_merge_recursive($result, $rnres); |
|||||||||||
2864 | } |
|||||||||||
2865 | } |
|||||||||||
2866 | if ($GLOBALS['elFinderTempFiles']) { |
|||||||||||
2867 | foreach (array_keys($GLOBALS['elFinderTempFiles']) as $_temp) { |
|||||||||||
2868 | unlink($_temp); |
|||||||||||
2869 | } |
|||||||||||
2870 | } |
|||||||||||
2871 | $result['removed'] = $volume->removed(); |
|||||||||||
2872 | ||||||||||||
2873 | View Code Duplication | if (! empty($args['node'])) { |
||||||||||
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
||||||||||||
2874 | $result['callback'] = [ |
|||||||||||
2875 | 'node' => $args['node'], |
|||||||||||
2876 | 'bind' => 'upload', |
|||||||||||
2877 | ]; |
|||||||||||
2878 | } |
|||||||||||
2879 | ||||||||||||
2880 | return $result; |
|||||||||||
2881 | } |
|||||||||||
2882 | ||||||||||||
2883 | /** |
|||||||||||
2884 | * Copy/move files into new destination. |
|||||||||||
2885 | * |
|||||||||||
2886 | * @param array command arguments |
|||||||||||
2887 | * @return array |
|||||||||||
2888 | * @author Dmitry (dio) Levashov |
|||||||||||
2889 | **/ |
|||||||||||
2890 | protected function paste($args) |
|||||||||||
2891 | { |
|||||||||||
2892 | $dst = $args['dst']; |
|||||||||||
2893 | $targets = is_array($args['targets']) ? $args['targets'] : []; |
|||||||||||
2894 | $cut = ! empty($args['cut']); |
|||||||||||
2895 | $error = $cut ? self::ERROR_MOVE : self::ERROR_COPY; |
|||||||||||
2896 | $result = ['changed' => [], 'added' => [], 'removed' => [], 'warning' => []]; |
|||||||||||
2897 | ||||||||||||
2898 | if (($dstVolume = $this->volume($dst)) == false) { |
|||||||||||
2899 | return ['error' => $this->error($error, '#'.$targets[0], self::ERROR_TRGDIR_NOT_FOUND, '#'.$dst)]; |
|||||||||||
2900 | } |
|||||||||||
2901 | ||||||||||||
2902 | $this->itemLock($dst); |
|||||||||||
2903 | ||||||||||||
2904 | $hashes = $renames = []; |
|||||||||||
2905 | $suffix = '~'; |
|||||||||||
2906 | if (! empty($args['renames'])) { |
|||||||||||
2907 | $renames = array_flip($args['renames']); |
|||||||||||
2908 | View Code Duplication | if (is_string($args['suffix']) && ! preg_match('/[\/\\?*:|"<>]/', $args['suffix'])) { |
||||||||||
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
||||||||||||
2909 | $suffix = $args['suffix']; |
|||||||||||
2910 | } |
|||||||||||
2911 | } |
|||||||||||
2912 | if (! empty($args['hashes'])) { |
|||||||||||
2913 | $hashes = array_flip($args['hashes']); |
|||||||||||
2914 | } |
|||||||||||
2915 | ||||||||||||
2916 | foreach ($targets as $target) { |
|||||||||||
2917 | self::extendTimeLimit(); |
|||||||||||
2918 | ||||||||||||
2919 | if (($srcVolume = $this->volume($target)) == false) { |
|||||||||||
2920 | $result['warning'] = array_merge($result['warning'], $this->error($error, '#'.$target, self::ERROR_FILE_NOT_FOUND)); |
|||||||||||
2921 | continue; |
|||||||||||
2922 | } |
|||||||||||
2923 | ||||||||||||
2924 | $rnres = []; |
|||||||||||
2925 | if ($renames) { |
|||||||||||
0 ignored issues
–
show
The expression
$renames of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using ![]() |
||||||||||||
2926 | $file = $srcVolume->file($target); |
|||||||||||
2927 | if (isset($renames[$file['name']])) { |
|||||||||||
2928 | $dir = $dstVolume->realpath($dst); |
|||||||||||
2929 | if (isset($hashes[$file['name']])) { |
|||||||||||
2930 | $hash = $hashes[$file['name']]; |
|||||||||||
2931 | } else { |
|||||||||||
2932 | $hash = $dstVolume->getHash($dir, $file['name']); |
|||||||||||
2933 | } |
|||||||||||
2934 | $rnres = $this->rename(['target' => $hash, 'name' => $dstVolume->uniqueName($dir, $file['name'], $suffix, true, 0)]); |
|||||||||||
2935 | if (! empty($rnres['error'])) { |
|||||||||||
2936 | $result['warning'] = array_merge($result['warning'], $rnres['error']); |
|||||||||||
2937 | continue; |
|||||||||||
2938 | } |
|||||||||||
2939 | } |
|||||||||||
2940 | } |
|||||||||||
2941 | ||||||||||||
2942 | if ($cut && $this->itemLocked($target)) { |
|||||||||||
2943 | $rm = $srcVolume->file($target); |
|||||||||||
2944 | $result['warning'] = array_merge($result['warning'], $this->error(self::ERROR_LOCKED, $rm['name'])); |
|||||||||||
2945 | continue; |
|||||||||||
2946 | } |
|||||||||||
2947 | ||||||||||||
2948 | if (($file = $dstVolume->paste($srcVolume, $target, $dst, $cut, $hashes)) == false) { |
|||||||||||
2949 | $result['warning'] = array_merge($result['warning'], $this->error($dstVolume->error())); |
|||||||||||
2950 | continue; |
|||||||||||
2951 | } |
|||||||||||
2952 | ||||||||||||
2953 | $dirChange = ! empty($file['dirChange']); |
|||||||||||
2954 | unset($file['dirChange']); |
|||||||||||
2955 | if ($dirChange) { |
|||||||||||
2956 | $result['changed'][] = $file; |
|||||||||||
2957 | } else { |
|||||||||||
2958 | $result['added'][] = $file; |
|||||||||||
2959 | } |
|||||||||||
2960 | if ($rnres) { |
|||||||||||
0 ignored issues
–
show
The expression
$rnres of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using ![]() |
||||||||||||
2961 | $result = array_merge_recursive($result, $rnres); |
|||||||||||
2962 | } |
|||||||||||
2963 | } |
|||||||||||
2964 | if (count($result['warning']) < 1) { |
|||||||||||
2965 | unset($result['warning']); |
|||||||||||
2966 | } |
|||||||||||
2967 | ||||||||||||
2968 | return $result; |
|||||||||||
2969 | } |
|||||||||||
2970 | ||||||||||||
2971 | /** |
|||||||||||
2972 | * Return file content. |
|||||||||||
2973 | * |
|||||||||||
2974 | * @param array $args command arguments |
|||||||||||
2975 | * @return array |
|||||||||||
2976 | * @author Dmitry (dio) Levashov |
|||||||||||
2977 | **/ |
|||||||||||
2978 | protected function get($args) |
|||||||||||
2979 | { |
|||||||||||
2980 | $target = $args['target']; |
|||||||||||
2981 | $volume = $this->volume($target); |
|||||||||||
2982 | $enc = false; |
|||||||||||
2983 | ||||||||||||
2984 | if (! $volume || ($file = $volume->file($target)) == false) { |
|||||||||||
2985 | return ['error' => $this->error(self::ERROR_OPEN, '#'.$target, self::ERROR_FILE_NOT_FOUND)]; |
|||||||||||
2986 | } |
|||||||||||
2987 | ||||||||||||
2988 | View Code Duplication | if (($content = $volume->getContents($target)) === false) { |
||||||||||
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
||||||||||||
2989 | return ['error' => $this->error(self::ERROR_OPEN, $volume->path($target), $volume->error())]; |
|||||||||||
2990 | } |
|||||||||||
2991 | ||||||||||||
2992 | $mime = isset($file['mime']) ? $file['mime'] : ''; |
|||||||||||
2993 | if ($mime && strtolower(substr($mime, 0, 4)) === 'text') { |
|||||||||||
2994 | $enc = ''; |
|||||||||||
2995 | if ($content !== '') { |
|||||||||||
2996 | if (! $args['conv'] || $args['conv'] == '1') { |
|||||||||||
2997 | // detect encoding |
|||||||||||
2998 | if (function_exists('mb_detect_encoding')) { |
|||||||||||
2999 | if ($enc = mb_detect_encoding($content, mb_detect_order(), true)) { |
|||||||||||
3000 | $encu = strtoupper($enc); |
|||||||||||
3001 | if ($encu === 'UTF-8' || $encu === 'ASCII') { |
|||||||||||
3002 | $enc = ''; |
|||||||||||
3003 | } |
|||||||||||
3004 | } else { |
|||||||||||
3005 | $enc = 'unknown'; |
|||||||||||
3006 | } |
|||||||||||
3007 | } elseif (! preg_match('//u', $content)) { |
|||||||||||
3008 | $enc = 'unknown'; |
|||||||||||
3009 | } |
|||||||||||
3010 | if ($enc === 'unknown') { |
|||||||||||
3011 | $enc = $volume->getOption('encoding'); |
|||||||||||
3012 | if (! $enc || strtoupper($enc) === 'UTF-8') { |
|||||||||||
3013 | $enc = 'unknown'; |
|||||||||||
3014 | } |
|||||||||||
3015 | } |
|||||||||||
3016 | if ($enc && $enc !== 'unknown') { |
|||||||||||
3017 | $utf8 = iconv($enc, 'UTF-8', $content); |
|||||||||||
3018 | if ($utf8 === false && function_exists('mb_convert_encoding')) { |
|||||||||||
3019 | $utf8 = mb_convert_encoding($content, 'UTF-8', $enc); |
|||||||||||
3020 | if (mb_convert_encoding($utf8, $enc, 'UTF-8') !== $content) { |
|||||||||||
3021 | $enc = 'unknown'; |
|||||||||||
3022 | } |
|||||||||||
3023 | } else { |
|||||||||||
3024 | if ($utf8 === false || iconv('UTF-8', $enc, $utf8) !== $content) { |
|||||||||||
3025 | $enc = 'unknown'; |
|||||||||||
3026 | } |
|||||||||||
3027 | } |
|||||||||||
3028 | if ($enc !== 'unknown') { |
|||||||||||
3029 | $content = $utf8; |
|||||||||||
3030 | } |
|||||||||||
3031 | } |
|||||||||||
3032 | if ($enc) { |
|||||||||||
3033 | if ($args['conv'] == '1') { |
|||||||||||
3034 | $args['conv'] = ''; |
|||||||||||
3035 | if ($enc === 'unknown') { |
|||||||||||
3036 | $content = false; |
|||||||||||
3037 | } |
|||||||||||
3038 | } elseif ($enc === 'unknown') { |
|||||||||||
3039 | return ['doconv' => $enc]; |
|||||||||||
3040 | } |
|||||||||||
3041 | } |
|||||||||||
3042 | } |
|||||||||||
3043 | if ($args['conv']) { |
|||||||||||
3044 | $enc = $args['conv']; |
|||||||||||
3045 | if (strtoupper($enc) !== 'UTF-8') { |
|||||||||||
3046 | $_content = $content; |
|||||||||||
3047 | $content = iconv($enc, 'UTF-8', $content); |
|||||||||||
3048 | if ($content === false && function_exists('mb_convert_encoding')) { |
|||||||||||
3049 | $content = mb_convert_encoding($_content, 'UTF-8', $enc); |
|||||||||||
3050 | } |
|||||||||||
3051 | } else { |
|||||||||||
3052 | $enc = ''; |
|||||||||||
3053 | } |
|||||||||||
3054 | } |
|||||||||||
3055 | } |
|||||||||||
3056 | } else { |
|||||||||||
3057 | $content = 'data:'.($mime ? $mime : 'application/octet-stream').';base64,'.base64_encode($content); |
|||||||||||
3058 | } |
|||||||||||
3059 | ||||||||||||
3060 | if ($enc !== false) { |
|||||||||||
3061 | if ($content !== false) { |
|||||||||||
3062 | $json = json_encode($content); |
|||||||||||
3063 | } |
|||||||||||
3064 | if ($content === false || $json === false || strlen($json) < strlen($content)) { |
|||||||||||
0 ignored issues
–
show
The variable
$json 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
![]() |
||||||||||||
3065 | return ['error' => $this->error(self::ERROR_CONV_UTF8, self::ERROR_NOT_UTF8_CONTENT, $volume->path($target))]; |
|||||||||||
3066 | } |
|||||||||||
3067 | } |
|||||||||||
3068 | ||||||||||||
3069 | $res = ['content' => $content]; |
|||||||||||
3070 | if ($enc) { |
|||||||||||
3071 | $res['encoding'] = $enc; |
|||||||||||
3072 | } |
|||||||||||
3073 | ||||||||||||
3074 | return $res; |
|||||||||||
3075 | } |
|||||||||||
3076 | ||||||||||||
3077 | /** |
|||||||||||
3078 | * Save content into text file. |
|||||||||||
3079 | * |
|||||||||||
3080 | * @param $args |
|||||||||||
3081 | * @return array |
|||||||||||
3082 | * @author Dmitry (dio) Levashov |
|||||||||||
3083 | */ |
|||||||||||
3084 | protected function put($args) |
|||||||||||
3085 | { |
|||||||||||
3086 | $target = $args['target']; |
|||||||||||
3087 | ||||||||||||
3088 | View Code Duplication | if (($volume = $this->volume($target)) == false |
||||||||||
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
||||||||||||
3089 | || ($file = $volume->file($target)) == false) { |
|||||||||||
3090 | return ['error' => $this->error(self::ERROR_SAVE, '#'.$target, self::ERROR_FILE_NOT_FOUND)]; |
|||||||||||
3091 | } |
|||||||||||
3092 | ||||||||||||
3093 | $this->itemLock($target); |
|||||||||||
3094 | ||||||||||||
3095 | if (preg_match('~^https?://~i', $args['content'])) { |
|||||||||||
3096 | $fp = $this->get_remote_contents($args['content'], 30, 5, 'Mozilla/5.0', tmpfile()); |
|||||||||||
3097 | if (! $fp) { |
|||||||||||
3098 | return ['error' => self::ERROR_SAVE, $args['content'], self::ERROR_FILE_NOT_FOUND]; |
|||||||||||
3099 | } |
|||||||||||
3100 | $fmeta = stream_get_meta_data($fp); |
|||||||||||
3101 | $mime = $this->detectMimeType($fmeta['uri']); |
|||||||||||
3102 | $args['content'] = 'data:'.$mime.';base64,'.base64_encode(file_get_contents($fmeta['uri'])); |
|||||||||||
3103 | } elseif (! empty($args['encoding'])) { |
|||||||||||
3104 | $content = iconv('UTF-8', $args['encoding'], $args['content']); |
|||||||||||
3105 | if ($content === false && function_exists('mb_detect_encoding')) { |
|||||||||||
3106 | $content = mb_convert_encoding($args['content'], $args['encoding'], 'UTF-8'); |
|||||||||||
3107 | } |
|||||||||||
3108 | if ($content !== false) { |
|||||||||||
3109 | $args['content'] = $content; |
|||||||||||
3110 | } |
|||||||||||
3111 | } |
|||||||||||
3112 | View Code Duplication | if (($file = $volume->putContents($target, $args['content'])) == false) { |
||||||||||
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
||||||||||||
3113 | return ['error' => $this->error(self::ERROR_SAVE, $volume->path($target), $volume->error())]; |
|||||||||||
3114 | } |
|||||||||||
3115 | ||||||||||||
3116 | return ['changed' => [$file]]; |
|||||||||||
3117 | } |
|||||||||||
3118 | ||||||||||||
3119 | /** |
|||||||||||
3120 | * Extract files from archive. |
|||||||||||
3121 | * |
|||||||||||
3122 | * @param array $args command arguments |
|||||||||||
3123 | * @return array |
|||||||||||
3124 | * @author Dmitry (dio) Levashov, |
|||||||||||
3125 | * @author Alexey Sukhotin |
|||||||||||
3126 | **/ |
|||||||||||
3127 | protected function extract($args) |
|||||||||||
3128 | { |
|||||||||||
3129 | $target = $args['target']; |
|||||||||||
3130 | $mimes = ! empty($args['mimes']) && is_array($args['mimes']) ? $args['mimes'] : []; |
|||||||||||
0 ignored issues
–
show
$mimes 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 ![]() |
||||||||||||
3131 | $error = [self::ERROR_EXTRACT, '#'.$target]; |
|||||||||||
0 ignored issues
–
show
$error 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 ![]() |
||||||||||||
3132 | $makedir = isset($args['makedir']) ? (bool) $args['makedir'] : null; |
|||||||||||
3133 | ||||||||||||
3134 | View Code Duplication | if (($volume = $this->volume($target)) == false |
||||||||||
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
||||||||||||
3135 | || ($file = $volume->file($target)) == false) { |
|||||||||||
3136 | return ['error' => $this->error(self::ERROR_EXTRACT, '#'.$target, self::ERROR_FILE_NOT_FOUND)]; |
|||||||||||
3137 | } |
|||||||||||
3138 | ||||||||||||
3139 | $res = []; |
|||||||||||
3140 | if ($file = $volume->extract($target, $makedir)) { |
|||||||||||
3141 | $res['added'] = isset($file['read']) ? [$file] : $file; |
|||||||||||
3142 | if ($err = $volume->error()) { |
|||||||||||
3143 | $res['warning'] = $err; |
|||||||||||
3144 | } |
|||||||||||
3145 | } else { |
|||||||||||
3146 | $res['error'] = $this->error(self::ERROR_EXTRACT, $volume->path($target), $volume->error()); |
|||||||||||
3147 | } |
|||||||||||
3148 | ||||||||||||
3149 | return $res; |
|||||||||||
3150 | } |
|||||||||||
3151 | ||||||||||||
3152 | /** |
|||||||||||
3153 | * Create archive. |
|||||||||||
3154 | * |
|||||||||||
3155 | * @param array $args command arguments |
|||||||||||
3156 | * @return array |
|||||||||||
3157 | * @author Dmitry (dio) Levashov, |
|||||||||||
3158 | * @author Alexey Sukhotin |
|||||||||||
3159 | **/ |
|||||||||||
3160 | protected function archive($args) |
|||||||||||
3161 | { |
|||||||||||
3162 | $type = $args['type']; |
|||||||||||
0 ignored issues
–
show
$type 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 ![]() |
||||||||||||
3163 | $targets = isset($args['targets']) && is_array($args['targets']) ? $args['targets'] : []; |
|||||||||||
3164 | $name = isset($args['name']) ? $args['name'] : ''; |
|||||||||||
3165 | ||||||||||||
3166 | View Code Duplication | if (($volume = $this->volume($targets[0])) == false) { |
||||||||||
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
||||||||||||
3167 | return $this->error(self::ERROR_ARCHIVE, self::ERROR_TRGDIR_NOT_FOUND); |
|||||||||||
3168 | } |
|||||||||||
3169 | ||||||||||||
3170 | foreach ($targets as $target) { |
|||||||||||
3171 | $this->itemLock($target); |
|||||||||||
3172 | } |
|||||||||||
3173 | ||||||||||||
3174 | return ($file = $volume->archive($targets, $args['type'], $name)) |
|||||||||||
3175 | ? ['added' => [$file]] |
|||||||||||
3176 | : ['error' => $this->error(self::ERROR_ARCHIVE, $volume->error())]; |
|||||||||||
3177 | } |
|||||||||||
3178 | ||||||||||||
3179 | /** |
|||||||||||
3180 | * Search files. |
|||||||||||
3181 | * |
|||||||||||
3182 | * @param array $args command arguments |
|||||||||||
3183 | * @return array |
|||||||||||
3184 | * @author Dmitry Levashov |
|||||||||||
3185 | **/ |
|||||||||||
3186 | protected function search($args) |
|||||||||||
3187 | { |
|||||||||||
3188 | $q = trim($args['q']); |
|||||||||||
3189 | $mimes = ! empty($args['mimes']) && is_array($args['mimes']) ? $args['mimes'] : []; |
|||||||||||
3190 | $target = ! empty($args['target']) ? $args['target'] : null; |
|||||||||||
3191 | $result = []; |
|||||||||||
3192 | $errors = []; |
|||||||||||
3193 | ||||||||||||
3194 | if ($target) { |
|||||||||||
3195 | View Code Duplication | if ($volume = $this->volume($target)) { |
||||||||||
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
||||||||||||
3196 | $result = $volume->search($q, $mimes, $target); |
|||||||||||
3197 | $errors = array_merge($errors, $volume->error()); |
|||||||||||
3198 | } |
|||||||||||
3199 | View Code Duplication | } else { |
||||||||||
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
||||||||||||
3200 | foreach ($this->volumes as $volume) { |
|||||||||||
3201 | $result = array_merge($result, $volume->search($q, $mimes)); |
|||||||||||
3202 | $errors = array_merge($errors, $volume->error()); |
|||||||||||
3203 | } |
|||||||||||
3204 | } |
|||||||||||
3205 | ||||||||||||
3206 | $result = ['files' => $result]; |
|||||||||||
3207 | if ($errors) { |
|||||||||||
0 ignored issues
–
show
The expression
$errors of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using ![]() |
||||||||||||
3208 | $result['warning'] = $errors; |
|||||||||||
3209 | } |
|||||||||||
3210 | ||||||||||||
3211 | return $result; |
|||||||||||
3212 | } |
|||||||||||
3213 | ||||||||||||
3214 | /** |
|||||||||||
3215 | * Return file info (used by client "places" ui). |
|||||||||||
3216 | * |
|||||||||||
3217 | * @param array $args command arguments |
|||||||||||
3218 | * @return array |
|||||||||||
3219 | * @author Dmitry Levashov |
|||||||||||
3220 | **/ |
|||||||||||
3221 | protected function info($args) |
|||||||||||
3222 | { |
|||||||||||
3223 | $files = []; |
|||||||||||
3224 | $sleep = 0; |
|||||||||||
0 ignored issues
–
show
$sleep is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
||||||||||||
3225 | $compare = null; |
|||||||||||
3226 | // long polling mode |
|||||||||||
3227 | if ($args['compare'] && count($args['targets']) === 1) { |
|||||||||||
3228 | $compare = intval($args['compare']); |
|||||||||||
3229 | $hash = $args['targets'][0]; |
|||||||||||
3230 | if ($volume = $this->volume($hash)) { |
|||||||||||
3231 | $standby = (int) $volume->getOption('plStandby'); |
|||||||||||
3232 | $_compare = false; |
|||||||||||
3233 | if (($syncCheckFunc = $volume->getOption('syncCheckFunc')) && is_callable($syncCheckFunc)) { |
|||||||||||
3234 | $_compare = call_user_func_array($syncCheckFunc, [$volume->realpath($hash), $standby, $compare, $volume, $this]); |
|||||||||||
3235 | } |
|||||||||||
3236 | if ($_compare !== false) { |
|||||||||||
3237 | $compare = $_compare; |
|||||||||||
3238 | } else { |
|||||||||||
3239 | $sleep = max(1, (int) $volume->getOption('tsPlSleep')); |
|||||||||||
3240 | $limit = max(1, $standby / $sleep) + 1; |
|||||||||||
3241 | do { |
|||||||||||
3242 | self::extendTimeLimit(30 + $sleep); |
|||||||||||
3243 | $volume->clearstatcache(); |
|||||||||||
3244 | if (($info = $volume->file($hash)) != false) { |
|||||||||||
3245 | if ($info['ts'] != $compare) { |
|||||||||||
3246 | $compare = $info['ts']; |
|||||||||||
3247 | break; |
|||||||||||
3248 | } |
|||||||||||
3249 | } else { |
|||||||||||
3250 | $compare = 0; |
|||||||||||
3251 | break; |
|||||||||||
3252 | } |
|||||||||||
3253 | if (--$limit) { |
|||||||||||
3254 | sleep($sleep); |
|||||||||||
3255 | } |
|||||||||||
3256 | } while ($limit); |
|||||||||||
3257 | } |
|||||||||||
3258 | } |
|||||||||||
3259 | } else { |
|||||||||||
3260 | foreach ($args['targets'] as $hash) { |
|||||||||||
3261 | if (($volume = $this->volume($hash)) != false |
|||||||||||
3262 | && ($info = $volume->file($hash)) != false) { |
|||||||||||
3263 | $info['path'] = $volume->path($hash); |
|||||||||||
3264 | $files[] = $info; |
|||||||||||
3265 | } |
|||||||||||
3266 | } |
|||||||||||
3267 | } |
|||||||||||
3268 | ||||||||||||
3269 | $result = ['files' => $files]; |
|||||||||||
3270 | if (! is_null($compare)) { |
|||||||||||
3271 | $result['compare'] = strval($compare); |
|||||||||||
3272 | } |
|||||||||||
3273 | ||||||||||||
3274 | return $result; |
|||||||||||
3275 | } |
|||||||||||
3276 | ||||||||||||
3277 | /** |
|||||||||||
3278 | * Return image dimensions. |
|||||||||||
3279 | * |
|||||||||||
3280 | * @param array $args command arguments |
|||||||||||
3281 | * @return array |
|||||||||||
3282 | * @author Dmitry (dio) Levashov |
|||||||||||
3283 | **/ |
|||||||||||
3284 | protected function dim($args) |
|||||||||||
3285 | { |
|||||||||||
3286 | $target = $args['target']; |
|||||||||||
3287 | ||||||||||||
3288 | if (($volume = $this->volume($target)) != false) { |
|||||||||||
3289 | $dim = $volume->dimensions($target); |
|||||||||||
3290 | ||||||||||||
3291 | return $dim ? ['dim' => $dim] : []; |
|||||||||||
3292 | } |
|||||||||||
3293 | ||||||||||||
3294 | return []; |
|||||||||||
3295 | } |
|||||||||||
3296 | ||||||||||||
3297 | /** |
|||||||||||
3298 | * Resize image. |
|||||||||||
3299 | * |
|||||||||||
3300 | * @param array command arguments |
|||||||||||
3301 | * @return array |
|||||||||||
3302 | * @author Dmitry (dio) Levashov |
|||||||||||
3303 | * @author Alexey Sukhotin |
|||||||||||
3304 | **/ |
|||||||||||
3305 | protected function resize($args) |
|||||||||||
3306 | { |
|||||||||||
3307 | $target = $args['target']; |
|||||||||||
3308 | $width = (int) $args['width']; |
|||||||||||
3309 | $height = (int) $args['height']; |
|||||||||||
3310 | $x = (int) $args['x']; |
|||||||||||
3311 | $y = (int) $args['y']; |
|||||||||||
3312 | $mode = $args['mode']; |
|||||||||||
3313 | $bg = $args['bg']; |
|||||||||||
3314 | $degree = (int) $args['degree']; |
|||||||||||
3315 | $quality = (int) $args['quality']; |
|||||||||||
3316 | ||||||||||||
3317 | View Code Duplication | if (($volume = $this->volume($target)) == false |
||||||||||
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
||||||||||||
3318 | || ($file = $volume->file($target)) == false) { |
|||||||||||
3319 | return ['error' => $this->error(self::ERROR_RESIZE, '#'.$target, self::ERROR_FILE_NOT_FOUND)]; |
|||||||||||
3320 | } |
|||||||||||
3321 | ||||||||||||
3322 | if ($mode !== 'rotate' && ($width < 1 || $height < 1)) { |
|||||||||||
3323 | return ['error' => $this->error(self::ERROR_RESIZESIZE)]; |
|||||||||||
3324 | } |
|||||||||||
3325 | ||||||||||||
3326 | return ($file = $volume->resize($target, $width, $height, $x, $y, $mode, $bg, $degree, $quality)) |
|||||||||||
3327 | ? ['changed' => [$file]] |
|||||||||||
3328 | : ['error' => $this->error(self::ERROR_RESIZE, $volume->path($target), $volume->error())]; |
|||||||||||
3329 | } |
|||||||||||
3330 | ||||||||||||
3331 | /** |
|||||||||||
3332 | * Return content URL. |
|||||||||||
3333 | * |
|||||||||||
3334 | * @param array $args command arguments |
|||||||||||
3335 | * @return array |
|||||||||||
3336 | * @author Naoki Sawada |
|||||||||||
3337 | **/ |
|||||||||||
3338 | protected function url($args) |
|||||||||||
3339 | { |
|||||||||||
3340 | $target = $args['target']; |
|||||||||||
3341 | $options = isset($args['options']) ? $args['options'] : []; |
|||||||||||
3342 | if (($volume = $this->volume($target)) != false) { |
|||||||||||
3343 | if (! $volume->commandDisabled('url')) { |
|||||||||||
3344 | $url = $volume->getContentUrl($target, $options); |
|||||||||||
3345 | ||||||||||||
3346 | return $url ? ['url' => $url] : []; |
|||||||||||
3347 | } |
|||||||||||
3348 | } |
|||||||||||
3349 | ||||||||||||
3350 | return []; |
|||||||||||
3351 | } |
|||||||||||
3352 | ||||||||||||
3353 | /** |
|||||||||||
3354 | * Output callback result with JavaScript that control elFinder |
|||||||||||
3355 | * or HTTP redirect to callbackWindowURL. |
|||||||||||
3356 | * |
|||||||||||
3357 | * @param array command arguments |
|||||||||||
3358 | * @author Naoki Sawada |
|||||||||||
3359 | */ |
|||||||||||
3360 | protected function callback($args) |
|||||||||||
3361 | { |
|||||||||||
3362 | $checkReg = '/[^a-zA-Z0-9;._-]/'; |
|||||||||||
3363 | $node = (isset($args['node']) && ! preg_match($checkReg, $args['node'])) ? $args['node'] : ''; |
|||||||||||
3364 | $json = (isset($args['json']) && json_decode($args['json'])) ? $args['json'] : '{}'; |
|||||||||||
3365 | $bind = (isset($args['bind']) && ! preg_match($checkReg, $args['bind'])) ? $args['bind'] : ''; |
|||||||||||
3366 | $done = (! empty($args['done'])); |
|||||||||||
3367 | ||||||||||||
3368 | while (ob_get_level()) { |
|||||||||||
3369 | if (! ob_end_clean()) { |
|||||||||||
3370 | break; |
|||||||||||
3371 | } |
|||||||||||
3372 | } |
|||||||||||
3373 | ||||||||||||
3374 | if ($done || ! $this->callbackWindowURL) { |
|||||||||||
3375 | $script = ''; |
|||||||||||
3376 | if ($node) { |
|||||||||||
3377 | if ($bind) { |
|||||||||||
3378 | $trigger = 'elf.trigger(\''.$bind.'\', data);'; |
|||||||||||
3379 | $triggerdone = 'elf.trigger(\''.$bind.'done\');'; |
|||||||||||
3380 | $triggerfail = 'elf.trigger(\''.$bind.'fail\', data);'; |
|||||||||||
3381 | } else { |
|||||||||||
3382 | $trigger = $triggerdone = $triggerfail = ''; |
|||||||||||
3383 | } |
|||||||||||
3384 | $script .= ' |
|||||||||||
3385 | var w = window.opener || window.parent || window; |
|||||||||||
3386 | try { |
|||||||||||
3387 | var elf = w.document.getElementById(\''.$node.'\').elfinder; |
|||||||||||
3388 | if (elf) { |
|||||||||||
3389 | var data = '.$json.'; |
|||||||||||
3390 | if (data.error) { |
|||||||||||
3391 | '.$triggerfail.' |
|||||||||||
3392 | elf.error(data.error); |
|||||||||||
3393 | } else { |
|||||||||||
3394 | data.warning && elf.error(data.warning); |
|||||||||||
3395 | data.removed && data.removed.length && elf.remove(data); |
|||||||||||
3396 | data.added && data.added.length && elf.add(data); |
|||||||||||
3397 | data.changed && data.changed.length && elf.change(data); |
|||||||||||
3398 | '.$trigger.' |
|||||||||||
3399 | '.$triggerdone.' |
|||||||||||
3400 | data.sync && elf.sync(); |
|||||||||||
3401 | } |
|||||||||||
3402 | } |
|||||||||||
3403 | } catch(e) { |
|||||||||||
3404 | // for CORS |
|||||||||||
3405 | w.postMessage && w.postMessage(JSON.stringify({bind:\''.$bind.'\',data:'.$json.'}), \'*\'); |
|||||||||||
3406 | }'; |
|||||||||||
3407 | } |
|||||||||||
3408 | $script .= 'window.close();'; |
|||||||||||
3409 | ||||||||||||
3410 | $out = '<!DOCTYPE html><html><head><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><script>'.$script.'</script></head><body><a href="#" onlick="window.close();return false;">Close this window</a></body></html>'; |
|||||||||||
3411 | ||||||||||||
3412 | header('Content-Type: text/html; charset=utf-8'); |
|||||||||||
3413 | header('Content-Length: '.strlen($out)); |
|||||||||||
3414 | header('Cache-Control: private'); |
|||||||||||
3415 | header('Pragma: no-cache'); |
|||||||||||
3416 | ||||||||||||
3417 | echo $out; |
|||||||||||
3418 | } else { |
|||||||||||
3419 | $url = $this->callbackWindowURL; |
|||||||||||
3420 | $url .= ((strpos($url, '?') === false) ? '?' : '&') |
|||||||||||
3421 | .'&node='.rawurlencode($node) |
|||||||||||
3422 | .(($json !== '{}') ? ('&json='.rawurlencode($json)) : '') |
|||||||||||
3423 | .($bind ? ('&bind='.rawurlencode($bind)) : '') |
|||||||||||
3424 | .'&done=1'; |
|||||||||||
3425 | ||||||||||||
3426 | header('Location: '.$url); |
|||||||||||
3427 | } |
|||||||||||
3428 | exit(); |
|||||||||||
0 ignored issues
–
show
The method
callback() contains an exit expression.
An exit expression should only be used in rare cases. For example, if you write a short command line script. In most cases however, using an ![]() |
||||||||||||
3429 | } |
|||||||||||
3430 | ||||||||||||
3431 | /***************************************************************************/ |
|||||||||||
3432 | /* utils */ |
|||||||||||
3433 | /***************************************************************************/ |
|||||||||||
3434 | ||||||||||||
3435 | /** |
|||||||||||
3436 | * Return root - file's owner. |
|||||||||||
3437 | * |
|||||||||||
3438 | * @param string file hash |
|||||||||||
3439 | * @return elFinderStorageDriver |
|||||||||||
3440 | * @author Dmitry (dio) Levashov |
|||||||||||
3441 | **/ |
|||||||||||
3442 | protected function volume($hash) |
|||||||||||
3443 | { |
|||||||||||
3444 | foreach ($this->volumes as $id => $v) { |
|||||||||||
3445 | if (strpos(''.$hash, $id) === 0) { |
|||||||||||
3446 | return $this->volumes[$id]; |
|||||||||||
3447 | } |
|||||||||||
3448 | } |
|||||||||||
3449 | ||||||||||||
3450 | return false; |
|||||||||||
3451 | } |
|||||||||||
3452 | ||||||||||||
3453 | /** |
|||||||||||
3454 | * Return files info array. |
|||||||||||
3455 | * |
|||||||||||
3456 | * @param array $data one file info or files info |
|||||||||||
3457 | * @return array |
|||||||||||
3458 | * @author Dmitry (dio) Levashov |
|||||||||||
3459 | **/ |
|||||||||||
3460 | protected function toArray($data) |
|||||||||||
3461 | { |
|||||||||||
3462 | return isset($data['hash']) || ! is_array($data) ? [$data] : $data; |
|||||||||||
3463 | } |
|||||||||||
3464 | ||||||||||||
3465 | /** |
|||||||||||
3466 | * Return fils hashes list. |
|||||||||||
3467 | * |
|||||||||||
3468 | * @param array $files files info |
|||||||||||
3469 | * @return array |
|||||||||||
3470 | * @author Dmitry (dio) Levashov |
|||||||||||
3471 | **/ |
|||||||||||
3472 | protected function hashes($files) |
|||||||||||
3473 | { |
|||||||||||
3474 | $ret = []; |
|||||||||||
3475 | foreach ($files as $file) { |
|||||||||||
3476 | $ret[] = $file['hash']; |
|||||||||||
3477 | } |
|||||||||||
3478 | ||||||||||||
3479 | return $ret; |
|||||||||||
3480 | } |
|||||||||||
3481 | ||||||||||||
3482 | /** |
|||||||||||
3483 | * Remove from files list hidden files and files with required mime types. |
|||||||||||
3484 | * |
|||||||||||
3485 | * @param array $files files info |
|||||||||||
3486 | * @return array |
|||||||||||
3487 | * @author Dmitry (dio) Levashov |
|||||||||||
3488 | **/ |
|||||||||||
3489 | protected function filter($files) |
|||||||||||
3490 | { |
|||||||||||
3491 | $exists = []; |
|||||||||||
3492 | foreach ($files as $i => $file) { |
|||||||||||
3493 | if (isset($exists[$file['hash']]) || ! empty($file['hidden']) || ! $this->default->mimeAccepted($file['mime'])) { |
|||||||||||
3494 | unset($files[$i]); |
|||||||||||
3495 | } |
|||||||||||
3496 | $exists[$file['hash']] = true; |
|||||||||||
3497 | } |
|||||||||||
3498 | ||||||||||||
3499 | return array_values($files); |
|||||||||||
3500 | } |
|||||||||||
3501 | ||||||||||||
3502 | protected function utime() |
|||||||||||
3503 | { |
|||||||||||
3504 | $time = explode(' ', microtime()); |
|||||||||||
3505 | ||||||||||||
3506 | return (float) $time[1] + (float) $time[0]; |
|||||||||||
3507 | } |
|||||||||||
3508 | ||||||||||||
3509 | /** |
|||||||||||
3510 | * Return Network mount volume unique ID. |
|||||||||||
3511 | * |
|||||||||||
3512 | * @param array $netVolumes Saved netvolumes array |
|||||||||||
3513 | * @param string $prefix Id prefix |
|||||||||||
3514 | * @return string|false |
|||||||||||
3515 | * @author Naoki Sawada |
|||||||||||
3516 | **/ |
|||||||||||
3517 | protected function getNetVolumeUniqueId($netVolumes = null, $prefix = 'nm') |
|||||||||||
3518 | { |
|||||||||||
3519 | $id = false; |
|||||||||||
0 ignored issues
–
show
$id 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 ![]() |
||||||||||||
3520 | if (is_null($netVolumes)) { |
|||||||||||
3521 | $netVolumes = $this->getNetVolumes(); |
|||||||||||
3522 | } |
|||||||||||
3523 | $ids = []; |
|||||||||||
3524 | foreach ($netVolumes as $vOps) { |
|||||||||||
3525 | if (isset($vOps['id']) && strpos($vOps['id'], $prefix) === 0) { |
|||||||||||
3526 | $ids[$vOps['id']] = true; |
|||||||||||
3527 | } |
|||||||||||
3528 | } |
|||||||||||
3529 | if (! $ids) { |
|||||||||||
0 ignored issues
–
show
The expression
$ids 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 ![]() |
||||||||||||
3530 | $id = $prefix.'1'; |
|||||||||||
3531 | } else { |
|||||||||||
3532 | $i = 0; |
|||||||||||
3533 | while (isset($ids[$prefix.++$i]) && $i < 10000); |
|||||||||||
3534 | $id = $prefix.$i; |
|||||||||||
3535 | if (isset($ids[$id])) { |
|||||||||||
3536 | $id = false; |
|||||||||||
3537 | } |
|||||||||||
3538 | } |
|||||||||||
3539 | ||||||||||||
3540 | return $id; |
|||||||||||
3541 | } |
|||||||||||
3542 | ||||||||||||
3543 | /** |
|||||||||||
3544 | * Is item locked? |
|||||||||||
3545 | * |
|||||||||||
3546 | * @param string $hash |
|||||||||||
3547 | * @return bool |
|||||||||||
3548 | */ |
|||||||||||
3549 | protected function itemLocked($hash) |
|||||||||||
3550 | { |
|||||||||||
3551 | if (! self::$commonTempPath) { |
|||||||||||
3552 | return false; |
|||||||||||
3553 | } |
|||||||||||
3554 | $lock = self::$commonTempPath.DIRECTORY_SEPARATOR.$hash.'.lock'; |
|||||||||||
3555 | if (file_exists($lock)) { |
|||||||||||
3556 | if (filemtime($lock) + $this->itemLockExpire < time()) { |
|||||||||||
3557 | unlink($lock); |
|||||||||||
3558 | ||||||||||||
3559 | return false; |
|||||||||||
3560 | } |
|||||||||||
3561 | ||||||||||||
3562 | return true; |
|||||||||||
3563 | } |
|||||||||||
3564 | ||||||||||||
3565 | return false; |
|||||||||||
3566 | } |
|||||||||||
3567 | ||||||||||||
3568 | /** |
|||||||||||
3569 | * Do lock target item. |
|||||||||||
3570 | * |
|||||||||||
3571 | * @param array|string $hashes |
|||||||||||
3572 | * @param bool $autoUnlock |
|||||||||||
3573 | * @return bool |
|||||||||||
3574 | */ |
|||||||||||
3575 | protected function itemLock($hashes, $autoUnlock = true) |
|||||||||||
3576 | { |
|||||||||||
3577 | if (! self::$commonTempPath) { |
|||||||||||
3578 | return false; |
|||||||||||
3579 | } |
|||||||||||
3580 | if (! is_array($hashes)) { |
|||||||||||
3581 | $hashes = [$hashes]; |
|||||||||||
3582 | } |
|||||||||||
3583 | foreach ($hashes as $hash) { |
|||||||||||
3584 | $lock = self::$commonTempPath.DIRECTORY_SEPARATOR.$hash.'.lock'; |
|||||||||||
3585 | if ($this->itemLocked($hash)) { |
|||||||||||
3586 | $cnt = file_get_contents($lock) + 1; |
|||||||||||
3587 | } else { |
|||||||||||
3588 | $cnt = 1; |
|||||||||||
3589 | } |
|||||||||||
3590 | if (file_put_contents($lock, $cnt, LOCK_EX)) { |
|||||||||||
3591 | if ($autoUnlock) { |
|||||||||||
3592 | $this->autoUnlocks[] = $hash; |
|||||||||||
3593 | } |
|||||||||||
3594 | } |
|||||||||||
3595 | } |
|||||||||||
3596 | } |
|||||||||||
3597 | ||||||||||||
3598 | /** |
|||||||||||
3599 | * Do unlock target item. |
|||||||||||
3600 | * |
|||||||||||
3601 | * @param string $hash |
|||||||||||
3602 | * @return bool |
|||||||||||
3603 | */ |
|||||||||||
3604 | protected function itemUnlock($hash) |
|||||||||||
3605 | { |
|||||||||||
3606 | if (! $this->itemLocked($hash)) { |
|||||||||||
3607 | return true; |
|||||||||||
3608 | } |
|||||||||||
3609 | $lock = self::$commonTempPath.DIRECTORY_SEPARATOR.$hash.'.lock'; |
|||||||||||
3610 | $cnt = file_get_contents($lock); |
|||||||||||
3611 | if (--$cnt < 1) { |
|||||||||||
3612 | unlink($lock); |
|||||||||||
3613 | } else { |
|||||||||||
3614 | file_put_contents($lock, $cnt, LOCK_EX); |
|||||||||||
3615 | } |
|||||||||||
3616 | } |
|||||||||||
3617 | ||||||||||||
3618 | /** |
|||||||||||
3619 | * Ensure directories recursively. |
|||||||||||
3620 | * |
|||||||||||
3621 | * @param object $volume Volume object |
|||||||||||
3622 | * @param string $target Target hash |
|||||||||||
3623 | * @param string $dirs Array of directory tree to ensure |
|||||||||||
3624 | * @param string $path Relative path form target hash |
|||||||||||
3625 | * @return array|false array('stats' => array([stat of maked directory]), 'hashes' => array('[path]' => '[hash]'), 'makes' => array([New directory hashes]), 'error' => array([Error name])) |
|||||||||||
3626 | * @author Naoki Sawada |
|||||||||||
3627 | **/ |
|||||||||||
3628 | protected function ensureDirsRecursively($volume, $target, $dirs, $path = '') |
|||||||||||
3629 | { |
|||||||||||
3630 | $res = ['stats' => [], 'hashes' => [], 'makes' => [], 'error' => []]; |
|||||||||||
3631 | foreach ($dirs as $name => $sub) { |
|||||||||||
0 ignored issues
–
show
|
||||||||||||
3632 | $name = (string) $name; |
|||||||||||
3633 | $newDir = null; |
|||||||||||
3634 | if ((($parent = $volume->realpath($target)) && ($dir = $volume->dir($volume->getHash($parent, $name)))) || ($newDir = $volume->mkdir($target, $name))) { |
|||||||||||
3635 | $_path = $path.'/'.$name; |
|||||||||||
3636 | if ($newDir) { |
|||||||||||
3637 | $res['makes'][] = $newDir['hash']; |
|||||||||||
3638 | $dir = $newDir; |
|||||||||||
3639 | } |
|||||||||||
3640 | $res['stats'][] = $dir; |
|||||||||||
3641 | $res['hashes'][$_path] = $dir['hash']; |
|||||||||||
3642 | if (count($sub)) { |
|||||||||||
3643 | $res = array_merge_recursive($res, $this->ensureDirsRecursively($volume, $dir['hash'], $sub, $_path)); |
|||||||||||
3644 | if ($res['error']) { |
|||||||||||
3645 | break; |
|||||||||||
3646 | } |
|||||||||||
3647 | } |
|||||||||||
3648 | } else { |
|||||||||||
3649 | $res['error'][] = $name; |
|||||||||||
3650 | } |
|||||||||||
3651 | } |
|||||||||||
3652 | ||||||||||||
3653 | return $res; |
|||||||||||
3654 | } |
|||||||||||
3655 | ||||||||||||
3656 | private function session_expires() |
|||||||||||
3657 | { |
|||||||||||
3658 | if (! $last = $this->session->get(':LAST_ACTIVITY')) { |
|||||||||||
3659 | $this->session->set(':LAST_ACTIVITY', time()); |
|||||||||||
3660 | ||||||||||||
3661 | return false; |
|||||||||||
3662 | } |
|||||||||||
3663 | ||||||||||||
3664 | if (($this->timeout > 0) && (time() - $last > $this->timeout)) { |
|||||||||||
3665 | return true; |
|||||||||||
3666 | } |
|||||||||||
3667 | ||||||||||||
3668 | $this->session->set(':LAST_ACTIVITY', time()); |
|||||||||||
3669 | ||||||||||||
3670 | return false; |
|||||||||||
3671 | } |
|||||||||||
3672 | ||||||||||||
3673 | /** |
|||||||||||
3674 | * Get temporary directory path. |
|||||||||||
3675 | * |
|||||||||||
3676 | * @param string $volumeTempPath |
|||||||||||
3677 | * @return string |
|||||||||||
3678 | * @author Naoki Sawada |
|||||||||||
3679 | */ |
|||||||||||
3680 | private function getTempDir($volumeTempPath = null) |
|||||||||||
3681 | { |
|||||||||||
3682 | $testDirs = []; |
|||||||||||
3683 | if ($this->uploadTempPath) { |
|||||||||||
3684 | $testDirs[] = rtrim(realpath($this->uploadTempPath), DIRECTORY_SEPARATOR); |
|||||||||||
3685 | } |
|||||||||||
3686 | if ($volumeTempPath) { |
|||||||||||
0 ignored issues
–
show
The expression
$volumeTempPath of type string|null is loosely compared to true ; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.
In PHP, under loose comparison (like For '' == false // true
'' == null // true
'ab' == false // false
'ab' == null // false
// It is often better to use strict comparison
'' === false // false
'' === null // false
![]() |
||||||||||||
3687 | $testDirs[] = rtrim(realpath($volumeTempPath), DIRECTORY_SEPARATOR); |
|||||||||||
3688 | } |
|||||||||||
3689 | if (function_exists('sys_get_temp_dir')) { |
|||||||||||
3690 | $testDirs[] = sys_get_temp_dir(); |
|||||||||||
3691 | } |
|||||||||||
3692 | $tempDir = ''; |
|||||||||||
3693 | foreach ($testDirs as $testDir) { |
|||||||||||
3694 | if (! $testDir || ! is_dir($testDir)) { |
|||||||||||
3695 | continue; |
|||||||||||
3696 | } |
|||||||||||
3697 | if (is_writable($testDir)) { |
|||||||||||
3698 | $tempDir = $testDir; |
|||||||||||
3699 | $gc = time() - 3600; |
|||||||||||
3700 | foreach (glob($tempDir.DIRECTORY_SEPARATOR.'ELF*') as $cf) { |
|||||||||||
3701 | if (filemtime($cf) < $gc) { |
|||||||||||
3702 | unlink($cf); |
|||||||||||
3703 | } |
|||||||||||
3704 | } |
|||||||||||
3705 | break; |
|||||||||||
3706 | } |
|||||||||||
3707 | } |
|||||||||||
3708 | ||||||||||||
3709 | return $tempDir; |
|||||||||||
3710 | } |
|||||||||||
3711 | ||||||||||||
3712 | /** |
|||||||||||
3713 | * Check chunked upload files. |
|||||||||||
3714 | * |
|||||||||||
3715 | * @param string $tmpname uploaded temporary file path |
|||||||||||
3716 | * @param string $chunk uploaded chunk file name |
|||||||||||
3717 | * @param string $cid uploaded chunked file id |
|||||||||||
3718 | * @param string $tempDir temporary dirctroy path |
|||||||||||
3719 | * @param null $volume |
|||||||||||
3720 | * @return array or (empty, empty) |
|||||||||||
3721 | * @author Naoki Sawada |
|||||||||||
3722 | */ |
|||||||||||
3723 | private function checkChunkedFile($tmpname, $chunk, $cid, $tempDir, $volume = null) |
|||||||||||
0 ignored issues
–
show
checkChunkedFile uses the super-global variable $_POST which is generally not recommended.
Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable: // Bad
class Router
{
public function generate($path)
{
return $_SERVER['HOST'].$path;
}
}
// Better
class Router
{
private $host;
public function __construct($host)
{
$this->host = $host;
}
public function generate($path)
{
return $this->host.$path;
}
}
class Controller
{
public function myAction(Request $request)
{
// Instead of
$page = isset($_GET['page']) ? intval($_GET['page']) : 1;
// Better (assuming you use the Symfony2 request)
$page = $request->query->get('page', 1);
}
}
![]() |
||||||||||||
3724 | { |
|||||||||||
3725 | if (preg_match('/^(.+)(\.\d+_(\d+))\.part$/s', $chunk, $m)) { |
|||||||||||
3726 | $fname = $m[1]; |
|||||||||||
3727 | $encname = md5($cid.'_'.$fname); |
|||||||||||
3728 | $base = $tempDir.DIRECTORY_SEPARATOR.'ELF'.$encname; |
|||||||||||
3729 | $clast = intval($m[3]); |
|||||||||||
3730 | if (is_null($tmpname)) { |
|||||||||||
3731 | ignore_user_abort(true); |
|||||||||||
3732 | sleep(10); // wait 10 sec |
|||||||||||
3733 | // chunked file upload fail |
|||||||||||
3734 | foreach (glob($base.'*') as $cf) { |
|||||||||||
3735 | unlink($cf); |
|||||||||||
3736 | } |
|||||||||||
3737 | ignore_user_abort(false); |
|||||||||||
3738 | ||||||||||||
3739 | return; |
|||||||||||
3740 | } |
|||||||||||
3741 | ||||||||||||
3742 | $range = isset($_POST['range']) ? trim($_POST['range']) : ''; |
|||||||||||
3743 | if ($range && preg_match('/^(\d+),(\d+),(\d+)$/', $range, $ranges)) { |
|||||||||||
3744 | $start = $ranges[1]; |
|||||||||||
3745 | $len = $ranges[2]; |
|||||||||||
3746 | $size = $ranges[3]; |
|||||||||||
3747 | $tmp = $base.'.part'; |
|||||||||||
3748 | $csize = filesize($tmpname); |
|||||||||||
3749 | ||||||||||||
3750 | $tmpExists = is_file($tmp); |
|||||||||||
3751 | if (! $tmpExists) { |
|||||||||||
3752 | // check upload max size |
|||||||||||
3753 | $uploadMaxSize = $volume->getUploadMaxSize(); |
|||||||||||
0 ignored issues
–
show
|
||||||||||||
3754 | if ($uploadMaxSize > 0 && $size > $uploadMaxSize) { |
|||||||||||
3755 | return [self::ERROR_UPLOAD_FILE_SIZE, false]; |
|||||||||||
3756 | } |
|||||||||||
3757 | // make temp file |
|||||||||||
3758 | $ok = false; |
|||||||||||
3759 | if ($fp = fopen($tmp, 'wb')) { |
|||||||||||
3760 | flock($fp, LOCK_EX); |
|||||||||||
3761 | $ok = ftruncate($fp, $size); |
|||||||||||
3762 | flock($fp, LOCK_UN); |
|||||||||||
3763 | fclose($fp); |
|||||||||||
3764 | touch($base); |
|||||||||||
3765 | } |
|||||||||||
3766 | if (! $ok) { |
|||||||||||
3767 | unlink($tmp); |
|||||||||||
3768 | ||||||||||||
3769 | return [self::ERROR_UPLOAD_TEMP, false]; |
|||||||||||
3770 | } |
|||||||||||
3771 | } else { |
|||||||||||
3772 | // wait until makeing temp file (for anothor session) |
|||||||||||
3773 | $cnt = 1200; // Time limit 120 sec |
|||||||||||
3774 | while (! is_file($base) && --$cnt) { |
|||||||||||
3775 | usleep(100000); // wait 100ms |
|||||||||||
3776 | } |
|||||||||||
3777 | if (! $cnt) { |
|||||||||||
3778 | return [self::ERROR_UPLOAD_TEMP, false]; |
|||||||||||
3779 | } |
|||||||||||
3780 | } |
|||||||||||
3781 | ||||||||||||
3782 | // check size info |
|||||||||||
3783 | if ($len != $csize || $start + $len > $size || ($tmpExists && $size != filesize($tmp))) { |
|||||||||||
3784 | return [self::ERROR_UPLOAD_TEMP, false]; |
|||||||||||
3785 | } |
|||||||||||
3786 | ||||||||||||
3787 | // write chunk data |
|||||||||||
3788 | $writelen = 0; |
|||||||||||
0 ignored issues
–
show
$writelen is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
||||||||||||
3789 | $src = fopen($tmpname, 'rb'); |
|||||||||||
3790 | $fp = fopen($tmp, 'cb'); |
|||||||||||
3791 | fseek($fp, $start); |
|||||||||||
3792 | $writelen = stream_copy_to_stream($src, $fp, $len); |
|||||||||||
3793 | fclose($fp); |
|||||||||||
3794 | fclose($src); |
|||||||||||
3795 | if ($writelen != $len) { |
|||||||||||
3796 | return [self::ERROR_UPLOAD_TEMP, false]; |
|||||||||||
3797 | } |
|||||||||||
3798 | ||||||||||||
3799 | // write counts |
|||||||||||
3800 | file_put_contents($base, "\0", FILE_APPEND | LOCK_EX); |
|||||||||||
3801 | ||||||||||||
3802 | if (filesize($base) >= $clast + 1) { |
|||||||||||
3803 | // Completion |
|||||||||||
3804 | unlink($base); |
|||||||||||
3805 | ||||||||||||
3806 | return [$tmp, $fname]; |
|||||||||||
3807 | } |
|||||||||||
3808 | } else { |
|||||||||||
3809 | // old way |
|||||||||||
3810 | $part = $base.$m[2]; |
|||||||||||
3811 | if (move_uploaded_file($tmpname, $part)) { |
|||||||||||
3812 | chmod($part, 0600); |
|||||||||||
3813 | if ($clast < count(glob($base.'*'))) { |
|||||||||||
3814 | $parts = []; |
|||||||||||
3815 | for ($i = 0; $i <= $clast; $i++) { |
|||||||||||
3816 | $name = $base.'.'.$i.'_'.$clast; |
|||||||||||
3817 | if (is_readable($name)) { |
|||||||||||
3818 | $parts[] = $name; |
|||||||||||
3819 | } else { |
|||||||||||
3820 | $parts = null; |
|||||||||||
3821 | break; |
|||||||||||
3822 | } |
|||||||||||
3823 | } |
|||||||||||
3824 | if ($parts) { |
|||||||||||
3825 | if (! is_file($base)) { |
|||||||||||
3826 | touch($base); |
|||||||||||
3827 | if ($resfile = tempnam($tempDir, 'ELF')) { |
|||||||||||
3828 | $target = fopen($resfile, 'wb'); |
|||||||||||
3829 | foreach ($parts as $f) { |
|||||||||||
3830 | $fp = fopen($f, 'rb'); |
|||||||||||
3831 | while (! feof($fp)) { |
|||||||||||
3832 | fwrite($target, fread($fp, 8192)); |
|||||||||||
3833 | } |
|||||||||||
3834 | fclose($fp); |
|||||||||||
3835 | unlink($f); |
|||||||||||
3836 | } |
|||||||||||
3837 | fclose($target); |
|||||||||||
3838 | unlink($base); |
|||||||||||
3839 | ||||||||||||
3840 | return [$resfile, $fname]; |
|||||||||||
3841 | } |
|||||||||||
3842 | unlink($base); |
|||||||||||
3843 | } |
|||||||||||
3844 | } |
|||||||||||
3845 | } |
|||||||||||
3846 | } |
|||||||||||
3847 | } |
|||||||||||
3848 | } |
|||||||||||
3849 | ||||||||||||
3850 | return ['', '']; |
|||||||||||
3851 | } |
|||||||||||
3852 | } // END class |
|||||||||||
3853 |
You can fix this by adding a namespace to your class:
When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.