futtta /
autoptimize
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly |
||
| 3 | |||
| 4 | abstract class autoptimizeBase { |
||
| 5 | protected $content = ''; |
||
| 6 | protected $tagWarning = false; |
||
| 7 | |||
| 8 | public function __construct($content) { |
||
| 9 | $this->content = $content; |
||
| 10 | } |
||
| 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) { |
||
| 116 | // make sure the url starts with something vaguely resembling a protocol |
||
| 117 | if ((strpos($in,"http")!==0) && (strpos($in,"//")!==0)) { |
||
| 118 | $in="http://".$in; |
||
| 119 | } |
||
| 120 | |||
| 121 | // do the actual parse_url |
||
| 122 | $out = parse_url($in,PHP_URL_HOST); |
||
| 123 | |||
| 124 | // fallback if parse_url does not understand the url is in fact a url |
||
| 125 | if (empty($out)) $out=$in; |
||
| 126 | |||
| 127 | return $out; |
||
| 128 | } |
||
| 129 | |||
| 130 | |||
| 131 | // logger |
||
| 132 | protected function ao_logger($logmsg,$appendHTML=true) { |
||
| 133 | if ($appendHTML) { |
||
| 134 | $logmsg="<!--noptimize--><!-- ".$logmsg." --><!--/noptimize-->"; |
||
| 135 | $this->content.=$logmsg; |
||
| 136 | } else { |
||
| 137 | error_log("Autoptimize: ".$logmsg); |
||
| 138 | } |
||
| 139 | } |
||
| 140 | |||
| 141 | // hide everything between noptimize-comment tags |
||
| 142 | protected function hide_noptimize($noptimize_in) { |
||
| 143 | if ( preg_match( '/<!--\s?noptimize\s?-->/', $noptimize_in ) ) { |
||
| 144 | $noptimize_out = preg_replace_callback( |
||
| 145 | '#<!--\s?noptimize\s?-->.*?<!--\s?/\s?noptimize\s?-->#is', |
||
| 146 | create_function( |
||
| 147 | '$matches', |
||
| 148 | 'return "%%NOPTIMIZE".AUTOPTIMIZE_HASH."%%".base64_encode($matches[0])."%%NOPTIMIZE%%";' |
||
| 149 | ), |
||
| 150 | $noptimize_in |
||
| 151 | ); |
||
| 152 | } else { |
||
| 153 | $noptimize_out = $noptimize_in; |
||
| 154 | } |
||
| 155 | return $noptimize_out; |
||
| 156 | } |
||
| 157 | |||
| 158 | // unhide noptimize-tags |
||
| 159 | View Code Duplication | protected function restore_noptimize($noptimize_in) { |
|
| 160 | if ( strpos( $noptimize_in, '%%NOPTIMIZE%%' ) !== false ) { |
||
| 161 | $noptimize_out = preg_replace_callback( |
||
| 162 | '#%%NOPTIMIZE'.AUTOPTIMIZE_HASH.'%%(.*?)%%NOPTIMIZE%%#is', |
||
| 163 | create_function( |
||
| 164 | '$matches', |
||
| 165 | 'return base64_decode($matches[1]);' |
||
| 166 | ), |
||
| 167 | $noptimize_in |
||
| 168 | ); |
||
| 169 | } else { |
||
| 170 | $noptimize_out = $noptimize_in; |
||
| 171 | } |
||
| 172 | return $noptimize_out; |
||
| 173 | } |
||
| 174 | |||
| 175 | View Code Duplication | protected function hide_iehacks($iehacks_in) { |
|
| 176 | if ( strpos( $iehacks_in, '<!--[if' ) !== false ) { |
||
| 177 | $iehacks_out = preg_replace_callback( |
||
| 178 | '#<!--\[if.*?\[endif\]-->#is', |
||
| 179 | create_function( |
||
| 180 | '$matches', |
||
| 181 | 'return "%%IEHACK".AUTOPTIMIZE_HASH."%%".base64_encode($matches[0])."%%IEHACK%%";' |
||
| 182 | ), |
||
| 183 | $iehacks_in |
||
| 184 | ); |
||
| 185 | } else { |
||
| 186 | $iehacks_out = $iehacks_in; |
||
| 187 | } |
||
| 188 | return $iehacks_out; |
||
| 189 | } |
||
| 190 | |||
| 191 | View Code Duplication | protected function restore_iehacks($iehacks_in) { |
|
| 192 | if ( strpos( $iehacks_in, '%%IEHACK%%' ) !== false ) { |
||
| 193 | $iehacks_out = preg_replace_callback( |
||
| 194 | '#%%IEHACK'.AUTOPTIMIZE_HASH.'%%(.*?)%%IEHACK%%#is', |
||
| 195 | create_function( |
||
| 196 | '$matches', |
||
| 197 | 'return base64_decode($matches[1]);' |
||
| 198 | ), |
||
| 199 | $iehacks_in |
||
| 200 | ); |
||
| 201 | } else { |
||
| 202 | $iehacks_out=$iehacks_in; |
||
| 203 | } |
||
| 204 | return $iehacks_out; |
||
| 205 | } |
||
| 206 | |||
| 207 | View Code Duplication | protected function hide_comments($comments_in) { |
|
| 208 | if ( strpos( $comments_in, '<!--' ) !== false ) { |
||
| 209 | $comments_out = preg_replace_callback( |
||
| 210 | '#<!--.*?-->#is', |
||
| 211 | create_function( |
||
| 212 | '$matches', |
||
| 213 | 'return "%%COMMENTS".AUTOPTIMIZE_HASH."%%".base64_encode($matches[0])."%%COMMENTS%%";' |
||
| 214 | ), |
||
| 215 | $comments_in |
||
| 216 | ); |
||
| 217 | } else { |
||
| 218 | $comments_out = $comments_in; |
||
| 219 | } |
||
| 220 | return $comments_out; |
||
| 221 | } |
||
| 222 | |||
| 223 | View Code Duplication | protected function restore_comments($comments_in) { |
|
| 224 | if ( strpos( $comments_in, '%%COMMENTS%%' ) !== false ) { |
||
| 225 | $comments_out = preg_replace_callback( |
||
| 226 | '#%%COMMENTS'.AUTOPTIMIZE_HASH.'%%(.*?)%%COMMENTS%%#is', |
||
| 227 | create_function( |
||
| 228 | '$matches', |
||
| 229 | 'return base64_decode($matches[1]);' |
||
| 230 | ), |
||
| 231 | $comments_in |
||
| 232 | ); |
||
| 233 | } else { |
||
| 234 | $comments_out=$comments_in; |
||
| 235 | } |
||
| 236 | return $comments_out; |
||
| 237 | } |
||
| 238 | |||
| 239 | protected function url_replace_cdn( $url ) { |
||
| 240 | // API filter to change base CDN URL |
||
| 241 | $cdn_url = apply_filters( 'autoptimize_filter_base_cdnurl', $this->cdn_url ); |
||
| 242 | |||
| 243 | if ( !empty($cdn_url) ) { |
||
| 244 | // prepend domain-less absolute URL's |
||
| 245 | if ( ( substr( $url, 0, 1 ) === '/' ) && ( substr( $url, 1, 1 ) !== '/' ) ) { |
||
| 246 | $url = rtrim( $cdn_url, '/' ) . $url; |
||
| 247 | } else { |
||
| 248 | // get wordpress base URL |
||
| 249 | $WPSiteBreakdown = parse_url( AUTOPTIMIZE_WP_SITE_URL ); |
||
| 250 | $WPBaseUrl = $WPSiteBreakdown['scheme'] . '://' . $WPSiteBreakdown['host']; |
||
| 251 | if ( ! empty( $WPSiteBreakdown['port'] ) ) { |
||
| 252 | $WPBaseUrl .= ":" . $WPSiteBreakdown['port']; |
||
| 253 | } |
||
| 254 | // replace full url's with scheme |
||
| 255 | $tmp_url = str_replace( $WPBaseUrl, rtrim( $cdn_url, '/' ), $url ); |
||
| 256 | if ( $tmp_url === $url ) { |
||
| 257 | // last attempt; replace scheme-less URL's |
||
| 258 | $url = str_replace( preg_replace( '/https?:/', '', $WPBaseUrl ), rtrim( $cdn_url, '/' ), $url ); |
||
| 259 | } else { |
||
| 260 | $url = $tmp_url; |
||
| 261 | } |
||
| 262 | } |
||
| 263 | } |
||
| 264 | |||
| 265 | // allow API filter to alter URL after CDN replacement |
||
| 266 | $url = apply_filters( 'autoptimize_filter_base_replace_cdn', $url ); |
||
| 267 | return $url; |
||
| 268 | } |
||
| 269 | |||
| 270 | protected function inject_in_html($payload,$replaceTag) { |
||
| 271 | if (strpos($this->content,$replaceTag[0])!== false) { |
||
| 272 | if ($replaceTag[1]==="after") { |
||
| 273 | $replaceBlock=$replaceTag[0].$payload; |
||
| 274 | } else if ($replaceTag[1]==="replace"){ |
||
| 275 | $replaceBlock=$payload; |
||
| 276 | } else { |
||
| 277 | $replaceBlock=$payload.$replaceTag[0]; |
||
| 278 | } |
||
| 279 | $this->content = substr_replace($this->content,$replaceBlock,strpos($this->content,$replaceTag[0]),strlen($replaceTag[0])); |
||
| 280 | } else { |
||
| 281 | $this->content .= $payload; |
||
| 282 | if (!$this->tagWarning) { |
||
| 283 | $this->content .= "<!--noptimize--><!-- Autoptimize found a problem with the HTML in your Theme, tag \"".str_replace(array("<",">"),"",$replaceTag[0])."\" missing --><!--/noptimize-->"; |
||
| 284 | $this->tagWarning=true; |
||
| 285 | } |
||
| 286 | } |
||
| 287 | } |
||
| 288 | |||
| 289 | protected function isremovable($tag, $removables) { |
||
| 290 | foreach ($removables as $match) { |
||
| 291 | if (strpos($tag,$match)!==false) { |
||
| 292 | return true; |
||
| 293 | } |
||
| 294 | } |
||
| 295 | return false; |
||
| 296 | } |
||
| 297 | |||
| 298 | // inject already minified code in optimized JS/CSS |
||
| 299 | View Code Duplication | protected function inject_minified($in) { |
|
| 300 | if ( strpos( $in, '%%INJECTLATER%%' ) !== false ) { |
||
| 301 | $out = preg_replace_callback( |
||
| 302 | '#\/\*\!%%INJECTLATER'.AUTOPTIMIZE_HASH.'%%(.*?)%%INJECTLATER%%\*\/#is', |
||
| 303 | create_function( |
||
| 304 | '$matches', |
||
| 305 | '$filepath=base64_decode(strtok($matches[1],"|")); |
||
| 306 | $filecontent=file_get_contents($filepath); |
||
| 307 | |||
| 308 | // remove BOM |
||
| 309 | $filecontent = preg_replace("#\x{EF}\x{BB}\x{BF}#","",$filecontent); |
||
| 310 | |||
| 311 | // remove comments and blank lines |
||
| 312 | if (substr($filepath,-3,3)===".js") { |
||
| 313 | $filecontent=preg_replace("#^\s*\/\/.*$#Um","",$filecontent); |
||
| 314 | } |
||
| 315 | |||
| 316 | $filecontent=preg_replace("#^\s*\/\*[^!].*\*\/\s?#Um","",$filecontent); |
||
| 317 | $filecontent=preg_replace("#(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+#", "\n", $filecontent); |
||
| 318 | |||
| 319 | // differentiate between JS, CSS and other files |
||
| 320 | if (substr($filepath,-3,3)===".js") { |
||
| 321 | if ((substr($filecontent,-1,1)!==";")&&(substr($filecontent,-1,1)!=="}")) { |
||
| 322 | $filecontent.=";"; |
||
| 323 | } |
||
| 324 | |||
| 325 | if (get_option("autoptimize_js_trycatch")==="on") { |
||
| 326 | $filecontent="try{".$filecontent."}catch(e){}"; |
||
| 327 | } |
||
| 328 | } else if ((substr($filepath,-4,4)===".css")) { |
||
| 329 | $filecontent=autoptimizeStyles::fixurls($filepath,$filecontent); |
||
| 330 | } else { |
||
| 331 | $filecontent=""; |
||
| 332 | } |
||
| 333 | |||
| 334 | // return |
||
| 335 | return "\n".$filecontent;' |
||
| 336 | ), |
||
| 337 | $in |
||
| 338 | ); |
||
| 339 | } else { |
||
| 340 | $out = $in; |
||
| 341 | } |
||
| 342 | return $out; |
||
| 343 | } |
||
| 344 | |||
| 345 | protected function minify_single($pathIn) { |
||
| 346 | // determine JS or CSS and set var (also mimetype), return false if neither |
||
| 347 | if ( $this->str_ends_in($pathIn,".js") === true ) { |
||
| 348 | $codeType="js"; |
||
| 349 | $codeMime="text/javascript"; |
||
| 350 | } else if ( $this->str_ends_in($pathIn,".css") === true ) { |
||
| 351 | $codeType="css"; |
||
| 352 | $codeMime="text/css"; |
||
| 353 | } else { |
||
| 354 | return false; |
||
| 355 | } |
||
| 356 | |||
| 357 | // if min.js or min.css return false |
||
| 358 | if (( $this->str_ends_in($pathIn,"-min.".$codeType) === true ) || ( $this->str_ends_in($pathIn,".min.".$codeType) === true ) || ( $this->str_ends_in($pathIn,"js/jquery/jquery.js") === true ) ) { |
||
| 359 | return false; |
||
| 360 | } |
||
| 361 | |||
| 362 | // read file, return false if empty |
||
| 363 | $_toMinify = file_get_contents($pathIn); |
||
| 364 | if ( empty($_toMinify) ) return false; |
||
| 365 | |||
| 366 | // check cache |
||
| 367 | $_md5hash = "single_".md5($_toMinify); |
||
| 368 | $_cache = new autoptimizeCache($_md5hash,$codeType); |
||
| 369 | if ($_cache->check() ) { |
||
| 370 | $_CachedMinifiedUrl = AUTOPTIMIZE_CACHE_URL.$_cache->getname(); |
||
| 371 | } else { |
||
| 372 | // if not in cache first minify |
||
| 373 | $_Minified = $_toMinify; |
||
| 374 | if ($codeType === "js") { |
||
| 375 | if (class_exists('JSMin') && apply_filters( 'autoptimize_js_do_minify' , true)) { |
||
| 376 | if (@is_callable(array("JSMin","minify"))) { |
||
| 377 | $tmp_code = trim(JSMin::minify($_toMinify)); |
||
| 378 | } |
||
| 379 | } |
||
| 380 | } else if ($codeType === "css") { |
||
| 381 | // make sure paths to background images/ imported css/ fonts .. are OK |
||
| 382 | $_toMinify = $this->fixurls($pathIn,$_toMinify); |
||
|
0 ignored issues
–
show
|
|||
| 383 | if (class_exists('Minify_CSS_Compressor')) { |
||
| 384 | $tmp_code = trim(Minify_CSS_Compressor::process($_toMinify)); |
||
| 385 | } else if(class_exists('CSSmin')) { |
||
| 386 | $cssmin = new CSSmin(); |
||
| 387 | if (method_exists($cssmin,"run")) { |
||
| 388 | $tmp_code = trim($cssmin->run($_toMinify)); |
||
| 389 | } elseif (@is_callable(array($cssmin,"minify"))) { |
||
| 390 | $tmp_code = trim(CssMin::minify($_toMinify)); |
||
| 391 | } |
||
| 392 | } |
||
| 393 | } |
||
| 394 | if (!empty($tmp_code)) { |
||
| 395 | $_Minified = $tmp_code; |
||
| 396 | unset($tmp_code); |
||
| 397 | } |
||
| 398 | // and then cache |
||
| 399 | $_cache->cache($_Minified,$codeMime); |
||
| 400 | $_CachedMinifiedUrl = AUTOPTIMIZE_CACHE_URL.$_cache->getname(); |
||
| 401 | } |
||
| 402 | unset($_cache); |
||
| 403 | |||
| 404 | // if CDN, then CDN |
||
| 405 | $_CachedMinifiedUrl = $this->url_replace_cdn($_CachedMinifiedUrl); |
||
| 406 | |||
| 407 | return $_CachedMinifiedUrl; |
||
| 408 | } |
||
| 409 | |||
| 410 | protected function str_ends_in($haystack,$needle) { |
||
| 411 | $needleLength = strlen($needle); |
||
| 412 | $haystackLength = strlen($haystack); |
||
| 413 | $lastPos=strrpos($haystack,$needle); |
||
| 414 | if ($lastPos === $haystackLength - $needleLength) { |
||
| 415 | return true; |
||
| 416 | } else { |
||
| 417 | return false; |
||
| 418 | } |
||
| 419 | } |
||
| 420 | } |
||
| 421 |
Let’s take a look at an example:
In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.
Available Fixes
Change the type-hint for the parameter:
Add an additional type-check:
Add the method to the parent class: