Complex classes like Filesystem often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use Filesystem, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
70 | class Filesystem { |
||
71 | |||
72 | /** |
||
73 | * @var Mount\Manager $mounts |
||
74 | */ |
||
75 | private static $mounts; |
||
76 | |||
77 | public static $loaded = false; |
||
78 | /** |
||
79 | * @var \OC\Files\View $defaultInstance |
||
80 | */ |
||
81 | static private $defaultInstance; |
||
82 | |||
83 | static private $usersSetup = array(); |
||
84 | |||
85 | static private $normalizedPathCache = null; |
||
86 | |||
87 | static private $listeningForProviders = false; |
||
88 | |||
89 | /** |
||
90 | * classname which used for hooks handling |
||
91 | * used as signalclass in OC_Hooks::emit() |
||
92 | */ |
||
93 | const CLASSNAME = 'OC_Filesystem'; |
||
94 | |||
95 | /** |
||
96 | * signalname emitted before file renaming |
||
97 | * |
||
98 | * @param string $oldpath |
||
99 | * @param string $newpath |
||
100 | */ |
||
101 | const signal_rename = 'rename'; |
||
102 | |||
103 | /** |
||
104 | * signal emitted after file renaming |
||
105 | * |
||
106 | * @param string $oldpath |
||
107 | * @param string $newpath |
||
108 | */ |
||
109 | const signal_post_rename = 'post_rename'; |
||
110 | |||
111 | /** |
||
112 | * signal emitted before file/dir creation |
||
113 | * |
||
114 | * @param string $path |
||
115 | * @param bool $run changing this flag to false in hook handler will cancel event |
||
116 | */ |
||
117 | const signal_create = 'create'; |
||
118 | |||
119 | /** |
||
120 | * signal emitted after file/dir creation |
||
121 | * |
||
122 | * @param string $path |
||
123 | * @param bool $run changing this flag to false in hook handler will cancel event |
||
124 | */ |
||
125 | const signal_post_create = 'post_create'; |
||
126 | |||
127 | /** |
||
128 | * signal emits before file/dir copy |
||
129 | * |
||
130 | * @param string $oldpath |
||
131 | * @param string $newpath |
||
132 | * @param bool $run changing this flag to false in hook handler will cancel event |
||
133 | */ |
||
134 | const signal_copy = 'copy'; |
||
135 | |||
136 | /** |
||
137 | * signal emits after file/dir copy |
||
138 | * |
||
139 | * @param string $oldpath |
||
140 | * @param string $newpath |
||
141 | */ |
||
142 | const signal_post_copy = 'post_copy'; |
||
143 | |||
144 | /** |
||
145 | * signal emits before file/dir save |
||
146 | * |
||
147 | * @param string $path |
||
148 | * @param bool $run changing this flag to false in hook handler will cancel event |
||
149 | */ |
||
150 | const signal_write = 'write'; |
||
151 | |||
152 | /** |
||
153 | * signal emits after file/dir save |
||
154 | * |
||
155 | * @param string $path |
||
156 | */ |
||
157 | const signal_post_write = 'post_write'; |
||
158 | |||
159 | /** |
||
160 | * signal emitted before file/dir update |
||
161 | * |
||
162 | * @param string $path |
||
163 | * @param bool $run changing this flag to false in hook handler will cancel event |
||
164 | */ |
||
165 | const signal_update = 'update'; |
||
166 | |||
167 | /** |
||
168 | * signal emitted after file/dir update |
||
169 | * |
||
170 | * @param string $path |
||
171 | * @param bool $run changing this flag to false in hook handler will cancel event |
||
172 | */ |
||
173 | const signal_post_update = 'post_update'; |
||
174 | |||
175 | /** |
||
176 | * signal emits when reading file/dir |
||
177 | * |
||
178 | * @param string $path |
||
179 | */ |
||
180 | const signal_read = 'read'; |
||
181 | |||
182 | /** |
||
183 | * signal emits when removing file/dir |
||
184 | * |
||
185 | * @param string $path |
||
186 | */ |
||
187 | const signal_delete = 'delete'; |
||
188 | |||
189 | /** |
||
190 | * parameters definitions for signals |
||
191 | */ |
||
192 | const signal_param_path = 'path'; |
||
193 | const signal_param_oldpath = 'oldpath'; |
||
194 | const signal_param_newpath = 'newpath'; |
||
195 | |||
196 | /** |
||
197 | * run - changing this flag to false in hook handler will cancel event |
||
198 | */ |
||
199 | const signal_param_run = 'run'; |
||
200 | |||
201 | const signal_create_mount = 'create_mount'; |
||
202 | const signal_delete_mount = 'delete_mount'; |
||
203 | const signal_param_mount_type = 'mounttype'; |
||
204 | const signal_param_users = 'users'; |
||
205 | |||
206 | /** |
||
207 | * @var \OC\Files\Storage\StorageFactory $loader |
||
208 | */ |
||
209 | private static $loader; |
||
210 | |||
211 | /** @var bool */ |
||
212 | private static $logWarningWhenAddingStorageWrapper = true; |
||
213 | |||
214 | /** |
||
215 | * @param bool $shouldLog |
||
216 | * @internal |
||
217 | */ |
||
218 | public static function logWarningWhenAddingStorageWrapper($shouldLog) { |
||
219 | self::$logWarningWhenAddingStorageWrapper = (bool) $shouldLog; |
||
220 | } |
||
221 | |||
222 | /** |
||
223 | * @param string $wrapperName |
||
224 | * @param callable $wrapper |
||
225 | * @param int $priority |
||
226 | */ |
||
227 | public static function addStorageWrapper($wrapperName, $wrapper, $priority = 50) { |
||
228 | if (self::$logWarningWhenAddingStorageWrapper) { |
||
229 | \OC::$server->getLogger()->warning("Storage wrapper '{wrapper}' was not registered via the 'OC_Filesystem - preSetup' hook which could cause potential problems.", [ |
||
230 | 'wrapper' => $wrapperName, |
||
231 | 'app' => 'filesystem', |
||
232 | ]); |
||
233 | } |
||
234 | |||
235 | $mounts = self::getMountManager()->getAll(); |
||
236 | if (!self::getLoader()->addStorageWrapper($wrapperName, $wrapper, $priority, $mounts)) { |
||
237 | // do not re-wrap if storage with this name already existed |
||
238 | return; |
||
239 | } |
||
240 | } |
||
241 | |||
242 | /** |
||
243 | * Returns the storage factory |
||
244 | * |
||
245 | * @return \OCP\Files\Storage\IStorageFactory |
||
246 | */ |
||
247 | public static function getLoader() { |
||
248 | if (!self::$loader) { |
||
249 | self::$loader = new StorageFactory(); |
||
250 | } |
||
251 | return self::$loader; |
||
252 | } |
||
253 | |||
254 | /** |
||
255 | * Returns the mount manager |
||
256 | * |
||
257 | * @return \OC\Files\Mount\Manager |
||
258 | */ |
||
259 | public static function getMountManager($user = '') { |
||
260 | if (!self::$mounts) { |
||
261 | \OC_Util::setupFS($user); |
||
262 | } |
||
263 | return self::$mounts; |
||
264 | } |
||
265 | |||
266 | /** |
||
267 | * get the mountpoint of the storage object for a path |
||
268 | * ( note: because a storage is not always mounted inside the fakeroot, the |
||
269 | * returned mountpoint is relative to the absolute root of the filesystem |
||
270 | * and doesn't take the chroot into account ) |
||
271 | * |
||
272 | * @param string $path |
||
273 | * @return string |
||
274 | */ |
||
275 | static public function getMountPoint($path) { |
||
276 | if (!self::$mounts) { |
||
277 | \OC_Util::setupFS(); |
||
278 | } |
||
279 | $mount = self::$mounts->find($path); |
||
280 | if ($mount) { |
||
281 | return $mount->getMountPoint(); |
||
282 | } else { |
||
283 | return ''; |
||
284 | } |
||
285 | } |
||
286 | |||
287 | /** |
||
288 | * get a list of all mount points in a directory |
||
289 | * |
||
290 | * @param string $path |
||
291 | * @return string[] |
||
292 | */ |
||
293 | static public function getMountPoints($path) { |
||
294 | if (!self::$mounts) { |
||
295 | \OC_Util::setupFS(); |
||
296 | } |
||
297 | $result = array(); |
||
298 | $mounts = self::$mounts->findIn($path); |
||
299 | foreach ($mounts as $mount) { |
||
300 | $result[] = $mount->getMountPoint(); |
||
301 | } |
||
302 | return $result; |
||
303 | } |
||
304 | |||
305 | /** |
||
306 | * get the storage mounted at $mountPoint |
||
307 | * |
||
308 | * @param string $mountPoint |
||
309 | * @return \OC\Files\Storage\Storage |
||
310 | */ |
||
311 | public static function getStorage($mountPoint) { |
||
312 | if (!self::$mounts) { |
||
313 | \OC_Util::setupFS(); |
||
314 | } |
||
315 | $mount = self::$mounts->find($mountPoint); |
||
316 | return $mount->getStorage(); |
||
317 | } |
||
318 | |||
319 | /** |
||
320 | * @param string $id |
||
321 | * @return Mount\MountPoint[] |
||
322 | */ |
||
323 | public static function getMountByStorageId($id) { |
||
324 | if (!self::$mounts) { |
||
325 | \OC_Util::setupFS(); |
||
326 | } |
||
327 | return self::$mounts->findByStorageId($id); |
||
328 | } |
||
329 | |||
330 | /** |
||
331 | * @param int $id |
||
332 | * @return Mount\MountPoint[] |
||
333 | */ |
||
334 | public static function getMountByNumericId($id) { |
||
335 | if (!self::$mounts) { |
||
336 | \OC_Util::setupFS(); |
||
337 | } |
||
338 | return self::$mounts->findByNumericId($id); |
||
339 | } |
||
340 | |||
341 | /** |
||
342 | * resolve a path to a storage and internal path |
||
343 | * |
||
344 | * @param string $path |
||
345 | * @return array an array consisting of the storage and the internal path |
||
346 | */ |
||
347 | static public function resolvePath($path) { |
||
348 | if (!self::$mounts) { |
||
349 | \OC_Util::setupFS(); |
||
350 | } |
||
351 | $mount = self::$mounts->find($path); |
||
352 | if ($mount) { |
||
353 | return array($mount->getStorage(), rtrim($mount->getInternalPath($path), '/')); |
||
354 | } else { |
||
355 | return array(null, null); |
||
356 | } |
||
357 | } |
||
358 | |||
359 | static public function init($user, $root) { |
||
360 | if (self::$defaultInstance) { |
||
361 | return false; |
||
362 | } |
||
363 | self::getLoader(); |
||
364 | self::$defaultInstance = new View($root); |
||
365 | |||
366 | if (!self::$mounts) { |
||
367 | self::$mounts = \OC::$server->getMountManager(); |
||
368 | } |
||
369 | |||
370 | //load custom mount config |
||
371 | self::initMountPoints($user); |
||
372 | |||
373 | self::$loaded = true; |
||
374 | |||
375 | return true; |
||
376 | } |
||
377 | |||
378 | static public function initMountManager() { |
||
379 | if (!self::$mounts) { |
||
380 | self::$mounts = \OC::$server->getMountManager(); |
||
381 | } |
||
382 | } |
||
383 | |||
384 | /** |
||
385 | * Initialize system and personal mount points for a user |
||
386 | * |
||
387 | * @param string $user |
||
388 | * @throws \OC\User\NoUserException if the user is not available |
||
389 | */ |
||
390 | public static function initMountPoints($user = '') { |
||
391 | if ($user == '') { |
||
392 | $user = \OC_User::getUser(); |
||
393 | } |
||
394 | if ($user === null || $user === false || $user === '') { |
||
395 | throw new \OC\User\NoUserException('Attempted to initialize mount points for null user and no user in session'); |
||
396 | } |
||
397 | if (isset(self::$usersSetup[$user])) { |
||
398 | return; |
||
399 | } |
||
400 | $root = \OC_User::getHome($user); |
||
401 | |||
402 | $userManager = \OC::$server->getUserManager(); |
||
403 | $userObject = $userManager->get($user); |
||
404 | |||
405 | if (is_null($userObject)) { |
||
406 | \OCP\Util::writeLog('files', ' Backends provided no user object for ' . $user, \OCP\Util::ERROR); |
||
407 | throw new \OC\User\NoUserException('Backends provided no user object for ' . $user); |
||
408 | } |
||
409 | |||
410 | self::$usersSetup[$user] = true; |
||
411 | |||
412 | $homeStorage = \OC::$server->getConfig()->getSystemValue('objectstore'); |
||
413 | if (!empty($homeStorage)) { |
||
414 | // sanity checks |
||
415 | if (empty($homeStorage['class'])) { |
||
416 | \OCP\Util::writeLog('files', 'No class given for objectstore', \OCP\Util::ERROR); |
||
417 | } |
||
418 | if (!isset($homeStorage['arguments'])) { |
||
419 | $homeStorage['arguments'] = array(); |
||
420 | } |
||
421 | // instantiate object store implementation |
||
422 | $homeStorage['arguments']['objectstore'] = new $homeStorage['class']($homeStorage['arguments']); |
||
423 | // mount with home object store implementation |
||
424 | $homeStorage['class'] = '\OC\Files\ObjectStore\HomeObjectStoreStorage'; |
||
425 | } else { |
||
426 | $homeStorage = array( |
||
427 | //default home storage configuration: |
||
428 | 'class' => '\OC\Files\Storage\Home', |
||
429 | 'arguments' => array() |
||
430 | ); |
||
431 | } |
||
432 | $homeStorage['arguments']['user'] = $userObject; |
||
433 | |||
434 | // check for legacy home id (<= 5.0.12) |
||
435 | if (\OC\Files\Cache\Storage::exists('local::' . $root . '/')) { |
||
436 | $homeStorage['arguments']['legacy'] = true; |
||
437 | } |
||
438 | |||
439 | $mount = new MountPoint($homeStorage['class'], '/' . $user, $homeStorage['arguments'], self::getLoader()); |
||
440 | self::getMountManager()->addMount($mount); |
||
441 | |||
442 | $home = \OC\Files\Filesystem::getStorage($user); |
||
|
|||
443 | |||
444 | // Chance to mount for other storages |
||
445 | /** @var \OC\Files\Config\MountProviderCollection $mountConfigManager */ |
||
446 | $mountConfigManager = \OC::$server->getMountProviderCollection(); |
||
447 | if ($userObject) { |
||
448 | $mounts = $mountConfigManager->getMountsForUser($userObject); |
||
449 | array_walk($mounts, array(self::$mounts, 'addMount')); |
||
450 | $mounts[] = $mount; |
||
451 | $mountConfigManager->registerMounts($userObject, $mounts); |
||
452 | } |
||
453 | |||
454 | self::listenForNewMountProviders($mountConfigManager, $userManager); |
||
455 | \OC_Hook::emit('OC_Filesystem', 'post_initMountPoints', array('user' => $user, 'user_dir' => $root)); |
||
456 | } |
||
457 | |||
458 | /** |
||
459 | * Get mounts from mount providers that are registered after setup |
||
460 | * |
||
461 | * @param MountProviderCollection $mountConfigManager |
||
462 | * @param IUserManager $userManager |
||
463 | */ |
||
464 | private static function listenForNewMountProviders(MountProviderCollection $mountConfigManager, IUserManager $userManager) { |
||
465 | if (!self::$listeningForProviders) { |
||
466 | self::$listeningForProviders = true; |
||
467 | $mountConfigManager->listen('\OC\Files\Config', 'registerMountProvider', function (IMountProvider $provider) use ($userManager) { |
||
468 | foreach (Filesystem::$usersSetup as $user => $setup) { |
||
469 | $userObject = $userManager->get($user); |
||
470 | if ($userObject) { |
||
471 | $mounts = $provider->getMountsForUser($userObject, Filesystem::getLoader()); |
||
472 | array_walk($mounts, array(self::$mounts, 'addMount')); |
||
473 | } |
||
474 | } |
||
475 | }); |
||
476 | } |
||
477 | } |
||
478 | |||
479 | /** |
||
480 | * get the default filesystem view |
||
481 | * |
||
482 | * @return View |
||
483 | */ |
||
484 | static public function getView() { |
||
485 | return self::$defaultInstance; |
||
486 | } |
||
487 | |||
488 | /** |
||
489 | * tear down the filesystem, removing all storage providers |
||
490 | */ |
||
491 | static public function tearDown() { |
||
492 | self::clearMounts(); |
||
493 | self::$defaultInstance = null; |
||
494 | } |
||
495 | |||
496 | /** |
||
497 | * get the relative path of the root data directory for the current user |
||
498 | * |
||
499 | * @return string |
||
500 | * |
||
501 | * Returns path like /admin/files |
||
502 | */ |
||
503 | static public function getRoot() { |
||
509 | |||
510 | /** |
||
511 | * clear all mounts and storage backends |
||
512 | */ |
||
513 | public static function clearMounts() { |
||
519 | |||
520 | /** |
||
521 | * mount an \OC\Files\Storage\Storage in our virtual filesystem |
||
522 | * |
||
523 | * @param \OC\Files\Storage\Storage|string $class |
||
524 | * @param array $arguments |
||
525 | * @param string $mountpoint |
||
526 | */ |
||
527 | static public function mount($class, $arguments, $mountpoint) { |
||
534 | |||
535 | /** |
||
536 | * return the path to a local version of the file |
||
537 | * we need this because we can't know if a file is stored local or not from |
||
538 | * outside the filestorage and for some purposes a local file is needed |
||
539 | * |
||
540 | * @param string $path |
||
541 | * @return string |
||
542 | */ |
||
543 | static public function getLocalFile($path) { |
||
546 | |||
547 | /** |
||
548 | * @param string $path |
||
549 | * @return string |
||
550 | */ |
||
551 | static public function getLocalFolder($path) { |
||
554 | |||
555 | /** |
||
556 | * return path to file which reflects one visible in browser |
||
557 | * |
||
558 | * @param string $path |
||
559 | * @return string |
||
560 | */ |
||
561 | static public function getLocalPath($path) { |
||
569 | |||
570 | /** |
||
571 | * check if the requested path is valid |
||
572 | * |
||
573 | * @param string $path |
||
574 | * @return bool |
||
575 | */ |
||
576 | static public function isValidPath($path) { |
||
586 | |||
587 | /** |
||
588 | * checks if a file is blacklisted for storage in the filesystem |
||
589 | * Listens to write and rename hooks |
||
590 | * |
||
591 | * @param array $data from hook |
||
592 | */ |
||
593 | static public function isBlacklisted($data) { |
||
605 | |||
606 | /** |
||
607 | * @param string $filename |
||
608 | * @return bool |
||
609 | */ |
||
610 | static public function isFileBlacklisted($filename) { |
||
617 | |||
618 | /** |
||
619 | * check if the directory should be ignored when scanning |
||
620 | * NOTE: the special directories . and .. would cause never ending recursion |
||
621 | * |
||
622 | * @param String $dir |
||
623 | * @return boolean |
||
624 | */ |
||
625 | static public function isIgnoredDir($dir) { |
||
631 | |||
632 | /** |
||
633 | * following functions are equivalent to their php builtin equivalents for arguments/return values. |
||
634 | */ |
||
635 | static public function mkdir($path) { |
||
638 | |||
639 | static public function rmdir($path) { |
||
642 | |||
643 | static public function opendir($path) { |
||
646 | |||
647 | static public function readdir($path) { |
||
650 | |||
651 | static public function is_dir($path) { |
||
654 | |||
655 | static public function is_file($path) { |
||
658 | |||
659 | static public function stat($path) { |
||
662 | |||
663 | static public function filetype($path) { |
||
666 | |||
667 | static public function filesize($path) { |
||
670 | |||
671 | static public function readfile($path) { |
||
674 | |||
675 | static public function isCreatable($path) { |
||
678 | |||
679 | static public function isReadable($path) { |
||
682 | |||
683 | static public function isUpdatable($path) { |
||
686 | |||
687 | static public function isDeletable($path) { |
||
690 | |||
691 | static public function isSharable($path) { |
||
694 | |||
695 | static public function file_exists($path) { |
||
698 | |||
699 | static public function filemtime($path) { |
||
702 | |||
703 | static public function touch($path, $mtime = null) { |
||
706 | |||
707 | /** |
||
708 | * @return string |
||
709 | */ |
||
710 | static public function file_get_contents($path) { |
||
713 | |||
714 | static public function file_put_contents($path, $data) { |
||
717 | |||
718 | static public function unlink($path) { |
||
721 | |||
722 | static public function rename($path1, $path2) { |
||
725 | |||
726 | static public function copy($path1, $path2) { |
||
729 | |||
730 | static public function fopen($path, $mode) { |
||
733 | |||
734 | /** |
||
735 | * @return string |
||
736 | */ |
||
737 | static public function toTmpFile($path) { |
||
740 | |||
741 | static public function fromTmpFile($tmpFile, $path) { |
||
744 | |||
745 | static public function getMimeType($path) { |
||
748 | |||
749 | static public function hash($type, $path, $raw = false) { |
||
752 | |||
753 | static public function free_space($path = '/') { |
||
756 | |||
757 | static public function search($query) { |
||
760 | |||
761 | /** |
||
762 | * @param string $query |
||
763 | */ |
||
764 | static public function searchByMime($query) { |
||
767 | |||
768 | /** |
||
769 | * @param string|int $tag name or tag id |
||
770 | * @param string $userId owner of the tags |
||
771 | * @return FileInfo[] array or file info |
||
772 | */ |
||
773 | static public function searchByTag($tag, $userId) { |
||
776 | |||
777 | /** |
||
778 | * check if a file or folder has been updated since $time |
||
779 | * |
||
780 | * @param string $path |
||
781 | * @param int $time |
||
782 | * @return bool |
||
783 | */ |
||
784 | static public function hasUpdated($path, $time) { |
||
787 | |||
788 | /** |
||
789 | * Fix common problems with a file path |
||
790 | * |
||
791 | * @param string $path |
||
792 | * @param bool $stripTrailingSlash |
||
793 | * @param bool $isAbsolutePath |
||
794 | * @return string |
||
795 | */ |
||
796 | public static function normalizePath($path, $stripTrailingSlash = true, $isAbsolutePath = false) { |
||
797 | if (is_null(self::$normalizedPathCache)) { |
||
798 | self::$normalizedPathCache = new CappedMemoryCache(); |
||
799 | } |
||
800 | |||
801 | /** |
||
802 | * FIXME: This is a workaround for existing classes and files which call |
||
803 | * this function with another type than a valid string. This |
||
863 | |||
864 | /** |
||
865 | * get the filesystem info |
||
866 | * |
||
867 | * @param string $path |
||
868 | * @param boolean $includeMountPoints whether to add mountpoint sizes, |
||
869 | * defaults to true |
||
870 | * @return \OC\Files\FileInfo|bool False if file does not exist |
||
871 | */ |
||
872 | public static function getFileInfo($path, $includeMountPoints = true) { |
||
875 | |||
876 | /** |
||
877 | * change file metadata |
||
878 | * |
||
879 | * @param string $path |
||
880 | * @param array $data |
||
881 | * @return int |
||
882 | * |
||
883 | * returns the fileid of the updated file |
||
884 | */ |
||
885 | public static function putFileInfo($path, $data) { |
||
888 | |||
889 | /** |
||
890 | * get the content of a directory |
||
891 | * |
||
892 | * @param string $directory path under datadirectory |
||
893 | * @param string $mimetype_filter limit returned content to this mimetype or mimepart |
||
894 | * @return \OC\Files\FileInfo[] |
||
895 | */ |
||
896 | public static function getDirectoryContent($directory, $mimetype_filter = '') { |
||
899 | |||
900 | /** |
||
901 | * Get the path of a file by id |
||
902 | * |
||
903 | * Note that the resulting path is not guaranteed to be unique for the id, multiple paths can point to the same file |
||
904 | * |
||
905 | * @param int $id |
||
906 | * @throws NotFoundException |
||
907 | * @return string |
||
908 | */ |
||
909 | public static function getPath($id) { |
||
912 | |||
913 | /** |
||
914 | * Get the owner for a file or folder |
||
915 | * |
||
916 | * @param string $path |
||
917 | * @return string |
||
918 | */ |
||
919 | public static function getOwner($path) { |
||
922 | |||
923 | /** |
||
924 | * get the ETag for a file or folder |
||
925 | * |
||
926 | * @param string $path |
||
927 | * @return string |
||
928 | */ |
||
929 | static public function getETag($path) { |
||
932 | } |
||
933 |
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.
Both the
$myVar
assignment in line 1 and the$higher
assignment in line 2 are dead. The first because$myVar
is never used and the second because$higher
is always overwritten for every possible time line.