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

288 lines 8.3 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 $this->maybe_set_converter_status();
20 $this->set_rewrite_status();
21 if (!is_admin()) {
22 $this->maybe_decide_webp_serve_method();
23 }
24 }
25
26 /**
27 * Returns singleton instance
28 *
29 * @return WP_Optimize_WebP
30 */
31 public static function get_instance() {
32 static $instance = null;
33 if (null === $instance) {
34 $instance = new WP_Optimize_WebP();
35 }
36 return $instance;
37 }
38
39 /**
40 * Detect working webp converters and set converter status, if needed
41 */
42 private function maybe_set_converter_status() {
43 $converters = WP_Optimize()->get_options()->get_option('webp_converters', false);
44 if (empty($converters)) {
45 $this->set_converter_status();
46 }
47 }
48
49 /**
50 * Test Run and find converter status
51 */
52 private function set_converter_status() {
53 if (!class_exists('WPO_WebP_Test_Run')) {
54 require_once WPO_PLUGIN_MAIN_PATH . 'webp/class-wpo-webp-test-run.php';
55 }
56 $converter_status = WPO_WebP_Test_Run::get_converter_status();
57 WP_Optimize()->get_options()->update_option('webp_converters', $converter_status['working_converters']);
58 }
59
60 /**
61 * Sets server's rewrite status
62 */
63 private function set_rewrite_status() {
64 $this->_rewrite_status = WP_Optimize()->get_options()->get_option('rewrite_status', false);
65 if ('true' === $this->_rewrite_status) {
66 $this->setup_htaccess_file();
67 return;
68 } elseif ('false' === $this->_rewrite_status) return;
69
70 if (!class_exists('WPO_Htaccess_Capabilities')) {
71 require_once WPO_PLUGIN_MAIN_PATH . 'webp/class-wpo-htaccess-capabilities.php';
72 }
73 $htc = WPO_Htaccess_Capabilities::get_instance();
74
75 if ($htc->htaccess_enabled && $htc->mod_rewrite && $htc->mod_headers && $htc->mod_mime) {
76 $this->_rewrite_status = 'true';
77 $this->setup_htaccess_file();
78 } else {
79 $this->_rewrite_status = 'false';
80 }
81 WP_Optimize()->get_options()->update_option('rewrite_status', $this->_rewrite_status);
82 }
83
84 /**
85 * If webp images should be used, then decide whether it is possible to server webp
86 * using rewrite rules or using altered html method
87 */
88 private function maybe_decide_webp_serve_method() {
89 $this->_should_use_webp = WP_Optimize()->get_options()->get_option('webp_conversion');
90 WP_Optimize()->log("Should we use webp? $this->_should_use_webp");
91 if ('true' === $this->_rewrite_status) {
92 if (!$this->_should_use_webp) {
93 $this->save_htaccess_rules(false);
94 return;
95 } else {
96 if (!$this->is_webp_redirection_possible()) {
97 $this->maybe_use_alter_html();
98 }
99 }
100 } else {
101 if ($this->_should_use_webp) {
102 $this->maybe_use_alter_html();
103 }
104 }
105 }
106
107 /**
108 * If alter html method is possible, then use it
109 */
110 private function maybe_use_alter_html() {
111 if ($this->is_alter_html_possible()) {
112 $this->use_alter_html();
113 }
114 }
115
116 /**
117 * Even if server support .htaccess rewrite, sometimes it is not possible
118 * to serve webp images. So, find it webp redirection is possible or not
119 *
120 * @return bool
121 */
122 private function is_webp_redirection_possible() {
123 if (!class_exists('WPO_WebP_Self_Test')) {
124 require_once WPO_PLUGIN_MAIN_PATH . 'webp/class-wpo-webp-self-test.php';
125 }
126 $self_test = WPO_WebP_Self_Test::get_instance();
127
128 if ($self_test->get_webp_image()) {
129 $this->save_htaccess_rules($this->_should_use_webp);
130 WP_Optimize()->log('Server can serve webp');
131 if ($self_test->is_webp_served()) return true;
132 }
133 $this->save_htaccess_rules();
134 WP_Optimize()->log('Could not serve webp');
135 return false;
136 }
137
138 /**
139 * Decide whether the browser requesting the URL can accept webp images or not
140 *
141 * @return bool
142 */
143 private function is_browser_accepting_webp() {
144 WP_Optimize()->log('Requested URI: ' . $_SERVER['REQUEST_URI']);
145 return (isset($_SERVER['HTTP_ACCEPT']) && false !== strpos($_SERVER['HTTP_ACCEPT'], 'image/webp'));
146 }
147
148 /**
149 * Detect whether using alter HTML method is possible or not
150 *
151 * @return bool
152 */
153 private function is_alter_html_possible() {
154 if ($this->is_browser_accepting_webp()) {
155 WP_Optimize()->log('Browser is accepting WebP, So alter HTML is possible');
156 return true;
157 }
158 WP_Optimize()->log('Browser is NOT accepting WebP, So alter HTML is NOT possible');
159 return false;
160 }
161
162 /**
163 * Setup alter html method
164 */
165 private function use_alter_html() {
166 if (!class_exists('WPO_WebP_Alter_HTML')) {
167 require_once WPO_PLUGIN_MAIN_PATH . 'webp/class-wpo-webp-alter-html.php';
168 }
169 WPO_WebP_Alter_HTML::get_instance();
170 }
171
172 /**
173 * Initialize .htaccess
174 */
175 private function setup_htaccess_file() {
176 if (null !== $this->_htaccess) return;
177 WP_Optimize()->log('Setting up .htaccess file');
178 $wp_uploads = wp_get_upload_dir();
179 $htaccess_file = $wp_uploads['basedir'] . '/.htaccess';
180 if (!file_exists($htaccess_file)) {
181 file_put_contents($htaccess_file, '');
182 }
183 if (!class_exists('WP_Optimize_Htaccess')) {
184 require_once WPO_PLUGIN_MAIN_PATH . 'includes/class-wp-optimize-htaccess.php';
185 }
186 $this->_htaccess = new WP_Optimize_Htaccess($htaccess_file);
187 $this->add_webp_mime_type();
188 }
189
190 /**
191 * Save .htaccess rules
192 *
193 * @return bool
194 */
195 private function save_htaccess_rules($webp_conversion_enabled = false) {
196 $htaccess_comment_section = 'WP-Optimize WebP Rules';
197
198 if ($this->_htaccess->is_exists() && !$webp_conversion_enabled) {
199 $this->_htaccess->remove_commented_section($htaccess_comment_section);
200 $this->_htaccess->write_file();
201 return true;
202 }
203 if ($this->_htaccess->is_commented_section_exists($htaccess_comment_section)) return false;
204 $this->_htaccess->update_commented_section($this->prepare_webp_htaccess_rules(), $htaccess_comment_section);
205 $this->_htaccess->write_file();
206 return true;
207 }
208
209 /**
210 * Prepare array of htaccess rules to use webp images.
211 *
212 * @return array
213 */
214 private function prepare_webp_htaccess_rules() {
215 return array(
216 array(
217 '<IfModule mod_rewrite.c>',
218 'RewriteEngine On',
219 '',
220 '# Redirect to existing converted image in same dir (if browser supports webp)',
221 'RewriteCond %{HTTP_ACCEPT} image/webp',
222 'RewriteCond %{REQUEST_FILENAME} (?i)(.*)(\.jpe?g|\.png)$',
223 'RewriteCond %1%2\.webp -f',
224 'RewriteRule (?i)(.*)(\.jpe?g|\.png)$ %1%2\.webp [T=image/webp,E=EXISTING:1,E=ADDVARY:1,L]',
225 '',
226 '# Make sure that browsers which does not support webp also gets the Vary:Accept header',
227 '# when requesting images that would be redirected to webp on browsers that does.',
228 array(
229 '<IfModule mod_headers.c>',
230 array(
231 '<FilesMatch "(?i)\.(jpe?g|png)$">',
232 'Header append "Vary" "Accept"',
233 '</FilesMatch>',
234 ),
235 '</IfModule>',
236 ),
237 '',
238 '</IfModule>',
239 '',
240 ),
241 array(
242 '# Rules for handling requests for webp images',
243 '# ---------------------------------------------',
244 '',
245 '# Set Vary:Accept header if we came here by way of our redirect, which set the ADDVARY environment variable',
246 '# The purpose is to make proxies and CDNs aware that the response varies with the Accept header',
247 '<IfModule mod_headers.c>',
248 array(
249 '<IfModule mod_setenvif.c>',
250 '# Apache appends "REDIRECT_" in front of the environment variables defined in mod_rewrite, but LiteSpeed does not',
251 '# So, the next lines are for Apache, in order to set environment variables without "REDIRECT_"',
252 'SetEnvIf REDIRECT_EXISTING 1 EXISTING=1',
253 'SetEnvIf REDIRECT_ADDVARY 1 ADDVARY=1',
254 '',
255 'Header append "Vary" "Accept" env=ADDVARY',
256 '',
257 '# Set X-WPO-WebP header for diagnose purposes',
258 'Header set "X-WPO-WebP" "Redirected directly to existing webp" env=EXISTING',
259 '</IfModule>',
260 ),
261 '</IfModule>',
262 ),
263 );
264 }
265
266 /**
267 * Prepare array of htaccess rules to use webp images.
268 *
269 * @return array
270 */
271 private function add_webp_mime_type() {
272 $htaccess_comment_section = 'Register webp mime type';
273 if ($this->_htaccess->is_exists() && !$this->_htaccess->is_commented_section_exists($htaccess_comment_section)) {
274 $webp_mime_type = array(
275 array(
276 '<IfModule mod_mime.c>',
277 'AddType image/webp .webp',
278 '</IfModule>',
279 ),
280 );
281 $this->_htaccess->update_commented_section($webp_mime_type, $htaccess_comment_section);
282 $this->_htaccess->write_file();
283 }
284 }
285 }
286
287 endif;
288