PluginProbe
Autoptimize / 1.6.0
Autoptimize v1.6.0
2.2.2 2.3.0 2.3.1 2.3.2 2.3.3 2.3.4 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.5.0 2.5.1 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 2.7.8 All 107 releases
← All changes | classes/autoptimizeBase.php +40 -412 2.3.31.6.0 View file →
@@ -1,420 +1,48 @@
1 1 <?php
2 -if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
3 2
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 - 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 - 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 - 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 - 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 - 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 - 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 = autoptimizeStyles::fixurls($pathIn,$_toMinify);
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);
3 +abstract class autoptimizeBase
4 +{
5 + protected $content = '';
403 6
404 - // if CDN, then CDN
405 - $_CachedMinifiedUrl = $this->url_replace_cdn($_CachedMinifiedUrl);
406 -
407 - return $_CachedMinifiedUrl;
7 + public function __construct($content)
8 + {
9 + $this->content = $content;
10 + //Best place to catch errors
408 11 }
409 12
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;
13 + //Reads the page and collects tags
14 + abstract public function read($justhead);
15 +
16 + //Joins and optimizes collected things
17 + abstract public function minify();
18 +
19 + //Caches the things
20 + abstract public function cache();
21 +
22 + //Returns the content
23 + abstract public function getcontent();
24 +
25 + //Converts an URL to a full path
26 + protected function getpath($url)
27 + {
28 + $siteurl = site_url();
29 + if ((strpos($url,'//')===false) && (strpos($url,parse_url($siteurl,PHP_URL_HOST))===false)) {
30 + $url = $siteurl.$url;
418 31 }
32 + $path = str_replace(WP_ROOT_URL,'',$url);
33 + if(preg_match('#^(https?|ftp)://#i',$path))
34 + {
35 + /** External script/css (adsense, etc) */
36 + return false;
37 + }
38 + $path = str_replace('//','/',WP_ROOT_PATH.$path);
39 + return $path;
40 + }
41 +
42 + // coz I'm a crappy developer and I need easy access to whatever I want to log
43 + protected function ao_logger($logmsg) {
44 + $logfile=WP_CONTENT_DIR.'/ao_log.txt';
45 + $logmsg.="\n";
46 + file_put_contents($logfile,$logmsg,FILE_APPEND);
419 47 }
420 48 }