PluginProbe
WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance / 3.2.9
WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance v3.2.9
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
wp-optimize / webp / class-wp-optimize-webp.php

class-wp-optimize-webp.php in WP-Optimize – Cache, Compress images, Minify & Clean database to boost page speed & performance 3.2.9, at webp/class-wp-optimize-webp.php

362 lines 10.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 if (!defined('WPO_VERSION')) die('No direct access allowed');
4
5 if (!class_exists('WP_Optimize_WebP')) :
6
7 class WP_Optimize_WebP {
8
9 private $_htaccess = null;
10
11 private $_rewrite_status = '';
12
13 private $_should_use_webp = false;
14
15 /**
16 * Constructor
17 */
18 private function __construct() {
19 if ($this->should_run_webp_conversion_test()) {
20 $this->set_converter_status();
21 }
22
23 if ($this->get_webp_conversion_test_result()) {
24 $this->maybe_set_rewrite_status();
25 if (!is_admin()) {
26 $this->maybe_decide_webp_serve_method();
27 }
28 } else {
29 $this->empty_htaccess_file();
30 }
31
32 $this->init_webp_cron_scheduler();
33 }
34
35 /**
36 * Returns singleton instance
37 *
38 * @return WP_Optimize_WebP
39 */
40 public static function get_instance() {
41 static $instance = null;
42 if (null === $instance) {
43 $instance = new WP_Optimize_WebP();
44 }
45 return $instance;
46 }
47
48 /**
49 * Test Run and find converter status
50 */
51 private function set_converter_status() {
52 if (!class_exists('WPO_WebP_Test_Run')) {
53 require_once WPO_PLUGIN_MAIN_PATH . 'webp/class-wpo-webp-test-run.php';
54 }
55 $converter_status = WPO_WebP_Test_Run::get_converter_status();
56 if ($this->is_webp_conversion_successful()) {
57 WP_Optimize()->get_options()->update_option('webp_conversion_test', true);
58 WP_Optimize()->get_options()->update_option('webp_converters', $converter_status['working_converters']);
59 }
60 }
61
62 /**
63 * May be set server's rewrite status
64 */
65 private function maybe_set_rewrite_status() {
66 $this->_should_use_webp = WP_Optimize()->get_options()->get_option('webp_conversion');
67 if ($this->_should_use_webp) {
68 $this->set_rewrite_status();
69 }
70 }
71
72 /**
73 * Sets server's rewrite status
74 */
75 private function set_rewrite_status() {
76 $this->_rewrite_status = WP_Optimize()->get_options()->get_option('rewrite_status', false);
77 if ('true' === $this->_rewrite_status) {
78 $this->setup_htaccess_file();
79 return;
80 } elseif ('false' === $this->_rewrite_status) return;
81
82 if (!class_exists('WPO_Htaccess_Capabilities')) {
83 require_once WPO_PLUGIN_MAIN_PATH . 'webp/class-wpo-htaccess-capabilities.php';
84 }
85 $htc = WPO_Htaccess_Capabilities::get_instance();
86
87 if ($htc->htaccess_enabled && $htc->mod_rewrite && $htc->mod_headers && $htc->mod_mime) {
88 $this->_rewrite_status = 'true';
89 $this->setup_htaccess_file();
90 } else {
91 $this->_rewrite_status = 'false';
92 }
93 WP_Optimize()->get_options()->update_option('rewrite_status', $this->_rewrite_status);
94 }
95
96 /**
97 * If webp images should be used, then decide whether it is possible to server webp
98 * using rewrite rules or using altered html method
99 */
100 private function maybe_decide_webp_serve_method() {
101 if ('true' === $this->_rewrite_status) {
102 if (!$this->_should_use_webp) {
103 $this->empty_htaccess_file();
104 } else {
105 $this->save_htaccess_rules();
106 if (!$this->is_webp_redirection_possible()) {
107 $this->empty_htaccess_file();
108 $this->maybe_use_alter_html();
109 }
110 }
111 } else {
112 if ($this->_should_use_webp) {
113 $this->maybe_use_alter_html();
114 } else {
115 $this->empty_htaccess_file();
116 }
117 }
118 }
119
120 /**
121 * If alter html method is possible, then use it
122 */
123 private function maybe_use_alter_html() {
124 if ($this->is_alter_html_possible()) {
125 $this->use_alter_html();
126 }
127 }
128
129 /**
130 * Even if server support .htaccess rewrite, sometimes it is not possible
131 * to serve webp images. So, find it webp redirection is possible or not
132 *
133 * @return bool
134 */
135 private function is_webp_redirection_possible() {
136 $redirection_possible = WP_Optimize()->get_options()->get_option('redirection_possible');
137 if ($redirection_possible) {
138 return 'true' === $redirection_possible;
139 }
140 return $this->run_webp_serving_self_test();
141 }
142
143 /**
144 * Decide whether the browser requesting the URL can accept webp images or not
145 *
146 * @return bool
147 */
148 private function is_browser_accepting_webp() {
149 return (isset($_SERVER['HTTP_ACCEPT']) && false !== strpos($_SERVER['HTTP_ACCEPT'], 'image/webp'));
150 }
151
152 /**
153 * Detect whether using alter HTML method is possible or not
154 *
155 * @return bool
156 */
157 private function is_alter_html_possible() {
158 if ($this->is_browser_accepting_webp()) {
159 return true;
160 }
161 return false;
162 }
163
164 /**
165 * Setup alter html method
166 */
167 private function use_alter_html() {
168 if (!class_exists('WPO_WebP_Alter_HTML')) {
169 require_once WPO_PLUGIN_MAIN_PATH . 'webp/class-wpo-webp-alter-html.php';
170 }
171 WPO_WebP_Alter_HTML::get_instance();
172 }
173
174 /**
175 * Initialize .htaccess
176 */
177 private function setup_htaccess_file() {
178 if (null !== $this->_htaccess) return;
179 $wp_uploads = wp_get_upload_dir();
180 $htaccess_file = $wp_uploads['basedir'] . '/.htaccess';
181 if (!file_exists($htaccess_file)) {
182 file_put_contents($htaccess_file, '');
183 }
184 if (!class_exists('WP_Optimize_Htaccess')) {
185 require_once WPO_PLUGIN_MAIN_PATH . 'includes/class-wp-optimize-htaccess.php';
186 }
187 $this->_htaccess = new WP_Optimize_Htaccess($htaccess_file);
188 $this->add_webp_mime_type();
189 }
190
191 /**
192 * Save .htaccess rules
193 *
194 * @return bool
195 */
196 private function save_htaccess_rules() {
197 $htaccess_comment_section = 'WP-Optimize WebP Rules';
198 if ($this->_htaccess->is_commented_section_exists($htaccess_comment_section)) return false;
199 $this->_htaccess->update_commented_section($this->prepare_webp_htaccess_rules(), $htaccess_comment_section);
200 $this->_htaccess->write_file();
201 return true;
202 }
203
204 /**
205 * Empty .htaccess file
206 */
207 public function empty_htaccess_file() {
208 $this->setup_htaccess_file();
209 $htaccess_comment_section = 'WP-Optimize WebP Rules';
210 $this->_htaccess->remove_commented_section($htaccess_comment_section);
211 $this->_htaccess->write_file();
212 }
213
214 /**
215 * Prepare array of htaccess rules to use webp images.
216 *
217 * @return array
218 */
219 private function prepare_webp_htaccess_rules() {
220 return array(
221 array(
222 '<IfModule mod_rewrite.c>',
223 'RewriteEngine On',
224 '',
225 '# Redirect to existing converted image in same dir (if browser supports webp)',
226 'RewriteCond %{HTTP_ACCEPT} image/webp',
227 'RewriteCond %{REQUEST_FILENAME} (?i)(.*)(\.jpe?g|\.png)$',
228 'RewriteCond %1%2\.webp -f',
229 'RewriteRule (?i)(.*)(\.jpe?g|\.png)$ %1%2\.webp [T=image/webp,E=EXISTING:1,E=ADDVARY:1,L]',
230 '',
231 '# Make sure that browsers which does not support webp also gets the Vary:Accept header',
232 '# when requesting images that would be redirected to webp on browsers that does.',
233 array(
234 '<IfModule mod_headers.c>',
235 array(
236 '<FilesMatch "(?i)\.(jpe?g|png)$">',
237 'Header append "Vary" "Accept"',
238 '</FilesMatch>',
239 ),
240 '</IfModule>',
241 ),
242 '',
243 '</IfModule>',
244 '',
245 ),
246 array(
247 '# Rules for handling requests for webp images',
248 '# ---------------------------------------------',
249 '',
250 '# Set Vary:Accept header if we came here by way of our redirect, which set the ADDVARY environment variable',
251 '# The purpose is to make proxies and CDNs aware that the response varies with the Accept header',
252 '<IfModule mod_headers.c>',
253 array(
254 '<IfModule mod_setenvif.c>',
255 '# Apache appends "REDIRECT_" in front of the environment variables defined in mod_rewrite, but LiteSpeed does not',
256 '# So, the next lines are for Apache, in order to set environment variables without "REDIRECT_"',
257 'SetEnvIf REDIRECT_EXISTING 1 EXISTING=1',
258 'SetEnvIf REDIRECT_ADDVARY 1 ADDVARY=1',
259 '',
260 'Header append "Vary" "Accept" env=ADDVARY',
261 '',
262 '# Set X-WPO-WebP header for diagnose purposes',
263 'Header set "X-WPO-WebP" "Redirected directly to existing webp" env=EXISTING',
264 '</IfModule>',
265 ),
266 '</IfModule>',
267 ),
268 );
269 }
270
271 /**
272 * Add webp mime type to htaccess rules.
273 */
274 private function add_webp_mime_type() {
275 $htaccess_comment_section = 'Register webp mime type';
276 if ($this->_htaccess->is_exists() && !$this->_htaccess->is_commented_section_exists($htaccess_comment_section)) {
277 $webp_mime_type = array(
278 array(
279 '<IfModule mod_mime.c>',
280 'AddType image/webp .webp',
281 '</IfModule>',
282 ),
283 );
284 $this->_htaccess->update_commented_section($webp_mime_type, $htaccess_comment_section);
285 $this->_htaccess->write_file();
286 }
287 }
288
289 /**
290 * Checks whether webp conversion test is successful or not
291 *
292 * @return bool
293 */
294 private function is_webp_conversion_successful() {
295 $upload_dir = wp_upload_dir();
296 $destination = $upload_dir['basedir']. '/wpo/images/wpo_logo_small.png.webp';
297 return file_exists($destination);
298 }
299
300 /**
301 * Checks whether sample webp conversion test should be run or not
302 *
303 * @return bool Returns true if sample test should be run, false otherwise
304 */
305 private function should_run_webp_conversion_test() {
306 $webp_conversion_test = $this->get_webp_conversion_test_result();
307 return (true != $webp_conversion_test);
308 }
309
310 /**
311 * Returns webp conversion test result
312 */
313 private function get_webp_conversion_test_result() {
314 return WP_Optimize()->get_options()->get_option('webp_conversion_test');
315 }
316
317 /**
318 * Checks whether the webp redirection is possible or not and sets flag
319 *
320 * @return bool Returns true if webp is served successfully, false otherwise
321 */
322 private function run_webp_serving_self_test() {
323 if (!class_exists('WPO_WebP_Self_Test')) {
324 require_once WPO_PLUGIN_MAIN_PATH . 'webp/class-wpo-webp-self-test.php';
325 }
326 $self_test = WPO_WebP_Self_Test::get_instance();
327
328 if ($self_test->get_webp_image()) {
329 $this->save_htaccess_rules();
330 if ($self_test->is_webp_served()) {
331 WP_Optimize()->get_options()->update_option('redirection_possible', 'true');
332 return true;
333 }
334 }
335 WP_Optimize()->get_options()->update_option('redirection_possible', 'false');
336 $this->empty_htaccess_file();
337 return false;
338 }
339
340 /**
341 * Resets webp serving method by setting all flags status to false
342 *
343 * @return bool
344 */
345 public function reset_webp_serving_method() {
346 $options = WP_Optimize()->get_options();
347 $options->update_option('redirection_possible', false);
348 $options->update_option('webp_conversion_test', false);
349 $options->update_option('webp_converters', false);
350 return $options->update_option('rewrite_status', false);
351 }
352
353 /**
354 * Initialize cron scheduler
355 */
356 private function init_webp_cron_scheduler() {
357 WPO_WebP_Cron_Scheduler::get_instance();
358 }
359 }
360
361 endif;
362