PluginProbe
Autoptimize / 3.1.4
Autoptimize v3.1.4
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/autoptimizeCriticalCSSCore.php +234 -228 2.7.73.1.4 View file →
@@ -8,90 +8,98 @@
8 8 exit;
9 9 }
10 10
11 11 class autoptimizeCriticalCSSCore {
12 - public function __construct()
13 - {
14 - // fetch all options at once and populate them individually explicitely as globals.
15 - $all_options = autoptimizeCriticalCSSBase::fetch_options();
16 - foreach ( $all_options as $_option => $_value ) {
17 - global ${$_option};
18 - ${$_option} = $_value;
19 - }
12 + /**
13 + * Critical CSS page types.
14 + *
15 + * @var array
16 + */
17 + protected $_types = null;
20 18
19 + public function __construct() {
20 + $this->criticalcss = autoptimize()->criticalcss();
21 21 $this->run();
22 22 }
23 23
24 24 public function run() {
25 - global $ao_css_defer;
26 - global $ao_ccss_deferjquery;
27 - global $ao_ccss_key;
28 - global $ao_ccss_unloadccss;
25 + $css_defer = $this->criticalcss->get_option( 'css_defer' );
26 + $deferjquery = $this->criticalcss->get_option( 'deferjquery' );
27 + $unloadccss = $this->criticalcss->get_option( 'unloadccss' );
29 28
30 - // add all filters to do CCSS if key present.
31 - if ( $ao_css_defer && isset( $ao_ccss_key ) && ! empty( $ao_ccss_key ) ) {
32 - // Set AO behavior: disable minification to avoid double minifying and caching.
33 - add_filter( 'autoptimize_filter_css_critcss_minify', '__return_false' );
34 - add_filter( 'autoptimize_filter_css_defer_inline', array( $this, 'ao_ccss_frontend' ), 10, 1 );
29 + if ( ! $css_defer ) {
30 + return;
31 + }
35 32
36 - // Add the action to enqueue jobs for CriticalCSS cron.
37 - add_action( 'autoptimize_action_css_hash', array( 'autoptimizeCriticalCSSEnqueue', 'ao_ccss_enqueue' ), 10, 1 );
33 + // add all filters to do CCSS
34 + // Set AO behavior: disable minification to avoid double minifying and caching.
35 + add_filter( 'autoptimize_filter_css_critcss_minify', '__return_false' );
36 + add_filter( 'autoptimize_filter_css_defer_inline', array( $this, 'ao_ccss_frontend' ), 10, 1 );
38 37
39 - // conditionally add the filter to defer jquery and others.
40 - if ( $ao_ccss_deferjquery ) {
41 - add_filter( 'autoptimize_html_after_minify', array( $this, 'ao_ccss_defer_jquery' ), 11, 1 );
42 - }
38 + // Add the action to enqueue jobs for CriticalCSS cron.
39 + if ( $this->criticalcss->is_api_active() ) {
40 + add_action( 'autoptimize_action_css_hash', array( $this->criticalcss, 'enqueue' ), 10, 1 );
41 + }
43 42
44 - // conditionally add filter to unload the CCSS.
45 - if ( $ao_ccss_unloadccss ) {
46 - add_filter( 'autoptimize_html_after_minify', array( $this, 'ao_ccss_unloadccss' ), 12, 1 );
47 - }
43 + // conditionally add the filter to defer jquery and others but only if not done so in autoptimizeScripts.
44 + $_native_defer = false;
45 + if ( 'on' === autoptimizeOptionWrapper::get_option( 'autoptimize_js_defer_not_aggregate' ) && 'on' === autoptimizeOptionWrapper::get_option( 'autoptimize_js_defer_inline' ) ) {
46 + $_native_defer = true;
47 + }
48 + if ( $deferjquery && ! $_native_defer ) {
49 + add_filter( 'autoptimize_html_after_minify', array( $this, 'ao_ccss_defer_jquery' ), 11, 1 );
50 + }
48 51
49 - // Order paths by length, as longest ones have greater priority in the rules.
50 - if ( ! empty( $ao_ccss_rules['paths'] ) ) {
51 - $keys = array_map( 'strlen', array_keys( $ao_ccss_rules['paths'] ) );
52 - array_multisort( $keys, SORT_DESC, $ao_ccss_rules['paths'] );
53 - }
52 + // conditionally add filter to unload the CCSS.
53 + if ( $unloadccss ) {
54 + add_filter( 'autoptimize_html_after_minify', array( $this, 'ao_ccss_unloadccss' ), 12, 1 );
55 + }
54 56
55 - // Add an array with default WordPress's conditional tags
56 - // NOTE: these tags are sorted.
57 - global $ao_ccss_types;
58 - $ao_ccss_types = $this->get_ao_ccss_core_types();
57 + // Order paths by length, as longest ones have greater priority in the rules.
58 + $rules = $this->criticalcss->get_option( 'rules' );
59 + if ( ! empty( $rules['paths'] ) ) {
60 + $keys = array_map( 'strlen', array_keys( $rules['paths'] ) );
61 + array_multisort( $keys, SORT_DESC, $rules['paths'] );
62 + // TODO: Not sure what we're doing here. Sorted the $keys,
63 + // but they don't seem to be used anywhere.
64 + }
59 65
60 - // Extend conditional tags on plugin initalization.
61 - add_action( apply_filters( 'autoptimize_filter_ccss_extend_types_hook', 'init' ), array( $this, 'ao_ccss_extend_types' ) );
66 + // Add an array with default WordPress's conditional tags
67 + // NOTE: these tags are sorted.
68 + $this->_types = $this->get_ao_ccss_core_types();
62 69
63 - // When autoptimize cache is cleared, also clear transient cache for page templates.
64 - add_action( 'autoptimize_action_cachepurged', array( 'autoptimizeCriticalCSSCore', 'ao_ccss_clear_page_tpl_cache' ), 10, 0 );
65 - }
70 + // Extend conditional tags on plugin initalization.
71 + add_action( apply_filters( 'autoptimize_filter_ccss_extend_types_hook', 'init' ), array( $this, 'ao_ccss_extend_types' ) );
72 +
73 + // When autoptimize cache is cleared, also clear transient cache for page templates.
74 + add_action( 'autoptimize_action_cachepurged', array( $this, 'ao_ccss_clear_page_tpl_cache' ), 10, 0 );
66 75 }
67 76
68 77 public function ao_ccss_frontend( $inlined ) {
69 78 // Apply CriticalCSS to frontend pages
70 79 // Attach types and settings arrays.
71 - global $ao_ccss_types;
72 - global $ao_ccss_rules;
73 - global $ao_ccss_additional;
74 - global $ao_ccss_loggedin;
75 - global $ao_ccss_debug;
76 - global $ao_ccss_keyst;
77 - $no_ccss = '';
80 + $rules = $this->criticalcss->get_option( 'rules' );
81 + $additional = $this->criticalcss->get_option( 'additional' );
82 + $loggedin = $this->criticalcss->get_option( 'loggedin' );
83 + $debug = $this->criticalcss->get_option( 'debug' );
84 + $no_ccss = '';
85 + $additional = autoptimizeStyles::sanitize_css( $additional );
78 86
79 87 // Only if keystatus is OK and option to add CCSS for logged on users is on or user is not logged in.
80 - if ( ( $ao_ccss_keyst && 2 == $ao_ccss_keyst ) && ( $ao_ccss_loggedin || ! is_user_logged_in() ) ) {
88 + if ( $loggedin || ! is_user_logged_in() ) {
81 89 // Check for a valid CriticalCSS based on path to return its contents.
82 90 $req_path = strtok( $_SERVER['REQUEST_URI'], '?' );
83 - if ( ! empty( $ao_ccss_rules['paths'] ) ) {
84 - foreach ( $ao_ccss_rules['paths'] as $path => $rule ) {
91 + if ( ! empty( $rules['paths'] ) ) {
92 + foreach ( $rules['paths'] as $path => $rule ) {
85 93 // explicit match OR partial match if MANUAL rule.
86 - if ( $req_path == $path || urldecode( $req_path ) == $path || ( false == $rule['hash'] && false != $rule['file'] && strpos( $req_path, str_replace( site_url(), '', $path ) ) !== false ) ) {
94 + if ( ( $this->criticalcss->is_api_active() || $this->criticalcss->is_rule_manual( $rule ) ) && ( $req_path == $path || urldecode( $req_path ) == $path || ( apply_filters( 'autoptimize_filter_ccss_core_path_partial_match', true ) && false == $rule['hash'] && false != $rule['file'] && strpos( $req_path, str_replace( site_url(), '', $path ) ) !== false ) ) ) {
87 95 if ( file_exists( AO_CCSS_DIR . $rule['file'] ) ) {
88 96 $_ccss_contents = file_get_contents( AO_CCSS_DIR . $rule['file'] );
89 97 if ( 'none' != $_ccss_contents ) {
90 - if ( $ao_ccss_debug ) {
98 + if ( $debug ) {
91 99 $_ccss_contents = '/* PATH: ' . $path . ' hash: ' . $rule['hash'] . ' file: ' . $rule['file'] . ' */ ' . $_ccss_contents;
92 100 }
93 - return apply_filters( 'autoptimize_filter_ccss_core_ccss', $_ccss_contents . $ao_ccss_additional );
101 + return apply_filters( 'autoptimize_filter_ccss_core_ccss', $_ccss_contents . $additional );
94 102 } else {
95 103 $no_ccss = 'none';
96 104 }
97 105 }
@@ -99,57 +107,57 @@
99 107 }
100 108 }
101 109
102 110 // Check for a valid CriticalCSS based on conditional tags to return its contents.
103 - if ( ! empty( $ao_ccss_rules['types'] ) && 'none' !== $no_ccss ) {
111 + if ( ! empty( $rules['types'] ) && 'none' !== $no_ccss ) {
104 112 // order types-rules by the order of the original $ao_ccss_types array so as not to depend on the order in which rules were added.
105 - $ao_ccss_rules['types'] = array_replace( array_intersect_key( array_flip( $ao_ccss_types ), $ao_ccss_rules['types'] ), $ao_ccss_rules['types'] );
106 - $is_front_page = is_front_page();
113 + $rules['types'] = array_replace( array_intersect_key( array_flip( $this->_types ), $rules['types'] ), $rules['types'] );
114 + $is_front_page = is_front_page();
107 115
108 - foreach ( $ao_ccss_rules['types'] as $type => $rule ) {
109 - if ( in_array( $type, $ao_ccss_types ) && file_exists( AO_CCSS_DIR . $rule['file'] ) ) {
116 + foreach ( $rules['types'] as $type => $rule ) {
117 + if ( ( $this->criticalcss->is_api_active() || $this->criticalcss->is_rule_manual( $rule ) ) && in_array( $type, $this->_types ) && file_exists( AO_CCSS_DIR . $rule['file'] ) ) {
110 118 $_ccss_contents = file_get_contents( AO_CCSS_DIR . $rule['file'] );
111 119 if ( $is_front_page && 'is_front_page' == $type ) {
112 120 if ( 'none' != $_ccss_contents ) {
113 - if ( $ao_ccss_debug ) {
121 + if ( $debug ) {
114 122 $_ccss_contents = '/* TYPES: ' . $type . ' hash: ' . $rule['hash'] . ' file: ' . $rule['file'] . ' */ ' . $_ccss_contents;
115 123 }
116 - return apply_filters( 'autoptimize_filter_ccss_core_ccss', $_ccss_contents . $ao_ccss_additional );
124 + return apply_filters( 'autoptimize_filter_ccss_core_ccss', $_ccss_contents . $additional );
117 125 } else {
118 126 $no_ccss = 'none';
119 127 }
120 - } elseif ( strpos( $type, 'custom_post_' ) === 0 && ! $is_front_page ) {
128 + } elseif ( ( $this->criticalcss->is_api_active() || $this->criticalcss->is_rule_manual( $rule ) ) && strpos( $type, 'custom_post_' ) === 0 && ! $is_front_page ) {
121 129 if ( get_post_type( get_the_ID() ) === substr( $type, 12 ) ) {
122 130 if ( 'none' != $_ccss_contents ) {
123 - if ( $ao_ccss_debug ) {
131 + if ( $debug ) {
124 132 $_ccss_contents = '/* TYPES: ' . $type . ' hash: ' . $rule['hash'] . ' file: ' . $rule['file'] . ' */ ' . $_ccss_contents;
125 133 }
126 - return apply_filters( 'autoptimize_filter_ccss_core_ccss', $_ccss_contents . $ao_ccss_additional );
134 + return apply_filters( 'autoptimize_filter_ccss_core_ccss', $_ccss_contents . $additional );
127 135 } else {
128 136 $no_ccss = 'none';
129 137 }
130 138 }
131 - } elseif ( 0 === strpos( $type, 'template_' ) && ! $is_front_page ) {
139 + } elseif ( ( $this->criticalcss->is_api_active() || $this->criticalcss->is_rule_manual( $rule ) ) && 0 === strpos( $type, 'template_' ) && ! $is_front_page ) {
132 140 if ( is_page_template( substr( $type, 9 ) ) ) {
133 141 if ( 'none' != $_ccss_contents ) {
134 - if ( $ao_ccss_debug ) {
142 + if ( $debug ) {
135 143 $_ccss_contents = '/* TYPES: ' . $type . ' hash: ' . $rule['hash'] . ' file: ' . $rule['file'] . ' */ ' . $_ccss_contents;
136 144 }
137 - return apply_filters( 'autoptimize_filter_ccss_core_ccss', $_ccss_contents . $ao_ccss_additional );
145 + return apply_filters( 'autoptimize_filter_ccss_core_ccss', $_ccss_contents . $additional );
138 146 } else {
139 147 $no_ccss = 'none';
140 148 }
141 149 }
142 - } elseif ( ! $is_front_page ) {
150 + } elseif ( ( $this->criticalcss->is_api_active() || $this->criticalcss->is_rule_manual( $rule ) ) && ! $is_front_page ) {
143 151 // all "normal" conditional tags, core + woo + buddypress + edd + bbpress
144 152 // but we have to remove the prefix for the non-core ones for them to function.
145 153 $type = str_replace( array( 'woo_', 'bp_', 'bbp_', 'edd_' ), '', $type );
146 154 if ( function_exists( $type ) && call_user_func( $type ) ) {
147 155 if ( 'none' != $_ccss_contents ) {
148 - if ( $ao_ccss_debug ) {
156 + if ( $debug ) {
149 157 $_ccss_contents = '/* TYPES: ' . $type . ' hash: ' . $rule['hash'] . ' file: ' . $rule['file'] . ' */ ' . $_ccss_contents;
150 158 }
151 - return apply_filters( 'autoptimize_filter_ccss_core_ccss', $_ccss_contents . $ao_ccss_additional );
159 + return apply_filters( 'autoptimize_filter_ccss_core_ccss', $_ccss_contents . $additional );
152 160 } else {
153 161 $no_ccss = 'none';
154 162 }
155 163 }
@@ -161,9 +169,9 @@
161 169
162 170 // Finally, inline the default CriticalCSS if any or else the entire CSS for the page
163 171 // This also applies to logged in users if the option to add CCSS for logged in users has been disabled.
164 172 if ( ! empty( $inlined ) && 'none' !== $no_ccss ) {
165 - return apply_filters( 'autoptimize_filter_ccss_core_ccss', $inlined . $ao_ccss_additional );
173 + return apply_filters( 'autoptimize_filter_ccss_core_ccss', $inlined . $additional );
166 174 } else {
167 175 add_filter( 'autoptimize_filter_css_inline', '__return_true' );
168 176 return;
169 177 }
@@ -169,11 +177,12 @@
169 177 }
170 178 }
171 179
172 180 public function ao_ccss_defer_jquery( $in ) {
173 - global $ao_ccss_loggedin;
181 + $loggedin = $this->criticalcss->get_option( 'loggedin' );
182 +
174 183 // defer all linked and inline JS.
175 - if ( ( ! is_user_logged_in() || $ao_ccss_loggedin ) && preg_match_all( '#<script.*>(.*)</script>#Usmi', $in, $matches, PREG_SET_ORDER ) ) {
184 + if ( ( ! is_user_logged_in() || $loggedin ) && preg_match_all( '#<script.*>(.*)</script>#Usmi', $in, $matches, PREG_SET_ORDER ) ) {
176 185 foreach ( $matches as $match ) {
177 186 if ( str_replace( apply_filters( 'autoptimize_filter_ccss_core_defer_exclude', array( 'data-noptimize="1"', 'data-cfasync="false"', 'data-pagespeed-no-defer' ) ), '', $match[0] ) !== $match[0] ) {
178 187 // do not touch JS with noptimize/ cfasync/ pagespeed-no-defer flags.
179 188 continue;
@@ -192,9 +201,9 @@
192 201 }
193 202
194 203 public function ao_ccss_unloadccss( $html_in ) {
195 204 // set media attrib of inline CCSS to none at onLoad to avoid it impacting full CSS (rarely needed).
196 - $_unloadccss_js = apply_filters( 'autoptimize_filter_ccss_core_unloadccss_js', '<script>window.addEventListener("load", function(event) {document.getElementById("aoatfcss").media="none";})</script>' );
205 + $_unloadccss_js = apply_filters( 'autoptimize_filter_ccss_core_unloadccss_js', '<script>window.addEventListener("load", function(event) {var el = document.getElementById("aoatfcss"); if(el) el.media = "none";})</script>' );
197 206
198 207 if ( false !== strpos( $html_in, $_unloadccss_js . '</body>' ) ) {
199 208 return $html_in;
200 209 }
@@ -201,17 +210,25 @@
201 210
202 211 return str_replace( '</body>', $_unloadccss_js . '</body>', $html_in );
203 212 }
204 213
214 + /**
215 + * Get the types array.
216 + *
217 + * @return array|null
218 + */
219 + public function get_types() {
220 + return $this->_types;
221 + }
222 +
205 223 public function ao_ccss_extend_types() {
206 224 // Extend contidional tags
207 225 // Attach the conditional tags array.
208 - global $ao_ccss_types;
209 226
210 227 // in some cases $ao_ccss_types is empty and/or not an array, this should work around that problem.
211 - if ( empty( $ao_ccss_types ) || ! is_array( $ao_ccss_types ) ) {
212 - $ao_ccss_types = get_ao_ccss_core_types();
213 - autoptimizeCriticalCSSCore::ao_ccss_log( 'Empty types array in extend, refetching array with core conditionals.', 3 );
228 + if ( empty( $this->_types ) || ! is_array( $this->_types ) ) {
229 + $this->_types = $this->get_ao_ccss_core_types();
230 + $this->ao_ccss_log( 'Empty types array in extend, refetching array with core conditionals.', 3 );
214 231 }
215 232
216 233 // Custom Post Types.
217 234 $cpts = get_post_types(
@@ -222,9 +239,9 @@
222 239 'names',
223 240 'and'
224 241 );
225 242 foreach ( $cpts as $cpt ) {
226 - array_unshift( $ao_ccss_types, 'custom_post_' . $cpt );
243 + array_unshift( $this->_types, 'custom_post_' . $cpt );
227 244 }
228 245
229 246 // Templates.
230 247 // Transient cache to avoid frequent disk reads.
@@ -233,14 +250,14 @@
233 250 $templates = wp_get_theme()->get_page_templates();
234 251 set_transient( 'autoptimize_ccss_page_templates', $templates, HOUR_IN_SECONDS );
235 252 }
236 253 foreach ( $templates as $tplfile => $tplname ) {
237 - array_unshift( $ao_ccss_types, 'template_' . $tplfile );
254 + array_unshift( $this->_types, 'template_' . $tplfile );
238 255 }
239 256
240 257 // bbPress tags.
241 258 if ( function_exists( 'is_bbpress' ) ) {
242 - $ao_ccss_types = array_merge(
259 + $this->_types = array_merge(
243 260 array(
244 261 'bbp_is_bbpress',
245 262 'bbp_is_favorites',
246 263 'bbp_is_forum_archive',
@@ -264,15 +281,16 @@
264 281 'bbp_is_topic_tag_edit',
265 282 'bbp_is_topics_created',
266 283 'bbp_is_user_home',
267 284 'bbp_is_user_home_edit',
268 - ), $ao_ccss_types
285 + ),
286 + $this->_types
269 287 );
270 288 }
271 289
272 290 // BuddyPress tags.
273 291 if ( function_exists( 'is_buddypress' ) ) {
274 - $ao_ccss_types = array_merge(
292 + $this->_types = array_merge(
275 293 array(
276 294 'bp_is_activation_page',
277 295 'bp_is_activity',
278 296 'bp_is_blogs',
@@ -306,27 +324,29 @@
306 324 'bp_is_settings_component',
307 325 'bp_is_user',
308 326 'bp_is_user_profile',
309 327 'bp_is_wire',
310 - ), $ao_ccss_types
328 + ),
329 + $this->_types
311 330 );
312 331 }
313 332
314 333 // Easy Digital Downloads (EDD) tags.
315 334 if ( function_exists( 'edd_is_checkout' ) ) {
316 - $ao_ccss_types = array_merge(
335 + $this->_types = array_merge(
317 336 array(
318 337 'edd_is_checkout',
319 338 'edd_is_failed_transaction_page',
320 339 'edd_is_purchase_history_page',
321 340 'edd_is_success_page',
322 - ), $ao_ccss_types
341 + ),
342 + $this->_types
323 343 );
324 344 }
325 345
326 346 // WooCommerce tags.
327 347 if ( class_exists( 'WooCommerce' ) ) {
328 - $ao_ccss_types = array_merge(
348 + $this->_types = array_merge(
329 349 array(
330 350 'woo_is_account_page',
331 351 'woo_is_cart',
332 352 'woo_is_checkout',
@@ -335,44 +355,36 @@
335 355 'woo_is_product_tag',
336 356 'woo_is_shop',
337 357 'woo_is_wc_endpoint_url',
338 358 'woo_is_woocommerce',
339 - ), $ao_ccss_types
359 + ),
360 + $this->_types
340 361 );
341 362 }
342 363 }
343 364
344 365 public function get_ao_ccss_core_types() {
345 - global $ao_ccss_types;
346 - if ( empty( $ao_ccss_types ) || ! is_array( $ao_ccss_types ) ) {
347 - return array(
348 - 'is_404',
349 - 'is_archive',
350 - 'is_author',
351 - 'is_category',
352 - 'is_front_page',
353 - 'is_home',
354 - 'is_page',
355 - 'is_post',
356 - 'is_search',
357 - 'is_attachment',
358 - 'is_single',
359 - 'is_sticky',
360 - 'is_paged',
361 - );
362 - } else {
363 - return $ao_ccss_types;
364 - }
366 + return array(
367 + 'is_404',
368 + 'is_front_page',
369 + 'is_home',
370 + 'is_page',
371 + 'is_single',
372 + 'is_category',
373 + 'is_author',
374 + 'is_archive',
375 + 'is_search',
376 + 'is_attachment',
377 + 'is_sticky',
378 + 'is_paged',
379 + );
365 380 }
366 381
367 - public static function ao_ccss_key_status( $render ) {
382 + public function ao_ccss_key_status( $render ) {
368 383 // Provide key status
369 384 // Get key and key status.
370 - global $ao_ccss_key;
371 - global $ao_ccss_keyst;
372 - $self = new self();
373 - $key = $ao_ccss_key;
374 - $key_status = $ao_ccss_keyst;
385 + $key = $this->criticalcss->get_option( 'key' );
386 + $key_status = $this->criticalcss->get_option( 'keyst' );
375 387
376 388 // Prepare returned variables.
377 389 $key_return = array();
378 390 $status = false;
@@ -393,9 +405,9 @@
393 405 $message = __( 'Your API key is invalid. Please enter a valid <a href="https://criticalcss.com/?aff=1" target="_blank">criticalcss.com</a> key.', 'autoptimize' );
394 406 } elseif ( $key && ! $key_status ) {
395 407 // Key exists but it has no valid status yet
396 408 // Perform key validation.
397 - $key_check = $self->ao_ccss_key_validation( $key );
409 + $key_check = $this->ao_ccss_key_validation( $key );
398 410
399 411 // Key is valid, set valid status.
400 412 if ( $key_check ) {
401 413 $status = 'valid';
@@ -435,9 +447,9 @@
435 447 return $key_return;
436 448 }
437 449
438 450 public function ao_ccss_key_validation( $key ) {
439 - global $ao_ccss_noptimize;
451 + $noptimize = $this->criticalcss->get_option( 'noptimize' );
440 452
441 453 // POST a dummy job to criticalcss.com to check for key validation
442 454 // Prepare home URL for the request.
443 455 $src_url = get_home_url();
@@ -442,127 +454,123 @@
442 454 // Prepare home URL for the request.
443 455 $src_url = get_home_url();
444 456
445 457 // Avoid AO optimizations if required by config or avoid lazyload if lazyload is active in AO.
446 - if ( ! empty( $ao_ccss_noptimize ) ) {
447 - $src_url .= '?ao_noptirocket=1';
458 + if ( ! empty( $noptimize ) ) {
459 + $src_url .= '/?ao_noptirocket=1';
448 460 } elseif ( class_exists( 'autoptimizeImages', false ) && autoptimizeImages::should_lazyload_wrapper() ) {
449 - $src_url .= '?ao_nolazy=1';
461 + $src_url .= '/?ao_nolazy=1';
450 462 }
451 463
452 464 $src_url = apply_filters( 'autoptimize_filter_ccss_cron_srcurl', $src_url );
453 465
454 - // Prepare the request.
455 - $url = esc_url_raw( AO_CCSS_API . 'generate' );
456 - $args = array(
457 - 'headers' => array(
458 - 'User-Agent' => 'Autoptimize v' . AO_CCSS_VER,
459 - 'Content-type' => 'application/json; charset=utf-8',
460 - 'Authorization' => 'JWT ' . $key,
461 - 'Connection' => 'close',
462 - ),
463 - // Body must be JSON.
464 - 'body' => json_encode(
465 - apply_filters( 'autoptimize_ccss_cron_api_generate_body',
466 + if ( true !== autoptimizeUtils::is_local_server( parse_url( $src_url, PHP_URL_HOST ) ) ) {
467 + // Prepare the request.
468 + $url = esc_url_raw( AO_CCSS_API . 'generate' );
469 + $args = array(
470 + 'headers' => apply_filters(
471 + 'autoptimize_ccss_cron_api_generate_headers',
466 472 array(
467 - 'url' => $src_url,
468 - 'aff' => 1,
469 - 'aocssv' => AO_CCSS_VER,
473 + 'User-Agent' => 'Autoptimize v' . AO_CCSS_VER,
474 + 'Content-type' => 'application/json; charset=utf-8',
475 + 'Authorization' => 'JWT ' . $key,
476 + 'Connection' => 'close',
470 477 )
471 - )
472 - ),
473 - );
478 + ),
479 + // Body must be JSON.
480 + 'body' => json_encode(
481 + apply_filters(
482 + 'autoptimize_ccss_cron_api_generate_body',
483 + array(
484 + 'url' => $src_url,
485 + 'aff' => 1,
486 + 'aocssv' => AO_CCSS_VER,
487 + )
488 + ),
489 + JSON_UNESCAPED_SLASHES
490 + ),
491 + );
474 492
475 - // Dispatch the request and store its response code.
476 - $req = wp_safe_remote_post( $url, $args );
477 - $code = wp_remote_retrieve_response_code( $req );
478 - $body = json_decode( wp_remote_retrieve_body( $req ), true );
493 + // Dispatch the request and store its response code.
494 + $req = wp_safe_remote_post( $url, $args );
495 + $code = wp_remote_retrieve_response_code( $req );
496 + $body = json_decode( wp_remote_retrieve_body( $req ), true );
479 497
480 - if ( 200 == $code ) {
481 - // Response is OK.
482 - // Set key status as valid and log key check.
483 - update_option( 'autoptimize_ccss_keyst', 2 );
484 - autoptimizeCriticalCSSCore::ao_ccss_log( 'criticalcss.com: API key is valid, updating key status', 3 );
498 + if ( 200 == $code ) {
499 + // Response is OK.
500 + // Set key status as valid and log key check.
501 + update_option( 'autoptimize_ccss_keyst', 2 );
502 + $this->ao_ccss_log( 'criticalcss.com: API key is valid, updating key status', 3 );
485 503
486 - // extract job-id from $body and put it in the queue as a P job
487 - // but only if no jobs and no rules!
488 - global $ao_ccss_queue;
489 - global $ao_ccss_rules;
504 + // extract job-id from $body and put it in the queue as a P job
505 + // but only if no jobs and no rules!
506 + $queue = $this->criticalcss->get_option( 'queue' );
507 + $rules = $this->criticalcss->get_option( 'rules' );
490 508
491 - if ( 0 == count( $ao_ccss_queue ) && 0 == count( $ao_ccss_rules['types'] ) && 0 == count( $ao_ccss_rules['paths'] ) ) {
492 - if ( 'JOB_QUEUED' == $body['job']['status'] || 'JOB_ONGOING' == $body['job']['status'] ) {
493 - $jprops['ljid'] = 'firstrun';
494 - $jprops['rtarget'] = 'types|is_front_page';
495 - $jprops['ptype'] = 'is_front_page';
496 - $jprops['hashes'][] = 'dummyhash';
497 - $jprops['hash'] = 'dummyhash';
498 - $jprops['file'] = null;
499 - $jprops['jid'] = $body['job']['id'];
500 - $jprops['jqstat'] = $body['job']['status'];
501 - $jprops['jrstat'] = null;
502 - $jprops['jvstat'] = null;
503 - $jprops['jctime'] = microtime( true );
504 - $jprops['jftime'] = null;
505 - $ao_ccss_queue['/'] = $jprops;
506 - $ao_ccss_queue_raw = json_encode( $ao_ccss_queue );
507 - update_option( 'autoptimize_ccss_queue', $ao_ccss_queue_raw, false );
508 - autoptimizeCriticalCSSCore::ao_ccss_log( 'Created P job for is_front_page based on API key check response.', 3 );
509 + if ( 0 == count( $queue ) && 0 == count( $rules['types'] ) && 0 == count( $rules['paths'] ) ) {
510 + if ( 'JOB_QUEUED' == $body['job']['status'] || 'JOB_ONGOING' == $body['job']['status'] ) {
511 + $jprops['ljid'] = 'firstrun';
512 + $jprops['rtarget'] = 'types|is_front_page';
513 + $jprops['ptype'] = 'is_front_page';
514 + $jprops['hashes'][] = 'dummyhash';
515 + $jprops['hash'] = 'dummyhash';
516 + $jprops['file'] = null;
517 + $jprops['jid'] = $body['job']['id'];
518 + $jprops['jqstat'] = $body['job']['status'];
519 + $jprops['jrstat'] = null;
520 + $jprops['jvstat'] = null;
521 + $jprops['jctime'] = microtime( true );
522 + $jprops['jftime'] = null;
523 + $queue['/'] = $jprops;
524 + $queue_raw = json_encode( $queue );
525 + update_option( 'autoptimize_ccss_queue', $queue_raw, false );
526 + $this->ao_ccss_log( 'Created P job for is_front_page based on API key check response.', 3 );
527 + }
509 528 }
529 + return true;
530 + } elseif ( 401 == $code ) {
531 + // Response is unauthorized
532 + // Set key status as invalid and log key check.
533 + update_option( 'autoptimize_ccss_keyst', 1 );
534 + $this->ao_ccss_log( 'criticalcss.com: API key is invalid, updating key status', 3 );
535 + return false;
536 + } else {
537 + // Response unkown
538 + // Log key check attempt.
539 + $this->ao_ccss_log( 'criticalcss.com: could not check API key status, this is a service error, body follows if any...', 2 );
540 + if ( ! empty( $body ) ) {
541 + $this->ao_ccss_log( print_r( $body, true ), 2 );
542 + }
543 + if ( is_wp_error( $req ) ) {
544 + $this->ao_ccss_log( $req->get_error_message(), 2 );
545 + }
546 + return false;
510 547 }
511 - return true;
512 - } elseif ( 401 == $code ) {
513 - // Response is unauthorized
514 - // Set key status as invalid and log key check.
515 - update_option( 'autoptimize_ccss_keyst', 1 );
516 - autoptimizeCriticalCSSCore::ao_ccss_log( 'criticalcss.com: API key is invalid, updating key status', 3 );
517 - return false;
518 548 } else {
519 - // Response unkown
520 - // Log key check attempt.
521 - autoptimizeCriticalCSSCore::ao_ccss_log( 'criticalcss.com: could not check API key status, this is a service error, body follows if any...', 2 );
522 - if ( ! empty( $body ) ) {
523 - autoptimizeCriticalCSSCore::ao_ccss_log( print_r( $body, true ), 2 );
524 - }
525 - if ( is_wp_error( $req ) ) {
526 - autoptimizeCriticalCSSCore::ao_ccss_log( $req->get_error_message(), 2 );
527 - }
549 + // localhost/ private network server, no API check possible.
528 550 return false;
529 551 }
530 552 }
531 553
532 - public static function ao_ccss_viewport() {
554 + public function ao_ccss_viewport() {
533 555 // Get viewport size
534 556 // Attach viewport option.
535 - global $ao_ccss_viewport;
557 + $viewport = $this->criticalcss->get_option( 'viewport' );
536 558
537 - // Prepare viewport array.
538 - $viewport = array();
539 -
540 - // Viewport Width.
541 - if ( ! empty( $ao_ccss_viewport['w'] ) ) {
542 - $viewport['w'] = $ao_ccss_viewport['w'];
543 - } else {
544 - $viewport['w'] = '';
545 - }
546 -
547 - // Viewport Height.
548 - if ( ! empty( $ao_ccss_viewport['h'] ) ) {
549 - $viewport['h'] = $ao_ccss_viewport['h'];
550 - } else {
551 - $viewport['h'] = '';
552 - }
553 -
554 - return $viewport;
559 + return array(
560 + 'w' => ! empty( $viewport['w'] ) ? $viewport['w'] : '',
561 + 'h' => ! empty( $viewport['h'] ) ? $viewport['h'] : '',
562 + );
555 563 }
556 564
557 - public static function ao_ccss_check_contents( $ccss ) {
565 + public function ao_ccss_check_contents( $ccss ) {
558 566 // Perform basic exploit avoidance and CSS validation.
559 567 if ( ! empty( $ccss ) ) {
560 568 // Try to avoid code injection.
561 - $blocklist = array( '#!/', 'function(', '<script', '<?php' );
569 + $blocklist = array( '#!/', 'function(', '<script', '<?php', '</style', ' onload=', ' onerror=', ' onmouse', ' onscroll=', ' onclick=' );
562 570 foreach ( $blocklist as $blocklisted ) {
563 - if ( strpos( $ccss, $blocklisted ) !== false ) {
564 - autoptimizeCriticalCSSCore::ao_ccss_log( 'Critical CSS received contained blocklisted content.', 2 );
571 + if ( stripos( $ccss, $blocklisted ) !== false ) {
572 + $this->ao_ccss_log( 'Critical CSS received contained blocklisted content.', 2 );
565 573 return false;
566 574 }
567 575 }
568 576
@@ -569,9 +577,9 @@
569 577 // Check for most basics CSS structures.
570 578 $needlist = array( '{', '}', ':' );
571 579 foreach ( $needlist as $needed ) {
572 580 if ( false === strpos( $ccss, $needed ) && 'none' !== $ccss ) {
573 - autoptimizeCriticalCSSCore::ao_ccss_log( 'Critical CSS received did not seem to contain real CSS.', 2 );
581 + $this->ao_ccss_log( 'Critical CSS received did not seem to contain real CSS.', 2 );
574 582 return false;
575 583 }
576 584 }
577 585 }
@@ -579,12 +587,12 @@
579 587 // Return true if file critical CSS is sane.
580 588 return true;
581 589 }
582 590
583 - public static function ao_ccss_log( $msg, $lvl ) {
591 + public function ao_ccss_log( $msg, $lvl ) {
584 592 // Commom logging facility
585 593 // Attach debug option.
586 - global $ao_ccss_debug;
594 + $debug = $this->criticalcss->get_option( 'debug' );
587 595
588 596 // Prepare log levels, where accepted $lvl are:
589 597 // 1: II (for info)
590 598 // 2: EE (for error)
@@ -590,23 +598,22 @@
590 598 // 2: EE (for error)
591 599 // 3: DD (for debug)
592 600 // Default: UU (for unkown).
593 601 $level = false;
594 - switch ( $lvl ) {
595 - case 1:
596 - $level = 'II';
597 - break;
598 - case 2:
599 - $level = 'EE';
600 - break;
601 - case 3:
602 - // Output debug messages only if debug mode is enabled.
603 - if ( $ao_ccss_debug ) {
602 + if ( $debug ) {
603 + switch ( $lvl ) {
604 + case 1:
605 + $level = 'II';
606 + break;
607 + case 2:
608 + $level = 'EE';
609 + break;
610 + case 3:
604 611 $level = 'DD';
605 - }
606 - break;
607 - default:
608 - $level = 'UU';
612 + break;
613 + default:
614 + $level = 'UU';
615 + }
609 616 }
610 617
611 618 // Prepare and write a log message if there's a valid level.
612 619 if ( $level ) {
@@ -611,9 +618,9 @@
611 618 // Prepare and write a log message if there's a valid level.
612 619 if ( $level ) {
613 620
614 621 // Prepare message.
615 - $message = date( 'c' ) . ' - [' . $level . '] ' . htmlentities( $msg ) . '<br>';
622 + $message = date( 'c' ) . ' - [' . $level . '] ' . htmlentities( $msg ) . '<br>'; // @codingStandardsIgnoreLine
616 623
617 624 // Write message to log file.
618 625 error_log( $message, 3, AO_CCSS_LOG );
619 626 }
@@ -618,10 +625,9 @@
618 625 error_log( $message, 3, AO_CCSS_LOG );
619 626 }
620 627 }
621 628
622 - public static function ao_ccss_clear_page_tpl_cache() {
629 + public function ao_ccss_clear_page_tpl_cache() {
623 630 // Clears transient cache for page templates.
624 631 delete_transient( 'autoptimize_ccss_page_templates' );
625 632 }
626 -
627 633 }