PluginProbe
WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance / 4.7.0
WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance v4.7.0
4.7.0 4.6.1 4.6.0 4.5.5 4.5.4 4.5.3 4.5.2 3.2.20 3.2.21 3.2.22 3.2.3 3.2.5 3.2.6 3.2.7 3.2.9 3.3.0 3.3.1 3.3.2 3.4.0 3.4.1 3.4.2 3.5.0 3.6.0 3.7.0 3.7.1 All 111 releases
← All changes | includes/class-wp-optimize-gzip-compression.php +187 -21 4.5.2 → 4.7.0 View file →
@@ -50,20 +50,42 @@
50 50 return $_instance;
51 51 }
52 52
53 53 /**
54 - * Make http request to theme style.css, get 'server' line and check headers for gzip/brotli encoding option.
54 + * Make http request to $url, get 'server' line and check headers for gzip/brotli encoding option.
55 55 *
56 + * @param string $url
57 + *
56 58 * @return array|WP_Error
57 59 */
58 - public function get_headers_information() {
59 - static $headers_information;
60 - if (isset($headers_information)) return $headers_information;
60 + public function get_headers_information($url) {
61 + static $cached_headers_information = array();
62 + if (isset($cached_headers_information[$url])) return $cached_headers_information[$url];
61 63
62 - $headers = $this->get_stylesheet_headers();
64 + $response = wp_remote_get($url, array('timeout' => 10));
63 65
64 - if (is_wp_error($headers)) return $headers;
66 + if (is_wp_error($response)) {
67 + return $response;
68 + }
65 69
70 + $response_code = wp_remote_retrieve_response_code($response);
71 +
72 + if (200 !== $response_code) {
73 + // translators: %1$s is a requested URL, %2$s is the HTTP response code
74 + return new WP_Error($response_code, sprintf(__('Unexpected response code when trying to get response for %1$s: %2$s (expected 200)', 'wp-optimize'), $url, $response_code));
75 + }
76 +
77 + $headers = wp_remote_retrieve_headers($response);
78 +
79 + if (empty($headers)) {
80 + // translators: %s is a requested URL
81 + return new WP_Error($response_code, sprintf(__('Unable to retrieve HTTP headers information for %s', 'wp-optimize'), $url));
82 + }
83 +
84 + if (is_object($headers) && method_exists($headers, 'getAll')) {
85 + $headers = $headers->getAll();
86 + }
87 +
66 88 $headers_information = array(
67 89 'server' => array_key_exists('server', $headers) ? $headers['server'] : '',
68 90 );
69 91
@@ -73,13 +95,17 @@
73 95 $this->disable();
74 96 } elseif (array_key_exists('content-encoding', $headers) && preg_match('/gzip/i', $headers['content-encoding'])) {
75 97 // check if there exists Content-encoding header with gzip value.
76 98 $headers_information['compression'] = 'gzip';
77 -
99 + } elseif (array_key_exists('content-encoding', $headers) && preg_match('/zstd/i', $headers['content-encoding'])) {
100 + // check if there exists Content-encoding header with zstd value.
101 + $headers_information['compression'] = 'zstd';
78 102 } else {
79 103 $headers_information['compression'] = false;
80 104 }
81 105
106 + $cached_headers_information[$url] = $headers_information;
107 +
82 108 return $headers_information;
83 109 }
84 110
85 111 /**
@@ -111,26 +137,22 @@
111 137
112 138 /**
113 139 * Check if Gzip compression is enabled.
114 140 *
115 - * @param boolean $force_check - force the check
141 + * @param boolean $use_cache - use cached data
116 142 * @return bool|WP_Error
117 143 */
118 - public function is_gzip_compression_enabled($force_check = false) {
144 + public function is_gzip_compression_enabled($use_cache = true) {
119 145
120 - if (!$force_check) return WP_Optimize()->get_options()->get_option('is_gzip_compression_enabled');
146 + $compression_types = $this->get_compression_types($use_cache);
121 147
122 - // trying to get info about gzip in headers.
123 - $headers_info = $this->get_headers_information();
148 + $is_gzip_compression_enabled = true;
124 149
125 - // we can't determine then return WP_Error.
126 - if (is_wp_error($headers_info)) return $headers_info;
150 + foreach ($compression_types as $compression) {
151 + if (is_wp_error($compression)) return $compression;
152 + if (!in_array($compression, array('gzip', 'brotli', 'zstd'))) $is_gzip_compression_enabled = false;
153 + }
127 154
128 - $is_gzip_compression_enabled = $headers_info['compression'];
129 -
130 - // if we got error then trying to get info from api otherwise get result from check_headers_for_gzip().
131 - // $is_gzip_compression_enabled = is_wp_error($is_gzip_compression_enabled) ? $this->check_api_for_gzip() : $is_gzip_compression_enabled;
132 -
133 155 // if Gzip is not enabled, but we have added settings and Apache modules nt loaded then return error.
134 156 if (!$is_gzip_compression_enabled && $this->is_gzip_compression_section_exists()) {
135 157 if (false === $this->_wp_optimize->is_apache_module_loaded(array('mod_filter', 'mod_deflate'))) {
136 158 return new WP_Error('gzip_missing_module', __('We successfully added Gzip compression settings into .htaccess file.', 'wp-optimize').' '.__('However, the test file we fetched was not Gzip-compressed.', 'wp-optimize').' '.__('It seems one of Apache modules - mod_filter or mod_deflate - is not active.', 'wp-optimize'));
@@ -140,14 +162,35 @@
140 162 return new WP_Error('gzip_unsuccessful', __('We successfully added Gzip compression settings into .htaccess file.', 'wp-optimize').' '.__('However, the test file we fetched was not Gzip-compressed.', 'wp-optimize').' '.__('You should speak to your web hosting support to find how to enable it.', 'wp-optimize'));
141 163 }
142 164 }
143 165
144 - WP_Optimize()->get_options()->update_option('is_gzip_compression_enabled', $is_gzip_compression_enabled);
166 + // Stored value used to restore gzip compression settings used when plugin being activated,
167 + // i.e. we need to update it only when we have added settings to .htaccess or gzip is disabled
168 + if (!$is_gzip_compression_enabled || $this->is_gzip_compression_section_exists()) {
169 + WP_Optimize()->get_options()->update_option('is_gzip_compression_enabled', $is_gzip_compression_enabled);
170 + }
145 171
146 172 return $is_gzip_compression_enabled;
147 173 }
148 174
149 175 /**
176 + * Returns the compression type of the given URL.
177 + *
178 + * @param string $url
179 + * @return string|WP_Error
180 + */
181 + private function get_compression_type($url) {
182 +
183 + $headers_info = $this->get_headers_information($url);
184 +
185 + if (is_wp_error($headers_info)) return $headers_info;
186 +
187 + if (!isset($headers_info['compression'])) return '';
188 +
189 + return $headers_info['compression'];
190 + }
191 +
192 + /**
150 193 * Check if section with Gzip options already exists in htaccess file.
151 194 *
152 195 * @return bool
153 196 */
@@ -207,9 +250,9 @@
207 250 // set correct $section-updated flag.
208 251 $section_updated = $enable === $section_exists;
209 252 }
210 253
211 - $is_gzip_compression_enabled = $this->is_gzip_compression_enabled(true);
254 + $is_gzip_compression_enabled = $this->is_gzip_compression_enabled(false);
212 255
213 256 if ($section_updated) {
214 257 return array(
215 258 'success' => true,
@@ -237,8 +280,131 @@
237 280 join(PHP_EOL, $this->_htaccess->get_flat_array($gzip_section)).
238 281 PHP_EOL.$this->_htaccess->get_section_end_comment($this->_htaccess_section_comment)),
239 282 );
240 283 }
284 + }
285 +
286 + /**
287 + * Retrieve the compression statuses for HTML, CSS, and JS resources in HTML format.
288 + *
289 + * @param bool $use_cache if true, the cached value will be returned if possible
290 + * @return string
291 + */
292 + public function get_compression_test_results_html($use_cache = false) {
293 +
294 + $compression_types = $this->get_compression_types($use_cache);
295 +
296 + $result_html = '';
297 +
298 + foreach ($compression_types as $title => $compression) {
299 + if (is_wp_error($compression)) {
300 + $value = $compression->get_error_message();
301 + } elseif (!empty($compression)) {
302 + $value = '<b>'.$compression.'</b>';
303 + } else {
304 + $value = __('No compression', 'wp-optimize');
305 + }
306 +
307 + $result_html .= $title.': '. $value . '<br>';
308 + }
309 +
310 + return wp_kses_post($result_html);
311 + }
312 +
313 + /**
314 + * Get list of content types for which enabled/disabled gzip compression (html, css, js).
315 + *
316 + * @param bool $use_cache if true, the cached value will be returned if possible
317 + *
318 + * @return array
319 + */
320 + public function get_enabled_disabled_compression_content_types($use_cache = false) {
321 + $result = array(
322 + 'enabled' => array(),
323 + 'disabled' => array(),
324 + );
325 +
326 + $compression_types = $this->get_compression_types($use_cache);
327 +
328 + foreach ($compression_types as $type => $status) {
329 + if (false !== $status && '' !== $status && !is_wp_error($status)) {
330 + $result['enabled'][] = $type;
331 + } else {
332 + $result['disabled'][] = $type;
333 + }
334 + }
335 +
336 + return $result;
337 + }
338 +
339 + /**
340 + * Get compression types for html, css, js files.
341 + *
342 + * @param bool $use_cache if true, the cached value will be returned if possible
343 + *
344 + * @return array
345 + */
346 + private function get_compression_types($use_cache = false) {
347 + $transient_key = 'wpo_compression_test_results';
348 + $compression_types = array('HTML' => '', 'CSS' => '', 'JS' => '');
349 + $cached_compression_types = array();
350 +
351 + if ($use_cache) {
352 + $cached_compression_types = get_transient($transient_key);
353 + }
354 +
355 + $should_update_cache = false;
356 +
357 + foreach ($compression_types as $content_type => $compression) {
358 + // if we have cached value and it is not WP_Error then use it, otherwise get compression type and update cache later.
359 + if ($use_cache && isset($cached_compression_types[$content_type]) && 'WP_Error' !== $cached_compression_types[$content_type]) {
360 + $compression_types[$content_type] = $cached_compression_types[$content_type];
361 + } else {
362 + $compression_types[$content_type] = $this->get_compression_type_by_content_type($content_type);
363 + $should_update_cache = true;
364 + }
365 + }
366 +
367 + if ($should_update_cache) {
368 + $compression_types_for_cache = $compression_types;
369 + foreach ($compression_types_for_cache as $content_type => $compression) {
370 + if (is_wp_error($compression)) {
371 + $compression_types_for_cache[$content_type] = 'WP_Error';
372 + }
373 + }
374 + set_transient($transient_key, $compression_types_for_cache, HOUR_IN_SECONDS);
375 + }
376 +
377 + return $compression_types;
378 + }
379 +
380 + /**
381 + * Get compression type for the given content type (html, css, js).
382 + *
383 + * @param string $content_type - content type (html, css, js)
384 + * @return string|false|WP_Error
385 + */
386 + private function get_compression_type_by_content_type($content_type) {
387 + $content_type = strtoupper($content_type);
388 + switch ($content_type) {
389 + case 'HTML':
390 + return $this->get_compression_type(get_home_url(null, '?cache=false'));
391 + case 'CSS':
392 + return $this->get_compression_type($this->css_resource_url());
393 + case 'JS':
394 + return $this->get_compression_type(site_url('wp-includes/js/admin-bar.min.js'));
395 + default:
396 + return '';
397 + }
398 + }
399 +
400 + /**
401 + * Get URL to the CSS resource for checking Gzip compression status of CSS files.
402 + *
403 + * @return string
404 + */
405 + public function css_resource_url() {
406 + return WPO_PLUGIN_URL . 'css/wp-optimize-admin.css';
241 407 }
242 408
243 409 /**
244 410 * Prepare array with options to switch on gzip in htaccess.