Complex classes like helper_plugin_extension_extension 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 helper_plugin_extension_extension, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
15 | class helper_plugin_extension_extension extends DokuWiki_Plugin |
||
16 | { |
||
17 | private $id; |
||
18 | private $base; |
||
19 | private $is_template = false; |
||
20 | private $localInfo; |
||
21 | private $remoteInfo; |
||
22 | /** $var string $forceSource */ |
||
23 | private $forceSource = null; |
||
24 | private $managerData; |
||
25 | /** @var helper_plugin_extension_repository $repository */ |
||
26 | private $repository = null; |
||
27 | |||
28 | /** @var array list of temporary directories */ |
||
29 | private $temporary = array(); |
||
30 | |||
31 | /** @var string where templates are installed to */ |
||
32 | private $tpllib = ''; |
||
33 | |||
34 | /** |
||
35 | * helper_plugin_extension_extension constructor. |
||
36 | */ |
||
37 | public function __construct() |
||
41 | |||
42 | /** |
||
43 | * Destructor |
||
44 | * |
||
45 | * deletes any dangling temporary directories |
||
46 | */ |
||
47 | public function __destruct() |
||
53 | |||
54 | /** |
||
55 | * @return bool false, this component is not a singleton |
||
56 | */ |
||
57 | public function isSingleton() |
||
61 | |||
62 | /** |
||
63 | * Set the name of the extension this instance shall represents, triggers loading the local and remote data |
||
64 | * |
||
65 | * @param string $id The id of the extension (prefixed with template: for templates) |
||
66 | * @return bool If some (local or remote) data was found |
||
67 | */ |
||
68 | public function setExtension($id) |
||
98 | |||
99 | /** |
||
100 | * If the extension is installed locally |
||
101 | * |
||
102 | * @return bool If the extension is installed locally |
||
103 | */ |
||
104 | public function isInstalled() |
||
108 | |||
109 | /** |
||
110 | * If the extension is under git control |
||
111 | * |
||
112 | * @return bool |
||
113 | */ |
||
114 | public function isGitControlled() |
||
119 | |||
120 | /** |
||
121 | * If the extension is bundled |
||
122 | * |
||
123 | * @return bool If the extension is bundled |
||
124 | */ |
||
125 | public function isBundled() |
||
138 | |||
139 | /** |
||
140 | * If the extension is protected against any modification (disable/uninstall) |
||
141 | * |
||
142 | * @return bool if the extension is protected |
||
143 | */ |
||
144 | public function isProtected() |
||
155 | |||
156 | /** |
||
157 | * If the extension is installed in the correct directory |
||
158 | * |
||
159 | * @return bool If the extension is installed in the correct directory |
||
160 | */ |
||
161 | public function isInWrongFolder() |
||
165 | |||
166 | /** |
||
167 | * If the extension is enabled |
||
168 | * |
||
169 | * @return bool If the extension is enabled |
||
170 | */ |
||
171 | public function isEnabled() |
||
182 | |||
183 | /** |
||
184 | * If the extension should be updated, i.e. if an updated version is available |
||
185 | * |
||
186 | * @return bool If an update is available |
||
187 | */ |
||
188 | public function updateAvailable() |
||
198 | |||
199 | /** |
||
200 | * If the extension is a template |
||
201 | * |
||
202 | * @return bool If this extension is a template |
||
203 | */ |
||
204 | public function isTemplate() |
||
208 | |||
209 | /** |
||
210 | * Set source (remote/local/null) that getters should be forced on |
||
211 | * |
||
212 | * @var string $source |
||
213 | * @return void |
||
214 | */ |
||
215 | public function setForceSource($source) |
||
219 | |||
220 | /** |
||
221 | * If the source should be ignored for getters |
||
222 | * |
||
223 | * @var string $source |
||
224 | * @return bool If this extension is a template |
||
225 | */ |
||
226 | public function isIgnoredSource($source) |
||
233 | |||
234 | /** |
||
235 | * Get the ID of the extension |
||
236 | * |
||
237 | * This is the same as getName() for plugins, for templates it's getName() prefixed with 'template:' |
||
238 | * |
||
239 | * @return string |
||
240 | */ |
||
241 | public function getID() |
||
245 | |||
246 | /** |
||
247 | * Get the name of the installation directory |
||
248 | * |
||
249 | * @return string The name of the installation directory |
||
250 | */ |
||
251 | public function getInstallName() |
||
255 | |||
256 | // Data from plugin.info.txt/template.info.txt or the repo when not available locally |
||
257 | /** |
||
258 | * Get the basename of the extension |
||
259 | * |
||
260 | * @return string The basename |
||
261 | */ |
||
262 | public function getBase() |
||
268 | |||
269 | /** |
||
270 | * Get the display name of the extension |
||
271 | * |
||
272 | * @return string The display name |
||
273 | */ |
||
274 | public function getDisplayName() |
||
282 | |||
283 | /** |
||
284 | * Get the author name of the extension |
||
285 | * |
||
286 | * @return string|bool The name of the author or false if there is none |
||
287 | */ |
||
288 | public function getAuthor() |
||
296 | |||
297 | /** |
||
298 | * Get the email of the author of the extension if there is any |
||
299 | * |
||
300 | * @return string|bool The email address or false if there is none |
||
301 | */ |
||
302 | public function getEmail() |
||
309 | |||
310 | /** |
||
311 | * Get the email id, i.e. the md5sum of the email |
||
312 | * |
||
313 | * @return string|bool The md5sum of the email if there is any, false otherwise |
||
314 | */ |
||
315 | public function getEmailID() |
||
323 | |||
324 | /** |
||
325 | * Get the description of the extension |
||
326 | * |
||
327 | * @return string The description |
||
328 | */ |
||
329 | public function getDescription() |
||
337 | |||
338 | /** |
||
339 | * Get the URL of the extension, usually a page on dokuwiki.org |
||
340 | * |
||
341 | * @return string The URL |
||
342 | */ |
||
343 | public function getURL() |
||
350 | |||
351 | /** |
||
352 | * Get the installed version of the extension |
||
353 | * |
||
354 | * @return string|bool The version, usually in the form yyyy-mm-dd if there is any |
||
355 | */ |
||
356 | public function getInstalledVersion() |
||
363 | |||
364 | /* |
||
365 | * Get the install date of the current version |
||
366 | * |
||
367 | * @return string|bool The date of the last update or false if not available |
||
368 | */ |
||
369 | public function getUpdateDate() |
||
374 | |||
375 | /** |
||
376 | * Get the date of the installation of the plugin |
||
377 | * |
||
378 | * @return string|bool The date of the installation or false if not available |
||
379 | */ |
||
380 | public function getInstallDate() |
||
385 | |||
386 | /** |
||
387 | * Get the names of the dependencies of this extension |
||
388 | * |
||
389 | * @return array The base names of the dependencies |
||
390 | */ |
||
391 | public function getDependencies() |
||
397 | |||
398 | /** |
||
399 | * Get the names of the missing dependencies |
||
400 | * |
||
401 | * @return array The base names of the missing dependencies |
||
402 | */ |
||
403 | public function getMissingDependencies() |
||
416 | |||
417 | /** |
||
418 | * Get the names of all conflicting extensions |
||
419 | * |
||
420 | * @return array The names of the conflicting extensions |
||
421 | */ |
||
422 | public function getConflicts() |
||
428 | |||
429 | /** |
||
430 | * Get the names of similar extensions |
||
431 | * |
||
432 | * @return array The names of similar extensions |
||
433 | */ |
||
434 | public function getSimilarExtensions() |
||
440 | |||
441 | /** |
||
442 | * Get the names of the tags of the extension |
||
443 | * |
||
444 | * @return array The names of the tags of the extension |
||
445 | */ |
||
446 | public function getTags() |
||
452 | |||
453 | /** |
||
454 | * Get the popularity information as floating point number [0,1] |
||
455 | * |
||
456 | * @return float|bool The popularity information or false if it isn't available |
||
457 | */ |
||
458 | public function getPopularity() |
||
464 | |||
465 | |||
466 | /** |
||
467 | * Get the text of the security warning if there is any |
||
468 | * |
||
469 | * @return string|bool The security warning if there is any, false otherwise |
||
470 | */ |
||
471 | public function getSecurityWarning() |
||
477 | |||
478 | /** |
||
479 | * Get the text of the security issue if there is any |
||
480 | * |
||
481 | * @return string|bool The security issue if there is any, false otherwise |
||
482 | */ |
||
483 | public function getSecurityIssue() |
||
489 | |||
490 | /** |
||
491 | * Get the URL of the screenshot of the extension if there is any |
||
492 | * |
||
493 | * @return string|bool The screenshot URL if there is any, false otherwise |
||
494 | */ |
||
495 | public function getScreenshotURL() |
||
501 | |||
502 | /** |
||
503 | * Get the URL of the thumbnail of the extension if there is any |
||
504 | * |
||
505 | * @return string|bool The thumbnail URL if there is any, false otherwise |
||
506 | */ |
||
507 | public function getThumbnailURL() |
||
513 | /** |
||
514 | * Get the last used download URL of the extension if there is any |
||
515 | * |
||
516 | * @return string|bool The previously used download URL, false if the extension has been installed manually |
||
517 | */ |
||
518 | public function getLastDownloadURL() |
||
523 | |||
524 | /** |
||
525 | * Get the download URL of the extension if there is any |
||
526 | * |
||
527 | * @return string|bool The download URL if there is any, false otherwise |
||
528 | */ |
||
529 | public function getDownloadURL() |
||
535 | |||
536 | /** |
||
537 | * If the download URL has changed since the last download |
||
538 | * |
||
539 | * @return bool If the download URL has changed |
||
540 | */ |
||
541 | public function hasDownloadURLChanged() |
||
547 | |||
548 | /** |
||
549 | * Get the bug tracker URL of the extension if there is any |
||
550 | * |
||
551 | * @return string|bool The bug tracker URL if there is any, false otherwise |
||
552 | */ |
||
553 | public function getBugtrackerURL() |
||
559 | |||
560 | /** |
||
561 | * Get the URL of the source repository if there is any |
||
562 | * |
||
563 | * @return string|bool The URL of the source repository if there is any, false otherwise |
||
564 | */ |
||
565 | public function getSourcerepoURL() |
||
571 | |||
572 | /** |
||
573 | * Get the donation URL of the extension if there is any |
||
574 | * |
||
575 | * @return string|bool The donation URL if there is any, false otherwise |
||
576 | */ |
||
577 | public function getDonationURL() |
||
583 | |||
584 | /** |
||
585 | * Get the extension type(s) |
||
586 | * |
||
587 | * @return array The type(s) as array of strings |
||
588 | */ |
||
589 | public function getTypes() |
||
596 | |||
597 | /** |
||
598 | * Get a list of all DokuWiki versions this extension is compatible with |
||
599 | * |
||
600 | * @return array The versions in the form yyyy-mm-dd => ('label' => label, 'implicit' => implicit) |
||
601 | */ |
||
602 | public function getCompatibleVersions() |
||
608 | |||
609 | /** |
||
610 | * Get the date of the last available update |
||
611 | * |
||
612 | * @return string|bool The last available update in the form yyyy-mm-dd if there is any, false otherwise |
||
613 | */ |
||
614 | public function getLastUpdate() |
||
620 | |||
621 | /** |
||
622 | * Get the base path of the extension |
||
623 | * |
||
624 | * @return string The base path of the extension |
||
625 | */ |
||
626 | public function getInstallDir() |
||
634 | |||
635 | /** |
||
636 | * The type of extension installation |
||
637 | * |
||
638 | * @return string One of "none", "manual", "git" or "automatic" |
||
639 | */ |
||
640 | public function getInstallType() |
||
647 | |||
648 | /** |
||
649 | * If the extension can probably be installed/updated or uninstalled |
||
650 | * |
||
651 | * @return bool|string True or error string |
||
652 | */ |
||
653 | public function canModify() |
||
668 | |||
669 | /** |
||
670 | * Install an extension from a user upload |
||
671 | * |
||
672 | * @param string $field name of the upload file |
||
673 | * @throws Exception when something goes wrong |
||
674 | * @return array The list of installed extensions |
||
675 | */ |
||
676 | public function installFromUpload($field) |
||
705 | |||
706 | /** |
||
707 | * Install an extension from a remote URL |
||
708 | * |
||
709 | * @param string $url |
||
710 | * @throws Exception when something goes wrong |
||
711 | * @return array The list of installed extensions |
||
712 | */ |
||
713 | public function installFromURL($url) |
||
728 | |||
729 | /** |
||
730 | * Install or update the extension |
||
731 | * |
||
732 | * @throws \Exception when something goes wrong |
||
733 | * @return array The list of installed extensions |
||
734 | */ |
||
735 | public function installOrUpdate() |
||
751 | |||
752 | /** |
||
753 | * Uninstall the extension |
||
754 | * |
||
755 | * @return bool If the plugin was sucessfully uninstalled |
||
756 | */ |
||
757 | public function uninstall() |
||
762 | |||
763 | /** |
||
764 | * Enable the extension |
||
765 | * |
||
766 | * @return bool|string True or an error message |
||
767 | */ |
||
768 | public function enable() |
||
783 | |||
784 | /** |
||
785 | * Disable the extension |
||
786 | * |
||
787 | * @return bool|string True or an error message |
||
788 | */ |
||
789 | public function disable() |
||
804 | |||
805 | /** |
||
806 | * Purge the cache by touching the main configuration file |
||
807 | */ |
||
808 | protected function purgeCache() |
||
816 | |||
817 | /** |
||
818 | * Read local extension data either from info.txt or getInfo() |
||
819 | */ |
||
820 | protected function readLocalData() |
||
858 | |||
859 | /** |
||
860 | * Save the given URL and current datetime in the manager.dat file of all installed extensions |
||
861 | * |
||
862 | * @param string $url Where the extension was downloaded from. (empty for manual installs via upload) |
||
863 | * @param array $installed Optional list of installed plugins |
||
864 | */ |
||
865 | protected function updateManagerData($url = '', $installed = null) |
||
890 | |||
891 | /** |
||
892 | * Read the manager.dat file |
||
893 | */ |
||
894 | protected function readManagerData() |
||
911 | |||
912 | /** |
||
913 | * Write the manager.data file |
||
914 | */ |
||
915 | protected function writeManagerData() |
||
924 | |||
925 | /** |
||
926 | * Returns a temporary directory |
||
927 | * |
||
928 | * The directory is registered for cleanup when the class is destroyed |
||
929 | * |
||
930 | * @return false|string |
||
931 | */ |
||
932 | protected function mkTmpDir() |
||
939 | |||
940 | /** |
||
941 | * downloads a file from the net and saves it |
||
942 | * |
||
943 | * - $file is the directory where the file should be saved |
||
944 | * - if successful will return the name used for the saved file, false otherwise |
||
945 | * |
||
946 | * @author Andreas Gohr <[email protected]> |
||
947 | * @author Chris Smith <[email protected]> |
||
948 | * |
||
949 | * @param string $url url to download |
||
950 | * @param string $file path to file or directory where to save |
||
951 | * @param string $defaultName fallback for name of download |
||
952 | * @return bool|string if failed false, otherwise true or the name of the file in the given dir |
||
953 | */ |
||
954 | protected function downloadToFile($url, $file, $defaultName = '') |
||
993 | |||
994 | /** |
||
995 | * Download an archive to a protected path |
||
996 | * |
||
997 | * @param string $url The url to get the archive from |
||
998 | * @throws Exception when something goes wrong |
||
999 | * @return string The path where the archive was saved |
||
1000 | */ |
||
1001 | public function download($url) |
||
1031 | |||
1032 | /** |
||
1033 | * @param string $file The path to the archive that shall be installed |
||
1034 | * @param bool $overwrite If an already installed plugin should be overwritten |
||
1035 | * @param string $base The basename of the plugin if it's known |
||
1036 | * @throws Exception when something went wrong |
||
1037 | * @return array list of installed extensions |
||
1038 | */ |
||
1039 | public function installArchive($file, $overwrite = false, $base = '') |
||
1128 | |||
1129 | /** |
||
1130 | * Find out what was in the extracted directory |
||
1131 | * |
||
1132 | * Correct folders are searched recursively using the "*.info.txt" configs |
||
1133 | * as indicator for a root folder. When such a file is found, it's base |
||
1134 | * setting is used (when set). All folders found by this method are stored |
||
1135 | * in the 'new' key of the $result array. |
||
1136 | * |
||
1137 | * For backwards compatibility all found top level folders are stored as |
||
1138 | * in the 'old' key of the $result array. |
||
1139 | * |
||
1140 | * When no items are found in 'new' the copy mechanism should fall back |
||
1141 | * the 'old' list. |
||
1142 | * |
||
1143 | * @author Andreas Gohr <[email protected]> |
||
1144 | * @param array $result - results are stored here |
||
1145 | * @param string $directory - the temp directory where the package was unpacked to |
||
1146 | * @param string $default_type - type used if no info.txt available |
||
1147 | * @param string $subdir - a subdirectory. do not set. used by recursion |
||
1148 | * @return bool - false on error |
||
1149 | */ |
||
1150 | protected function findFolders(&$result, $directory, $default_type = 'plugin', $subdir = '') |
||
1212 | |||
1213 | /** |
||
1214 | * Decompress a given file to the given target directory |
||
1215 | * |
||
1216 | * Determines the compression type from the file extension |
||
1217 | * |
||
1218 | * @param string $file archive to extract |
||
1219 | * @param string $target directory to extract to |
||
1220 | * @throws Exception |
||
1221 | * @return bool |
||
1222 | */ |
||
1223 | private function decompress($file, $target) |
||
1255 | |||
1256 | /** |
||
1257 | * Determine the archive type of the given file |
||
1258 | * |
||
1259 | * Reads the first magic bytes of the given file for content type guessing, |
||
1260 | * if neither bz, gz or zip are recognized, tar is assumed. |
||
1261 | * |
||
1262 | * @author Andreas Gohr <[email protected]> |
||
1263 | * @param string $file The file to analyze |
||
1264 | * @return string|false false if the file can't be read, otherwise an "extension" |
||
1265 | */ |
||
1266 | private function guessArchiveType($file) |
||
1278 | |||
1279 | /** |
||
1280 | * Copy with recursive sub-directory support |
||
1281 | * |
||
1282 | * @param string $src filename path to file |
||
1283 | * @param string $dst filename path to file |
||
1284 | * @return bool|int|string |
||
1285 | */ |
||
1286 | private function dircopy($src, $dst) |
||
1312 | |||
1313 | /** |
||
1314 | * Delete outdated files from updated plugins |
||
1315 | * |
||
1316 | * @param array $installed |
||
1317 | */ |
||
1318 | private function removeDeletedfiles($installed) |
||
1347 | } |
||
1348 | |||
1350 |
Let’s assume that you have a directory layout like this:
and let’s assume the following content of
Bar.php
:If both files
OtherDir/Foo.php
andSomeDir/Foo.php
are loaded in the same runtime, you will see a PHP error such as the following:PHP Fatal error: Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php
However, as
OtherDir/Foo.php
does not necessarily have to be loaded and the error is only triggered if it is loaded beforeOtherDir/Bar.php
, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias: