Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like elFinderVolumeFTP 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 elFinderVolumeFTP, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
18 | class elFinderVolumeFTP extends elFinderVolumeDriver { |
||
19 | |||
20 | /** |
||
21 | * Driver id |
||
22 | * Must be started from letter and contains [a-z0-9] |
||
23 | * Used as part of volume id |
||
24 | * |
||
25 | * @var string |
||
26 | **/ |
||
27 | protected $driverId = 'f'; |
||
28 | |||
29 | /** |
||
30 | * FTP Connection Instance |
||
31 | * |
||
32 | * @var ftp |
||
33 | **/ |
||
34 | protected $connect = null; |
||
35 | |||
36 | /** |
||
37 | * Directory for tmp files |
||
38 | * If not set driver will try to use tmbDir as tmpDir |
||
39 | * |
||
40 | * @var string |
||
41 | **/ |
||
42 | protected $tmpPath = ''; |
||
43 | |||
44 | /** |
||
45 | * Last FTP error message |
||
46 | * |
||
47 | * @var string |
||
48 | **/ |
||
49 | protected $ftpError = ''; |
||
50 | |||
51 | /** |
||
52 | * FTP server output list as ftp on linux |
||
53 | * |
||
54 | * @var bool |
||
55 | **/ |
||
56 | protected $ftpOsUnix; |
||
57 | |||
58 | /** |
||
59 | * Tmp folder path |
||
60 | * |
||
61 | * @var string |
||
62 | **/ |
||
63 | protected $tmp = ''; |
||
64 | |||
65 | /** |
||
66 | * Constructor |
||
67 | * Extend options with required fields |
||
68 | * |
||
69 | * @return void |
||
|
|||
70 | * @author Dmitry (dio) Levashov |
||
71 | * @author Cem (DiscoFever) |
||
72 | **/ |
||
73 | public function __construct() { |
||
91 | |||
92 | /*********************************************************************/ |
||
93 | /* INIT AND CONFIGURE */ |
||
94 | /*********************************************************************/ |
||
95 | |||
96 | /** |
||
97 | * Prepare FTP connection |
||
98 | * Connect to remote server and check if credentials are correct, if so, store the connection id in $ftp_conn |
||
99 | * |
||
100 | * @return bool |
||
101 | * @author Dmitry (dio) Levashov |
||
102 | * @author Cem (DiscoFever) |
||
103 | **/ |
||
104 | protected function init() { |
||
138 | |||
139 | |||
140 | /** |
||
141 | * Configure after successfull mount. |
||
142 | * |
||
143 | * @return void |
||
144 | * @author Dmitry (dio) Levashov |
||
145 | **/ |
||
146 | protected function configure() { |
||
172 | |||
173 | /** |
||
174 | * Connect to ftp server |
||
175 | * |
||
176 | * @return bool |
||
177 | * @author Dmitry (dio) Levashov |
||
178 | **/ |
||
179 | protected function connect() { |
||
215 | |||
216 | /*********************************************************************/ |
||
217 | /* FS API */ |
||
218 | /*********************************************************************/ |
||
219 | |||
220 | /** |
||
221 | * Close opened connection |
||
222 | * |
||
223 | * @return void |
||
224 | * @author Dmitry (dio) Levashov |
||
225 | **/ |
||
226 | public function umount() { |
||
229 | |||
230 | |||
231 | /** |
||
232 | * Parse line from ftp_rawlist() output and return file stat (array) |
||
233 | * |
||
234 | * @param string $raw line from ftp_rawlist() output |
||
235 | * @return array |
||
236 | * @author Dmitry Levashov |
||
237 | **/ |
||
238 | protected function parseRaw($raw) { |
||
299 | |||
300 | /** |
||
301 | * Parse permissions string. Return array(read => true/false, write => true/false) |
||
302 | * |
||
303 | * @param string $perm permissions string |
||
304 | * @return string |
||
305 | * @author Dmitry (dio) Levashov |
||
306 | **/ |
||
307 | protected function parsePermissions($perm) { |
||
322 | |||
323 | /** |
||
324 | * Cache dir contents |
||
325 | * |
||
326 | * @param string $path dir path |
||
327 | * @return void |
||
328 | * @author Dmitry Levashov |
||
329 | **/ |
||
330 | protected function cacheDir($path) { |
||
353 | |||
354 | /** |
||
355 | * Return ftp transfer mode for file |
||
356 | * |
||
357 | * @param string $path file path |
||
358 | * @return string |
||
359 | * @author Dmitry (dio) Levashov |
||
360 | **/ |
||
361 | protected function ftpMode($path) { |
||
364 | |||
365 | /*********************** paths/urls *************************/ |
||
366 | |||
367 | /** |
||
368 | * Return parent directory path |
||
369 | * |
||
370 | * @param string $path file path |
||
371 | * @return string |
||
372 | * @author Dmitry (dio) Levashov |
||
373 | **/ |
||
374 | protected function _dirname($path) { |
||
377 | |||
378 | /** |
||
379 | * Return file name |
||
380 | * |
||
381 | * @param string $path file path |
||
382 | * @return string |
||
383 | * @author Dmitry (dio) Levashov |
||
384 | **/ |
||
385 | protected function _basename($path) { |
||
388 | |||
389 | /** |
||
390 | * Join dir name and file name and retur full path |
||
391 | * |
||
392 | * @param string $dir |
||
393 | * @param string $name |
||
394 | * @return string |
||
395 | * @author Dmitry (dio) Levashov |
||
396 | **/ |
||
397 | protected function _joinPath($dir, $name) { |
||
400 | |||
401 | /** |
||
402 | * Return normalized path, this works the same as os.path.normpath() in Python |
||
403 | * |
||
404 | * @param string $path path |
||
405 | * @return string |
||
406 | * @author Troex Nevelin |
||
407 | **/ |
||
408 | protected function _normpath($path) { |
||
453 | |||
454 | /** |
||
455 | * Return file path related to root dir |
||
456 | * |
||
457 | * @param string $path file path |
||
458 | * @return string |
||
459 | * @author Dmitry (dio) Levashov |
||
460 | **/ |
||
461 | protected function _relpath($path) { |
||
464 | |||
465 | /** |
||
466 | * Convert path related to root dir into real path |
||
467 | * |
||
468 | * @param string $path file path |
||
469 | * @return string |
||
470 | * @author Dmitry (dio) Levashov |
||
471 | **/ |
||
472 | protected function _abspath($path) { |
||
475 | |||
476 | /** |
||
477 | * Return fake path started from root dir |
||
478 | * |
||
479 | * @param string $path file path |
||
480 | * @return string |
||
481 | * @author Dmitry (dio) Levashov |
||
482 | **/ |
||
483 | protected function _path($path) { |
||
486 | |||
487 | /** |
||
488 | * Return true if $path is children of $parent |
||
489 | * |
||
490 | * @param string $path path to check |
||
491 | * @param string $parent parent path |
||
492 | * @return bool |
||
493 | * @author Dmitry (dio) Levashov |
||
494 | **/ |
||
495 | protected function _inpath($path, $parent) { |
||
498 | |||
499 | /***************** file stat ********************/ |
||
500 | /** |
||
501 | * Return stat for given path. |
||
502 | * Stat contains following fields: |
||
503 | * - (int) size file size in b. required |
||
504 | * - (int) ts file modification time in unix time. required |
||
505 | * - (string) mime mimetype. required for folders, others - optionally |
||
506 | * - (bool) read read permissions. required |
||
507 | * - (bool) write write permissions. required |
||
508 | * - (bool) locked is object locked. optionally |
||
509 | * - (bool) hidden is object hidden. optionally |
||
510 | * - (string) alias for symlinks - link target path relative to root path. optionally |
||
511 | * - (string) target for symlinks - link target path. optionally |
||
512 | * |
||
513 | * If file does not exists - returns empty array or false. |
||
514 | * |
||
515 | * @param string $path file path |
||
516 | * @return array|false |
||
517 | * @author Dmitry (dio) Levashov |
||
518 | **/ |
||
519 | protected function _stat($path) { |
||
621 | |||
622 | /** |
||
623 | * Return true if path is dir and has at least one childs directory |
||
624 | * |
||
625 | * @param string $path dir path |
||
626 | * @return bool |
||
627 | * @author Dmitry (dio) Levashov |
||
628 | **/ |
||
629 | protected function _subdirs($path) { |
||
647 | |||
648 | /** |
||
649 | * Return object width and height |
||
650 | * Ususaly used for images, but can be realize for video etc... |
||
651 | * |
||
652 | * @param string $path file path |
||
653 | * @param string $mime file mime type |
||
654 | * @return string |
||
655 | * @author Dmitry (dio) Levashov |
||
656 | **/ |
||
657 | protected function _dimensions($path, $mime) { |
||
660 | |||
661 | /******************** file/dir content *********************/ |
||
662 | |||
663 | /** |
||
664 | * Return files list in directory. |
||
665 | * |
||
666 | * @param string $path dir path |
||
667 | * @return array |
||
668 | * @author Dmitry (dio) Levashov |
||
669 | * @author Cem (DiscoFever) |
||
670 | **/ |
||
671 | protected function _scandir($path) { |
||
682 | |||
683 | /** |
||
684 | * Open file and return file pointer |
||
685 | * |
||
686 | * @param string $path file path |
||
687 | * @param bool $write open file for writing |
||
688 | * @return resource|false |
||
689 | * @author Dmitry (dio) Levashov |
||
690 | **/ |
||
691 | protected function _fopen($path, $mode='rb') { |
||
703 | |||
704 | /** |
||
705 | * Close opened file |
||
706 | * |
||
707 | * @param resource $fp file pointer |
||
708 | * @return bool |
||
709 | * @author Dmitry (dio) Levashov |
||
710 | **/ |
||
711 | protected function _fclose($fp, $path='') { |
||
717 | |||
718 | /******************** file/dir manipulations *************************/ |
||
719 | |||
720 | /** |
||
721 | * Create dir and return created dir path or false on failed |
||
722 | * |
||
723 | * @param string $path parent dir path |
||
724 | * @param string $name new directory name |
||
725 | * @return string|bool |
||
726 | * @author Dmitry (dio) Levashov |
||
727 | **/ |
||
728 | protected function _mkdir($path, $name) { |
||
737 | |||
738 | /** |
||
739 | * Create file and return it's path or false on failed |
||
740 | * |
||
741 | * @param string $path parent dir path |
||
742 | * @param string $name new file name |
||
743 | * @return string|bool |
||
744 | * @author Dmitry (dio) Levashov |
||
745 | **/ |
||
746 | protected function _mkfile($path, $name) { |
||
756 | |||
757 | /** |
||
758 | * Create symlink. FTP driver does not support symlinks. |
||
759 | * |
||
760 | * @param string $target link target |
||
761 | * @param string $path symlink path |
||
762 | * @return bool |
||
763 | * @author Dmitry (dio) Levashov |
||
764 | **/ |
||
765 | protected function _symlink($target, $path, $name) { |
||
768 | |||
769 | /** |
||
770 | * Copy file into another file |
||
771 | * |
||
772 | * @param string $source source file path |
||
773 | * @param string $targetDir target directory path |
||
774 | * @param string $name new file name |
||
775 | * @return bool |
||
776 | * @author Dmitry (dio) Levashov |
||
777 | **/ |
||
778 | protected function _copy($source, $targetDir, $name) { |
||
794 | |||
795 | /** |
||
796 | * Move file into another parent dir. |
||
797 | * Return new file path or false. |
||
798 | * |
||
799 | * @param string $source source file path |
||
800 | * @param string $target target dir path |
||
801 | * @param string $name file name |
||
802 | * @return string|bool |
||
803 | * @author Dmitry (dio) Levashov |
||
804 | **/ |
||
805 | protected function _move($source, $targetDir, $name) { |
||
809 | |||
810 | /** |
||
811 | * Remove file |
||
812 | * |
||
813 | * @param string $path file path |
||
814 | * @return bool |
||
815 | * @author Dmitry (dio) Levashov |
||
816 | **/ |
||
817 | protected function _unlink($path) { |
||
820 | |||
821 | /** |
||
822 | * Remove dir |
||
823 | * |
||
824 | * @param string $path dir path |
||
825 | * @return bool |
||
826 | * @author Dmitry (dio) Levashov |
||
827 | **/ |
||
828 | protected function _rmdir($path) { |
||
831 | |||
832 | /** |
||
833 | * Create new file and write into it from file pointer. |
||
834 | * Return new file path or false on error. |
||
835 | * |
||
836 | * @param resource $fp file pointer |
||
837 | * @param string $dir target dir path |
||
838 | * @param string $name file name |
||
839 | * @param array $stat file stat (required by some virtual fs) |
||
840 | * @return bool|string |
||
841 | * @author Dmitry (dio) Levashov |
||
842 | **/ |
||
843 | protected function _save($fp, $dir, $name, $stat) { |
||
849 | |||
850 | /** |
||
851 | * Get file contents |
||
852 | * |
||
853 | * @param string $path file path |
||
854 | * @return string|false |
||
855 | * @author Dmitry (dio) Levashov |
||
856 | **/ |
||
857 | protected function _getContents($path) { |
||
868 | |||
869 | /** |
||
870 | * Write a string to a file |
||
871 | * |
||
872 | * @param string $path file path |
||
873 | * @param string $content new file content |
||
874 | * @return bool |
||
875 | * @author Dmitry (dio) Levashov |
||
876 | **/ |
||
877 | protected function _filePutContents($path, $content) { |
||
894 | |||
895 | /** |
||
896 | * Detect available archivers |
||
897 | * |
||
898 | * @return void |
||
899 | **/ |
||
900 | protected function _checkArchivers() { |
||
904 | |||
905 | /** |
||
906 | * Unpack archive |
||
907 | * |
||
908 | * @param string $path archive path |
||
909 | * @param array $arc archiver command and arguments (same as in $this->archivers) |
||
910 | * @return true |
||
911 | * @return void |
||
912 | * @author Dmitry (dio) Levashov |
||
913 | * @author Alexey Sukhotin |
||
914 | **/ |
||
915 | protected function _unpack($path, $arc) { |
||
919 | |||
920 | /** |
||
921 | * Recursive symlinks search |
||
922 | * |
||
923 | * @param string $path file/dir path |
||
924 | * @return bool |
||
925 | * @author Dmitry (dio) Levashov |
||
926 | **/ |
||
927 | View Code Duplication | protected function _findSymlinks($path) { |
|
952 | |||
953 | /** |
||
954 | * Extract files from archive |
||
955 | * |
||
956 | * @param string $path archive path |
||
957 | * @param array $arc archiver command and arguments (same as in $this->archivers) |
||
958 | * @return true |
||
959 | * @author Dmitry (dio) Levashov, |
||
960 | * @author Alexey Sukhotin |
||
961 | **/ |
||
962 | protected function _extract($path, $arc) |
||
1057 | |||
1058 | /** |
||
1059 | * Create archive and return its path |
||
1060 | * |
||
1061 | * @param string $dir target dir |
||
1062 | * @param array $files files names list |
||
1063 | * @param string $name archive name |
||
1064 | * @param array $arc archiver options |
||
1065 | * @return string|bool |
||
1066 | * @author Dmitry (dio) Levashov, |
||
1067 | * @author Alexey Sukhotin |
||
1068 | **/ |
||
1069 | protected function _archive($dir, $files, $name, $arc) |
||
1138 | |||
1139 | /** |
||
1140 | * Create writable temporary directory and return path to it. |
||
1141 | * @return string path to the new temporary directory or false in case of error. |
||
1142 | */ |
||
1143 | private function tempDir() |
||
1162 | |||
1163 | /** |
||
1164 | * Gets in a single FTP request an array of absolute remote FTP paths of files and |
||
1165 | * folders in $remote_directory omitting symbolic links. |
||
1166 | * @param $remote_directory string remote FTP path to scan for file and folders recursively |
||
1167 | * @return array of elements each of which is an array of two elements: |
||
1168 | * <ul> |
||
1169 | * <li>$item['path'] - absolute remote FTP path</li> |
||
1170 | * <li>$item['type'] - either 'f' for file or 'd' for directory</li> |
||
1171 | * </ul> |
||
1172 | */ |
||
1173 | protected function ftp_scan_dir($remote_directory) |
||
1208 | |||
1209 | /** |
||
1210 | * Downloads specified files from remote directory |
||
1211 | * if there is a directory among files it is downloaded recursively (omitting symbolic links). |
||
1212 | * @param $remote_directory string remote FTP path to a source directory to download from. |
||
1213 | * @param array $files list of files to download from remote directory. |
||
1214 | * @param $dest_local_directory string destination folder to store downloaded files. |
||
1215 | * @return bool true on success and false on failure. |
||
1216 | */ |
||
1217 | private function ftp_download_files($remote_directory, array $files, $dest_local_directory) |
||
1252 | |||
1253 | /** |
||
1254 | * Delete local directory recursively. |
||
1255 | * @param $dirPath string to directory to be erased. |
||
1256 | * @return bool true on success and false on failure. |
||
1257 | */ |
||
1258 | private function deleteDir($dirPath) |
||
1287 | |||
1288 | /** |
||
1289 | * Returns array of strings containing all files and folders in the specified local directory. |
||
1290 | * @param $dir |
||
1291 | * @param string $prefix |
||
1292 | * @internal param string $path path to directory to scan. |
||
1293 | * @return array array of files and folders names relative to the $path |
||
1294 | * or an empty array if the directory $path is empty, |
||
1295 | * <br /> |
||
1296 | * false if $path is not a directory or does not exist. |
||
1297 | */ |
||
1298 | private static function listFilesInDirectory($dir, $omitSymlinks, $prefix = '') |
||
1332 | |||
1333 | /** |
||
1334 | * Resize image |
||
1335 | * @param string $hash |
||
1336 | * @param int $width |
||
1337 | * @param int $height |
||
1338 | * @param int $x |
||
1339 | * @param int $y |
||
1340 | * @param string $mode |
||
1341 | * @param string $bg |
||
1342 | * @param int $degree |
||
1343 | * @return array|bool|false |
||
1344 | */ |
||
1345 | public function resize($hash, $width, $height, $x, $y, $mode = 'resize', $bg = '', $degree = 0) { |
||
1416 | |||
1417 | } // END class |
||
1418 | |||
1419 |
Adding a
@return
annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.Please refer to the PHP core documentation on constructors.