|
<?php |
|
if (!defined('ABSPATH')) { // Or some other WordPress constant |
|
exit; |
|
} |
|
|
|
/** |
|
* Generated by the WordPress Option Page generator |
|
* at http://jeremyhixon.com/wp-tools/option-page/ |
|
*/ |
|
|
|
class PMCache |
|
{ |
|
private $pm_cache_options; |
|
|
|
public function __construct() |
|
{ |
|
add_action('admin_menu', array($this, 'pm_cache_add_plugin_page')); |
|
add_action('admin_init', array($this, 'pm_cache_page_init')); |
|
} |
|
|
|
public function pm_cache_add_plugin_page() |
|
{ |
|
add_menu_page( |
|
'PM Cache', // page_title |
|
'PM Cache', // menu_title |
|
'manage_options', // capability |
|
'pm-cache', // menu_slug |
|
array($this, 'pm_cache_create_admin_page'), // function |
|
'dashicons-index-card', // icon_url |
|
2 // position |
|
); |
|
} |
|
|
|
public function pm_cache_create_admin_page() |
|
{ |
|
$this->pm_cache_options = get_option('pm_cache_option_name'); ?> |
|
|
|
<div class="wrap"> |
|
<h2>PM Cache</h2> |
|
<p></p> |
|
<?php settings_errors(); ?> |
|
|
|
<form method="post" action="options.php"> |
|
<?php |
|
settings_fields('pm_cache_option_group'); |
|
do_settings_sections('pm-cache-admin'); |
|
submit_button(); |
|
|
|
?> |
|
</form> |
|
<p></p> |
|
<hr> |
|
<div> |
|
<?php |
|
|
|
if (isset($_POST['pm_purge_cache'])) { |
|
|
|
if (isset($_POST['pm_purge_cache_single_section'])) { |
|
|
|
if (isset($_POST['section'])) { |
|
if (file_exists($_POST['section'])) { |
|
unlink($_POST['section']); |
|
} |
|
} |
|
} else { |
|
purge_all_pm_cache(); |
|
} |
|
|
|
?> |
|
<div class="notice notice-success is-dismissible"> |
|
<p>Purge Success </p> |
|
</div> |
|
<?php |
|
} |
|
?> |
|
<h2>Purge Cached pages</h2> |
|
<?php |
|
$pm_irsh_cache_dir_path = get_pm_cache_dir(); |
|
$files = glob($pm_irsh_cache_dir_path . '/*.html'); |
|
?> |
|
<form method="post" action="#"> |
|
<input type="hidden" name="pm_purge_cache"> |
|
<p>Total cached files <?php echo count($files); ?> |
|
<button class="button" type="submit"><span class="dashicons dashicons-trash"></span> Purge All Cache</button> |
|
</p> |
|
</form> |
|
<br> |
|
|
|
<?php |
|
foreach ($files as $filename) { |
|
?> |
|
<form method="post" action="#"> |
|
<input type="hidden" name="pm_purge_cache"> |
|
<input type="hidden" name="pm_purge_cache_single_section"> |
|
<input type="hidden" name="section" value="<?php echo $filename ?>"> |
|
<p> |
|
<?php echo basename($filename); ?> |
|
<button class="button" type="submit"><span class="dashicons dashicons-trash"></span> Purge </button> |
|
</p> |
|
</form> |
|
<?php |
|
|
|
} |
|
|
|
?> |
|
</div> |
|
</div> |
|
<?php |
|
|
|
|
|
} |
|
|
|
public function pm_cache_page_init() |
|
{ |
|
register_setting( |
|
'pm_cache_option_group', // option_group |
|
'pm_cache_option_name', // option_name |
|
array($this, 'pm_cache_sanitize') // sanitize_callback |
|
); |
|
|
|
add_settings_section( |
|
'pm_cache_setting_section', // id |
|
'Settings', // title |
|
array($this, 'pm_cache_section_info'), // callback |
|
'pm-cache-admin' // page |
|
); |
|
|
|
add_settings_field( |
|
'enable_caching_0', // id |
|
'Enable Caching', // title |
|
array($this, 'enable_caching_0_callback'), // callback |
|
'pm-cache-admin', // page |
|
'pm_cache_setting_section' // section |
|
); |
|
|
|
add_settings_field( |
|
'skip_these', // id |
|
'Dont cache these slugs', // title |
|
array($this, 'skip_these_callback'), // callback |
|
'pm-cache-admin', // page |
|
'pm_cache_setting_section' // section |
|
); |
|
} |
|
|
|
public function pm_cache_sanitize($input) |
|
{ |
|
$sanitary_values = array(); |
|
if (isset($input['enable_caching_0'])) { |
|
$sanitary_values['enable_caching_0'] = $input['enable_caching_0']; |
|
} |
|
|
|
if (isset($input['skip_these'])) { |
|
$sanitary_values['skip_these'] = esc_textarea($input['skip_these']); |
|
} |
|
|
|
return $sanitary_values; |
|
} |
|
|
|
public function pm_cache_section_info() |
|
{ |
|
} |
|
|
|
public function enable_caching_0_callback() |
|
{ |
|
printf( |
|
'<input type="checkbox" name="pm_cache_option_name[enable_caching_0]" id="enable_caching_0" value="enable_caching_0" %s>', |
|
(isset($this->pm_cache_options['enable_caching_0']) && $this->pm_cache_options['enable_caching_0'] === 'enable_caching_0') ? 'checked' : '' |
|
); |
|
} |
|
|
|
public function skip_these_callback() |
|
{ |
|
printf( |
|
'<textarea class="large-text" rows="2" name="pm_cache_option_name[skip_these]" id="skip_these">%s</textarea>', |
|
isset($this->pm_cache_options['skip_these']) ? esc_attr($this->pm_cache_options['skip_these']) : '' |
|
); |
|
} |
|
} |
|
if (is_admin()) { |
|
$pm_cache = new PMCache(); |
|
} |
|
|
|
function is_pm_cache_enabled() |
|
{ |
|
$pm_cache_options = get_option('pm_cache_option_name'); |
|
|
|
return (array_key_exists('enable_caching_0', $pm_cache_options)) ? true : false; |
|
} |
|
|
|
function pm_get_skiped_slugs() |
|
{ |
|
$pm_cache_options = get_option('pm_cache_option_name'); |
|
return $pm_cache_options['skip_these']; |
|
} |
|
|
|
/* |
|
* Retrieve this value with: |
|
* $pm_cache_options = get_option( 'pm_cache_option_name' ); // Array of All Options |
|
* $enable_caching_0 = $pm_cache_options['enable_caching_0']; // Enable Caching |
|
*/ |
|
|
|
//PM_CACHE_ENABLED |
|
//get section from cache |
|
function get_sction_from_cache($section) |
|
{ |
|
if (!empty($section) && is_pm_cache_enabled()) { |
|
$pm_irsh_cache_dir_path = get_pm_cache_dir(); |
|
|
|
$scetion_file = $pm_irsh_cache_dir_path . '/' . $section . '-cached.html'; |
|
//check if our folder has this scetion |
|
if (file_exists($scetion_file)) { |
|
return $scetion_file; |
|
} else { |
|
return false; |
|
} |
|
} |
|
return false; |
|
} |
|
|
|
//add section in cache |
|
function add_section_in_cache($section, $content) |
|
{ |
|
if (!empty($section) && is_pm_cache_enabled()) { |
|
$pm_irsh_cache_dir_path = get_pm_cache_dir(); |
|
|
|
$scetion_file = $pm_irsh_cache_dir_path . '/' . $section . '-cached.html'; |
|
$content = str_replace('<?xml version="1.0" encoding="utf-8"?>', '', $content); |
|
// file_put_contents($scetion_file, pm_minify_html($content)); |
|
file_put_contents($scetion_file, $content); |
|
} |
|
} |
|
|
|
|
|
//get cache dir path |
|
function get_pm_cache_dir() |
|
{ |
|
$upload_dir = wp_upload_dir(); |
|
|
|
if (!empty($upload_dir['basedir'])) { |
|
$pm_irsh_cache_dir_name = $upload_dir['basedir'] . '/pm_irsh_cache'; |
|
if (!file_exists($pm_irsh_cache_dir_name)) { |
|
if (wp_mkdir_p($pm_irsh_cache_dir_name)) { |
|
$pm_irsh_cache_dir_name = $upload_dir['basedir'] . '/pm_irsh_cache'; |
|
} |
|
} |
|
$pm_irsh_cache_dir_path = $pm_irsh_cache_dir_name; |
|
} |
|
return $pm_irsh_cache_dir_path; |
|
} |
|
|
|
|
|
//remove all cache dir |
|
function purge_all_pm_cache() |
|
{ |
|
$pm_irsh_cache_dir_path = get_pm_cache_dir(); |
|
$files = glob($pm_irsh_cache_dir_path . '/*.html'); // get all file names |
|
foreach ($files as $file) { // iterate files |
|
if (is_file($file)) { |
|
unlink($file); // delete file |
|
} |
|
} |
|
return count(glob($pm_irsh_cache_dir_path . '/*.html')); |
|
} |
|
|
|
|
|
function pm_minify_html($html) |
|
{ |
|
$search = array( |
|
'/(\n|^)(\x20+|\t)/', |
|
'/(\n|^)\/\/(.*?)(\n|$)/', |
|
'/\n/', |
|
'/\<\!--.*?-->/', |
|
'/(\x20+|\t)/', # Delete multispace (Without \n) |
|
'/\>\s+\</', # strip whitespaces between tags |
|
'/(\"|\')\s+\>/', # strip whitespaces between quotation ("') and end tags |
|
'/=\s+(\"|\')/' |
|
); # strip whitespaces between = "' |
|
|
|
$replace = array( |
|
"\n", |
|
"\n", |
|
" ", |
|
"", |
|
" ", |
|
"><", |
|
"$1>", |
|
"=$1" |
|
); |
|
|
|
$html = preg_replace($search, $replace, $html); |
|
return $html; |
|
} |
|
|
|
|
|
function pm_url_to_section_name() |
|
{ |
|
$base = wp_parse_url(trailingslashit(get_option('home')), PHP_URL_PATH); |
|
$path = wp_parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); |
|
|
|
$path = str_replace($base, '', $path); |
|
$path = rtrim($path, '/'); |
|
$path = str_replace('/', '-', $path); |
|
|
|
if ($path) { |
|
return $path; |
|
} |
|
|
|
$post_id = url_to_postid($_SERVER['REQUEST_URI']); |
|
$post = get_post($post_id); |
|
return $post->post_name; |
|
} |
|
class Obstart |
|
{ |
|
public static function callback($buffer) |
|
{ |
|
return $buffer; |
|
} |
|
|
|
public static function add_ob_start() |
|
{ |
|
if (pm_is_cachable()) { |
|
|
|
if ($home_page_cachhe = get_sction_from_cache(pm_url_to_section_name())) { |
|
include($home_page_cachhe); |
|
die(); |
|
} else { |
|
global $buffer; |
|
ob_start(self::callback($buffer)); |
|
} |
|
} |
|
} |
|
|
|
public static function flush_ob_end() |
|
{ |
|
if (pm_is_cachable() && !get_sction_from_cache(pm_url_to_section_name()) && $html = ob_get_contents()) { |
|
ob_end_clean(); |
|
$html = _parse_dynamic($html); |
|
// if (_has_dynamic($html)) { |
|
// } |
|
// echo $html; |
|
add_section_in_cache(pm_url_to_section_name(), $html); |
|
include(get_sction_from_cache(pm_url_to_section_name())); |
|
} |
|
} |
|
} |
|
|
|
add_action('pm_html_start', array('Obstart', 'add_ob_start')); |
|
add_action('pm_html_end', array('Obstart', 'flush_ob_end')); |
|
|
|
function pm_on_post_status_changed($old_status, $new_status, $post) |
|
{ |
|
if (!wp_is_post_revision($post->ID)) { |
|
pm_purge_cache_single($post->post_name); |
|
} |
|
} |
|
add_action('transition_post_status', 'pm_on_post_status_changed', 10, 3); |
|
|
|
function pm_purge_cache_single($section) |
|
{ |
|
if ($home_page_cachhe = get_sction_from_cache($section)) { |
|
if (file_exists($home_page_cachhe)) { |
|
unlink($home_page_cachhe); |
|
} |
|
} |
|
} |
|
|
|
function pm_is_cachable() |
|
{ |
|
global $wp_query; |
|
|
|
$cache_exempt = array('checkout', 'cart', 'wp-admin'); |
|
|
|
array_push($cache_exempt, rest_get_url_prefix()); |
|
|
|
$skiped = pm_get_skiped_slugs(); |
|
|
|
if ($skiped) { |
|
$skiped_array = array_map('trim', explode(',', $skiped)); |
|
|
|
if (count($skiped_array) > 0) { |
|
$cache_exempt = array_merge($cache_exempt, $skiped_array); |
|
} |
|
} |
|
|
|
$return = true; |
|
|
|
// if (defined('PMDONOTCACHEPAGE') && PMDONOTCACHEPAGE === true) { |
|
// $return = false; |
|
// } else |
|
if (defined('DOING_AJAX')) { |
|
$return = false; |
|
} elseif ('private' === get_post_status()) { |
|
$return = false; |
|
} elseif (isset($wp_query) && is_search()) { |
|
$return = false; |
|
} elseif (isset($wp_query) && is_404()) { |
|
$return = false; |
|
} elseif (is_admin()) { |
|
$return = false; |
|
} elseif (false === get_option('permalink_structure')) { |
|
$return = false; |
|
} elseif (function_exists('is_user_logged_in') && is_user_logged_in()) { |
|
$return = false; |
|
} elseif (isset($_GET) && !empty($_GET)) { |
|
$return = false; |
|
} elseif (isset($_POST) && !empty($_POST)) { |
|
$return = false; |
|
} elseif (isset($wp_query) && is_feed()) { |
|
$return = false; |
|
} elseif (class_exists('WooCommerce')) { |
|
if (is_shop()) { |
|
$return = false; |
|
} elseif (is_product_category() || is_product_tag()) { |
|
$return = false; |
|
} elseif (is_product()) { |
|
$return = false; |
|
} elseif (is_account_page()) { |
|
$return = false; |
|
} elseif (is_wc_endpoint_url()) { |
|
$return = false; |
|
} elseif (is_ajax()) { |
|
$return = false; |
|
} |
|
} |
|
|
|
if (empty($_SERVER['REQUEST_URI'])) { |
|
$return = false; |
|
} else { |
|
foreach ($cache_exempt as $exclude) { |
|
if (false !== strpos($_SERVER['REQUEST_URI'], $exclude)) { |
|
$return = false; |
|
} |
|
} |
|
} |
|
|
|
return $return; |
|
} |
|
|
|
/** |
|
* Checks if buffer has dynamic tags |
|
* |
|
* @param string $buffer |
|
* @return boolean |
|
*/ |
|
function _has_dynamic($buffer) |
|
{ |
|
if (!defined('W3TC_DYNAMIC_SECURITY')) |
|
return false; |
|
|
|
return preg_match('~<!--\s*mfunc\s*' . W3TC_DYNAMIC_SECURITY . '(.*)-->(.*)<!--\s*/mfunc\s*' . W3TC_DYNAMIC_SECURITY . '\s*-->~Uis', $buffer); |
|
} |
|
|
|
function _parse_dynamic($buffer) |
|
{ |
|
$buffer = preg_replace_callback('~<!--\s*mfunc\s*' . W3TC_DYNAMIC_SECURITY . '(.*)-->(.*)<!--\s*/mfunc\s*' . W3TC_DYNAMIC_SECURITY . '\s*-->~Uis', '_parse_dynamic_mfunc', $buffer); |
|
|
|
return $buffer; |
|
} |
|
|
|
function _parse_dynamic_mfunc($matches) |
|
{ |
|
$code1 = trim($matches[1]); |
|
$code2 = trim($matches[2]); |
|
$code = ($code1 ? $code1 : $code2); |
|
|
|
if ($code) { |
|
$code = trim($code, ';') . ';'; |
|
$result = true; |
|
try { |
|
$output = '<?php ' . $code . ' ?>'; |
|
} catch (\Exception $ex) { |
|
$result = false; |
|
} |
|
|
|
if ($result === false) { |
|
$output = sprintf('Unable to execute code: %s', htmlspecialchars($code)); |
|
} |
|
} else { |
|
$output = htmlspecialchars('Invalid mfunc tag syntax. The correct format is: <!-- W3TC_DYNAMIC_SECURITY mfunc PHP code --><!-- /mfunc W3TC_DYNAMIC_SECURITY --> or <!-- W3TC_DYNAMIC_SECURITY mfunc -->PHP code<!-- /mfunc W3TC_DYNAMIC_SECURITY -->.'); |
|
} |
|
return $output; |
|
} |