HamroKhanpin/hamrokhaanpaan/wp-content/__plugins/wp-optimize/includes/class-wp-optimize-browser-cache.php
2024-04-29 13:12:44 +05:45

298 lines
8.6 KiB
PHP

<?php
if (!defined('WPO_VERSION')) die('No direct access allowed');
require_once 'class-wp-optimize-htaccess.php';
/**
* Class WP_Optimize_Browser_Cache
*/
class WP_Optimize_Browser_Cache {
private $_htaccess = null;
private $_options = null;
private $_wp_optimize = null;
/**
* Browser cache section in htaccess will wrapped with this comment
*
* @var string
*/
private $_htaccess_section_comment = 'WP-Optimize Browser Cache';
/**
* WP_Optimize_Browser_Cache constructor.
*/
public function __construct() {
$this->_wp_optimize = WP_Optimize();
$this->_htaccess = new WP_Optimize_Htaccess();
$this->_options = $this->_wp_optimize->get_options();
}
/**
* Check headers for Cache-Control and Etag. And if they are exist return true.
*
* @return bool|WP_Error
**/
public function is_enabled() {
static $is_enabled;
if (isset($is_enabled)) return $is_enabled;
$headers = WP_Optimize()->get_stylesheet_headers();
if (is_wp_error($headers)) return $headers;
if (array_key_exists('cache-control', $headers) && array_key_exists('expires', $headers)) {
$is_enabled = true;
} else {
$is_enabled = false;
}
if ($this->is_browser_cache_section_exists() && false === $this->_wp_optimize->is_apache_module_loaded(array('mod_expires', 'mod_headers'))) {
$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'));
}
return $is_enabled;
}
/**
* Enable browser cache - add settings into .htaccess.
*
* @param string $expiry_time
*/
public function enable($expiry_time = '1 month') {
$this->_htaccess->update_commented_section($this->prepare_browser_cache_section($expiry_time), $this->_htaccess_section_comment);
$this->_htaccess->write_file();
}
/**
* Disable cache - remove settings from .htaccess added in enable() function.
*/
public function disable() {
$this->_htaccess->remove_commented_section($this->_htaccess_section_comment);
$this->_htaccess->write_file();
}
/**
* Check if browser chache option is set to true then add section with gzip settings into .htaccess (used when plugin being activated).
*/
public function restore() {
$expire_days = $this->_options->get_option('browser_cache_expire_days', '');
$expire_hours = $this->_options->get_option('browser_cache_expire_hours', '');
$expiry_time = $this->prepare_interval($expire_days, $expire_hours);
$enabled = ('' == $expiry_time) ? false : true;
if ($enabled && $this->_htaccess->is_writable()) $this->enable($expiry_time);
}
/**
* Check if section with browser cache settings already exists.
*/
public function is_browser_cache_section_exists() {
return $this->_htaccess->is_commented_section_exists($this->_htaccess_section_comment);
}
/**
* Handle for enable_browser_cache command used in WP_Optimize_Commands.
*
* @param array $params - ['browser_cache_expire' => '1 month 15 days 2 hours' || '' - for disable cache]
* @return array
*/
public function enable_browser_cache_command_handler($params) {
$expire_days = isset($params['browser_cache_expire_days']) ? $params['browser_cache_expire_days'] : '';
$expire_hours = isset($params['browser_cache_expire_hours']) ? $params['browser_cache_expire_hours'] : '';
$current_expire_days = $this->_options->get_option('browser_cache_expire_days', '');
$current_expire_hours = $this->_options->get_option('browser_cache_expire_hours', '');
$section_updated = false;
$expiry_time = $this->prepare_interval($expire_days, $expire_hours);
$enable = ('' == $expiry_time) ? false : true;
/**
* If we don't need to do anything in .htaccess then return message.
*/
if ($enable == $this->_htaccess->is_commented_section_exists() && $expire_days == $current_expire_days && $expire_hours == $current_expire_hours) {
$message = __('Browser static caching settings already exists in the .htaccess file', 'wp-optimize');
return array(
'success' => true,
'enabled' => $enable,
'message' => $message,
);
}
if ($this->_htaccess->is_writable()) {
// update commented section
if ($enable) {
$this->enable($expiry_time);
} else {
$this->disable();
}
// read updated file.
$this->_htaccess->read_file();
// check if section added or removed successfully.
$section_exists = $this->_htaccess->is_commented_section_exists();
// set correct $section-updated flag.
$section_updated = $enable === $section_exists;
}
if ($section_updated) {
$enabled = $this->is_enabled();
// save $expire value to options.
$this->_options->update_option('browser_cache_expire_days', $expire_days);
$this->_options->update_option('browser_cache_expire_hours', $expire_hours);
if (is_wp_error($enabled)) {
return array(
'success' => true,
'enabled' => $enabled,
'error_message' => $enabled->get_error_message(),
);
} else {
return array(
'success' => true,
'enabled' => $enabled,
'message' => __('We successfully updated your .htaccess file.', 'wp-optimize'),
);
}
} else {
$cache_section = $this->prepare_browser_cache_section($expiry_time);
if ($enable) {
$message = sprintf(__('We can\'t update your %s file. Please try to add following lines manually:', 'wp-optimize'), $this->_htaccess->get_filename());
$output = htmlentities($this->_htaccess->get_section_begin_comment() . PHP_EOL .
join(PHP_EOL, $this->_htaccess->get_flat_array($cache_section)).
PHP_EOL . $this->_htaccess->get_section_end_comment());
} else {
$message = sprintf(__('We can\'t update your %s file. Please try to remove following lines manually:', 'wp-optimize'), $this->_htaccess->get_filename());
$output = htmlentities($this->_htaccess->get_section_begin_comment() . PHP_EOL .
' ... ... ... '.
PHP_EOL . $this->_htaccess->get_section_end_comment());
}
return array(
'success' => false,
'enabled' => $this->is_enabled(),
'error_message' => $message,
'output' => $output,
);
}
}
/**
* 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.
*
* @param int $days
* @param int $hours
* @return string
*/
private function prepare_interval($days, $hours) {
$days = is_numeric($days) ? floor($days) : 0;
$hours = is_numeric($hours) ? floor($hours) : 0;
if (0 == $days && 0 == $hours) {
return '';
}
$parts = array();
// if hours value more than one day then fix it.
$days += floor($hours / 24);
$hours = $hours % 24;
$years = floor($days / 365);
$days = $days % 365;
$months = floor($days / 30);
$days = $days % 30;
if ($years > 0) {
$parts[] = $years . ($years > 1 ? ' years' : ' year');
}
if ($months > 0) {
$parts[] = $months . ($months > 1 ? ' months' : ' month');
}
if ($days > 0) {
$parts[] = $days . ($days > 1 ? ' days' : ' day');
}
if ($hours > 0) {
$parts[] = $hours . ($hours > 1 ? ' hours' : ' hour');
}
return join(' ', $parts);
}
/**
* Build browser cache section array.
*
* @param string $expire - value like - 1 day 12 hours 15 minutes
* @return array
*/
public function prepare_browser_cache_section($expire) {
return array(
array(
'<IfModule mod_expires.c>',
'ExpiresActive On',
'ExpiresByType text/css "access '.$expire.'"',
'ExpiresByType text/html "access '.$expire.'"',
'ExpiresByType image/gif "access '.$expire.'"',
'ExpiresByType image/png "access '.$expire.'"',
'ExpiresByType image/jpg "access '.$expire.'"',
'ExpiresByType image/jpeg "access '.$expire.'"',
'ExpiresByType image/webp "access '.$expire.'"',
'ExpiresByType image/x-icon "access '.$expire.'"',
'ExpiresByType application/pdf "access '.$expire.'"',
'ExpiresByType application/javascript "access '.$expire.'"',
'ExpiresByType text/x-javascript "access '.$expire.'"',
'ExpiresByType application/x-shockwave-flash "access '.$expire.'"',
'ExpiresDefault "access '.$expire.'"',
'</IfModule>',
),
'',
array(
'<IfModule mod_headers.c>',
array(
'<filesMatch "\.(ico|jpe?g|png|gif|webp|swf)$">',
'Header set Cache-Control "public"',
'</filesMatch>',
),
array(
'<filesMatch "\.(css)$">',
'Header set Cache-Control "public"',
'</filesMatch>',
),
array(
'<filesMatch "\.(js)$">',
'Header set Cache-Control "private"',
'</filesMatch>',
),
array(
'<filesMatch "\.(x?html?|php)$">',
'Header set Cache-Control "private, must-revalidate"',
'</filesMatch>',
),
'</IfModule>',
),
'',
'#Disable ETag',
'FileETag None',
);
}
}