Skip to content

Instantly share code, notes, and snippets.

@irshad-pugMarker
Last active May 9, 2022 04:59
Show Gist options
  • Save irshad-pugMarker/c333588ae84cca8b0047c7abb7d95ae0 to your computer and use it in GitHub Desktop.
Save irshad-pugMarker/c333588ae84cca8b0047c7abb7d95ae0 to your computer and use it in GitHub Desktop.
PM Caching
  • Create file pm-cache-control.php

  • Include it In functions.php

  • Add define('W3TC_DYNAMIC_SECURITY', 'FRAGMENT_CACHING'); to wp-config.php

  • Add following code to header.php before everything <?php do_action('pm_html_start')?>

  • then replace wp_head() call with following

    <?php
    if (pm_is_cachable()) {
    ?>
        <!-- mfunc FRAGMENT_CACHING -->
        wp_head();
        <!-- /mfunc FRAGMENT_CACHING -->
    <?php
    } else {
        wp_head();
    } ?>
    
  • Add following code to footer.php after everything <?php do_action('pm_html_end')?>

  • then replace wp_footer() call with following

    <?php
    if (pm_is_cachable()) {
    ?>
        <!-- mfunc FRAGMENT_CACHING -->
        wp_footer();
        <!-- /mfunc FRAGMENT_CACHING -->
    <?php
    } else {
        wp_footer();
    } ?>
    

How to Use

To exicute any php code or to include gravity form in cahed pages use following Wrap php code in

<?php
if (pm_is_cachable()) {
?>
    <!-- mfunc FRAGMENT_CACHING -->
    php_code_without_php_tags
    <!-- /mfunc FRAGMENT_CACHING -->
<?php
} else {
    php_code
} ?>

Examples

<?php
if (pm_is_cachable()) {
?>
    <!-- mfunc FRAGMENT_CACHING -->
    the_content();
    <!-- /mfunc FRAGMENT_CACHING -->
<?php
} else {
    the_content();
} ?>
<?php
if (pm_is_cachable()) {
?>
    <!-- mfunc FRAGMENT_CACHING -->
    echo do_shortcode('[gravityforms id="5" title="true" description="false" ajax="false"]');
    <!-- /mfunc FRAGMENT_CACHING -->
<?php
} else {
    echo do_shortcode('[gravityforms id="5" title="true" description="false" ajax="false"]');
} ?>
<?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;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment