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 autoptimizeBase 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 autoptimizeBase, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
4 | abstract class autoptimizeBase { |
||
5 | protected $content = ''; |
||
6 | protected $tagWarning = false; |
||
7 | |||
8 | public function __construct($content) { |
||
11 | |||
12 | //Reads the page and collects tags |
||
13 | abstract public function read($justhead); |
||
14 | |||
15 | //Joins and optimizes collected things |
||
16 | abstract public function minify(); |
||
17 | |||
18 | //Caches the things |
||
19 | abstract public function cache(); |
||
20 | |||
21 | //Returns the content |
||
22 | abstract public function getcontent(); |
||
23 | |||
24 | //Converts an URL to a full path |
||
25 | protected function getpath($url) { |
||
26 | $url=apply_filters( 'autoptimize_filter_cssjs_alter_url', $url); |
||
27 | |||
28 | if (strpos($url,'%')!==false) { |
||
29 | $url=urldecode($url); |
||
30 | } |
||
31 | |||
32 | $siteHost=parse_url(AUTOPTIMIZE_WP_SITE_URL,PHP_URL_HOST); |
||
33 | $contentHost=parse_url(AUTOPTIMIZE_WP_ROOT_URL,PHP_URL_HOST); |
||
34 | |||
35 | // normalize |
||
36 | if (strpos($url,'//')===0) { |
||
37 | if (is_ssl()) { |
||
38 | $url = "https:".$url; |
||
39 | } else { |
||
40 | $url = "http:".$url; |
||
41 | } |
||
42 | } else if ((strpos($url,'//')===false) && (strpos($url,$siteHost)===false)) { |
||
43 | if (AUTOPTIMIZE_WP_SITE_URL === $siteHost) { |
||
44 | $url = AUTOPTIMIZE_WP_SITE_URL.$url; |
||
45 | } else { |
||
46 | $subdir_levels=substr_count(preg_replace("/https?:\/\//","",AUTOPTIMIZE_WP_SITE_URL),"/"); |
||
47 | $url = AUTOPTIMIZE_WP_SITE_URL.str_repeat("/..",$subdir_levels).$url; |
||
48 | } |
||
49 | } |
||
50 | |||
51 | if ($siteHost !== $contentHost) { |
||
52 | $url=str_replace(AUTOPTIMIZE_WP_CONTENT_URL,AUTOPTIMIZE_WP_SITE_URL.AUTOPTIMIZE_WP_CONTENT_NAME,$url); |
||
53 | } |
||
54 | |||
55 | // first check; hostname wp site should be hostname of url |
||
56 | $thisHost=@parse_url($url,PHP_URL_HOST); |
||
57 | if ($thisHost !== $siteHost) { |
||
58 | /* |
||
59 | * first try to get all domains from WPML (if available) |
||
60 | * then explicitely declare $this->cdn_url as OK as well |
||
61 | * then apply own filter autoptimize_filter_cssjs_multidomain takes an array of hostnames |
||
62 | * each item in that array will be considered part of the same WP multisite installation |
||
63 | */ |
||
64 | $multidomains = array(); |
||
65 | |||
66 | $multidomainsWPML = apply_filters('wpml_setting', array(), 'language_domains'); |
||
67 | if (!empty($multidomainsWPML)) { |
||
68 | $multidomains = array_map(array($this,"ao_getDomain"),$multidomainsWPML); |
||
69 | } |
||
70 | |||
71 | if (!empty($this->cdn_url)) { |
||
72 | $multidomains[]=parse_url($this->cdn_url,PHP_URL_HOST); |
||
|
|||
73 | } |
||
74 | |||
75 | $multidomains = apply_filters('autoptimize_filter_cssjs_multidomain', $multidomains); |
||
76 | |||
77 | if (!empty($multidomains)) { |
||
78 | if (in_array($thisHost,$multidomains)) { |
||
79 | $url=str_replace($thisHost, parse_url(AUTOPTIMIZE_WP_SITE_URL,PHP_URL_HOST), $url); |
||
80 | } else { |
||
81 | return false; |
||
82 | } |
||
83 | } else { |
||
84 | return false; |
||
85 | } |
||
86 | } |
||
87 | |||
88 | // try to remove "wp root url" from url while not minding http<>https |
||
89 | $tmp_ao_root = preg_replace('/https?:/','',AUTOPTIMIZE_WP_ROOT_URL); |
||
90 | if ($siteHost !== $contentHost) { |
||
91 | // as we replaced the content-domain with the site-domain, we should match against that |
||
92 | $tmp_ao_root = preg_replace('/https?:/','',AUTOPTIMIZE_WP_SITE_URL); |
||
93 | } |
||
94 | $tmp_url = preg_replace('/https?:/','',$url); |
||
95 | $path = str_replace($tmp_ao_root,'',$tmp_url); |
||
96 | |||
97 | // if path starts with :// or //, this is not a URL in the WP context and we have to assume we can't aggregate |
||
98 | if (preg_match('#^:?//#',$path)) { |
||
99 | /** External script/css (adsense, etc) */ |
||
100 | return false; |
||
101 | } |
||
102 | |||
103 | // prepend with WP_ROOT_DIR to have full path to file |
||
104 | $path = str_replace('//','/',WP_ROOT_DIR.$path); |
||
105 | |||
106 | // final check: does file exist and is it readable |
||
107 | if (file_exists($path) && is_file($path) && is_readable($path)) { |
||
108 | return $path; |
||
109 | } else { |
||
110 | return false; |
||
111 | } |
||
112 | } |
||
113 | |||
114 | // needed for WPML-filter |
||
115 | protected function ao_getDomain($in) { |
||
129 | |||
130 | |||
131 | // logger |
||
132 | protected function ao_logger($logmsg,$appendHTML=true) { |
||
140 | |||
141 | // hide everything between noptimize-comment tags |
||
142 | protected function hide_noptimize($noptimize_in) { |
||
157 | |||
158 | // unhide noptimize-tags |
||
159 | View Code Duplication | protected function restore_noptimize($noptimize_in) { |
|
174 | |||
175 | View Code Duplication | protected function hide_iehacks($iehacks_in) { |
|
190 | |||
191 | View Code Duplication | protected function restore_iehacks($iehacks_in) { |
|
206 | |||
207 | View Code Duplication | protected function hide_comments($comments_in) { |
|
222 | |||
223 | View Code Duplication | protected function restore_comments($comments_in) { |
|
238 | |||
239 | protected function url_replace_cdn( $url ) { |
||
269 | |||
270 | protected function inject_in_html($payload,$replaceTag) { |
||
288 | |||
289 | protected function isremovable($tag, $removables) { |
||
297 | |||
298 | // inject already minified code in optimized JS/CSS |
||
299 | View Code Duplication | protected function inject_minified($in) { |
|
351 | |||
352 | protected function minify_single($pathIn) { |
||
414 | |||
415 | protected function str_ends_in($haystack,$needle) { |
||
425 | } |
||
426 |
In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:
Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion: