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/autoptimizeCriticalCSSCron.php +276 -246 2.7.33.1.4 View file →
@@ -8,16 +8,10 @@
8 8 exit;
9 9 }
10 10
11 11 class autoptimizeCriticalCSSCron {
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 + public function __construct() {
13 + $this->criticalcss = autoptimize()->criticalcss();
20 14
21 15 // Add queue control to a registered event.
22 16 add_action( 'ao_ccss_queue', array( $this, 'ao_ccss_queue_control' ) );
23 17 // Add cleaning job to a registered event.
@@ -25,12 +19,13 @@
25 19 }
26 20
27 21 public function ao_ccss_queue_control() {
28 22 // The queue execution backend.
29 - global $ao_ccss_key;
30 - if ( ! isset( $ao_ccss_key ) || empty( $ao_ccss_key ) ) {
23 + $key = $this->criticalcss->get_option( 'key' );
24 +
25 + if ( empty( $key ) ) {
31 26 // no key set, not processing the queue!
32 - autoptimizeCriticalCSSCore::ao_ccss_log( 'No key set, so not processing queue.', 3 );
27 + $this->criticalcss->log( 'No key set, so not processing queue.', 3 );
33 28 return;
34 29 }
35 30
36 31 /**
@@ -55,9 +50,9 @@
55 50 $qdobj = json_decode( $qdobj_raw, true );
56 51 if ( $qdobj ) {
57 52 if ( 1 === $qdobj['enable'] ) {
58 53 $queue_debug = true;
59 - autoptimizeCriticalCSSCore::ao_ccss_log( 'Queue operating in debug mode with the following settings: <' . $qdobj_raw . '>', 3 );
54 + $this->criticalcss->log( 'Queue operating in debug mode with the following settings: <' . $qdobj_raw . '>', 3 );
60 55 }
61 56 }
62 57 }
63 58
@@ -75,27 +70,32 @@
75 70 // Proceed with the queue if it's not already running.
76 71 if ( ! $queue_lock ) {
77 72
78 73 // Log queue start and create the lock file.
79 - autoptimizeCriticalCSSCore::ao_ccss_log( 'Queue control started', 3 );
74 + $this->criticalcss->log( 'Queue control started', 3 );
80 75 if ( touch( AO_CCSS_LOCK ) ) {
81 - autoptimizeCriticalCSSCore::ao_ccss_log( 'Queue control locked', 3 );
76 + $this->criticalcss->log( 'Queue control locked', 3 );
82 77 }
83 78
84 79 // Attach required variables.
85 - global $ao_ccss_queue;
86 - global $ao_ccss_rlimit;
80 + $queue = $this->criticalcss->get_option( 'queue' );
81 + $rtimelimit = $this->criticalcss->get_option( 'rtimelimit' );
87 82
88 - // Initialize job counters.
89 - $jc = 1;
90 - $jr = 1;
91 - $jt = count( $ao_ccss_queue );
83 + // Initialize counters.
84 + if ( 0 == $rtimelimit ) {
85 + // no time limit set, let's go with 1000 seconds.
86 + $rtimelimit = 1000;
87 + }
88 + $mt = time() + $rtimelimit; // maxtime queue processing can run.
89 + $jc = 1; // job count number.
90 + $jr = 1; // jobs requests number.
91 + $jt = count( $queue ); // number of jobs in queue.
92 92
93 93 // Sort queue by ascending job status (e.g. ERROR, JOB_ONGOING, JOB_QUEUED, NEW...).
94 - array_multisort( array_column( $ao_ccss_queue, 'jqstat' ), $ao_ccss_queue ); // @codingStandardsIgnoreLine
94 + array_multisort( array_column( $queue, 'jqstat' ), $queue ); // @codingStandardsIgnoreLine
95 95
96 96 // Iterates over the entire queue.
97 - foreach ( $ao_ccss_queue as $path => $jprops ) {
97 + foreach ( $queue as $path => $jprops ) {
98 98 // Prepare flags and target rule.
99 99 $update = false;
100 100 $deljob = false;
101 101 $rule_update = false;
@@ -102,15 +102,15 @@
102 102 $oldccssfile = false;
103 103 $trule = explode( '|', $jprops['rtarget'] );
104 104
105 105 // Log job count.
106 - autoptimizeCriticalCSSCore::ao_ccss_log( 'Processing job ' . $jc . ' of ' . $jt . ' with id <' . $jprops['ljid'] . '> and status <' . $jprops['jqstat'] . '>', 3 );
106 + $this->criticalcss->log( 'Processing job ' . $jc . ' of ' . $jt . ' with id <' . $jprops['ljid'] . '> and status <' . $jprops['jqstat'] . '>', 3 );
107 107
108 108 // Process NEW jobs.
109 109 if ( 'NEW' == $jprops['jqstat'] ) {
110 110
111 111 // Log the new job.
112 - autoptimizeCriticalCSSCore::ao_ccss_log( 'Found NEW job with local ID <' . $jprops['ljid'] . '>, starting its queue processing', 3 );
112 + $this->criticalcss->log( 'Found NEW job with local ID <' . $jprops['ljid'] . '>, starting its queue processing', 3 );
113 113
114 114 // Compare job and rule hashes (if any).
115 115 $hash = $this->ao_ccss_diff_hashes( $jprops['ljid'], $jprops['hash'], $jprops['hashes'], $jprops['rtarget'] );
116 116
@@ -115,38 +115,32 @@
115 115 $hash = $this->ao_ccss_diff_hashes( $jprops['ljid'], $jprops['hash'], $jprops['hashes'], $jprops['rtarget'] );
116 116
117 117 // If job hash is new or different of a previous one.
118 118 if ( $hash ) {
119 + if ( $jr > 2 ) {
120 + // we already posted 2 jobs to criticalcss.com, don't post more this run
121 + // but we can keep on processing the queue to keep it tidy.
122 + $this->criticalcss->log( 'Holding off on generating request for job with local ID <' . $jprops['ljid'] . '>, maximum number of POSTS reached.', 3 );
123 + continue;
124 + }
125 +
119 126 // Set job hash.
120 127 $jprops['hash'] = $hash;
121 128
122 - // If this is not the first job, wait 10 seconds before process next job due criticalcss.com API limits.
123 - if ( $jr > 1 ) {
124 - autoptimizeCriticalCSSCore::ao_ccss_log( 'Waiting ' . AO_CCSS_SLEEP . ' seconds due to criticalcss.com API limits', 3 );
125 - sleep( AO_CCSS_SLEEP );
126 - }
127 -
128 129 // Dispatch the job generate request and increment request count.
129 130 $apireq = $this->ao_ccss_api_generate( $path, $queue_debug, $qdobj['htcode'] );
130 131 $jr++;
131 132
132 133 // NOTE: All the following conditions maps to the ones in admin_settings_queue.js.php.
133 - if ( 'JOB_QUEUED' == $apireq['job']['status'] || 'JOB_ONGOING' == $apireq['job']['status'] ) {
134 - // SUCCESS: request has a valid result.
134 + if ( empty( $apireq ) ) {
135 + // ERROR: no response
135 136 // Update job properties.
136 - $jprops['jid'] = $apireq['job']['id'];
137 - $jprops['jqstat'] = $apireq['job']['status'];
138 - autoptimizeCriticalCSSCore::ao_ccss_log( 'Job id <' . $jprops['ljid'] . '> generate request successful, remote id <' . $jprops['jid'] . '>, status now is <' . $jprops['jqstat'] . '>', 3 );
139 - } elseif ( 'STATUS_JOB_BAD' == $apireq['job']['status'] ) {
140 - // ERROR: concurrent requests
141 - // Update job properties.
142 - $jprops['jid'] = $apireq['job']['id'];
143 - $jprops['jqstat'] = $apireq['job']['status'];
144 - $jprops['jrstat'] = $apireq['error'];
137 + $jprops['jqstat'] = 'NO_RESPONSE';
138 + $jprops['jrstat'] = 'NONE';
145 139 $jprops['jvstat'] = 'NONE';
146 140 $jprops['jftime'] = microtime( true );
147 - autoptimizeCriticalCSSCore::ao_ccss_log( 'Concurrent requests when processing job id <' . $jprops['ljid'] . '>, job status is now <' . $jprops['jqstat'] . '>', 3 );
148 - } elseif ( 'INVALID_JWT_TOKEN' == $apireq['errorCode'] ) {
141 + $this->criticalcss->log( 'Job id <' . $jprops['ljid'] . '> request has no response, status now is <' . $jprops['jqstat'] . '>', 3 );
142 + } elseif ( array_key_exists( 'errorCode', $apireq ) && 'INVALID_JWT_TOKEN' == $apireq['errorCode'] ) {
149 143 // ERROR: key validation
150 144 // Update job properties.
151 145 $jprops['jqstat'] = $apireq['errorCode'];
152 146 $jprops['jrstat'] = $apireq['error'];
@@ -151,17 +145,28 @@
151 145 $jprops['jqstat'] = $apireq['errorCode'];
152 146 $jprops['jrstat'] = $apireq['error'];
153 147 $jprops['jvstat'] = 'NONE';
154 148 $jprops['jftime'] = microtime( true );
155 - autoptimizeCriticalCSSCore::ao_ccss_log( 'API key validation error when processing job id <' . $jprops['ljid'] . '>, job status is now <' . $jprops['jqstat'] . '>', 3 );
156 - } elseif ( empty( $apireq ) ) {
157 - // ERROR: no response
149 + $this->criticalcss->log( 'API key validation error when processing job id <' . $jprops['ljid'] . '>, job status is now <' . $jprops['jqstat'] . '>', 3 );
150 + } elseif ( array_key_exists( 'job', $apireq ) && 'JOB_QUEUED' == $apireq['job']['status'] || 'JOB_ONGOING' == $apireq['job']['status'] ) {
151 + // SUCCESS: request has a valid result.
158 152 // Update job properties.
159 - $jprops['jqstat'] = 'NO_RESPONSE';
160 - $jprops['jrstat'] = 'NONE';
153 + $jprops['jid'] = $apireq['job']['id'];
154 + $jprops['jqstat'] = $apireq['job']['status'];
155 + $this->criticalcss->log( 'Job id <' . $jprops['ljid'] . '> generate request successful, remote id <' . $jprops['jid'] . '>, status now is <' . $jprops['jqstat'] . '>', 3 );
156 + } elseif ( 'STATUS_JOB_BAD' == $apireq['job']['status'] ) {
157 + // ERROR: concurrent requests
158 + // Update job properties.
159 + $jprops['jid'] = $apireq['job']['id'];
160 + $jprops['jqstat'] = $apireq['job']['status'];
161 + if ( $apireq['job']['error'] ) {
162 + $jprops['jrstat'] = $apireq['job']['error'];
163 + } else {
164 + $jprops['jrstat'] = 'Baby did a bad bad thing';
165 + }
161 166 $jprops['jvstat'] = 'NONE';
162 167 $jprops['jftime'] = microtime( true );
163 - autoptimizeCriticalCSSCore::ao_ccss_log( 'Job id <' . $jprops['ljid'] . '> request has no response, status now is <' . $jprops['jqstat'] . '>', 3 );
168 + $this->criticalcss->log( 'Concurrent requests when processing job id <' . $jprops['ljid'] . '>, job status is now <' . $jprops['jqstat'] . '>', 3 );
164 169 } else {
165 170 // UNKNOWN: unhandled generate exception
166 171 // Update job properties.
167 172 $jprops['jqstat'] = 'JOB_UNKNOWN';
@@ -167,10 +172,10 @@
167 172 $jprops['jqstat'] = 'JOB_UNKNOWN';
168 173 $jprops['jrstat'] = 'NONE';
169 174 $jprops['jvstat'] = 'NONE';
170 175 $jprops['jftime'] = microtime( true );
171 - autoptimizeCriticalCSSCore::ao_ccss_log( 'Job id <' . $jprops['ljid'] . '> generate request has an UNKNOWN condition, status now is <' . $jprops['jqstat'] . '>, check log messages above for more information', 2 );
172 - autoptimizeCriticalCSSCore::ao_ccss_log( 'Job response was: ' . json_encode( $apireq ), 3 );
176 + $this->criticalcss->log( 'Job id <' . $jprops['ljid'] . '> generate request has an UNKNOWN condition, status now is <' . $jprops['jqstat'] . '>, check log messages above for more information', 2 );
177 + $this->criticalcss->log( 'Job response was: ' . json_encode( $apireq ), 3 );
173 178 }
174 179 } else {
175 180 // SUCCESS: Job hash is equal to a previous one, so it's done
176 181 // Update job status and finish time.
@@ -175,9 +180,9 @@
175 180 // SUCCESS: Job hash is equal to a previous one, so it's done
176 181 // Update job status and finish time.
177 182 $jprops['jqstat'] = 'JOB_DONE';
178 183 $jprops['jftime'] = microtime( true );
179 - autoptimizeCriticalCSSCore::ao_ccss_log( 'Job id <' . $jprops['ljid'] . '> requires no further processing, status now is <' . $jprops['jqstat'] . '>', 3 );
184 + $this->criticalcss->log( 'Job id <' . $jprops['ljid'] . '> requires no further processing, status now is <' . $jprops['jqstat'] . '>', 3 );
180 185 }
181 186
182 187 // Set queue update flag.
183 188 $update = true;
@@ -184,19 +189,12 @@
184 189
185 190 } elseif ( 'JOB_QUEUED' == $jprops['jqstat'] || 'JOB_ONGOING' == $jprops['jqstat'] ) {
186 191 // Process QUEUED and ONGOING jobs
187 192 // Log the pending job.
188 - autoptimizeCriticalCSSCore::ao_ccss_log( 'Found PENDING job with local ID <' . $jprops['ljid'] . '>, continuing its queue processing', 3 );
193 + $this->criticalcss->log( 'Found PENDING job with local ID <' . $jprops['ljid'] . '>, continuing its queue processing', 3 );
189 194
190 - // If this is not the first job, wait before process next job due criticalcss.com API limits.
191 - if ( $jr > 1 ) {
192 - autoptimizeCriticalCSSCore::ao_ccss_log( 'Waiting ' . AO_CCSS_SLEEP . ' seconds due to criticalcss.com API limits', 3 );
193 - sleep( AO_CCSS_SLEEP );
194 - }
195 -
196 195 // Dispatch the job result request and increment request count.
197 196 $apireq = $this->ao_ccss_api_results( $jprops['jid'], $queue_debug, $qdobj['htcode'] );
198 - $jr++;
199 197
200 198 // NOTE: All the following condigitons maps to the ones in admin_settings_queue.js.php
201 199 // Replace API response values if queue debugging is enabled and some value is set.
202 200 if ( $queue_debug ) {
@@ -215,9 +213,9 @@
215 213 // SUCCESS: request has a valid result
216 214 // Process a PENDING job
217 215 // Update job properties.
218 216 $jprops['jqstat'] = $apireq['status'];
219 - autoptimizeCriticalCSSCore::ao_ccss_log( 'Job id <' . $jprops['ljid'] . '> result request successful, remote id <' . $jprops['jid'] . '>, status <' . $jprops['jqstat'] . '> unchanged', 3 );
217 + $this->criticalcss->log( 'Job id <' . $jprops['ljid'] . '> result request successful, remote id <' . $jprops['jid'] . '>, status <' . $jprops['jqstat'] . '> unchanged', 3 );
220 218 } elseif ( 'JOB_DONE' == $apireq['status'] ) {
221 219 // Process a DONE job
222 220 // New resultStatus from ccss.com "HTML_404", consider as "GOOD" for now.
223 221 if ( 'HTML_404' == $apireq['resultStatus'] ) {
@@ -223,10 +221,10 @@
223 221 if ( 'HTML_404' == $apireq['resultStatus'] ) {
224 222 $apireq['resultStatus'] = 'GOOD';
225 223 }
226 224
227 - if ( 'GOOD' == $apireq['resultStatus'] && 'GOOD' == $apireq['validationStatus'] ) {
228 - // SUCCESS: GOOD job with GOOD validation
225 + if ( 'GOOD' == $apireq['resultStatus'] && ( 'GOOD' == $apireq['validationStatus'] || 'WARN' == $apireq['validationStatus'] ) ) {
226 + // SUCCESS: GOOD job with GOOD or WARN validation
229 227 // Update job properties.
230 228 $jprops['file'] = $this->ao_ccss_save_file( $apireq['css'], $trule, false );
231 229 $jprops['jqstat'] = $apireq['status'];
232 230 $jprops['jrstat'] = $apireq['resultStatus'];
@@ -232,19 +230,25 @@
232 230 $jprops['jrstat'] = $apireq['resultStatus'];
233 231 $jprops['jvstat'] = $apireq['validationStatus'];
234 232 $jprops['jftime'] = microtime( true );
235 233 $rule_update = true;
236 - autoptimizeCriticalCSSCore::ao_ccss_log( 'Job id <' . $jprops['ljid'] . '> result request successful, remote id <' . $jprops['jid'] . '>, status <' . $jprops['jqstat'] . '>, file saved <' . $jprops['file'] . '>', 3 );
237 - } elseif ( 'GOOD' == $apireq['resultStatus'] && ( 'WARN' == $apireq['validationStatus'] || 'BAD' == $apireq['validationStatus'] || 'SCREENSHOT_WARN_BLANK' == $apireq['validationStatus'] ) ) {
238 - // SUCCESS: GOOD job with WARN or BAD validation
234 + do_action( 'autoptimize_action_ccss_cron_rule_saved', $jprops['rtarget'], $jprops['file'] );
235 + $this->criticalcss->log( 'Job id <' . $jprops['ljid'] . '> result request successful, remote id <' . $jprops['jid'] . '>, status <' . $jprops['jqstat'] . '>, file saved <' . $jprops['file'] . '>', 3 );
236 + } elseif ( 'GOOD' == $apireq['resultStatus'] && ( 'BAD' == $apireq['validationStatus'] || 'SCREENSHOT_WARN_BLANK' == $apireq['validationStatus'] ) ) {
237 + // SUCCESS: GOOD job with BAD or SCREENSHOT_WARN_BLANK validation
239 238 // Update job properties.
240 - $jprops['file'] = $this->ao_ccss_save_file( $apireq['css'], $trule, true );
241 239 $jprops['jqstat'] = $apireq['status'];
242 240 $jprops['jrstat'] = $apireq['resultStatus'];
243 241 $jprops['jvstat'] = $apireq['validationStatus'];
244 242 $jprops['jftime'] = microtime( true );
245 - $rule_update = true;
246 - autoptimizeCriticalCSSCore::ao_ccss_log( 'Job id <' . $jprops['ljid'] . '> result request successful, remote id <' . $jprops['jid'] . '>, status <' . $jprops['jqstat'] . ', file saved <' . $jprops['file'] . '> but requires REVIEW', 3 );
243 + if ( apply_filters( 'autoptimize_filter_ccss_save_review_rules', true ) ) {
244 + $jprops['file'] = $this->ao_ccss_save_file( $apireq['css'], $trule, true );
245 + $rule_update = true;
246 + do_action( 'autoptimize_action_ccss_cron_rule_saved', $jprops['rtarget'], $jprops['file'] );
247 + $this->criticalcss->log( 'Job id <' . $jprops['ljid'] . '> result request successful, remote id <' . $jprops['jid'] . '>, status <' . $jprops['jqstat'] . ', file saved <' . $jprops['file'] . '> but requires REVIEW', 3 );
248 + } else {
249 + $this->criticalcss->log( 'Job id <' . $jprops['ljid'] . '> result request successful, remote id <' . $jprops['jid'] . '>, status <' . $jprops['jqstat'] . ', file not saved because it required REVIEW.', 3 );
250 + }
247 251 } elseif ( 'GOOD' != $apireq['resultStatus'] && ( 'GOOD' != $apireq['validationStatus'] || 'WARN' != $apireq['validationStatus'] || 'BAD' != $apireq['validationStatus'] || 'SCREENSHOT_WARN_BLANK' != $apireq['validationStatus'] ) ) {
248 252 // ERROR: no GOOD, WARN or BAD results
249 253 // Update job properties.
250 254 $jprops['jqstat'] = $apireq['status'];
@@ -250,11 +254,11 @@
250 254 $jprops['jqstat'] = $apireq['status'];
251 255 $jprops['jrstat'] = $apireq['resultStatus'];
252 256 $jprops['jvstat'] = $apireq['validationStatus'];
253 257 $jprops['jftime'] = microtime( true );
254 - autoptimizeCriticalCSSCore::ao_ccss_log( 'Job id <' . $jprops['ljid'] . '> result request successful but job FAILED, status now is <' . $jprops['jqstat'] . '>', 3 );
258 + $this->criticalcss->log( 'Job id <' . $jprops['ljid'] . '> result request successful but job FAILED, status now is <' . $jprops['jqstat'] . '>', 3 );
255 259 $apireq['css'] = '/* critical css removed for DEBUG logging purposes */';
256 - autoptimizeCriticalCSSCore::ao_ccss_log( 'Job response was: ' . json_encode( $apireq ), 3 );
260 + $this->criticalcss->log( 'Job response was: ' . json_encode( $apireq ), 3 );
257 261 } else {
258 262 // UNKNOWN: unhandled JOB_DONE exception
259 263 // Update job properties.
260 264 $jprops['jqstat'] = 'JOB_UNKNOWN';
@@ -260,23 +264,24 @@
260 264 $jprops['jqstat'] = 'JOB_UNKNOWN';
261 265 $jprops['jrstat'] = $apireq['resultStatus'];
262 266 $jprops['jvstat'] = $apireq['validationStatus'];
263 267 $jprops['jftime'] = microtime( true );
264 - autoptimizeCriticalCSSCore::ao_ccss_log( 'Job id <' . $jprops['ljid'] . '> result request successful but job is UNKNOWN, status now is <' . $jprops['jqstat'] . '>', 2 );
268 + $this->criticalcss->log( 'Job id <' . $jprops['ljid'] . '> result request successful but job is UNKNOWN, status now is <' . $jprops['jqstat'] . '>', 2 );
265 269 $apireq['css'] = '/* critical css removed for DEBUG logging purposes */';
266 - autoptimizeCriticalCSSCore::ao_ccss_log( 'Job response was: ' . json_encode( $apireq ), 3 );
270 + $this->criticalcss->log( 'Job response was: ' . json_encode( $apireq ), 3 );
267 271 }
268 272 } elseif ( 'JOB_FAILED' == $apireq['job']['status'] || 'STATUS_JOB_BAD' == $apireq['job']['status'] ) {
269 273 // ERROR: failed job
270 274 // Update job properties.
271 275 $jprops['jqstat'] = $apireq['job']['status'];
272 - if ( $apireq['error'] ) {
276 + if ( $apireq['job']['error'] ) {
273 277 $jprops['jrstat'] = $apireq['job']['error'];
274 278 } else {
279 + $jprops['jrstat'] = 'Baby did a bad bad thing';
275 280 }
276 281 $jprops['jvstat'] = 'NONE';
277 282 $jprops['jftime'] = microtime( true );
278 - autoptimizeCriticalCSSCore::ao_ccss_log( 'Job id <' . $jprops['ljid'] . '> result request successful but job FAILED, status now is <' . $jprops['jqstat'] . '>', 3 );
283 + $this->criticalcss->log( 'Job id <' . $jprops['ljid'] . '> result request successful but job FAILED, status now is <' . $jprops['jqstat'] . '>', 3 );
279 284 } elseif ( 'This css no longer exists. Please re-generate it.' == $apireq['error'] ) {
280 285 // ERROR: CSS doesn't exist
281 286 // Update job properties.
282 287 $jprops['jqstat'] = 'NO_CSS';
@@ -282,9 +287,9 @@
282 287 $jprops['jqstat'] = 'NO_CSS';
283 288 $jprops['jrstat'] = $apireq['error'];
284 289 $jprops['jvstat'] = 'NONE';
285 290 $jprops['jftime'] = microtime( true );
286 - autoptimizeCriticalCSSCore::ao_ccss_log( 'Job id <' . $jprops['ljid'] . '> result request successful but job FAILED, status now is <' . $jprops['jqstat'] . '>', 3 );
291 + $this->criticalcss->log( 'Job id <' . $jprops['ljid'] . '> result request successful but job FAILED, status now is <' . $jprops['jqstat'] . '>', 3 );
287 292 } elseif ( empty( $apireq ) ) {
288 293 // ERROR: no response
289 294 // Update job properties.
290 295 $jprops['jqstat'] = 'NO_RESPONSE';
@@ -290,9 +295,9 @@
290 295 $jprops['jqstat'] = 'NO_RESPONSE';
291 296 $jprops['jrstat'] = 'NONE';
292 297 $jprops['jvstat'] = 'NONE';
293 298 $jprops['jftime'] = microtime( true );
294 - autoptimizeCriticalCSSCore::ao_ccss_log( 'Job id <' . $jprops['ljid'] . '> request has no response, status now is <' . $jprops['jqstat'] . '>', 3 );
299 + $this->criticalcss->log( 'Job id <' . $jprops['ljid'] . '> request has no response, status now is <' . $jprops['jqstat'] . '>', 3 );
295 300 } else {
296 301 // UNKNOWN: unhandled results exception
297 302 // Update job properties.
298 303 $jprops['jqstat'] = 'JOB_UNKNOWN';
@@ -298,9 +303,9 @@
298 303 $jprops['jqstat'] = 'JOB_UNKNOWN';
299 304 $jprops['jrstat'] = 'NONE';
300 305 $jprops['jvstat'] = 'NONE';
301 306 $jprops['jftime'] = microtime( true );
302 - autoptimizeCriticalCSSCore::ao_ccss_log( 'Job id <' . $jprops['ljid'] . '> result request has an UNKNOWN condition, status now is <' . $jprops['jqstat'] . '>, check log messages above for more information', 2 );
307 + $this->criticalcss->log( 'Job id <' . $jprops['ljid'] . '> result request has an UNKNOWN condition, status now is <' . $jprops['jqstat'] . '>, check log messages above for more information', 2 );
303 308 }
304 309
305 310 // Set queue update flag.
306 311 $update = true;
@@ -315,33 +320,33 @@
315 320 // Persist updated queue object.
316 321 if ( $update ) {
317 322 if ( ! $deljob ) {
318 323 // Update properties of a NEW or PENDING job...
319 - $ao_ccss_queue[ $path ] = $jprops;
324 + $queue[ $path ] = $jprops;
320 325 } else {
321 326 // ...or remove the DONE job.
322 - unset( $ao_ccss_queue[ $path ] );
323 - autoptimizeCriticalCSSCore::ao_ccss_log( 'Job id <' . $jprops['ljid'] . '> is DONE and was removed from the queue', 3 );
327 + unset( $queue[ $path ] );
328 + $this->criticalcss->log( 'Job id <' . $jprops['ljid'] . '> is DONE and was removed from the queue', 3 );
324 329 }
325 330
326 331 // Update queue object.
327 - $ao_ccss_queue_raw = json_encode( $ao_ccss_queue );
328 - update_option( 'autoptimize_ccss_queue', $ao_ccss_queue_raw, false );
329 - autoptimizeCriticalCSSCore::ao_ccss_log( 'Queue updated by job id <' . $jprops['ljid'] . '>', 3 );
332 + $queue_raw = json_encode( $queue );
333 + update_option( 'autoptimize_ccss_queue', $queue_raw, false );
334 + $this->criticalcss->log( 'Queue updated by job id <' . $jprops['ljid'] . '>', 3 );
330 335
331 336 // Update target rule.
332 337 if ( $rule_update ) {
333 338 $this->ao_ccss_rule_update( $jprops['ljid'], $jprops['rtarget'], $jprops['file'], $jprops['hash'] );
334 - autoptimizeCriticalCSSCore::ao_ccss_log( 'Job id <' . $jprops['ljid'] . '> updated the target rule <' . $jprops['rtarget'] . '>', 3 );
339 + $this->criticalcss->log( 'Job id <' . $jprops['ljid'] . '> updated the target rule <' . $jprops['rtarget'] . '>', 3 );
335 340 }
336 341 } else {
337 342 // Or log no queue action.
338 - autoptimizeCriticalCSSCore::ao_ccss_log( 'Nothing to do on this job', 3 );
343 + $this->criticalcss->log( 'Nothing to do on this job', 3 );
339 344 }
340 345
341 - // Break the loop if request limit is set and was reached.
342 - if ( $ao_ccss_rlimit && $ao_ccss_rlimit == $jr ) {
343 - autoptimizeCriticalCSSCore::ao_ccss_log( 'The limit of ' . $ao_ccss_rlimit . ' request(s) to criticalcss.com was reached, queue control must finish now', 3 );
346 + // Break the loop if request time limit is (almost exceeded).
347 + if ( time() > $mt ) {
348 + $this->criticalcss->log( 'The time limit of ' . $rtimelimit . ' seconds was exceeded, queue control must finish now', 3 );
344 349 break;
345 350 }
346 351
347 352 // Increment job counter.
@@ -350,15 +355,15 @@
350 355
351 356 // Remove the lock file and log the queue end.
352 357 if ( file_exists( AO_CCSS_LOCK ) ) {
353 358 unlink( AO_CCSS_LOCK );
354 - autoptimizeCriticalCSSCore::ao_ccss_log( 'Queue control unlocked', 3 );
359 + $this->criticalcss->log( 'Queue control unlocked', 3 );
355 360 }
356 - autoptimizeCriticalCSSCore::ao_ccss_log( 'Queue control finished', 3 );
361 + $this->criticalcss->log( 'Queue control finished', 3 );
357 362
358 363 // Log that queue is locked.
359 364 } else {
360 - autoptimizeCriticalCSSCore::ao_ccss_log( 'Queue is already running, skipping the attempt to run it again', 3 );
365 + $this->criticalcss->log( 'Queue is already running, skipping the attempt to run it again', 3 );
361 366 }
362 367 }
363 368
364 369 public function ao_ccss_diff_hashes( $ljid, $hash, $hashes, $rule ) {
@@ -367,9 +372,9 @@
367 372 if ( 1 == count( $hashes ) ) {
368 373 // Job with a single hash
369 374 // Set job hash.
370 375 $hash = $hashes[0];
371 - autoptimizeCriticalCSSCore::ao_ccss_log( 'Job id <' . $ljid . '> updated with SINGLE hash <' . $hash . '>', 3 );
376 + $this->criticalcss->log( 'Job id <' . $ljid . '> updated with SINGLE hash <' . $hash . '>', 3 );
372 377 } else {
373 378 // Job with multiple hashes
374 379 // Loop through hashes to concatenate them.
375 380 $nhash = '';
@@ -378,18 +383,18 @@
378 383 }
379 384
380 385 // Set job hash.
381 386 $hash = md5( $nhash );
382 - autoptimizeCriticalCSSCore::ao_ccss_log( 'Job id <' . $ljid . '> updated with a COMPOSITE hash <' . $hash . '>', 3 );
387 + $this->criticalcss->log( 'Job id <' . $ljid . '> updated with a COMPOSITE hash <' . $hash . '>', 3 );
383 388 }
384 389
385 390 // STEP 2: compare job to existing jobs to prevent double submission for same type+hash.
386 - global $ao_ccss_queue;
391 + $queue = $this->criticalcss->get_option( 'queue' );
387 392
388 - foreach ( $ao_ccss_queue as $queue_item ) {
389 - autoptimizeCriticalCSSCore::ao_ccss_log( 'Comparing <' . $rule . $hash . '> with <' . $queue_item['rtarget'] . $queue_item['hash'] . '>', 3 );
393 + foreach ( $queue as $queue_item ) {
394 + $this->criticalcss->log( 'Comparing <' . $rule . $hash . '> with <' . $queue_item['rtarget'] . $queue_item['hash'] . '>', 3 );
390 395 if ( $queue_item['hash'] == $hash && $queue_item['rtarget'] == $rule && in_array( $queue_item['jqstat'], array( 'JOB_QUEUED', 'JOB_ONGOING', 'JOB_DONE' ) ) ) {
391 - autoptimizeCriticalCSSCore::ao_ccss_log( 'Job id <' . $ljid . '> matches the already pending job <' . $queue_item['ljid'] . '>', 3 );
396 + $this->criticalcss->log( 'Job id <' . $ljid . '> matches the already pending job <' . $queue_item['ljid'] . '>', 3 );
392 397 return false;
393 398 }
394 399 }
395 400
@@ -394,32 +399,42 @@
394 399 }
395 400
396 401 // STEP 3: compare job and existing rule (if any) hashes
397 402 // Attach required arrays.
398 - global $ao_ccss_rules;
403 + $rules = $this->criticalcss->get_option( 'rules' );
399 404
400 405 // Prepare rule variables.
401 406 $trule = explode( '|', $rule );
402 - $srule = $ao_ccss_rules[ $trule[0] ][ $trule[1] ];
407 + if ( is_array( $trule ) && ! empty( $trule ) && array_key_exists( $trule[1], $rules[ $trule[0] ] ) ) {
408 + $srule = $rules[ $trule[0] ][ $trule[1] ];
409 + } else {
410 + $srule = '';
411 + }
403 412
413 + // If hash is empty, set it to now for a "forced job".
414 + if ( empty( $hash ) ) {
415 + $hash = 'new';
416 + $this->criticalcss->log( 'Job id <' . $ljid . '> had no hash, assuming forced job so setting hash to new', 3 );
417 + }
418 +
404 419 // Check if a MANUAL rule exist and return false.
405 420 if ( ! empty( $srule ) && ( 0 == $srule['hash'] && 0 != $srule['file'] ) ) {
406 - autoptimizeCriticalCSSCore::ao_ccss_log( 'Job id <' . $ljid . '> matches the MANUAL rule <' . $trule[0] . '|' . $trule[1] . '>', 3 );
421 + $this->criticalcss->log( 'Job id <' . $ljid . '> matches the MANUAL rule <' . $trule[0] . '|' . $trule[1] . '>', 3 );
407 422 return false;
408 423 } elseif ( ! empty( $srule ) ) {
409 424 // Check if an AUTO rule exist.
410 425 if ( $hash === $srule['hash'] && is_file( AO_CCSS_DIR . $srule['file'] ) && 0 != filesize( AO_CCSS_DIR . $srule['file'] ) ) {
411 426 // Check if job hash matches rule, if the CCSS file exists said file is not empty and return FALSE is so.
412 - autoptimizeCriticalCSSCore::ao_ccss_log( 'Job id <' . $ljid . '> with hash <' . $hash . '> MATCH the one in rule <' . $trule[0] . '|' . $trule[1] . '>', 3 );
427 + $this->criticalcss->log( 'Job id <' . $ljid . '> with hash <' . $hash . '> MATCH the one in rule <' . $trule[0] . '|' . $trule[1] . '>', 3 );
413 428 return false;
414 429 } else {
415 430 // Or return the new hash if they differ.
416 - autoptimizeCriticalCSSCore::ao_ccss_log( 'Job id <' . $ljid . '> with hash <' . $hash . '> DOES NOT MATCH the one in rule <' . $trule[0] . '|' . $trule[1] . '> or rule\'s CCSS file was invalid.', 3 );
431 + $this->criticalcss->log( 'Job id <' . $ljid . '> with hash <' . $hash . '> DOES NOT MATCH the one in rule <' . $trule[0] . '|' . $trule[1] . '> or rule\'s CCSS file was invalid.', 3 );
417 432 return $hash;
418 433 }
419 434 } else {
420 - // Or just return the hash if no rule exist yet.
421 - autoptimizeCriticalCSSCore::ao_ccss_log( 'Job id <' . $ljid . '> with hash <' . $hash . '> has no rule yet', 3 );
435 + // Return the hash for a job that has no rule yet.
436 + $this->criticalcss->log( 'Job id <' . $ljid . '> with hash <' . $hash . '> has no rule yet', 3 );
422 437 return $hash;
423 438 }
424 439 }
425 440
@@ -425,16 +440,13 @@
425 440
426 441 public function ao_ccss_api_generate( $path, $debug, $dcode ) {
427 442 // POST jobs to criticalcss.com and return responses
428 443 // Get key and key status.
429 - global $ao_ccss_key;
430 - global $ao_ccss_keyst;
431 - $key = $ao_ccss_key;
432 - $key_status = $ao_ccss_keyst;
444 + $key = $this->criticalcss->get_option( 'key' );
445 + $key_status = $this->criticalcss->get_option( 'keyst' );
446 + $noptimize = $this->criticalcss->get_option( 'noptimize' );
433 447
434 448 // Prepare full URL to request.
435 - global $ao_ccss_noptimize;
436 -
437 449 $site_host = get_site_url();
438 450 $site_path = parse_url( $site_host, PHP_URL_PATH );
439 451
440 452 if ( ! empty( $site_path ) ) {
@@ -443,15 +455,15 @@
443 455
444 456 // Logic to bind to one domain to avoid site clones of sites would
445 457 // automatically begin spawning requests to criticalcss.com which has
446 458 // a per domain cost.
447 - global $ao_ccss_domain;
448 - if ( empty( $ao_ccss_domain ) ) {
459 + $domain = $this->criticalcss->get_option( 'domain' );
460 + if ( empty( $domain ) ) {
449 461 // first request being done, update option to allow future requests are only allowed if from same domain.
450 462 update_option( 'autoptimize_ccss_domain', str_rot13( $site_host ) );
451 - } elseif ( trim( $ao_ccss_domain, '\'"' ) !== 'none' && parse_url( $site_host, PHP_URL_HOST ) !== parse_url( $ao_ccss_domain, PHP_URL_HOST ) && apply_filters( 'autoptimize_filter_ccss_bind_domain', true ) ) {
463 + } elseif ( trim( $domain, '\'"' ) !== 'none' && parse_url( $site_host, PHP_URL_HOST ) !== parse_url( $domain, PHP_URL_HOST ) && apply_filters( 'autoptimize_filter_ccss_bind_domain', true ) ) {
452 464 // not the same domain, log as error and return without posting to criticalcss.com.
453 - autoptimizeCriticalCSSCore::ao_ccss_log( 'Request for domain ' . $site_host . ' does not match bound domain ' . $ao_ccss_domain . ' so not proceeding.', 2 );
465 + $this->criticalcss->log( 'Request for domain ' . $site_host . ' does not match bound domain ' . $domain . ' so not proceeding.', 2 );
454 466 return false;
455 467 }
456 468
457 469 $src_url = $site_host . $path;
@@ -456,110 +468,119 @@
456 468
457 469 $src_url = $site_host . $path;
458 470
459 471 // Avoid AO optimizations if required by config or avoid lazyload if lazyload is active in AO.
460 - if ( ! empty( $ao_ccss_noptimize ) ) {
472 + if ( ! empty( $noptimize ) ) {
461 473 $src_url .= '?ao_noptirocket=1';
462 - } elseif ( class_exists( 'autoptimizeImages', false ) && autoptimizeImages::should_lazyload_wrapper() ) {
474 + } elseif ( ( class_exists( 'autoptimizeImages', false ) && autoptimizeImages::should_lazyload_wrapper() ) || apply_filters( 'autoptimize_filter_ccss_enforce_nolazy', false ) ) {
463 475 $src_url .= '?ao_nolazy=1';
464 476 }
465 477
466 478 $src_url = apply_filters( 'autoptimize_filter_ccss_cron_srcurl', $src_url );
467 479
468 - // Initialize request body.
469 - $body = array();
470 - $body['url'] = $src_url;
471 - $body['aff'] = 1;
472 - $body['aocssv'] = AO_CCSS_VER;
480 + if ( true !== autoptimizeUtils::is_local_server( parse_url( $src_url, PHP_URL_HOST ) ) ) {
481 + // Initialize request body.
482 + $body = array();
483 + $body['url'] = $src_url;
484 + $body['aff'] = 1;
485 + $body['aocssv'] = AO_CCSS_VER;
473 486
474 - // Prepare and add viewport size to the body if available.
475 - $viewport = autoptimizeCriticalCSSCore::ao_ccss_viewport();
476 - if ( ! empty( $viewport['w'] ) && ! empty( $viewport['h'] ) ) {
477 - $body['width'] = $viewport['w'];
478 - $body['height'] = $viewport['h'];
479 - }
487 + // Prepare and add viewport size to the body if available.
488 + $viewport = $this->criticalcss->viewport();
489 + if ( ! empty( $viewport['w'] ) && ! empty( $viewport['h'] ) ) {
490 + $body['width'] = $viewport['w'];
491 + $body['height'] = $viewport['h'];
492 + }
480 493
481 - // Prepare and add forceInclude to the body if available.
482 - global $ao_ccss_finclude;
483 - $finclude = $this->ao_ccss_finclude( $ao_ccss_finclude );
484 - if ( ! empty( $finclude ) ) {
485 - $body['forceInclude'] = $finclude;
486 - }
494 + // Prepare and add forceInclude to the body if available.
495 + $finclude = $this->criticalcss->get_option( 'finclude' );
496 + $finclude = $this->ao_ccss_finclude( $finclude );
497 + if ( ! empty( $finclude ) ) {
498 + $body['forceInclude'] = $finclude;
499 + }
487 500
488 - // Add filter to allow the body array to be altered (e.g. to add customPageHeaders).
489 - $body = apply_filters( 'autoptimize_ccss_cron_api_generate_body', $body );
501 + // Add filter to allow the body array to be altered (e.g. to add customPageHeaders).
502 + $body = apply_filters( 'autoptimize_ccss_cron_api_generate_body', $body );
490 503
491 - // Body must be json and log it.
492 - $body = json_encode( $body );
493 - autoptimizeCriticalCSSCore::ao_ccss_log( 'criticalcss.com: POST generate request body is ' . $body, 3 );
504 + // Body must be json and log it.
505 + $body = json_encode( $body, JSON_UNESCAPED_SLASHES );
506 + $this->criticalcss->log( 'criticalcss.com: POST generate request body is ' . $body, 3 );
494 507
495 - // Prepare the request.
496 - $url = esc_url_raw( AO_CCSS_API . 'generate?aover=' . AO_CCSS_VER );
497 - $args = array(
498 - 'headers' => array(
499 - 'User-Agent' => 'Autoptimize v' . AO_CCSS_VER,
500 - 'Content-type' => 'application/json; charset=utf-8',
501 - 'Authorization' => 'JWT ' . $key,
502 - 'Connection' => 'close',
503 - ),
504 - 'body' => $body,
505 - );
508 + // Prepare the request.
509 + $url = esc_url_raw( AO_CCSS_API . 'generate?aover=' . AO_CCSS_VER );
510 + $args = array(
511 + 'headers' => apply_filters(
512 + 'autoptimize_ccss_cron_api_generate_headers',
513 + array(
514 + 'User-Agent' => 'Autoptimize v' . AO_CCSS_VER,
515 + 'Content-type' => 'application/json; charset=utf-8',
516 + 'Authorization' => 'JWT ' . $key,
517 + 'Connection' => 'close',
518 + )
519 + ),
520 + 'body' => $body,
521 + );
506 522
507 - // Dispatch the request and store its response code.
508 - $req = wp_safe_remote_post( $url, $args );
509 - $code = wp_remote_retrieve_response_code( $req );
510 - $body = json_decode( wp_remote_retrieve_body( $req ), true );
523 + // Dispatch the request and store its response code.
524 + $req = wp_safe_remote_post( $url, $args );
525 + $code = wp_remote_retrieve_response_code( $req );
526 + $body = json_decode( wp_remote_retrieve_body( $req ), true );
511 527
512 - if ( $debug && $dcode ) {
513 - // If queue debug is active, change response code.
514 - $code = $dcode;
515 - }
528 + if ( $debug && $dcode ) {
529 + // If queue debug is active, change response code.
530 + $code = $dcode;
531 + }
516 532
517 - if ( 200 == $code ) {
518 - // Response code is OK.
519 - // Workaround criticalcss.com non-RESTful reponses.
520 - if ( 'JOB_QUEUED' == $body['job']['status'] || 'JOB_ONGOING' == $body['job']['status'] || 'STATUS_JOB_BAD' == $body['job']['status'] ) {
521 - // Log successful and return encoded request body.
522 - autoptimizeCriticalCSSCore::ao_ccss_log( 'criticalcss.com: POST generate request for path <' . $src_url . '> replied successfully', 3 );
533 + if ( 200 == $code ) {
534 + // Response code is OK.
535 + // Workaround criticalcss.com non-RESTful reponses.
536 + if ( 'JOB_QUEUED' == $body['job']['status'] || 'JOB_ONGOING' == $body['job']['status'] || 'STATUS_JOB_BAD' == $body['job']['status'] ) {
537 + // Log successful and return encoded request body.
538 + $this->criticalcss->log( 'criticalcss.com: POST generate request for path <' . $src_url . '> replied successfully', 3 );
523 539
524 - // This code also means the key is valid, so cache key status for 24h if not already cached.
525 - if ( ( ! $key_status || 2 != $key_status ) && $key ) {
526 - update_option( 'autoptimize_ccss_keyst', 2 );
527 - autoptimizeCriticalCSSCore::ao_ccss_log( 'criticalcss.com: API key is valid, updating key status', 3 );
540 + // This code also means the key is valid, so cache key status for 24h if not already cached.
541 + if ( ( ! $key_status || 2 != $key_status ) && $key ) {
542 + update_option( 'autoptimize_ccss_keyst', 2 );
543 + $this->criticalcss->log( 'criticalcss.com: API key is valid, updating key status', 3 );
544 + }
545 +
546 + // Return the request body.
547 + return $body;
548 + } else {
549 + // Log successful requests with invalid reponses.
550 + $this->criticalcss->log( 'criticalcss.com: POST generate request for path <' . $src_url . '> replied with code <' . $code . '> and an UNKNOWN error condition, body follows...', 2 );
551 + $this->criticalcss->log( print_r( $body, true ), 2 );
552 + return $body;
528 553 }
554 + } else {
555 + // Response code is anything else.
556 + // Log failed request with a valid response code and return body.
557 + if ( $code ) {
558 + $this->criticalcss->log( 'criticalcss.com: POST generate request for path <' . $src_url . '> replied with error code <' . $code . '>, body follows...', 2 );
559 + $this->criticalcss->log( print_r( $body, true ), 2 );
529 560
530 - // Return the request body.
531 - return $body;
532 - } else {
533 - // Log successful requests with invalid reponses.
534 - autoptimizeCriticalCSSCore::ao_ccss_log( 'criticalcss.com: POST generate request for path <' . $src_url . '> replied with code <' . $code . '> and an UNKNOWN error condition, body follows...', 2 );
535 - autoptimizeCriticalCSSCore::ao_ccss_log( print_r( $body, true ), 2 );
536 - return $body;
537 - }
538 - } else {
539 - // Response code is anything else.
540 - // Log failed request with a valid response code and return body.
541 - if ( $code ) {
542 - autoptimizeCriticalCSSCore::ao_ccss_log( 'criticalcss.com: POST generate request for path <' . $src_url . '> replied with error code <' . $code . '>, body follows...', 2 );
543 - autoptimizeCriticalCSSCore::ao_ccss_log( print_r( $body, true ), 2 );
561 + if ( 401 == $code ) {
562 + // If request is unauthorized, also clear key status.
563 + update_option( 'autoptimize_ccss_keyst', 1 );
564 + $this->criticalcss->log( 'criticalcss.com: API key is invalid, updating key status', 3 );
565 + }
544 566
545 - if ( 401 == $code ) {
546 - // If request is unauthorized, also clear key status.
547 - update_option( 'autoptimize_ccss_keyst', 1 );
548 - autoptimizeCriticalCSSCore::ao_ccss_log( 'criticalcss.com: API key is invalid, updating key status', 3 );
549 - }
567 + // Return the request body.
568 + return $body;
569 + } else {
570 + // Log failed request with no response and return false.
571 + $this->criticalcss->log( 'criticalcss.com: POST generate request for path <' . $src_url . '> has no response, this could be a service timeout', 2 );
572 + if ( is_wp_error( $req ) ) {
573 + $this->criticalcss->log( $req->get_error_message(), 2 );
574 + }
550 575
551 - // Return the request body.
552 - return $body;
553 - } else {
554 - // Log failed request with no response and return false.
555 - autoptimizeCriticalCSSCore::ao_ccss_log( 'criticalcss.com: POST generate request for path <' . $src_url . '> has no response, this could be a service timeout', 2 );
556 - if ( is_wp_error( $req ) ) {
557 - autoptimizeCriticalCSSCore::ao_ccss_log( $req->get_error_message(), 2 );
576 + return false;
558 577 }
559 -
560 - return false;
561 578 }
579 + } else {
580 + // localhost/ private network server, no CCSS possible.
581 + $this->criticalcss->log( 'ccss cron: job not created at ccss.com as for local server', 3 );
582 + return false;
562 583 }
563 584 }
564 585
565 586 public function ao_ccss_api_results( $jobid, $debug, $dcode ) {
@@ -564,18 +585,20 @@
564 585
565 586 public function ao_ccss_api_results( $jobid, $debug, $dcode ) {
566 587 // GET jobs from criticalcss.com and return responses
567 588 // Get key.
568 - global $ao_ccss_key;
569 - $key = $ao_ccss_key;
589 + $key = $this->criticalcss->get_option( 'key' );
570 590
571 591 // Prepare the request.
572 592 $url = AO_CCSS_API . 'results?resultId=' . $jobid;
573 593 $args = array(
574 - 'headers' => array(
575 - 'User-Agent' => 'Autoptimize CriticalCSS Power-Up v' . AO_CCSS_VER,
576 - 'Authorization' => 'JWT ' . $key,
577 - 'Connection' => 'close',
594 + 'headers' => apply_filters(
595 + 'autoptimize_ccss_cron_api_generate_headers',
596 + array(
597 + 'User-Agent' => 'Autoptimize CriticalCSS Power-Up v' . AO_CCSS_VER,
598 + 'Authorization' => 'JWT ' . $key,
599 + 'Connection' => 'close',
600 + )
578 601 ),
579 602 );
580 603
581 604 // Dispatch the request and store its response code.
@@ -592,19 +615,19 @@
592 615 // Response code is OK.
593 616 if ( is_array( $body ) && ( array_key_exists( 'status', $body ) || array_key_exists( 'job', $body ) ) && ( 'JOB_QUEUED' == $body['status'] || 'JOB_ONGOING' == $body['status'] || 'JOB_DONE' == $body['status'] || 'JOB_FAILED' == $body['status'] || 'JOB_UNKNOWN' == $body['status'] || 'STATUS_JOB_BAD' == $body['job']['status'] ) ) {
594 617 // Workaround criticalcss.com non-RESTful reponses
595 618 // Log successful and return encoded request body.
596 - autoptimizeCriticalCSSCore::ao_ccss_log( 'criticalcss.com: GET results request for remote job id <' . $jobid . '> replied successfully', 3 );
619 + $this->criticalcss->log( 'criticalcss.com: GET results request for remote job id <' . $jobid . '> replied successfully', 3 );
597 620 return $body;
598 621 } elseif ( is_array( $body ) && ( array_key_exists( 'error', $body ) && 'This css no longer exists. Please re-generate it.' == $body['error'] ) ) {
599 622 // Handle no CSS reply
600 623 // Log no CSS error and return encoded request body.
601 - autoptimizeCriticalCSSCore::ao_ccss_log( 'criticalcss.com: GET results request for remote job id <' . $jobid . '> replied successfully but the CSS for it does not exist anymore', 3 );
624 + $this->criticalcss->log( 'criticalcss.com: GET results request for remote job id <' . $jobid . '> replied successfully but the CSS for it does not exist anymore', 3 );
602 625 return $body;
603 626 } else {
604 627 // Log failed request and return false.
605 - autoptimizeCriticalCSSCore::ao_ccss_log( 'criticalcss.com: GET results request for remote job id <' . $jobid . '> replied with code <' . $code . '> and an UNKNOWN error condition, body follows...', 2 );
606 - autoptimizeCriticalCSSCore::ao_ccss_log( print_r( $body, true ), 2 );
628 + $this->criticalcss->log( 'criticalcss.com: GET results request for remote job id <' . $jobid . '> replied with code <' . $code . '> and an UNKNOWN error condition, body follows...', 2 );
629 + $this->criticalcss->log( print_r( $body, true ), 2 );
607 630 return false;
608 631 }
609 632 } else {
610 633 // Response code is anything else
@@ -609,14 +632,14 @@
609 632 } else {
610 633 // Response code is anything else
611 634 // Log failed request with a valid response code and return body.
612 635 if ( $code ) {
613 - autoptimizeCriticalCSSCore::ao_ccss_log( 'criticalcss.com: GET results request for remote job id <' . $jobid . '> replied with error code <' . $code . '>, body follows...', 2 );
614 - autoptimizeCriticalCSSCore::ao_ccss_log( print_r( $body, true ), 2 );
636 + $this->criticalcss->log( 'criticalcss.com: GET results request for remote job id <' . $jobid . '> replied with error code <' . $code . '>, body follows...', 2 );
637 + $this->criticalcss->log( print_r( $body, true ), 2 );
615 638 if ( 401 == $code ) {
616 639 // If request is unauthorized, also clear key status.
617 640 update_option( 'autoptimize_ccss_keyst', 1 );
618 - autoptimizeCriticalCSSCore::ao_ccss_log( 'criticalcss.com: API key is invalid, updating key status', 3 );
641 + $this->criticalcss->log( 'criticalcss.com: API key is invalid, updating key status', 3 );
619 642 }
620 643
621 644 // Return the request body.
622 645 return $body;
@@ -621,9 +644,9 @@
621 644 // Return the request body.
622 645 return $body;
623 646 } else {
624 647 // Log failed request with no response and return false.
625 - autoptimizeCriticalCSSCore::ao_ccss_log( 'criticalcss.com: GET results request for remote job id <' . $jobid . '> has no response, this could be a service timeout', 2 );
648 + $this->criticalcss->log( 'criticalcss.com: GET results request for remote job id <' . $jobid . '> has no response, this could be a service timeout', 2 );
626 649 return false;
627 650 }
628 651 }
629 652 }
@@ -640,41 +663,42 @@
640 663 // Prepare target rule, filename and content.
641 664 $filename = false;
642 665 $content = $ccss;
643 666
644 - if ( autoptimizeCriticalCSSCore::ao_ccss_check_contents( $content ) ) {
667 + if ( $this->criticalcss->check_contents( $content ) ) {
645 668 // Sanitize content, set filename and try to save file.
646 669 $file = AO_CCSS_DIR . 'ccss_' . md5( $ccss . $target[1] ) . $rmark . '.css';
647 670 $status = file_put_contents( $file, $content, LOCK_EX );
648 671 $filename = pathinfo( $file, PATHINFO_BASENAME );
649 - autoptimizeCriticalCSSCore::ao_ccss_log( 'Critical CSS file for the rule <' . $target[0] . '|' . $target[1] . '> was saved as <' . $filename . '>, size in bytes is <' . $status . '>', 3 );
672 + $this->criticalcss->log( 'Critical CSS file for the rule <' . $target[0] . '|' . $target[1] . '> was saved as <' . $filename . '>, size in bytes is <' . $status . '>', 3 );
650 673
651 674 if ( ! $status ) {
652 675 // If file has not been saved, reset filename.
653 - autoptimizeCriticalCSSCore::ao_ccss_log( 'Critical CSS file <' . $filename . '> could not be not saved', 2 );
676 + $this->criticalcss->log( 'Critical CSS file <' . $filename . '> could not be not saved', 2 );
654 677 $filename = false;
655 678 return $filename;
656 679 }
657 680 } else {
658 - autoptimizeCriticalCSSCore::ao_ccss_log( 'Critical CSS received did not pass content check', 2 );
681 + $this->criticalcss->log( 'Critical CSS received did not pass content check', 2 );
659 682 return $filename;
660 683 }
661 684
662 685 // Remove old critical CSS if a previous one existed in the rule and if that file exists in filesystem
663 - // NOTE: out of scope critical CSS file removal (issue #5)
664 686 // Attach required arrays.
665 - global $ao_ccss_rules;
687 + $rules = $this->criticalcss->get_option( 'rules' );
666 688
667 - // Prepare rule variables.
668 - $srule = $ao_ccss_rules[ $target[0] ][ $target[1] ];
669 - $oldfile = $srule['file'];
689 + // Only proceed if the rule already existed.
690 + if ( array_key_exists( $target[1], $rules[ $target[0] ] ) ) {
691 + $srule = $rules[ $target[0] ][ $target[1] ];
692 + $oldfile = $srule['file'];
670 693
671 - if ( $oldfile && $oldfile !== $filename ) {
672 - $delfile = AO_CCSS_DIR . $oldfile;
673 - if ( file_exists( $delfile ) ) {
674 - $unlinkst = unlink( $delfile );
675 - if ( $unlinkst ) {
676 - autoptimizeCriticalCSSCore::ao_ccss_log( 'A previous critical CSS file <' . $oldfile . '> was removed for the rule <' . $target[0] . '|' . $target[1] . '>', 3 );
694 + if ( $oldfile && $oldfile !== $filename ) {
695 + $delfile = AO_CCSS_DIR . $oldfile;
696 + if ( file_exists( $delfile ) ) {
697 + $unlinkst = unlink( $delfile );
698 + if ( $unlinkst ) {
699 + $this->criticalcss->log( 'A previous critical CSS file <' . $oldfile . '> was removed for the rule <' . $target[0] . '|' . $target[1] . '>', 3 );
700 + }
677 701 }
678 702 }
679 703 }
680 704
@@ -684,21 +708,25 @@
684 708
685 709 public function ao_ccss_rule_update( $ljid, $srule, $file, $hash ) {
686 710 // Update or create a rule
687 711 // Attach required arrays.
688 - global $ao_ccss_rules;
712 + $rules = $this->criticalcss->get_option( 'rules' );
689 713
690 714 // Prepare rule variables.
691 715 $trule = explode( '|', $srule );
692 - $rule = $ao_ccss_rules[ $trule[0] ][ $trule[1] ];
716 + if ( array_key_exists( $trule[1], $rules[ $trule[0] ] ) ) {
717 + $rule = $rules[ $trule[0] ][ $trule[1] ];
718 + } else {
719 + $rule = array();
720 + }
693 721 $action = false;
694 722 $rtype = '';
695 723
696 - if ( 0 === $rule['hash'] && 0 !== $rule['file'] ) {
724 + if ( is_array( $rule ) && 0 === $rule['hash'] && 0 !== $rule['file'] ) {
697 725 // manual rule, don't ever overwrite.
698 726 $action = 'NOT UPDATED';
699 727 $rtype = 'MANUAL';
700 - } elseif ( 0 === $rule['hash'] && 0 === $rule['file'] ) {
728 + } elseif ( is_array( $rule ) && 0 === $rule['hash'] && 0 === $rule['file'] ) {
701 729 // If this is an user created AUTO rule with no hash and file yet, update its hash and filename
702 730 // Set rule hash, file and action flag.
703 731 $rule['hash'] = $hash;
704 732 $rule['file'] = $file;
@@ -703,9 +731,9 @@
703 731 $rule['hash'] = $hash;
704 732 $rule['file'] = $file;
705 733 $action = 'UPDATED';
706 734 $rtype = 'AUTO';
707 - } elseif ( 0 !== $rule['hash'] && ctype_alnum( $rule['hash'] ) ) {
735 + } elseif ( is_array( $rule ) && 0 !== $rule['hash'] && ctype_alnum( $rule['hash'] ) ) {
708 736 // If this is an genuine AUTO rule, update its hash and filename
709 737 // Set rule hash, file and action flag.
710 738 $rule['hash'] = $hash;
711 739 $rule['file'] = $file;
@@ -713,9 +741,9 @@
713 741 $rtype = 'AUTO';
714 742 } else {
715 743 // If rule doesn't exist, create an AUTO rule
716 744 // AUTO rules were only for types, but will now also work for paths.
717 - if ( 'types' == $trule[0] || 'paths' == $trule[0] ) {
745 + if ( ( 'types' == $trule[0] || 'paths' == $trule[0] ) && ! empty( $trule[1] ) ) {
718 746 // Set rule hash and file and action flag.
719 747 $rule['hash'] = $hash;
720 748 $rule['file'] = $file;
721 749 $action = 'CREATED';
@@ -721,20 +749,21 @@
721 749 $action = 'CREATED';
722 750 $rtype = 'AUTO';
723 751 } else {
724 752 // Log that no rule was created.
725 - autoptimizeCriticalCSSCore::ao_ccss_log( 'Exception, no AUTO rule created', 3 );
753 + $this->criticalcss->log( 'Exception, no AUTO rule created', 3 );
726 754 }
727 755 }
728 756
729 757 if ( $action ) {
730 758 // If a rule creation/update is required, persist updated rules object.
731 - $ao_ccss_rules[ $trule[0] ][ $trule[1] ] = $rule;
732 - $ao_ccss_rules_raw = json_encode( $ao_ccss_rules );
733 - update_option( 'autoptimize_ccss_rules', $ao_ccss_rules_raw );
734 - autoptimizeCriticalCSSCore::ao_ccss_log( 'Target rule <' . $srule . '> of type <' . $rtype . '> was ' . $action . ' for job id <' . $ljid . '>', 3 );
759 + $rules[ $trule[0] ][ $trule[1] ] = $rule;
760 + $rules_raw = json_encode( $rules );
761 + update_option( 'autoptimize_ccss_rules', $rules_raw );
762 + $this->criticalcss->flush_options();
763 + $this->criticalcss->log( 'Target rule <' . $srule . '> of type <' . $rtype . '> was ' . $action . ' for job id <' . $ljid . '>', 3 );
735 764 } else {
736 - autoptimizeCriticalCSSCore::ao_ccss_log( 'No rule action required', 3 );
765 + $this->criticalcss->log( 'No rule action required', 3 );
737 766 }
738 767 }
739 768
740 769 function ao_ccss_finclude( $finclude_raw ) {
@@ -796,12 +825,13 @@
796 825 wp_schedule_event( time(), apply_filters( 'ao_ccss_queue_schedule', 'ao_ccss' ), 'ao_ccss_queue' );
797 826 }
798 827
799 828 // Queue cleaning.
800 - global $ao_ccss_queue;
829 + $queue = $this->criticalcss->get_option( 'queue' );
830 +
801 831 $queue_purge_threshold = 100;
802 832 $queue_purge_age = 24 * 60 * 60;
803 - $queue_length = count( $ao_ccss_queue );
833 + $queue_length = count( $queue );
804 834 $timestamp_yesterday = microtime( true ) - $queue_purge_age;
805 835 $remove_old_new = false;
806 836 $queue_altered = false;
807 837
@@ -808,11 +838,11 @@
808 838 if ( $queue_length > $queue_purge_threshold ) {
809 839 $remove_old_new = true;
810 840 }
811 841
812 - foreach ( $ao_ccss_queue as $path => $job ) {
842 + foreach ( $queue as $path => $job ) {
813 843 if ( ( $remove_old_new && 'NEW' == $job['jqstat'] && $job['jctime'] < $timestamp_yesterday ) || in_array( $job['jqstat'], array( 'JOB_FAILED', 'STATUS_JOB_BAD', 'NO_CSS', 'NO_RESPONSE' ) ) ) {
814 - unset( $ao_ccss_queue[ $path ] );
844 + unset( $queue[ $path ] );
815 845 $queue_altered = true;
816 846 }
817 847 }
818 848
@@ -817,16 +847,16 @@
817 847 }
818 848
819 849 // save queue to options!
820 850 if ( $queue_altered ) {
821 - $ao_ccss_queue_raw = json_encode( $ao_ccss_queue );
822 - update_option( 'autoptimize_ccss_queue', $ao_ccss_queue_raw, false );
823 - autoptimizeCriticalCSSCore::ao_ccss_log( 'Queue cleaning done.', 3 );
851 + $queue_raw = json_encode( $queue );
852 + update_option( 'autoptimize_ccss_queue', $queue_raw, false );
853 + $this->criticalcss->log( 'Queue cleaning done.', 3 );
824 854 }
825 855
826 856 // re-check key if invalid.
827 - global $ao_ccss_keyst;
828 - if ( 1 == $ao_ccss_keyst ) {
857 + $keyst = $this->criticalcss->get_option( 'keyst' );
858 + if ( 1 == $keyst ) {
829 859 $this->ao_ccss_api_generate( '', '', '' );
830 860 }
831 861 }
832 862 }