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

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

298 lines 8.6 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 require_once 'class-wp-optimize-htaccess.php';
6
7 /**
8 * Class WP_Optimize_Browser_Cache
9 */
10 class WP_Optimize_Browser_Cache {
11
12 private $_htaccess = null;
13
14 private $_options = null;
15
16 private $_wp_optimize = null;
17
18 /**
19 * Browser cache section in htaccess will wrapped with this comment
20 *
21 * @var string
22 */
23 private $_htaccess_section_comment = 'WP-Optimize Browser Cache';
24
25 /**
26 * WP_Optimize_Browser_Cache constructor.
27 */
28 public function __construct() {
29 $this->_wp_optimize = WP_Optimize();
30
31 $this->_htaccess = new WP_Optimize_Htaccess();
32
33 $this->_options = $this->_wp_optimize->get_options();
34 }
35
36 /**
37 * Check headers for Cache-Control and Etag. And if they are exist return true.
38 *
39 * @return bool|WP_Error
40 **/
41 public function is_enabled() {
42
43 static $is_enabled;
44 if (isset($is_enabled)) return $is_enabled;
45
46 $headers = WP_Optimize()->get_stylesheet_headers();
47
48 if (is_wp_error($headers)) return $headers;
49
50 if (array_key_exists('cache-control', $headers) && array_key_exists('expires', $headers)) {
51 $is_enabled = true;
52 } else {
53 $is_enabled = false;
54 }
55
56 if ($this->is_browser_cache_section_exists() && false === $this->_wp_optimize->is_apache_module_loaded(array('mod_expires', 'mod_headers'))) {
57 $is_enabled = new WP_Error('Browser cache', __('We successfully updated your .htaccess file. But it seems one of Apache modules - mod_expires or mod_headers is not active.', 'wp-optimize'));
58 }
59
60 return $is_enabled;
61 }
62
63 /**
64 * Enable browser cache - add settings into .htaccess.
65 *
66 * @param string $expiry_time
67 */
68 public function enable($expiry_time = '1 month') {
69 $this->_htaccess->update_commented_section($this->prepare_browser_cache_section($expiry_time), $this->_htaccess_section_comment);
70 $this->_htaccess->write_file();
71 }
72
73 /**
74 * Disable cache - remove settings from .htaccess added in enable() function.
75 */
76 public function disable() {
77 $this->_htaccess->remove_commented_section($this->_htaccess_section_comment);
78 $this->_htaccess->write_file();
79 }
80
81 /**
82 * Check if browser chache option is set to true then add section with gzip settings into .htaccess (used when plugin being activated).
83 */
84 public function restore() {
85 $expire_days = $this->_options->get_option('browser_cache_expire_days', '');
86 $expire_hours = $this->_options->get_option('browser_cache_expire_hours', '');
87
88 $expiry_time = $this->prepare_interval($expire_days, $expire_hours);
89
90 $enabled = ('' == $expiry_time) ? false : true;
91
92 if ($enabled && $this->_htaccess->is_writable()) $this->enable($expiry_time);
93 }
94
95 /**
96 * Check if section with browser cache settings already exists.
97 */
98 public function is_browser_cache_section_exists() {
99 return $this->_htaccess->is_commented_section_exists($this->_htaccess_section_comment);
100 }
101
102 /**
103 * Handle for enable_browser_cache command used in WP_Optimize_Commands.
104 *
105 * @param array $params - ['browser_cache_expire' => '1 month 15 days 2 hours' || '' - for disable cache]
106 * @return array
107 */
108 public function enable_browser_cache_command_handler($params) {
109 $expire_days = isset($params['browser_cache_expire_days']) ? $params['browser_cache_expire_days'] : '';
110 $expire_hours = isset($params['browser_cache_expire_hours']) ? $params['browser_cache_expire_hours'] : '';
111
112 $current_expire_days = $this->_options->get_option('browser_cache_expire_days', '');
113 $current_expire_hours = $this->_options->get_option('browser_cache_expire_hours', '');
114
115 $section_updated = false;
116
117 $expiry_time = $this->prepare_interval($expire_days, $expire_hours);
118
119 $enable = ('' == $expiry_time) ? false : true;
120
121 /**
122 * If we don't need to do anything in .htaccess then return message.
123 */
124 if ($enable == $this->_htaccess->is_commented_section_exists() && $expire_days == $current_expire_days && $expire_hours == $current_expire_hours) {
125 $message = __('Browser static caching settings already exists in the .htaccess file', 'wp-optimize');
126
127 return array(
128 'success' => true,
129 'enabled' => $enable,
130 'message' => $message,
131 );
132 }
133
134 if ($this->_htaccess->is_writable()) {
135 // update commented section
136
137 if ($enable) {
138 $this->enable($expiry_time);
139 } else {
140 $this->disable();
141 }
142
143 // read updated file.
144 $this->_htaccess->read_file();
145 // check if section added or removed successfully.
146 $section_exists = $this->_htaccess->is_commented_section_exists();
147 // set correct $section-updated flag.
148 $section_updated = $enable === $section_exists;
149 }
150
151 if ($section_updated) {
152 $enabled = $this->is_enabled();
153
154 // save $expire value to options.
155 $this->_options->update_option('browser_cache_expire_days', $expire_days);
156 $this->_options->update_option('browser_cache_expire_hours', $expire_hours);
157
158 if (is_wp_error($enabled)) {
159 return array(
160 'success' => true,
161 'enabled' => $enabled,
162 'error_message' => $enabled->get_error_message(),
163 );
164 } else {
165 return array(
166 'success' => true,
167 'enabled' => $enabled,
168 'message' => __('We successfully updated your .htaccess file.', 'wp-optimize'),
169 );
170 }
171 } else {
172 $cache_section = $this->prepare_browser_cache_section($expiry_time);
173
174 if ($enable) {
175 $message = sprintf(__('We can\'t update your %s file. Please try to add following lines manually:', 'wp-optimize'), $this->_htaccess->get_filename());
176 $output = htmlentities($this->_htaccess->get_section_begin_comment() . PHP_EOL .
177 join(PHP_EOL, $this->_htaccess->get_flat_array($cache_section)).
178 PHP_EOL . $this->_htaccess->get_section_end_comment());
179 } else {
180 $message = sprintf(__('We can\'t update your %s file. Please try to remove following lines manually:', 'wp-optimize'), $this->_htaccess->get_filename());
181 $output = htmlentities($this->_htaccess->get_section_begin_comment() . PHP_EOL .
182 ' ... ... ... '.
183 PHP_EOL . $this->_htaccess->get_section_end_comment());
184 }
185
186 return array(
187 'success' => false,
188 'enabled' => $this->is_enabled(),
189 'error_message' => $message,
190 'output' => $output,
191 );
192 }
193 }
194
195 /**
196 * Use $days an $hours values to build correct time interval as a string like '2 days 3 hours' or empty string if date is empty.
197 *
198 * @param int $days
199 * @param int $hours
200 * @return string
201 */
202 private function prepare_interval($days, $hours) {
203
204 $days = is_numeric($days) ? floor($days) : 0;
205 $hours = is_numeric($hours) ? floor($hours) : 0;
206
207 if (0 == $days && 0 == $hours) {
208 return '';
209 }
210
211 $parts = array();
212
213 // if hours value more than one day then fix it.
214 $days += floor($hours / 24);
215 $hours = $hours % 24;
216
217 $years = floor($days / 365);
218 $days = $days % 365;
219 $months = floor($days / 30);
220 $days = $days % 30;
221
222 if ($years > 0) {
223 $parts[] = $years . ($years > 1 ? ' years' : ' year');
224 }
225
226 if ($months > 0) {
227 $parts[] = $months . ($months > 1 ? ' months' : ' month');
228 }
229
230 if ($days > 0) {
231 $parts[] = $days . ($days > 1 ? ' days' : ' day');
232 }
233
234 if ($hours > 0) {
235 $parts[] = $hours . ($hours > 1 ? ' hours' : ' hour');
236 }
237
238 return join(' ', $parts);
239 }
240
241 /**
242 * Build browser cache section array.
243 *
244 * @param string $expire - value like - 1 day 12 hours 15 minutes
245 * @return array
246 */
247 public function prepare_browser_cache_section($expire) {
248 return array(
249 array(
250 '<IfModule mod_expires.c>',
251 'ExpiresActive On',
252 'ExpiresByType text/css "access '.$expire.'"',
253 'ExpiresByType text/html "access '.$expire.'"',
254 'ExpiresByType image/gif "access '.$expire.'"',
255 'ExpiresByType image/png "access '.$expire.'"',
256 'ExpiresByType image/jpg "access '.$expire.'"',
257 'ExpiresByType image/jpeg "access '.$expire.'"',
258 'ExpiresByType image/webp "access '.$expire.'"',
259 'ExpiresByType image/x-icon "access '.$expire.'"',
260 'ExpiresByType application/pdf "access '.$expire.'"',
261 'ExpiresByType application/javascript "access '.$expire.'"',
262 'ExpiresByType text/x-javascript "access '.$expire.'"',
263 'ExpiresByType application/x-shockwave-flash "access '.$expire.'"',
264 'ExpiresDefault "access '.$expire.'"',
265 '</IfModule>',
266 ),
267 '',
268 array(
269 '<IfModule mod_headers.c>',
270 array(
271 '<filesMatch "\.(ico|jpe?g|png|gif|webp|swf)$">',
272 'Header set Cache-Control "public"',
273 '</filesMatch>',
274 ),
275 array(
276 '<filesMatch "\.(css)$">',
277 'Header set Cache-Control "public"',
278 '</filesMatch>',
279 ),
280 array(
281 '<filesMatch "\.(js)$">',
282 'Header set Cache-Control "private"',
283 '</filesMatch>',
284 ),
285 array(
286 '<filesMatch "\.(x?html?|php)$">',
287 'Header set Cache-Control "private, must-revalidate"',
288 '</filesMatch>',
289 ),
290 '</IfModule>',
291 ),
292 '',
293 '#Disable ETag',
294 'FileETag None',
295 );
296 }
297 }
298