Plugin Directory

Changeset 3027335


Ignore:
Timestamp:
01/26/2024 12:25:18 PM (2 years ago)
Author:
megaoptim
Message:

Version 1.2.0

Location:
rapid-cache/trunk
Files:
4 added
1 deleted
37 edited

Legend:

Unmodified
Added
Removed
  • rapid-cache/trunk/includes/src/Classes/AbsBaseAp.php

    r2380046 r3027335  
    7878            return call_user_func_array($this->{$closure}, $args);
    7979        }
    80         throw new \Exception(sprintf(__('Undefined method/closure: `%1$s`.', 'rapid-cache'), $closure));
     80        throw new \Exception(sprintf('Undefined method/closure: `%1$s`.', $closure));
    8181    }
    8282}
  • rapid-cache/trunk/includes/src/Classes/AdvancedCache.php

    r2380046 r3027335  
    8686        $this->maybeIgnoreUserAbort();
    8787        $this->maybeStopBrowserCaching();
    88        
    89         $this->maybeStartOutputBuffering();
     88        $this->maybePostloadInvalidateWhenLoggedIn();
     89        $this->maybeStartOutputBuffering();
    9090    }
    9191}
  • rapid-cache/trunk/includes/src/Classes/MenuPageOptions.php

    r2500432 r3027335  
    1616class MenuPageOptions extends MenuPage
    1717{
    18     /**
    19      * Constructor.
    20      *
    21      * @since 1.0.0
    22      */
    23     public function __construct()
    24     {
    25         parent::__construct(); // Parent constructor.
    26 
    27         echo '<form id="plugin-menu-page" class="plugin-menu-page" method="post" enctype="multipart/form-data" autocomplete="off"'.
    28              ' action="'.esc_attr(add_query_arg(urlencode_deep(['page' => MEGAOPTIM_RAPID_CACHE_GLOBAL_NS, '_wpnonce' => wp_create_nonce()]), self_admin_url('/admin.php'))).'">'."\n";
    29 
    30         /* ----------------------------------------------------------------------------------------- */
    31 
    32         echo '<div class="plugin-menu-page-heading">'."\n";
    33 
    34         if (is_multisite()) {
    35             echo '<button type="button" class="plugin-menu-page-wipe-cache" style="float:right; margin-left:15px;" title="'.esc_attr(__('Wipe Cache (Start Fresh); clears the cache for all sites in this network at once!', 'rapid-cache')).'"'.
    36                  '  data-action="'.esc_attr(add_query_arg(urlencode_deep(['page' => MEGAOPTIM_RAPID_CACHE_GLOBAL_NS, '_wpnonce' => wp_create_nonce(), MEGAOPTIM_RAPID_CACHE_GLOBAL_NS => ['wipeCache' => '1']]), self_admin_url('/admin.php'))).'">'.
    37                  '  '.__('Wipe', 'rapid-cache').' <img src="'.esc_attr($this->plugin->url('/assets/images/wipe.png')).'" style="width:16px; height:16px; display:inline-block;" /></button>'."\n";
    38         }
    39         echo '   <button type="button" class="plugin-menu-page-clear-cache" style="float:right;" title="'.esc_attr(__('Clear Cache (Start Fresh)', 'rapid-cache').((is_multisite()) ? __('; affects the current site only.', 'rapid-cache') : '')).'"'.
    40              '      data-action="'.esc_attr(add_query_arg(urlencode_deep(['page' => MEGAOPTIM_RAPID_CACHE_GLOBAL_NS, '_wpnonce' => wp_create_nonce(), MEGAOPTIM_RAPID_CACHE_GLOBAL_NS => ['clearCache' => '1']]), self_admin_url('/admin.php'))).'">'.
    41              '      '.__('Clear', 'rapid-cache').' <img src="'.esc_attr($this->plugin->url('/assets/images/clear.png')).'" style="width:16px; height:16px; display:inline-block;" /></button>'."\n";
    42 
    43         echo '   <button type="button" class="plugin-menu-page-restore-defaults"'.// Restores default options.
    44              '      data-confirmation="'.esc_attr(__('Restore default plugin options? You will lose all of your current settings! Are you absolutely sure about this?', 'rapid-cache')).'"'.
    45              '      data-action="'.esc_attr(add_query_arg(urlencode_deep(['page' => MEGAOPTIM_RAPID_CACHE_GLOBAL_NS, '_wpnonce' => wp_create_nonce(), MEGAOPTIM_RAPID_CACHE_GLOBAL_NS => ['restoreDefaultOptions' => '1']]), self_admin_url('/admin.php'))).'">'.
    46              '      '.__('Restore', 'rapid-cache').' <i class="si si-ambulance"></i></button>'."\n";
    47 
    48         echo '   <div class="plugin-menu-page-panel-togglers" title="'.esc_attr(__('All Panels', 'rapid-cache')).'">'."\n";
    49         echo '      <button type="button" class="plugin-menu-page-panels-open"><i class="si si-chevron-down"></i></button>'."\n";
    50         echo '      <button type="button" class="plugin-menu-page-panels-close"><i class="si si-chevron-up"></i></button>'."\n";
    51         echo '   </div>'."\n";
    52 
    53         echo '  <div class="plugin-menu-page-support-links">'."\n";
    54         echo '      <a href="'.esc_attr('https://github.com/megaoptim/rapid-cache/wiki').'" target="_blank"><i class="si si-book"></i> '.__('Wiki', 'rapid-cache').'</a>'."\n";
    55         echo '      <a href="'.esc_attr('https://megaoptim.com/blog/category/rapid-cache/').'" target="_blank"><i class="si si-rss-square"></i> '.__('Blog', 'rapid-cache').'</a>'."\n";
    56         echo '      <a href="'.esc_attr('https://github.com/megaoptim/rapid-cache/wiki/Report-Issue').'" target="_blank"><i class="si si-ticket"></i> '.__('Report Issue', 'rapid-cache').'</a>'."\n";
    57         echo '   </div>'."\n";
    58 
    59         echo '<div class="plugin-menu-page-version">'."\n";
    60         echo    sprintf(__('%1$s v%2$s', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME), esc_html(MEGAOPTIM_RAPID_CACHE_VERSION))."\n";
    61         echo    '(<a href="'.esc_attr('https://wordpress.org/plugins/rapid-cache/#developers').'" target="_blank">'.__('changelog', 'rapid-cache').'</a>)'."\n";
    62         echo '</div>'."\n";
    63         echo '    <img src="'.$this->plugin->url('/assets/images/options-logo.png').'" alt="'.esc_attr(__('Plugin Options', 'rapid-cache')).'" />'."\n";
    64 
    65         echo '<div style="clear:both;"></div>'."\n";
    66 
    67         echo '</div>'."\n";
    68 
    69         /* ----------------------------------------------------------------------------------------- */
    70 
    71         echo '<hr />'."\n";
    72 
    73         /* ----------------------------------------------------------------------------------------- */
    74 
    75         if (!empty($_REQUEST[MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_updated'])) {
    76             echo '<div class="plugin-menu-page-notice notice">'."\n";
    77             echo '   <i class="si si-thumbs-up"></i> '.__('Options updated successfully.', 'rapid-cache')."\n";
    78             echo '</div>'."\n";
    79         }
    80         if (!empty($_REQUEST[MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_restored'])) {
    81             echo '<div class="plugin-menu-page-notice notice">'."\n";
    82             echo '   <i class="si si-thumbs-up"></i> '.__('Default options successfully restored.', 'rapid-cache')."\n";
    83             echo '</div>'."\n";
    84         }
    85         if (!empty($_REQUEST[MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_migrated'])) {
    86             echo '<div class="plugin-menu-page-notice notice">'."\n";
    87             echo '   <i class="si si-thumbs-up"></i> '.sprintf(__('Legacy %s options preserved successfully!', 'rapid-cache'), '<strong>'.MEGAOPTIM_RAPID_CACHE_OLD_NAME.'</strong>')."\n";
    88             echo '</div>'."\n";
    89         }
    90         if (!empty($_REQUEST[MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_cache_wiped'])) {
    91             echo '<div class="plugin-menu-page-notice notice">'."\n";
    92             echo '   <img src="'.esc_attr($this->plugin->url('/assets/images/wipe.png')).'" /> '.__('Cache wiped across all sites; re-creation will occur automatically over time.', 'rapid-cache')."\n";
    93             echo '</div>'."\n";
    94         }
    95         if (!empty($_REQUEST[MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_cache_cleared'])) {
    96             echo '<div class="plugin-menu-page-notice notice">'."\n";
    97             if (is_multisite() && is_main_site()) {
    98                 echo '<img src="'.esc_attr($this->plugin->url('/assets/images/clear.png')).'" /> '.__('Cache cleared for main site; re-creation will occur automatically over time.', 'rapid-cache')."\n";
    99             } else {
    100                 echo '<img src="'.esc_attr($this->plugin->url('/assets/images/clear.png')).'" /> '.__('Cache cleared for this site; re-creation will occur automatically over time.', 'rapid-cache')."\n";
    101             }
    102             echo '</div>'."\n";
    103         }
    104         if (!empty($_REQUEST[MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_wp_htaccess_add_failure'])) {
    105             echo '<div class="plugin-menu-page-notice error">'."\n";
    106             echo '   <i class="si si-thumbs-down"></i> '.sprintf(__('Failed to update your <code>/.htaccess</code> file automatically. Most likely a permissions error. Please make sure it has permissions <code>644</code> or higher (perhaps <code>666</code>). Once you\'ve done this, please try saving the %1$s options again.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME))."\n";
    107             echo '</div>'."\n";
    108         }
    109         if (!empty($_REQUEST[MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_wp_htaccess_remove_failure'])) {
    110             echo '<div class="plugin-menu-page-notice error">'."\n";
    111             echo '   <i class="si si-thumbs-down"></i> '.sprintf(__('Failed to update your <code>/.htaccess</code> file automatically. Most likely a permissions error. Please make sure it has permissions <code>644</code> or higher (perhaps <code>666</code>). Once you\'ve done this, please try saving the %1$s options again.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME))."\n";
    112             echo '</div>'."\n";
    113         }
    114         if (!empty($_REQUEST[MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_wp_htaccess_nginx_notice'])) {
    115             echo '<div class="plugin-menu-page-notice error">'."\n";
    116             echo '   <i class="si si-thumbs-down"></i> '.__('It appears that your server is running NGINX and does not support <code>.htaccess</code> rules. Please <a href="https://github.com/megaoptim/rapid-cache/wiki/Recommended-Nginx-Configuration-for-Rapid-Cache" target="_new">update your server configuration manually</a>. If you\'ve already updated your NGINX configuration, you can safely <a href="https://github.com/megaoptim/rapid-cache/wiki/How-to-disable-the-Nginx-htaccess-notice" target="_new">ignore this message</a>.', 'rapid-cache')."\n";
    117             echo '</div>'."\n";
    118         }
    119         if (!empty($_REQUEST[MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_wp_config_wp_cache_add_failure'])) {
    120             echo '<div class="plugin-menu-page-notice error">'."\n";
    121             echo '   <i class="si si-thumbs-down"></i> '.__('Failed to update your <code>/wp-config.php</code> file automatically. Please add the following line to your <code>/wp-config.php</code> file (right after the opening <code>&lt;?php</code> tag; on it\'s own line). <pre class="code"><code>define( \'WP_CACHE\', true );</code></pre>', 'rapid-cache')."\n";
    122             echo '</div>'."\n";
    123         }
    124         if (!empty($_REQUEST[MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_wp_config_wp_cache_remove_failure'])) {
    125             echo '<div class="plugin-menu-page-notice error">'."\n";
    126             echo '   <i class="si si-thumbs-down"></i> '.__('Failed to update your <code>/wp-config.php</code> file automatically. Please remove the following line from your <code>/wp-config.php</code> file, or set <code>WP_CACHE</code> to a <code>FALSE</code> value. <pre class="code"><code>define( \'WP_CACHE\', true );</code></pre>', 'rapid-cache')."\n";
    127             echo '</div>'."\n";
    128         }
    129         if (!empty($_REQUEST[MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_advanced_cache_add_failure'])) {
    130             echo '<div class="plugin-menu-page-notice error">'."\n";
    131             if ($_REQUEST[MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_advanced_cache_add_failure'] === 'advanced-cache') {
    132                 echo '<i class="si si-thumbs-down"></i> '.sprintf(__('Failed to update your <code>/wp-content/advanced-cache.php</code> file. Cannot write file: <code>%1$s/%2$s-advanced-cache</code>. Please be sure this directory exists (and that it\'s writable): <code>%1$s</code>. Please use directory permissions <code>755</code> or higher (perhaps <code>777</code>). Once you\'ve done this, please try again.', 'rapid-cache'), esc_html($this->plugin->cacheDir()), esc_html(mb_strtolower(MEGAOPTIM_RAPID_CACHE_SHORT_NAME)))."\n";
    133             } else {
    134                 echo '<i class="si si-thumbs-down"></i> '.__('Failed to update your <code>/wp-content/advanced-cache.php</code> file. Most likely a permissions error. Please create an empty file here: <code>/wp-content/advanced-cache.php</code> (just an empty PHP file, with nothing in it); give it permissions <code>644</code> or higher (perhaps <code>666</code>). Once you\'ve done this, please try again.', 'rapid-cache')."\n";
    135             }
    136             echo '</div>'."\n";
    137         }
    138         if (!empty($_REQUEST[MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_advanced_cache_remove_failure'])) {
    139             echo '<div class="plugin-menu-page-notice error">'."\n";
    140             echo '   <i class="si si-thumbs-down"></i> '.__('Failed to remove your <code>/wp-content/advanced-cache.php</code> file. Most likely a permissions error. Please delete (or empty the contents of) this file: <code>/wp-content/advanced-cache.php</code>.', 'rapid-cache')."\n";
    141             echo '</div>'."\n";
    142         }
    143         if (!empty($_REQUEST[MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_ua_info_dir_population_failure'])) {
    144             echo '<div class="plugin-menu-page-notice error">'."\n";
    145             echo '   <i class="si si-thumbs-down"></i> '.sprintf(__('Failed to populate User-Agent detection files for Mobile-Adaptive Mode. User-Agent detection files are pulled from a remote location so you\'ll always have the most up-to-date information needed for accurate detection. However, it appears the remote source of this information is currently unvailable. Please wait 15 minutes, then try saving your %1$s options again.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME))."\n";
    146             echo '</div>'."\n";
    147         }
    148         if (!MEGAOPTIM_RAPID_CACHE_IS_PRO && $this->plugin->isProPreview()) {
    149             echo '<div class="plugin-menu-page-notice info">'."\n";
    150             echo '<a href="'.add_query_arg(urlencode_deep(['page' => MEGAOPTIM_RAPID_CACHE_GLOBAL_NS]), self_admin_url('/admin.php')).'" class="pull-right" style="margin:0 0 15px 25px; float:right; font-variant:small-caps; text-decoration:none;">'.__('close', 'rapid-cache').' <i class="si si-eye-slash"></i></a>'."\n";
    151             echo '   <i class="si si-eye"></i> '.sprintf(__('<strong>Pro Features (Preview)</strong> ~ New option panels below. Please explore before <a href="#" target="_blank">upgrading <i class="si si-heart-o"></i></a>.<br /><small>NOTE: the free version of %1$s (this lite version) is more-than-adequate for most sites. Please upgrade only if you desire advanced features or would like to support the developer.</small>', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME))."\n";
    152             echo '</div>'."\n";
    153         }
    154         if (!$this->plugin->options['enable']) {
    155             echo '<div class="plugin-menu-page-notice warning">'."\n";
    156             echo '   <i class="si si-warning"></i> '.sprintf(__('%1$s is currently disabled; please review options below.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME))."\n";
    157             echo '</div>'."\n";
    158         }
    159         /* ----------------------------------------------------------------------------------------- */
    160 
    161         echo '<div class="plugin-menu-page-body">'."\n";
    162 
    163         /* ----------------------------------------------------------------------------------------- */
    164 
    165         echo '<h2 class="plugin-menu-page-section-heading">'.
    166              '  '.__('Basic Configuration (Required)', 'rapid-cache').
    167              '  <small><span>'.sprintf(__('Review these basic options and %1$s will be ready-to-go!', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</span></small>'.
    168              '</h2>';
    169 
    170         /* --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
    171 
    172         echo '<div class="plugin-menu-page-panel">'."\n";
    173 
    174         echo '   <a href="#" class="plugin-menu-page-panel-heading'.((!$this->plugin->options['enable']) ? ' open' : '').'">'."\n";
    175         echo '      <i class="si si-enty-gauge"></i> '.__('Enable/Disable', 'rapid-cache')."\n";
    176         echo '   </a>'."\n";
    177 
    178         echo '   <div class="plugin-menu-page-panel-body'.((!$this->plugin->options['enable']) ? ' open' : '').' clearfix">'."\n";
    179         echo '      <p class="speed"><img src="'.esc_attr($this->plugin->url('/assets/images/tach.png')).'" style="float:right; width:100px; margin-left:1em;" />'.sprintf(__('%1$s = SPEED<em>!!</em>', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
    180         echo '      <p><label class="switch-primary"><input type="radio" name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][enable]" value="1"'.checked($this->plugin->options['enable'], '1', false).' /> '.sprintf(__('Yes, enable %1$s', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).' <i class="si si-magic si-flip-horizontal"></i></label> &nbsp;&nbsp;&nbsp; <label><input type="radio" name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][enable]" value="0"'.checked($this->plugin->options['enable'], '0', false).' /> '.__('No, disable.', 'rapid-cache').'</label></p>'."\n";
    181         echo '      <p class="info" style="font-family:\'Georgia\', serif; font-size:110%; margin-top:1.5em;">'.sprintf(__('<strong>HUGE Time-Saver:</strong> Approx. 95%% of all WordPress sites running %1$s, simply enable it here; and that\'s it :-) <strong>No further configuration is necessary (really).</strong> All of the other options (down below) are already tuned for the BEST performance on a typical WordPress installation. Simply enable %1$s here and click "Save All Changes". If you get any warnings please follow the instructions given. Otherwise, you\'re good <i class="si si-smile-o"></i>. This plugin is designed to run just fine like it is. Take it for a spin right away; you can always fine-tune things later if you deem necessary.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
    182         echo '      <hr />'."\n";
    183         echo '      <img src="'.esc_attr($this->plugin->url('/assets/images/source-code-ss.png')).'" class="screenshot" />'."\n";
    184         echo '      <h3>'.sprintf(__('How Can I Tell %1$s is Working?', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</h3>'."\n";
    185         echo '      <p>'.sprintf(__('First of all, please make sure that you\'ve enabled %1$s here; then scroll down to the bottom of this page and click "Save All Changes". All of the other options (below) are already pre-configured for typical usage. Feel free to skip them all for now. You can go back through all of these later and fine-tune things the way you like them.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
    186         echo '      <p>'.sprintf(__('Once %1$s has been enabled, <strong>you\'ll need to log out (and/or clear browser cookies)</strong>. By default, cache files are NOT served to visitors who are logged-in, and that includes you too ;-) Cache files are NOT served to recent comment authors either. If you\'ve commented (or replied to a comment lately); please clear your browser cookies before testing.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
    187         echo '      <p>'.sprintf(__('<strong>To verify that %1$s is working</strong>, navigate your site like a normal visitor would. Right-click on any page (choose View Source), then scroll to the very bottom of the document. At the bottom, you\'ll find comments that show %1$s stats and information. You should also notice that page-to-page navigation is <i class="si si-flash"></i> <strong>lightning fast</strong> now that %1$s is running; and it gets faster over time!', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
    188         echo '      <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][debugging_enable]" class="-no-if-enabled">'."\n";
    189         echo '            <option value="1"'.selected($this->plugin->options['debugging_enable'], '1', false).'>'.__('Yes, enable notes in the source code so I can see it\'s working (recommended).', 'rapid-cache').'</option>'."\n";
    190         echo '            <option value="2"'.selected($this->plugin->options['debugging_enable'], '2', false).'>'.__('Yes, enable notes in the source code AND show debugging details (not recommended for production).', 'rapid-cache').'</option>'."\n";
    191         echo '            <option value="0"'.selected($this->plugin->options['debugging_enable'], '0', false).'>'.__('No, I don\'t want my source code to contain any of these notes.', 'rapid-cache').'</option>'."\n";
    192         echo '         </select></p>'."\n";
    193         echo '   </div>'."\n";
    194 
    195         echo '</div>'."\n";
    196 
    197         /* ----------------------------------------------------------------------------------------- */
    198 
    199         echo '<div class="plugin-menu-page-panel">'."\n";
    200 
    201         echo '   <a href="#" class="plugin-menu-page-panel-heading">'."\n";
    202         echo '      <i class="si si-shield"></i> '.__('Plugin Deletion Safeguards', 'rapid-cache')."\n";
    203         echo '   </a>'."\n";
    204 
    205         echo '   <div class="plugin-menu-page-panel-body clearfix">'."\n";
    206         echo '      <i class="si si-shield si-4x" style="float:right; margin: 0 0 0 25px;"></i>'."\n";
    207         echo '      <h3>'.__('Uninstall on Plugin Deletion; or Safeguard Options?', 'rapid-cache').'</h3>'."\n";
    208         echo '      <p>'.sprintf(__('<strong>Tip:</strong> By default, if you delete %1$s using the plugins menu in WordPress, nothing is lost. However, if you want to completely uninstall %1$s you should set this to <code>Yes</code> and <strong>THEN</strong> deactivate &amp; delete %1$s from the plugins menu in WordPress. This way %1$s will erase your options for the plugin, erase directories/files created by the plugin, remove the <code>advanced-cache.php</code> file, terminate CRON jobs, etc. It erases itself from existence completely.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
    209         echo '      <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][uninstall_on_deletion]">'."\n";
    210         echo '            <option value="0"'.selected($this->plugin->options['uninstall_on_deletion'], '0', false).'>'.__('Safeguard my options and the cache (recommended).', 'rapid-cache').'</option>'."\n";
    211         echo '            <option value="1"'.selected($this->plugin->options['uninstall_on_deletion'], '1', false).'>'.sprintf(__('Yes, uninstall (completely erase) %1$s on plugin deletion.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</option>'."\n";
    212         echo '         </select></p>'."\n";
    213         echo '   </div>'."\n";
    214 
    215         echo '</div>'."\n";
    216 
    217         /* ----------------------------------------------------------------------------------------- */
    218 
    219         echo '<h2 class="plugin-menu-page-section-heading">'.
    220              '  '.__('Advanced Configuration (All Optional)', 'rapid-cache').
    221              '  <small>'.__('Recommended for advanced site owners only; already pre-configured for most WP installs.', 'rapid-cache').'</small>'.
    222              '</h2>';
    223 
    224         /* --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
    225 
    226         if (MEGAOPTIM_RAPID_CACHE_IS_PRO || $this->plugin->isProPreview()) {
    227             echo '<div class="plugin-menu-page-panel">'."\n";
    228 
    229             echo '   <a href="#" class="plugin-menu-page-panel-heading" data-pro-version-only="'.(!MEGAOPTIM_RAPID_CACHE_IS_PRO ? __('pro version only', 'rapid-cache') : '').'">'."\n";
    230             echo '      <i class="si si-broom"></i> '.__('Manual Cache Clearing', 'rapid-cache')."\n";
    231             echo '   </a>'."\n";
    232 
    233             echo '   <div class="plugin-menu-page-panel-body clearfix">'."\n";
    234             echo '      <h3>'.__('Clearing the Cache Manually', 'rapid-cache').'</h3>'."\n";
    235             echo '      <img src="'.esc_attr($this->plugin->url('/assets/images/clear-cache-ops1-ss.png')).'" class="-clear-cache-ops-ss screenshot" />'."\n";
    236             echo '      <p>'.sprintf(__('Once %1$s is enabled, you will find this new option in your WordPress Admin Bar (screenshot on right). Clicking this button will clear the cache and you can start fresh at anytime (e.g., you can do this manually; and as often as you wish).', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
    237             echo '      <p>'.sprintf(__('Depending on the structure of your site, there could be many reasons to clear the cache. However, the most common reasons are related to Post/Page edits or deletions, Category/Tag edits or deletions, and Theme changes. %1$s handles most scenarios all by itself. However, many site owners like to clear the cache manually; for a variety of reasons (just to force a refresh).', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
    238             echo '      <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][cache_clear_admin_bar_enable]" data-target=".-cache-clear-admin-bar-options, .-cache-clear-admin-bar-roles-caps" style="width:auto;">'."\n";
    239             echo '          <option value="1"'.selected($this->plugin->options['cache_clear_admin_bar_enable'], '1', false).'>'.__('Yes, enable &quot;Clear Cache&quot; button in admin bar', 'rapid-cache').'</option>'."\n";
    240             echo '          <option value="0"'.selected($this->plugin->options['cache_clear_admin_bar_enable'], '0', false).'>'.__('No, I don\'t intend to clear the cache manually.', 'rapid-cache').'</option>'."\n";
    241             echo '         </select>'."\n";
    242             echo '         <span class="plugin-menu-page-panel-if-enabled -cache-clear-admin-bar-options"><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][cache_clear_admin_bar_options_enable]" class="-no-if-enabled" style="width:auto;">'."\n";
    243             echo '             <option value="1"'.selected($this->plugin->options['cache_clear_admin_bar_options_enable'], '1', false).'>'.__('w/ dropdown options.', 'rapid-cache').'</option>'."\n";
    244             echo '             <option value="2"'.selected($this->plugin->options['cache_clear_admin_bar_options_enable'], '2', false).'>'.__('w/ dropdown options in split menu.', 'rapid-cache').'</option>'."\n";
    245             echo '             <option value="0"'.selected($this->plugin->options['cache_clear_admin_bar_options_enable'], '0', false).'>'.__('w/o dropdown options.', 'rapid-cache').'</option>'."\n";
    246             echo '         </select></span></p>'."\n";
    247 
    248             if (is_multisite()) {
    249                 echo '  <div class="plugin-menu-page-panel-if-enabled -cache-clear-admin-bar-roles-caps">'."\n";
    250                 echo '      <h4 style="margin-bottom:0;">'.__('Also allow Child Sites in a Network to clear the cache from their Admin Bar?', 'rapid-cache').'</h4>'."\n";
    251                 echo '      <p style="margin-top:2px;">'.sprintf(__('In a Multisite Network, each child site can clear its own cache. If you want child sites to see the "Clear Cache" button in their WordPress Admin Bar, you can specify a comma-delimited list of <a href="https://wordpress.org/support/article/roles-and-capabilities/" target="_blank">Roles and/or Capabilities</a> that are allowed. For example, if I want Administrators to be capable of clearing the cache from their Admin Bar, I could enter <code>administrator</code> here. If I also want to allow Editors, I can use a comma-delimited list: <code>administrator,editor</code>. Or, I could use a single Capability of: <code>edit_others_posts</code>; which covers both Administrators &amp; Editors at the same time.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
    252                 echo '      <p style="margin-bottom:0;"><input type="text" name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][cache_clear_admin_bar_roles_caps]" value="'.esc_attr($this->plugin->options['cache_clear_admin_bar_roles_caps']).'" /></p>'."\n";
    253                 echo '      <p style="margin-top:0;">'.sprintf(__('<strong>Note:</strong> As a security measure, in addition to the Role(s) and/or Capabilities that you list here, each child site owner must also have the ability to <code>%1$s</code>.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_IS_PRO ? $this->plugin->clear_min_cap : 'edit_posts')).'</p>'."\n";
    254                 echo '  </div>'."\n";
    255             } else {
    256                 echo '  <div class="plugin-menu-page-panel-if-enabled -cache-clear-admin-bar-roles-caps">'."\n";
    257                 echo '      <h4 style="margin-bottom:0;">'.__('Also allow others to clear the cache from their Admin Bar?', 'rapid-cache').'</h4>'."\n";
    258                 echo '      <p style="margin-top:2px;">'.sprintf(__('If you want others to see the "Clear Cache" button in their WordPress Admin Bar, you can specify a comma-delimited list of <a href="https://wordpress.org/support/article/roles-and-capabilities/" target="_blank">Roles and/or Capabilities</a> that are allowed. For example, if I want Editors to be capable of clearing the cache from their Admin Bar, I could enter <code>editor</code> here. If I also want to allow Authors, I can use a comma-delimited list: <code>editor,author</code>. Or, I could use a single Capability of: <code>publish_posts</code>; which covers both Editors &amp; Authors at the same time.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
    259                 echo '      <p style="margin-bottom:0;"><input type="text" name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][cache_clear_admin_bar_roles_caps]" value="'.esc_attr($this->plugin->options['cache_clear_admin_bar_roles_caps']).'" /></p>'."\n";
    260                 echo '      <p style="margin-top:0;">'.sprintf(__('<strong>Note:</strong> As a security measure, in addition to the Role(s) and/or Capabilities that you list here, each user must also have the ability to <code>%1$s</code>.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_IS_PRO ? $this->plugin->clear_min_cap : 'edit_posts')).'</p>'."\n";
    261                 echo '  </div>'."\n";
    262             }
    263             if ($this->plugin->functionIsPossible('opcache_reset')) {
    264                 echo '  <hr />'."\n";
    265                 echo '  <h3>'.__('Clear the <a href="https://www.php.net/manual/en/book.opcache.php" target="_blank">PHP OPcache</a> Too?', 'rapid-cache').'</h3>'."\n";
    266                 echo '  <p>'.sprintf(__('If you clear the cache manually, do you want %1$s to clear the PHP OPcache too? This is not necessary, but if you want a truly clean start, this will clear all PHP files in the server\'s opcode cache also. Note: If you don\'t already know what the PHP OPcache is, it is suggested that you leave this disabled. It really is not necessary. This is just an added feature for advanced users.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
    267                 echo '  <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][cache_clear_opcache_enable]" class="-no-if-enabled">'."\n";
    268                 echo '      <option value="0"'.selected($this->plugin->options['cache_clear_opcache_enable'], '0', false).'>'.__('No, I don\'t use the PHP OPcache extension; or, I don\'t want the opcode cache cleared.', 'rapid-cache').'</option>'."\n";
    269                 echo '      <option value="1"'.selected($this->plugin->options['cache_clear_opcache_enable'], '1', false).'>'.__('Yes, if the PHP OPcache extension is enabled, also clear the entire PHP opcode cache.', 'rapid-cache').'</option>'."\n";
    270                 echo '  </select></p>'."\n";
    271             }
    272             if ($this->plugin->functionIsPossible('s2clean')) {
    273                 echo '  <hr />'."\n";
    274                 echo '  <h3>'.__('Clear the <a href="http://websharks-inc.com/product/s2clean/" target="_blank">s2Clean</a> Cache Too?', 'rapid-cache').'</h3>'."\n";
    275                 echo '  <p>'.sprintf(__('If the s2Clean theme is installed, and you clear the cache manually, %1$s can clear the s2Clean Markdown cache too (if you\'ve enabled Markdown processing with s2Clean).', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
    276                 echo '  <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][cache_clear_s2clean_enable]" class="-no-if-enabled">'."\n";
    277                 echo '      <option value="1"'.selected($this->plugin->options['cache_clear_s2clean_enable'], '1', false).'>'.__('Yes, if the s2Clean theme is installed, also clear s2Clean-related caches.', 'rapid-cache').'</option>'."\n";
    278                 echo '      <option value="0"'.selected($this->plugin->options['cache_clear_s2clean_enable'], '0', false).'>'.__('No, I don\'t use s2Clean; or, I don\'t want s2Clean-related caches cleared.', 'rapid-cache').'</option>'."\n";
    279                 echo '  </select></p>'."\n";
    280             }
    281             echo '      <hr />'."\n";
    282             echo '      <h3>'.__('Evaluate Custom PHP Code when Clearing the Cache?', 'rapid-cache').'</h3>'."\n";
    283             echo '      <p>'.sprintf(__('If you have any custom routines you\'d like to process when the cache is cleared manually, please enter PHP code here. If your PHP code outputs a message, it will be displayed along with any other notes from %1$s itself. This feature is intended for developers, and it may come in handy if you need to clear any system caches not already covered by %1$s configuration options.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
    284             echo '      <p style="margin-bottom:0;"><textarea name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][cache_clear_eval_code]" rows="5" spellcheck="false" class="monospace">'.format_to_edit($this->plugin->options['cache_clear_eval_code']).'</textarea></p>'."\n";
    285             echo '      <p class="info" style="margin-top:0;">'.__('<strong>Example:</strong> <code>&lt;?php apc_clear_cache(); echo \'&lt;p&gt;Also cleared APC cache.&lt;/p&gt;\'; ?&gt;</code>', 'rapid-cache').'</p>'."\n";
    286 
    287             echo '      <hr />'."\n";
    288             echo '      <h3>'.__('Clear the CDN Cache Too?', 'rapid-cache').'</h3>'."\n";
    289             echo '      <p>'.sprintf(__('If you clear the cache manually, do you want %1$s to automatically bump the CDN invalidation counter too? i.e., automatically increment the <code>?%2$s=[counter]</code> in all static CDN URLs?', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME), esc_html($this->plugin->options['cdn_invalidation_var'])).'</p>'."\n";
    290             echo '      <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][cache_clear_cdn_enable]" class="-no-if-enabled">'."\n";
    291             echo '            <option value="0"'.selected($this->plugin->options['cache_clear_cdn_enable'], '0', false).'>'.__('No, I don\'t use Static CDN Filters; or, I don\'t want the CDN cache cleared.', 'rapid-cache').'</option>'."\n";
    292             echo '            <option value="1"'.selected($this->plugin->options['cache_clear_cdn_enable'], '1', false).'>'.__('Yes, if Static CDN Filters are enabled, also clear the CDN cache.', 'rapid-cache').'</option>'."\n";
    293             echo '      </select></p>'."\n";
    294             echo '   </div>'."\n";
    295 
    296             echo '</div>'."\n";
    297         }
    298         /* --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
    299 
    300         echo '<div class="plugin-menu-page-panel'.(!MEGAOPTIM_RAPID_CACHE_IS_PRO && $this->plugin->isProPreview() ? ' pro-preview' : '').'">'."\n";
    301 
    302         echo '   <a href="#" class="plugin-menu-page-panel-heading" data-additional-pro-features="'.(!MEGAOPTIM_RAPID_CACHE_IS_PRO && $this->plugin->isProPreview() ? __('additional pro features', 'rapid-cache') : '').'">'."\n";
    303         echo '      <i class="si si-server"></i> '.__('Automatic Cache Clearing', 'rapid-cache')."\n";
    304         echo '   </a>'."\n";
    305 
    306         echo '   <div class="plugin-menu-page-panel-body clearfix">'."\n";
    307 
    308         echo '      <h3>'.__('Clearing the Cache Automatically', 'rapid-cache').'</h3>'."\n";
    309         echo '      <img src="'.esc_attr($this->plugin->url('/assets/images/auto-clear-ss.png')).'" class="screenshot" />'."\n";
    310         echo '      <p>'.sprintf(__('This is built into the %1$s plugin; i.e., this functionality is "always on". If you edit a Post/Page (or delete one), %1$s will automatically clear the cache file(s) associated with that content. This way a new updated version of the cache will be created automatically the next time this content is accessed. Simple updates like this occur each time you make changes in the Dashboard, and %1$s will notify you of these as they occur. %1$s monitors changes to Posts (of any kind, including Pages), Categories, Tags, Links, Themes (even Users), and more.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
    311         if (MEGAOPTIM_RAPID_CACHE_IS_PRO || $this->plugin->isProPreview()) {
    312             echo '  <div data-pro-version-only="'.(!MEGAOPTIM_RAPID_CACHE_IS_PRO ? __('pro version only', 'rapid-cache') : '').'">'."\n";
    313             echo '      <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][change_notifications_enable]" class="-no-if-enabled" style="width:auto;">'."\n";
    314             echo '          <option value="1"'.selected($this->plugin->options['change_notifications_enable'], '1', false).'>'.sprintf(__('Yes, enable %1$s notifications in the Dashboard when cache files are cleared automatically.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</option>'."\n";
    315             echo '          <option value="0"'.selected($this->plugin->options['change_notifications_enable'], '0', false).'>'.sprintf(__('No, I don\'t want to know (don\'t really care) what %1$s is doing behind-the-scene.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</option>'."\n";
    316             echo '      </select></p>'."\n";
    317             echo '  </div>'."\n";
    318         }
    319         echo '      <hr />'."\n";
    320         echo '      <h3>'.__('Primary Page Options', 'rapid-cache').'</h3>'."\n";
    321 
    322         echo '      <h4 style="margin-bottom:0;">'.__('Auto-Clear Designated "Home Page" Too?', 'rapid-cache').'</h4>'."\n";
    323         echo '      <p style="margin-top:2px;">'.sprintf(__('On many sites, the Home Page (aka: the Front Page) offers an archive view of all Posts (or even Pages). Therefore, if a single Post/Page is changed in some way; and %1$s clears/resets the cache for a single Post/Page, would you like %1$s to also clear any existing cache files for the "Home Page"?', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
    324         echo '      <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][cache_clear_home_page_enable]" class="-no-if-enabled">'."\n";
    325         echo '            <option value="1"'.selected($this->plugin->options['cache_clear_home_page_enable'], '1', false).'>'.__('Yes, if any single Post/Page is cleared/reset; also clear the "Home Page".', 'rapid-cache').'</option>'."\n";
    326         echo '            <option value="0"'.selected($this->plugin->options['cache_clear_home_page_enable'], '0', false).'>'.__('No, my Home Page does not provide a list of Posts/Pages; e.g., this is not necessary.', 'rapid-cache').'</option>'."\n";
    327         echo '         </select></p>'."\n";
    328         echo '      <h4 style="margin-bottom:0;">'.__('Auto-Clear Designated "Posts Page" Too?', 'rapid-cache').'</h4>'."\n";
    329         echo '      <p style="margin-top:2px;">'.sprintf(__('On many sites, the Posts Page (aka: the Blog Page) offers an archive view of all Posts (or even Pages). Therefore, if a single Post/Page is changed in some way; and %1$s clears/resets the cache for a single Post/Page, would you like %1$s to also clear any existing cache files for the "Posts Page"?', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
    330         echo '      <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][cache_clear_posts_page_enable]" class="-no-if-enabled">'."\n";
    331         echo '            <option value="1"'.selected($this->plugin->options['cache_clear_posts_page_enable'], '1', false).'>'.__('Yes, if any single Post/Page is cleared/reset; also clear the "Posts Page".', 'rapid-cache').'</option>'."\n";
    332         echo '            <option value="0"'.selected($this->plugin->options['cache_clear_posts_page_enable'], '0', false).'>'.__('No, I don\'t use a separate Posts Page; e.g., my Home Page IS my Posts Page.', 'rapid-cache').'</option>'."\n";
    333         echo '         </select></p>'."\n";
    334 
    335         echo '      <hr />'."\n";
    336         echo '      <h3>'.__('Author, Archive, and Tag/Term Options', 'rapid-cache').'</h3>'."\n";
    337 
    338         echo '      <h4 style="margin-bottom:0;">'.__('Auto-Clear "Author Page" Too?', 'rapid-cache').'</h4>'."\n";
    339         echo '      <p style="margin-top:2px;">'.sprintf(__('On many sites, each author has a related "Author Page" that offers an archive view of all posts associated with that author. Therefore, if a single Post/Page is changed in some way; and %1$s clears/resets the cache for a single Post/Page, would you like %1$s to also clear any existing cache files for the related "Author Page"?', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
    340         echo '      <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][cache_clear_author_page_enable]" class="-no-if-enabled">'."\n";
    341         echo '            <option value="1"'.selected($this->plugin->options['cache_clear_author_page_enable'], '1', false).'>'.__('Yes, if any single Post/Page is cleared/reset; also clear the "Author Page".', 'rapid-cache').'</option>'."\n";
    342         echo '            <option value="0"'.selected($this->plugin->options['cache_clear_author_page_enable'], '0', false).'>'.__('No, my site doesn\'t use multiple authors and/or I don\'t have any "Author Page" archive views.', 'rapid-cache').'</option>'."\n";
    343         echo '         </select></p>'."\n";
    344 
    345         echo '      <h4 style="margin-bottom:0;">'.__('Auto-Clear "Category Archives" Too?', 'rapid-cache').'</h4>'."\n";
    346         echo '      <p style="margin-top:2px;">'.sprintf(__('On many sites, each post is associated with at least one Category. Each category then has an archive view that contains all the posts within that category. Therefore, if a single Post/Page is changed in some way; and %1$s clears/resets the cache for a single Post/Page, would you like %1$s to also clear any existing cache files for the associated Category archive views?', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
    347         echo '      <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][cache_clear_term_category_enable]" class="-no-if-enabled">'."\n";
    348         echo '            <option value="1"'.selected($this->plugin->options['cache_clear_term_category_enable'], '1', false).'>'.__('Yes, if any single Post/Page is cleared/reset; also clear the associated Category archive views.', 'rapid-cache').'</option>'."\n";
    349         echo '            <option value="0"'.selected($this->plugin->options['cache_clear_term_category_enable'], '0', false).'>'.__('No, my site doesn\'t use Categories and/or I don\'t have any Category archive views.', 'rapid-cache').'</option>'."\n";
    350         echo '         </select></p>'."\n";
    351 
    352         echo '      <h4 style="margin-bottom:0;">'.__('Auto-Clear "Tag Archives" Too?', 'rapid-cache').'</h4>'."\n";
    353         echo '      <p style="margin-top:2px;">'.sprintf(__('On many sites, each post may be associated with at least one Tag. Each tag then has an archive view that contains all the posts assigned that tag. Therefore, if a single Post/Page is changed in some way; and %1$s clears/resets the cache for a single Post/Page, would you like %1$s to also clear any existing cache files for the associated Tag archive views?', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
    354         echo '      <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][cache_clear_term_post_tag_enable]" class="-no-if-enabled">'."\n";
    355         echo '            <option value="1"'.selected($this->plugin->options['cache_clear_term_post_tag_enable'], '1', false).'>'.__('Yes, if any single Post/Page is cleared/reset; also clear the associated Tag archive views.', 'rapid-cache').'</option>'."\n";
    356         echo '            <option value="0"'.selected($this->plugin->options['cache_clear_term_post_tag_enable'], '0', false).'>'.__('No, my site doesn\'t use Tags and/or I don\'t have any Tag archive views.', 'rapid-cache').'</option>'."\n";
    357         echo '         </select></p>'."\n";
    358 
    359         echo '      <h4 style="margin-bottom:0;">'.__('Auto-Clear "Date-Based Archives" Too?', 'rapid-cache').'</h4>'."\n";
    360         echo '      <p style="margin-top:2px;">'.sprintf(__('Date-Based Archives allow visitors to browse Posts by the year, month, or day they were originally published. If a single Post (of any type) is changed in some way; and %1$s clears/resets the cache for that Post, would you like %1$s to also clear any existing cache files for Dated-Based Archives that match the publication time?', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
    361         echo '      <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][cache_clear_date_archives_enable]" class="-no-if-enabled">'."\n";
    362         echo '            <option value="1"'.selected($this->plugin->options['cache_clear_date_archives_enable'], '1', false).'>'.__('Yes, if any single Post is cleared/reset, also clear the associated Date archive views.', 'rapid-cache').'</option>'."\n";
    363         echo '            <option value="2"'.selected($this->plugin->options['cache_clear_date_archives_enable'], '2', false).'>'.__('Yes, but only clear the associated Day and Month archive views.', 'rapid-cache').'</option>'."\n";
    364         echo '            <option value="3"'.selected($this->plugin->options['cache_clear_date_archives_enable'], '3', false).'>'.__('Yes, but only clear the associated Day archive view.', 'rapid-cache').'</option>'."\n";
    365         echo '            <option value="0"'.selected($this->plugin->options['cache_clear_date_archives_enable'], '0', false).'>'.__('No, don\'t clear any associated Date archive views.', 'rapid-cache').'</option>'."\n";
    366         echo '         </select></p>'."\n";
    367 
    368         echo '      <h4 style="margin-bottom:0;">'.__('Auto-Clear "Custom Term Archives" Too?', 'rapid-cache').'</h4>'."\n";
    369         echo '      <p style="margin-top:2px;">'.sprintf(__('Most sites do not use any custom Terms so it should be safe to leave this disabled. However, if your site uses custom Terms and they have their own Term archive views, you may want to clear those when the associated post is cleared. Therefore, if a single Post/Page is changed in some way; and %1$s clears/resets the cache for a single Post/Page, would you like %1$s to also clear any existing cache files for the associated Tag archive views?', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
    370         echo '      <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][cache_clear_term_other_enable]" class="-no-if-enabled">'."\n";
    371         echo '            <option value="1"'.selected($this->plugin->options['cache_clear_term_other_enable'], '1', false).'>'.__('Yes, if any single Post/Page is cleared/reset; also clear any associated custom Term archive views.', 'rapid-cache').'</option>'."\n";
    372         echo '            <option value="0"'.selected($this->plugin->options['cache_clear_term_other_enable'], '0', false).'>'.__('No, my site doesn\'t use any custom Terms and/or I don\'t have any custom Term archive views.', 'rapid-cache').'</option>'."\n";
    373         echo '         </select></p>'."\n";
    374 
    375         echo '      <h4 style="margin-bottom:0;">'.__('Auto-Clear "Custom Post Type Archives" Too?', 'rapid-cache').'</h4>'."\n";
    376         echo '      <p style="margin-top:2px;">'.sprintf(__('Most sites do not use any Custom Post Types so it should be safe to disable this option. However, if your site uses Custom Post Types and they have their own Custom Post Type archive views, you may want to clear those when any associated post is cleared. Therefore, if a single Post with a Custom Post Type is changed in some way; and %1$s clears/resets the cache for that post, would you like %1$s to also clear any existing cache files for the associated Custom Post Type archive views?', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
    377         echo '      <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][cache_clear_custom_post_type_enable]" class="-no-if-enabled">'."\n";
    378         echo '            <option value="1"'.selected($this->plugin->options['cache_clear_custom_post_type_enable'], '1', false).'>'.__('Yes, if any single Post with a Custom Post Type is cleared/reset; also clear any associated Custom Post Type archive views.', 'rapid-cache').'</option>'."\n";
    379         echo '            <option value="0"'.selected($this->plugin->options['cache_clear_custom_post_type_enable'], '0', false).'>'.__('No, my site doesn\'t use any Custom Post Types and/or I don\'t have any Custom Post Type archive views.', 'rapid-cache').'</option>'."\n";
    380         echo '         </select></p>'."\n";
    381 
    382         echo '      <hr />'."\n";
    383         echo '      <h3>'.__('Feed-Related Options', 'rapid-cache').'</h3>'."\n";
    384 
    385         echo '      <h4 style="margin-bottom:0;">'.__('Auto-Clear "RSS/RDF/ATOM Feeds" Too?', 'rapid-cache').'</h4>'."\n";
    386         echo '      <p style="margin-top:2px;">'.sprintf(__('If you enable Feed Caching (below), this can be quite handy. If enabled, when you update a Post/Page, approve a Comment, or make other changes where %1$s can detect that certain types of Feeds should be cleared to keep your site up-to-date, then %1$s will do this for you automatically. For instance, the blog\'s master feed, the blog\'s master comments feed, feeds associated with comments on a Post/Page, term-related feeds (including mixed term-related feeds), author-related feeds, etc. Under various circumstances (i.e., as you work in the Dashboard) these can be cleared automatically to keep your site up-to-date.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
    387         echo '      <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][cache_clear_xml_feeds_enable]" class="-no-if-enabled">'."\n";
    388         echo '            <option value="1"'.selected($this->plugin->options['cache_clear_xml_feeds_enable'], '1', false).'>'.__('Yes, automatically clear RSS/RDF/ATOM Feeds from the cache when certain changes occur.', 'rapid-cache').'</option>'."\n";
    389         echo '            <option value="0"'.selected($this->plugin->options['cache_clear_xml_feeds_enable'], '0', false).'>'.__('No, I don\'t have Feed Caching enabled, or I prefer not to automatically clear Feeds.', 'rapid-cache').'</option>'."\n";
    390         echo '         </select></p>'."\n";
    391 
    392         echo '      <hr />'."\n";
    393         echo '      <h3>'.__('Sitemap-Related Options', 'rapid-cache').'</h3>'."\n";
    394 
    395         echo '      <h4 style="margin-bottom:0;">'.__('Auto-Clear "XML Sitemaps" Too?', 'rapid-cache').'</h4>'."\n";
    396         echo '      <p style="margin-top:2px;">'.sprintf(__('If you\'re generating XML Sitemaps with a plugin like <a href="http://wordpress.org/plugins/google-sitemap-generator/" target="_blank">Google XML Sitemaps</a>, you can tell %1$s to automatically clear the cache of any XML Sitemaps whenever it clears a Post/Page. Note: This does NOT clear the XML Sitemap itself of course, only the cache. The point being, to clear the cache and allow changes to a Post/Page to be reflected by a fresh copy of your XML Sitemap; sooner rather than later.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
    397         echo '      <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][cache_clear_xml_sitemaps_enable]" data-target=".-cache-clear-xml-sitemap-patterns">'."\n";
    398         echo '            <option value="1"'.selected($this->plugin->options['cache_clear_xml_sitemaps_enable'], '1', false).'>'.__('Yes, if any single Post/Page is cleared/reset; also clear the cache for any XML Sitemaps.', 'rapid-cache').'</option>'."\n";
    399         echo '            <option value="0"'.selected($this->plugin->options['cache_clear_xml_sitemaps_enable'], '0', false).'>'.__('No, my site doesn\'t use any XML Sitemaps and/or I prefer NOT to clear the cache for XML Sitemaps.', 'rapid-cache').'</option>'."\n";
    400         echo '         </select></p>'."\n";
    401         echo '      <div class="plugin-menu-page-panel-if-enabled -cache-clear-xml-sitemap-patterns">'."\n";
    402         echo '          <p>'.__('<strong style="font-size:110%;">XML Sitemap Patterns (one per line):</strong> A default value of <code>/sitemap**.xml</code> covers all XML Sitemaps for most installations. However, you may customize this further if you deem necessary. Please list one pattern per line. XML Sitemap Pattern searches are performed against the <a href="https://gist.github.com/jaswsinc/338b6eb03a36c048c26f" target="_blank">REQUEST_URI</a>. A wildcard <code>**</code> (double asterisk) can be used when necessary; e.g., <code>/sitemap**.xml</code>. Note that <code>**</code> = 0 or more characters of any kind, including <code>/</code> slashes. <code>*</code> (a single asterisk) means 0 or more characters that are NOT a slash <code>/</code>. Your patterns must match from beginning to end; i.e., the special chars: <code>^</code> (beginning of string) and <code>$</code> (end of the string) are always on for these patterns (i.e., applied internally). For that reason, if you want to match part of a URI, use <code>**</code> to match anything before and/or after the fragment you\'re searching for. For example, <code>**/sitemap**.xml</code> will match any URI containing <code>/sitemap</code> (anywhere), so long as the URI also ends with <code>.xml</code>. On the other hand, <code>/sitemap*.xml</code> will only match URIs that begin with <code>/sitemap</code>, and it will only match URIs ending in <code>.xml</code> in that immediate directory — bypassing any inside nested sub-directories. To learn more about this syntax, please see <a href="https://github.com/megaoptim/rapid-cache/wiki/Watered-Down-Regex-Syntax" target="_blank">this KB article</a>.', 'rapid-cache').'</p>'."\n";
    403         echo '          <p><textarea name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][cache_clear_xml_sitemap_patterns]" rows="5" spellcheck="false" class="monospace">'.format_to_edit($this->plugin->options['cache_clear_xml_sitemap_patterns']).'</textarea></p>'."\n";
    404         if (is_multisite()) {
    405             echo '      <p class="info" style="display:block; margin-top:-15px;">'.__('In a Multisite Network, each child blog (whether it be a sub-domain, a sub-directory, or a mapped domain); will automatically change the leading <code>http://[sub.]domain/[sub-directory]</code> used in pattern matching. In short, there is no need to add sub-domains or sub-directories for each child blog in these patterns. Please include only the <a href="https://gist.github.com/jaswsinc/338b6eb03a36c048c26f" target="_blank">REQUEST_URI</a> (i.e., the path) which leads to the XML Sitemap on all child blogs in the network.', 'rapid-cache').'</p>'."\n";
    406         }
    407         echo '      </div>'."\n";
    408 
    409         if (MEGAOPTIM_RAPID_CACHE_IS_PRO || $this->plugin->isProPreview()) {
    410             echo '      <hr />'."\n";
    411             echo '      <h3 data-pro-version-only="'.(!MEGAOPTIM_RAPID_CACHE_IS_PRO ? __('pro version only', 'rapid-cache') : '').'">'.__('Misc. Auto-Clear Options', 'rapid-cache').'</h3>'."\n";
    412             echo '      <h4 style="margin-bottom:0;">'.__('Auto-Clear Custom URL Patterns Too?', 'rapid-cache').'</h4>'."\n";
    413             echo '      <p style="margin-top:2px;">'.sprintf(__('<strong>Auto-Clear Custom URL Patterns (one per line):</strong> When you update a Post/Page, approve a Comment, etc., %1$s will detect that a Post/Page cache should be cleared to keep your site up-to-date. When this occurs, %1$s can also clear a list of custom URLs that you enter here. Please list one URL per line. A wildcard <code>*</code> character can be used when necessary; e.g., <code>https://example.com/category/abc/**</code>. Note that <code>**</code> (double asterisk) means 0 or more characters of any kind, including <code>/</code> slashes. <code>*</code> (a single asterisk) means 0 or more characters that are NOT a slash <code>/</code>. Your patterns must match from beginning to end; i.e., the special chars: <code>^</code> (beginning of string) and <code>$</code> (end of the string) are always on for these patterns (i.e., applied internally). For that reason, if you want to match part of a URL, use <code>**</code> to match anything before and/or after the fragment you\'re searching for. For example, <code>https://**/category/abc/**</code> will find all URLs containing <code>/category/abc/</code> (anywhere); whereas <code>https://*/category/abc/*</code> will match URLs on any domain, but the path must then begin with <code>/category/abc/</code> and the pattern will only match paths in that immediate directory — bypassing any additional paths in sub-directories. To learn more about this syntax, please see <a href="https://github.com/megaoptim/rapid-cache/wiki/Watered-Down-Regex-Syntax" target="_blank">this KB article</a>.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
    414             echo '      <p><textarea name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][cache_clear_urls]" spellcheck="false" wrap="off" rows="5">'.format_to_edit($this->plugin->options['cache_clear_urls']).'</textarea></p>'."\n";
    415             echo '      <p class="info" style="display:block;">'.__('<strong>Note:</strong> Relative URLs (e.g., <code>/name-of-post</code>) should NOT be used. Each entry above should start with <code>http://</code> or <code>https://</code> and include a fully qualified domain name (or wildcard characters in your pattern that will match the domain).', 'rapid-cache').'</p>'."\n";
    416         }
    417         echo '   </div>'."\n";
    418 
    419         echo '</div>'."\n";
    420 
    421         /* ----------------------------------------------------------------------------------------- */
    422 
    423         if (MEGAOPTIM_RAPID_CACHE_IS_PRO || $this->plugin->isProPreview()) {
    424             echo '<div class="plugin-menu-page-panel">'."\n";
    425 
    426             echo '   <a href="#" class="plugin-menu-page-panel-heading" data-pro-version-only="'.(!MEGAOPTIM_RAPID_CACHE_IS_PRO ? __('pro version only', 'rapid-cache') : '').'">'."\n";
    427             echo '      <i class="si si-pie-chart"></i> '.__('Cache-Related Statistics', 'rapid-cache')."\n";
    428             echo '   </a>'."\n";
    429 
    430             echo '   <div class="plugin-menu-page-panel-body clearfix">'."\n";
    431             if ($this->plugin->isProPreview()) {
    432                 echo '      <img src="'.esc_attr($this->plugin->url('/assets/images/stats-preview.png')).'" style="width:100%;border: 1px dashed #cac9c9;margin-bottom: 20px;">';
    433             }
    434             echo '      <i class="si si-pie-chart si-4x" style="float:right; margin: 0 0 0 25px;"></i>'."\n";
    435             echo '      <h3>'.__('Enable Cache-Related Stats &amp; Charts?', 'rapid-cache').'</h3>'."\n";
    436             echo '      <p>'.sprintf(__('%1$s can collect and display cache-related statistics (including charts). Stats are displayed in the WordPress Admin Bar, and also in your Dashboard under: <strong>%1$s → Stats/Charts</strong>. Cache-related stats provide you with a quick look at what\'s happening behind-the-scenes. Your site grows faster and faster as the cache grows larger in size.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
    437             echo '      <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][stats_enable]" data-target=".-stats-admin-bar-enable">'."\n";
    438             echo '            <option value="1"'.selected($this->plugin->options['stats_enable'], '1', false).'>'.__('Yes, enable stats collection &amp; the menu page in WordPress for viewing stats.', 'rapid-cache').'</option>'."\n";
    439             echo '            <option value="0"'.selected($this->plugin->options['stats_enable'], '0', false).'>'.__('No, I have a VERY large site and I want to avoid any unnecessary directory scans.', 'rapid-cache').'</option>'."\n";
    440             echo '         </select></p>'."\n";
    441             echo '      <p class="info">'.sprintf(__('<strong>Note:</strong> %1$s does a great job of collecting stats, in ways that don\'t cause a performance issue. In addition, as your cache grows larger than several hundred files in total size, statistics are collected less often and at longer intervals. All of that being said, if you run a VERY large site (e.g., more than 20K posts), you might want to disable stats collection in favor of blazing fast speeds not impeded by any directory scans needed to collect stats.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
    442             echo '      <hr />'."\n";
    443 
    444             echo '      <div class="plugin-menu-page-panel-if-enabled -stats-admin-bar-enable">'."\n";
    445             echo '          <h3>'.__('Show Stats in the WordPress Admin Bar?', 'rapid-cache').'</h3>'."\n";
    446             echo '          <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][stats_admin_bar_enable]" data-target=".-stats-admin-bar-roles-caps">'."\n";
    447             echo '              <option value="1"'.selected($this->plugin->options['stats_admin_bar_enable'], '1', false).'>'.__('Yes, enable stats in the WordPress admin bar.', 'rapid-cache').'</option>'."\n";
    448             echo '              <option value="0"'.selected($this->plugin->options['stats_admin_bar_enable'], '0', false).'>'.__('No, I\'ll review stats from the menu page in WordPress if I need to.', 'rapid-cache').'</option>'."\n";
    449             echo '          </select></p>'."\n";
    450             if (is_multisite()) {
    451                 echo '      <div class="plugin-menu-page-panel-if-enabled -stats-admin-bar-roles-caps">'."\n";
    452                 echo '          <h4 style="margin-bottom:0;">'.__('Allow Child Sites in a Network to See Stats in Admin Bar?', 'rapid-cache').'</h4>'."\n";
    453                 echo '          <p style="margin-top:2px;">'.sprintf(__('In a Multisite Network, each child site has stats of its own. If you want child sites to see cache-related stats in their WordPress Admin Bar, you can specify a comma-delimited list of <a href="https://wordpress.org/support/article/roles-and-capabilities/" target="_blank">Roles and/or Capabilities</a> that are allowed to see stats. For example, if I want the Administrator to see stats in their Admin Bar, I could enter <code>administrator</code> here. If I also want to show stats to Editors, I can use a comma-delimited list: <code>administrator,editor</code>. Or, I could use a single Capability of: <code>edit_others_posts</code>; which covers both Administrators &amp; Editors at the same time.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
    454                 echo '          <p style="margin-bottom:0;"><input type="text" name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][stats_admin_bar_roles_caps]" value="'.esc_attr($this->plugin->options['stats_admin_bar_roles_caps']).'" /></p>'."\n";
    455                 echo '          <p style="margin-top:0;">'.sprintf(__('<strong>Note:</strong> As a security measure, in addition to the Role(s) and/or Capabilities that you list here, each child site owner must also have the ability to <code>%1$s</code>.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_IS_PRO ? $this->plugin->stats_min_cap : 'edit_posts')).'</p>'."\n";
    456                 echo '      </div>'."\n";
    457             } else {
    458                 echo '      <div class="plugin-menu-page-panel-if-enabled -stats-admin-bar-roles-caps">'."\n";
    459                 echo '          <h4 style="margin-bottom:0;">'.__('Allow Others to See Stats in Admin Bar?', 'rapid-cache').'</h4>'."\n";
    460                 echo '          <p style="margin-top:2px;">'.sprintf(__('If you want others to see cache-related stats in their WordPress Admin Bar, you can specify a comma-delimited list of <a href="https://wordpress.org/support/article/roles-and-capabilities/" target="_blank">Roles and/or Capabilities</a> that are allowed to see stats. For example, if I want Editors to see stats in their Admin Bar, I could enter <code>editor</code> here. If I also want to show stats to Authors, I can use a comma-delimited list: <code>editor,author</code>. Or, I could use a single Capability of: <code>publish_posts</code>; which covers both Editors &amp; Authors at the same time.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
    461                 echo '          <p style="margin-bottom:0;"><input type="text" name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][stats_admin_bar_roles_caps]" value="'.esc_attr($this->plugin->options['stats_admin_bar_roles_caps']).'" /></p>'."\n";
    462                 echo '          <p style="margin-top:0;">'.sprintf(__('<strong>Note:</strong> As a security measure, in addition to the Role(s) and/or Capabilities that you list here, each user must also have the ability to <code>%1$s</code>.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_IS_PRO ? $this->plugin->stats_min_cap : 'edit_posts')).'</p>'."\n";
    463                 echo '      </div>'."\n";
    464             }
    465             echo '      </div>'."\n";
    466             echo '   </div>'."\n";
    467 
    468             echo '</div>'."\n";
    469         }
    470         /* ----------------------------------------------------------------------------------------- */
    471 
    472         echo '<div class="plugin-menu-page-panel">'."\n";
    473 
    474         echo '   <a href="#" class="plugin-menu-page-panel-heading">'."\n";
    475         echo '      <i class="si si-folder-open"></i> '.__('Cache Directory', 'rapid-cache')."\n";
    476         echo '   </a>'."\n";
    477 
    478         echo '   <div class="plugin-menu-page-panel-body clearfix">'."\n";
    479         echo '      <h3>'.__('Base Cache Directory (Must be Writable; i.e., <a href="https://wordpress.org/support/article/changing-file-permissions/" target="_blank">Permissions</a> <code>755</code> or Higher)', 'rapid-cache').'</h3>'."\n";
    480         echo '      <p>'.sprintf(__('This is where %1$s will store the cached version of your site. If you\'re not sure how to deal with directory permissions, don\'t worry too much about this. If there is a problem, %1$s will let you know about it. By default, this directory is created by %1$s and the permissions are setup automatically. In most cases there is nothing more you need to do.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
    481         echo '      <table style="width:100%;"><tr><td style="width:1px; font-weight:bold; white-space:pre;">'.esc_html(WP_CONTENT_DIR).'/</td><td><input type="text" name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][base_dir]" value="'.esc_attr($this->plugin->options['base_dir']).'" /></td><td style="width:1px; font-weight:bold; white-space:pre;">/</td></tr></table>'."\n";
    482         echo '   </div>'."\n";
    483 
    484         echo '</div>'."\n";
    485 
    486         /* ----------------------------------------------------------------------------------------- */
    487 
    488         echo '<div class="plugin-menu-page-panel'.(!MEGAOPTIM_RAPID_CACHE_IS_PRO && $this->plugin->isProPreview() ? ' pro-preview' : '').'">'."\n";
    489 
    490         echo '   <a href="#" class="plugin-menu-page-panel-heading" data-additional-pro-features="'.(!MEGAOPTIM_RAPID_CACHE_IS_PRO && $this->plugin->isProPreview() ? __('additional pro features', 'rapid-cache') : '').'">'."\n";
    491         echo '      <i class="si si-clock-o"></i> '.__('Cache Expiration Time', 'rapid-cache')."\n";
    492         echo '   </a>'."\n";
    493 
    494         echo '   <div class="plugin-menu-page-panel-body clearfix">'."\n";
    495         echo '      <i class="si si-clock-o si-4x" style="float:right; margin: 0 0 0 25px;"></i>'."\n";
    496         echo '      <h3>'.__('Automatic Expiration Time (Max Age)', 'rapid-cache').'</h3>'."\n";
    497         echo '      <p>'.__('If you don\'t update your site much, you could set this to <code>6 months</code> and optimize everything even further. The longer the Cache Expiration Time is, the greater your performance gain. Alternatively, the shorter the Expiration Time, the fresher everything will remain on your site. A default value of <code>7 days</code> (recommended); is a good conservative middle-ground.', 'rapid-cache').'</p>'."\n";
    498         echo '      <p>'.sprintf(__('Keep in mind that your Expiration Time is only one part of the big picture. %1$s will also clear the cache automatically as changes are made to the site (i.e., you edit a post, someone comments on a post, you change your theme, you add a new navigation menu item, etc., etc.). Thus, your Expiration Time is really just a fallback; e.g., the maximum amount of time that a cache file could ever possibly live.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
    499         echo '      <p>'.sprintf(__('All of that being said, you could set this to just <code>60 seconds</code> and you would still see huge differences in speed and performance. If you\'re just starting out with %1$s (perhaps a bit nervous about old cache files being served to your visitors); you could set this to something like <code>30 minutes</code> and experiment with it while you build confidence in %1$s. It\'s not necessary to do so, but many site owners have reported this makes them feel like they\'re more-in-control when the cache has a short expiration time. All-in-all, it\'s a matter of preference <i class="si si-smile-o"></i>.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
    500         echo '      <p><input type="text" name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][cache_max_age]" value="'.esc_attr($this->plugin->options['cache_max_age']).'" /></p>'."\n";
    501         echo '      <p class="info">'.__('<strong>Tip:</strong> the value that you specify here MUST be compatible with PHP\'s <a href="http://php.net/manual/en/function.strtotime.php" target="_blank" style="text-decoration:none;"><code>strtotime()</code></a> function. Examples: <code>30 seconds</code>, <code>2 hours</code>, <code>7 days</code>, <code>6 months</code>, <code>1 year</code>.', 'rapid-cache').'</p>'."\n";
    502         echo '      <p class="info">'.sprintf(__('<strong>Note:</strong> %1$s will never serve a cache file that is older than what you specify here (even if one exists in your cache directory; stale cache files are never used). In addition, a WP Cron job will automatically cleanup your cache directory (once per hour); purging expired cache files periodically. This prevents a HUGE cache from building up over time, creating a potential storage issue.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
    503 
    504         echo '      <hr />'."\n";
    505 
    506         echo '      <h3>'.__('Cache Cleanup Schedule', 'rapid-cache').'</h3>'."\n";
    507         echo '      <p>'.sprintf(__('If you have an extremely large site and you lower the default Cache Expiration Time of <code>7 days</code>, expired cache files can build up more quickly. By default, %1$s cleans up expired cache files via <a href="https://codex.wordpress.org/Category:WP-Cron_Functions" target="_blank">WP Cron</a> at an <code>hourly</code> interval, but you can tell %1$s to use a custom Cache Cleanup Schedule below to run the cleanup process more or less frequently, depending on your specific needs.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
    508         echo '      <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][cache_cleanup_schedule]">'."\n";
    509         foreach (wp_get_schedules() as $_wp_cron_schedule_key => $_wp_cron_schedule) {
    510             echo '       <option value="'.esc_attr($_wp_cron_schedule_key).'"'.selected($this->plugin->options['cache_cleanup_schedule'], $_wp_cron_schedule_key, false).'>'.esc_html($_wp_cron_schedule['display']).'</option>'."\n";
    511         } // This builds the list of options using WP_Cron schedules configured for this WP installation.
    512         unset($_wp_cron_schedule_key, $_wp_cron_schedule);
    513         echo '      </select></p>'."\n";
    514 
    515         if (MEGAOPTIM_RAPID_CACHE_IS_PRO || $this->plugin->isProPreview()) {
    516             $_sys_getloadavg_unavailable = ($this->plugin->isProPreview() ? false : !$this->plugin->sysLoadAverages());
    517             echo '  <div>'."\n";
    518             echo '      <hr />'."\n";
    519             echo '      <h3 data-pro-version-only="'.(!MEGAOPTIM_RAPID_CACHE_IS_PRO ? __('pro version only', 'rapid-cache') : '').'" style="'.($_sys_getloadavg_unavailable ? 'opacity: 0.5;' : '').'">'.__('Disable Cache Expiration If Server Load Average is High?', 'rapid-cache').'</h3>'."\n";
    520             echo '      <p style="'.($_sys_getloadavg_unavailable ? 'opacity: 0.5;' : '').'">'.sprintf(__('If you have high traffic at certain times of the day, %1$s can be told to check the current load average via <a href="https://www.php.net/manual/en/function.sys-getloadavg.php" target="_blank"><code>sys_getloadavg()</code></a>. If your server\'s load average has been high in the last 15 minutes or so, cache expiration is disabled automatically to help reduce stress on the server; i.e., to avoid generating a new version of the cache while the server is very busy.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
    521             echo '      <p style="'.($_sys_getloadavg_unavailable ? 'opacity: 0.5;' : '').'">'.sprintf(__('To enable this functionality you should first determine what a high load average is for your server. If you log into your machine via SSH you can run the <code>top</code> command to get a feel for what a high load average looks like. Once you know the number, you can enter it in the field below; e.g., <code>1.05</code> might be a high load average for a server with one CPU. See also: <a href="https://bit.ly/2QZLwkI" target="_blank">Understanding Load Average</a>', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
    522             echo '      <p><input '.($_sys_getloadavg_unavailable ? 'disabled' : '').' type="text" name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][cache_max_age_disable_if_load_average_is_gte]" value="'.esc_attr($this->plugin->options['cache_max_age_disable_if_load_average_is_gte']).'" /></p>'."\n";
    523             if ($_sys_getloadavg_unavailable && mb_stripos(PHP_OS, 'win') === 0) { // See: <http://jas.xyz/1HZsZ9v>
    524                 echo '  <p class="warning">'.__('<strong>Note:</strong> It appears that your server is running Windows. The <code>sys_getloadavg()</code> function has not been implemented in PHP for Windows servers yet.', 'rapid-cache').'</p>'."\n";
    525             } elseif ($_sys_getloadavg_unavailable && mb_stripos(PHP_OS, 'win') !== 0) {
    526                 echo '  <p class="warning">'.__('<strong>Note:</strong> <code>sys_getloadavg()</code> has been disabled by your web hosting company or is not available on your server.', 'rapid-cache').'</p>'."\n";
    527             }
    528             echo '   </div>'."\n";
    529         }
    530         echo '   </div>'."\n";
    531 
    532         echo '</div>'."\n";
    533 
    534         /* ----------------------------------------------------------------------------------------- */
    535 
    536         echo '<div class="plugin-menu-page-panel">'."\n";
    537 
    538         echo '   <a href="#" class="plugin-menu-page-panel-heading">'."\n";
    539         echo '      <i class="si si-octi-tach"></i> '.__('Client-Side Cache', 'rapid-cache')."\n";
    540         echo '   </a>'."\n";
    541 
    542         echo '   <div class="plugin-menu-page-panel-body clearfix">'."\n";
    543         echo '      <i class="si si-desktop si-4x" style="float:right; margin: 0 0 0 25px;"></i>'."\n";
    544         echo '      <h3>'.__('Allow Double-Caching In The Client-Side Browser?', 'rapid-cache').'</h3>'."\n";
    545         echo '      <p>'.__('Recommended setting: <code>No</code> (for membership sites, very important). Otherwise, <code>Yes</code> would be better (if users do NOT log in/out of your site).', 'rapid-cache').'</p>'."\n";
    546         echo '      <p>'.__('<strong>This option is NOT the same as "Leverage Browser Caching"</strong>, which refers to the caching of static resources in the browser (e.g., images, CSS, JS). This Client-Side Cache option is different in that it controls the caching of <em>page content</em> in the browser, i.e., the caching of HTML content generated by PHP itself, which is generally NOT static. If you\'re looking to Leverage Browser Caching for static resources (highly recommended), see the <strong>Apache Optimizations</strong> panel below.', 'rapid-cache').'</p>'."\n";
    547         echo '      <p>'.sprintf(__('%1$s handles content delivery through its ability to communicate with a browser using PHP. If you allow a browser to (cache) the caching system itself, you are momentarily losing some control; and this can have a negative impact on users that see more than one version of your site; e.g., one version while logged-in, and another while NOT logged-in. For instance, a user may log out of your site, but upon logging out they report seeing pages on the site which indicate they are STILL logged in (even though they\'re not — that\'s bad). This can happen if you allow a client-side cache, because their browser may cache web pages they visited while logged into your site which persist even after logging out. Sending no-cache headers will work to prevent this issue.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
    548         echo '      <p>'.__('All of that being said, if all you care about is blazing fast speed and users don\'t log in/out of your site (only you do); you can safely set this to <code>Yes</code> (recommended in this case). Allowing a client-side browser cache will improve speed and reduce outgoing bandwidth when this option is feasible.', 'rapid-cache').'</p>'."\n";
    549         echo '      <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][allow_client_side_cache]" data-toggle="enable-disable" data-target=".-client-side-cache-options">'."\n";
    550         echo '            <option value="0"'.selected($this->plugin->options['allow_client_side_cache'], '0', false).'>'.__('No, prevent a client-side browser cache of dynamic page content (safest option).', 'rapid-cache').'</option>'."\n";
    551         echo '            <option value="1"'.selected($this->plugin->options['allow_client_side_cache'], '1', false).'>'.__('Yes, I will allow a client-side browser cache of pages on the site.', 'rapid-cache').'</option>'."\n";
    552         echo '         </select></p>'."\n";
    553         echo '      <p class="info">'.__('<strong>Tip:</strong> Setting this to <code>No</code> is highly recommended when running a membership plugin like <a href="http://wordpress.org/plugins/s2member/" target="_blank">s2Member</a> (as one example). In fact, many plugins like s2Member will send <a href="http://codex.wordpress.org/Function_Reference/nocache_headers" target="_blank">nocache_headers()</a> on their own, so your configuration here will likely be overwritten when you run such plugins (which is better anyway). In short, if you run a membership plugin, you should NOT allow a client-side browser cache.', 'rapid-cache').'</p>'."\n";
    554         echo '      <p class="info">'.__('<strong>Tip:</strong> Setting this to <code>No</code> will NOT impact static content; e.g., CSS, JS, images, or other media. This setting pertains only to dynamic PHP scripts which produce content generated by WordPress.', 'rapid-cache').'</p>'."\n";
    555         echo '      <p class="info">'.sprintf(__('<strong>Advanced Tip:</strong> if you have this set to <code>No</code>, but you DO want to allow a few special URLs to be cached by the browser; you can add this parameter to your URL <code>?%2$sABC=1</code>. This tells %1$s that it\'s OK for the browser to cache that particular URL. In other words, the <code>%2$sABC=1</code> parameter tells %1$s NOT to send no-cache headers to the browser.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME), esc_html(mb_strtolower(MEGAOPTIM_RAPID_CACHE_NAME))).'</p>'."\n";
    556         echo '      <hr />'."\n";
    557         echo '      <div class="plugin-menu-page-panel-if-enabled -client-side-cache-options">'."\n";
    558         echo '        <h3>'.__('Exclusion Patterns for Client-Side Caching', 'rapid-cache').'</h3>'."\n";
    559         echo '        <p>'.__('When you enable Client-Side Caching above, you may want to prevent certain pages on your site from being cached by a client-side browser. This is where you will enter those if you need to (one per line). Searches are performed against the <a href="https://gist.github.com/jaswsinc/338b6eb03a36c048c26f" target="_blank" style="text-decoration:none;"><code>REQUEST_URI</code></a>; i.e., <code>/path/?query</code> (caSe insensitive). So, don\'t put in full URLs here, just word fragments found in the file path (or query string) is all you need, excluding the http:// and domain name. A wildcard <code>*</code> character can also be used when necessary; e.g., <code>/category/abc-followed-by-*</code> (where <code>*</code> = 0 or more characters that are NOT a slash <code>/</code>). Other special characters include: <code>**</code> = 0 or more characters of any kind, including <code>/</code> slashes; <code>^</code> = beginning of the string; <code>$</code> = end of the string. To learn more about this syntax, please see <a href ="https://github.com/megaoptim/rapid-cache/wiki/Watered-Down-Regex-Syntax" target="_blank">this KB article</a>.', 'rapid-cache').'</p>'."\n";
    560         echo '        <p><textarea name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][exclude_client_side_uris]" rows="5" spellcheck="false" class="monospace">'.format_to_edit($this->plugin->options['exclude_client_side_uris']).'</textarea></p>'."\n";
    561         echo '        <p class="info">'.__('<strong>Tip:</strong> let\'s use this example URL: <code>http://www.example.com/post/example-post-123</code>. To exclude this URL, you would put this line into the field above: <code>/post/example-post-123</code>. Or, you could also just put in a small fragment, like: <code>example</code> or <code>example-*-123</code> and that would exclude any URI containing that word fragment.', 'rapid-cache').'</p>'."\n";
    562         echo '        <p class="info">'.__('<strong>Note:</strong> please remember that your entries here should be formatted as a line-delimited list; e.g., one exclusion pattern per line.', 'rapid-cache').'</p>'."\n";
    563         echo '      </div>'."\n";
    564         echo '   </div>'."\n";
    565 
    566         echo '</div>'."\n";
    567 
    568         /* ----------------------------------------------------------------------------------------- */
    569 
    570         if (MEGAOPTIM_RAPID_CACHE_IS_PRO || $this->plugin->isProPreview()) {
    571             echo '<div class="plugin-menu-page-panel'.(!MEGAOPTIM_RAPID_CACHE_IS_PRO ? ' pro-preview' : '').'">'."\n";
    572 
    573             echo '   <a href="#" class="plugin-menu-page-panel-heading" data-pro-version-only="'.(!MEGAOPTIM_RAPID_CACHE_IS_PRO ? __('pro version only', 'rapid-cache') : '').'">'."\n";
    574             echo '      <i class="si si-octi-organization"></i> '.__('Logged-In Users', 'rapid-cache')."\n";
    575             echo '   </a>'."\n";
    576 
    577             echo '   <div class="plugin-menu-page-panel-body clearfix">'."\n";
    578             echo '      <i class="si si-group si-4x" style="float:right; margin: 0 0 0 25px;"></i>'."\n";
    579             echo '      <h3>'.__('Caching Enabled for Logged-In Users &amp; Comment Authors?', 'rapid-cache').'</h3>'."\n";
    580             echo '      <p>'.__('This should almost always be set to <code>No</code>. Most sites don\'t cache content generated while a user is logged-in. Doing so could result in a cache of dynamic content generated specifically for a particular user, where the content being cached may contain details that pertain only to the user that was logged-in when the cache was generated. In short, don\'t turn this on unless you know what you\'re doing. Note also that most sites get most (sometimes all) of their traffic from users who <em>are not</em> logged-in. When a user <em>is</em> logged-in, disabling the cache is generally a good idea because a logged-in user has a session open with your site. The content they view should remain very dynamic in this scenario.', 'rapid-cache').'</p>'."\n";
    581             echo '      <i class="si si-sitemap si-4x" style="float:right; margin: 0 0 0 25px;"></i>'."\n";
    582             echo '      <p>'.sprintf(__('<strong>Exception (Membership Sites):</strong> If you run a site with many users and the majority of your traffic comes from users who <em>are</em> logged-in, choose: <code>Yes (maintain separate cache)</code>. %1$s will operate normally, but when a user is logged-in the cache is user-specific. %1$s will intelligently refresh the cache when/if a user submits a form on your site with the GET or POST method. Or, if you make changes to their account (or another plugin makes changes to their account); including user <a href="http://codex.wordpress.org/Function_Reference/update_user_option" target="_blank">option</a>|<a href="http://codex.wordpress.org/Function_Reference/update_user_meta" target="_blank">meta</a> additions, updates &amp; deletions too. However, please note that enabling this feature (i.e., user-specific cache entries) will eat up much more disk space. That being said, the benefits of this feature for most sites will outweigh the disk overhead; i.e., it\'s not an issue in most cases. In other words, unless you\'re short on disk space, or you have thousands of users, the disk overhead is neglible.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
    583             echo '      <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][when_logged_in]" data-toggle="enable-disable" data-enabled-strings="1,postload" data-target=".-logged-in-users-options">'."\n";
    584             echo '            <option value="0"'.(!MEGAOPTIM_RAPID_CACHE_IS_PRO ? '' : selected($this->plugin->options['when_logged_in'], '0', false)).'>'.__('No, do NOT cache; or serve a cache file when a user is logged-in (safest option).', 'rapid-cache').'</option>'."\n";
    585             echo '            <option value="postload"'.(!MEGAOPTIM_RAPID_CACHE_IS_PRO ? ' selected' : selected($this->plugin->options['when_logged_in'], 'postload', false)).'>'.__('Yes, and maintain a separate cache for each user (recommended for membership sites).', 'rapid-cache').'</option>'."\n";
    586             if ($this->plugin->options['when_logged_in'] === '1' || get_site_option(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_when_logged_in_was_1')) {
    587                 update_site_option(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_when_logged_in_was_1', '1');
    588                 echo '            <option value="1"'.selected($this->plugin->options['when_logged_in'], '1', false).'>'.__('Yes, but DON\'T maintain a separate cache for each user (I know what I\'m doing).', 'rapid-cache').'</option>'."\n";
    589             }
    590             echo '         </select></p>'."\n";
    591             if ($this->plugin->options['when_logged_in'] === '1' && $this->plugin->applyWpFilters(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_when_logged_in_no_admin_bar', true)) {
    592                 echo '<p class="warning">'.sprintf(__('<strong>Warning:</strong> Whenever you enable caching for logged-in users (without a separate cache for each user), the WordPress Admin Bar <em>must</em> be disabled to prevent one user from seeing another user\'s details in the Admin Bar. <strong>Given your current configuration, %1$s will automatically hide the WordPress Admin Bar on the front-end of your site.</strong>', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
    593             }
    594             echo '      <p class="info">'.sprintf(__('<strong>Note:</strong> %1$s includes comment authors as part of it\'s logged-in user check. This way comment authors will be able to see updates to comment threads immediately. And, so that any dynamically-generated messages displayed by your theme will work as intended. In short, %1$s thinks of a comment author as a logged-in user, even though technically they are not. Users who gain access to password-protected Posts/Pages are also considered by the logged-in user check.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
    595 
    596             echo '      <hr />'."\n";
    597 
    598             echo '      <div class="plugin-menu-page-panel-if-enabled -logged-in-users-options">'."\n";
    599             echo '        <h3>'.__('Cache Pages Containing Nonce Values in Markup?', 'rapid-cache').'</h3>'."\n";
    600             echo '        <p>'.sprintf(__('This should almost always be set to <code>Yes</code>. WordPress injects Nonces (<a href="https://developer.wordpress.org/themes/theme-security/using-nonces/" target="_blank" rel="external">numbers used once</a>) into the markup on any given page that a logged-in user lands on. These Nonce values are generally used to improve security when actions are taken by a user; e.g., posting a form or clicking a link that performs an action. If you set this to <code>No</code>, any page containing an Nonce will bypass the cache and be served dynamically (a performance hit). Even the Admin Bar in WordPress injects Nonce values. That\'s reason enough to leave this at the default value of <code>Yes</code>; i.e., so Nonce values in the markup don\'t result in a cache bypass. In short, don\'t set this to <code>No</code> unless you know what you\'re doing.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
    601             echo '        <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][cache_nonce_values_when_logged_in]">'."\n";
    602             echo '           <option value="1"'.selected($this->plugin->options['cache_nonce_values_when_logged_in'], '1', false).'>'.__('Yes, for logged-in users, intelligently cache pages containing Nonce values (recommended).', 'rapid-cache').'</option>'."\n";
    603             echo '           <option value="0"'.selected($this->plugin->options['cache_nonce_values_when_logged_in'], '0', false).'>'.__('No, for logged-in users, refuse to cache pages containing Nonce values.', 'rapid-cache').'</option>'."\n";
    604             echo '           </select></p>'."\n";
    605             echo '        <p class="info">'.sprintf(__('<strong>Note:</strong> Nonce values in WordPress have a limited lifetime. They can expire just 12 hours after they were first generated. For this reason, %1$s will automatically force cache files containing Nonce values to expire once they are 12+ hours old; i.e., a new request for an expired page containing Nonce values will be rebuilt automatically, generating new Nonces that will continue to operate as expected. This rule is enforced no matter what your overall Cache Expiration Time is set to.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
    606             echo '        <hr />'."\n";
    607             echo '        <h3>'.__('Static CDN Filters Enabled for Logged-In Users &amp; Comment Authors?', 'rapid-cache').'</h3>'."\n";
    608             echo '        <p>'.__('While this defaults to a value of <code>No</code>, it should almost always be set to <code>Yes</code>. This value defaults to <code>No</code> only because Logged-In User caching (see above) defaults to <code>No</code> and setting this value to <code>Yes</code> by default can cause confusion for some site owners. Once you understand that Static CDN Filters can be applied safely for all visitors (logged-in or not logged-in), please choose <code>Yes</code> in the dropdown below. If you are not using Static CDN Filters, the value below is ignored.', 'rapid-cache').'</p>'."\n";
    609             echo '        <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][cdn_when_logged_in]">'."\n";
    610             echo '              <option value="0"'.selected($this->plugin->options['cdn_when_logged_in'], '0', false).'>'.__('No, disable Static CDN Filters when a user is logged-in.', 'rapid-cache').'</option>'."\n";
    611             echo '                <option value="postload"'.selected($this->plugin->options['cdn_when_logged_in'], 'postload', false).'>'.__('Yes, enable Static CDN Filters for logged-in users (recommended) .', 'rapid-cache').'</option>'."\n";
    612             echo '          </select></p>'."\n";
    613             echo '        <p class="info">'.__('<strong>Note:</strong> Static CDN Filters serve <em>static</em> resources. Static resources, are, simply put, static. Thus, it is not a problem to cache these resources for any visitor (logged-in or not logged-in). To avoid confusion, this defaults to a value of <code>No</code>, and we ask that you set it to <code>Yes</code> on your own so that you\'ll know to expect this behavior; i.e., that static resources will always be served from the CDN (logged-in or not logged-in) even though Logged-In User caching may be disabled above.', 'rapid-cache').'</p>'."\n";
    614             echo '        <hr />'."\n";
    615             echo '        <h3>'.__('Enable HTML Compression for Logged-In Users?', 'rapid-cache').'</h3>'."\n";
    616             echo '        <p>'.__('Disabled by default. This setting is only applicable when HTML Compression is enabled. HTML Compression should remain disabled for logged-in users because the user-specific cache has a much shorter Time To Live (TTL) which means their cache is likely to expire more quickly than a normal visitor. Rebuilding the HTML Compressor cache is time-consuming and doing it too frequently will actually slow things down for them. For example, if you\'re logged into the site as a user and you submit a form, that triggers a clearing of the cache for that user, including the HTML Compressor cache. Lots of little actions you take can result in a clearing of the cache. This shorter TTL is not ideal when running the HTML Compressor because it does a deep analysis of the page content and the associated resources in order to intelligently compress things. For logged-in users, it is better to skip that extra work and just cache the HTML source as-is, avoiding that extra overhead. In short, do NOT turn this on unless you know what you\'re doing.', 'rapid-cache').'</p>'."\n";
    617             echo '        <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][htmlc_when_logged_in]">'."\n";
    618             echo '           <option value="0"'.selected($this->plugin->options['htmlc_when_logged_in'], '0', false).'>'.__('No, disable HTML Compression for logged-in users (recommended).', 'rapid-cache').'</option>'."\n";
    619             echo '           <option value="postload"'.selected($this->plugin->options['htmlc_when_logged_in'], 'postload', false).'>'.__('Yes, enable HTML Compression for logged-in users.', 'rapid-cache').'</option>'."\n";
    620             echo '           </select></p>'."\n";
    621             echo '      </div>'."\n";
    622             echo '   </div>'."\n";
    623 
    624             echo '</div>'."\n";
    625         }
    626         /* ----------------------------------------------------------------------------------------- */
    627 
    628         echo '<div class="plugin-menu-page-panel'.(!MEGAOPTIM_RAPID_CACHE_IS_PRO && $this->plugin->isProPreview() ? ' pro-preview' : '').'">'."\n";
    629 
    630         echo '   <a href="#" class="plugin-menu-page-panel-heading" data-additional-pro-features="'.(!MEGAOPTIM_RAPID_CACHE_IS_PRO && $this->plugin->isProPreview() ? __('additional pro features', 'rapid-cache') : '').'">'."\n";
    631         echo '      <i class="si si-question-circle"></i> '.__('GET Requests', 'rapid-cache')."\n";
    632         echo '   </a>'."\n";
    633 
    634         echo '   <div class="plugin-menu-page-panel-body clearfix">'."\n";
    635 
    636         echo '      <i class="si si-question-circle si-4x" style="float:right; margin: 0 0 0 25px;"></i>'."\n";
    637         echo '      <h3>'.__('Caching Enabled for GET (Query String) Requests?', 'rapid-cache').'</h3>'."\n";
    638         echo '      <p>'.__('This should almost always be set to <code>No</code>. UNLESS, you\'re using unfriendly Permalinks; i.e., if all of your URLs contain a query string (like <code>?p=123</code>). In such a case, you should set this option to <code>Yes</code>. However, it\'s better to update your Permalink options and use friendly Permalinks, which also optimizes your site for search engines. Again, if you\'re using friendly Permalinks (recommended) you can leave this at the default value of <code>No</code>.', 'rapid-cache').'</p>'."\n";
    639         echo '      <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][get_requests]">'."\n";
    640         echo '            <option value="0"'.selected($this->plugin->options['get_requests'], '0', false).'>'.__('No, do NOT cache (or serve a cache file) when a query string is present.', 'rapid-cache').'</option>'."\n";
    641         echo '            <option value="1"'.selected($this->plugin->options['get_requests'], '1', false).'>'.__('Yes, I would like to cache URLs that contain a query string.', 'rapid-cache').'</option>'."\n";
    642         echo '         </select></p>'."\n";
    643         echo '      <p class="info">'.sprintf(__('<strong>Advanced Tip:</strong> If you are not caching GET requests (recommended), but you <em>do</em> want to allow some special URLs that include query string parameters to be cached, you can add this special parameter to any URL <code>?%2$sAC=1</code>. This tells %1$s that it\'s OK to cache that particular URL, even though it contains query string arguments. If you <em>are</em> caching GET requests and you want to force %1$s to <em>not</em> cache a specific request, you can add this special parameter to any URL <code>?%2$sAC=0</code>.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME), esc_html(mb_strtolower(MEGAOPTIM_RAPID_CACHE_SHORT_NAME))).'</p>'."\n";
    644         echo '      <p style="font-style:italic;">'.__('<strong>Other Request Types:</strong> POST requests (i.e., forms with <code>method=&quot;post&quot;</code>) are always excluded from the cache, which is the way it should be. Any <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html" target="_blank">POST/PUT/DELETE</a> request should never, ever be cached. CLI and self-serve requests are also excluded from the cache automatically. A CLI request is one that comes from the command line; commonly used by CRON jobs and other automated routines. A self-serve request is an HTTP connection established from your site, to your site. For instance, a WP Cron job, or any other HTTP request that is spawned not by a user, but by the server itself.', 'rapid-cache').'</p>'."\n";
    645 
    646         if (MEGAOPTIM_RAPID_CACHE_IS_PRO || $this->plugin->isProPreview()) {
    647             echo '<div>'."\n";
    648             echo    '<hr />'."\n";
    649             echo    '<h3 data-pro-version-only="'.(!MEGAOPTIM_RAPID_CACHE_IS_PRO ? __('pro version only', 'rapid-cache') : '').'">'.__('List of GET Variable Names to Ignore', 'rapid-cache').'</h3>'."\n";
    650             echo    '<p>'.__('You can enter one variable name per line. Each of the variable names that you list here will be ignored entirely; i.e., not considered when caching any given page, and not considered when serving any page that is already cached. For example, many sites use Google Analytics and there are <a href="https://support.google.com/analytics/answer/1033863?hl=en" target="_blank" rel="external">GET request variables used by Google Analytics</a>, which are read by client-side JavaScript only. Those GET variables can be ignored altogether when it comes to the cache algorithm — speeding up your site even further.', 'rapid-cache').'</p>'."\n";
    651             echo    '<p><textarea name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][ignore_get_request_vars]" rows="5" spellcheck="false" class="monospace">'.format_to_edit($this->plugin->options['ignore_get_request_vars']).'</textarea></p>'."\n";
    652             echo    '<p style="font-style:italic;">'.__('A wildcard <code>*</code> character can also be used when necessary; e.g., <code>utm_*</code> (where <code>*</code> = 0 or more characters that are NOT a slash <code>/</code>). To learn more about this syntax, please see <a href ="https://github.com/megaoptim/rapid-cache/wiki/Watered-Down-Regex-Syntax" target="_blank">this KB article</a>.', 'rapid-cache').'</p>'."\n";
    653             echo '</div>'."\n";
    654         }
    655         echo '   </div>'."\n";
    656 
    657         echo '</div>'."\n";
    658 
    659         /* ----------------------------------------------------------------------------------------- */
    660 
    661         echo '<div class="plugin-menu-page-panel">'."\n";
    662 
    663         echo '   <a href="#" class="plugin-menu-page-panel-heading">'."\n";
    664         echo '      <i class="si si-chain-broken"></i> '.__('404 Requests', 'rapid-cache')."\n";
    665         echo '   </a>'."\n";
    666 
    667         echo '   <div class="plugin-menu-page-panel-body clearfix">'."\n";
    668         echo '      <i class="si si-question-circle si-4x" style="float:right; margin: 0 0 0 25px;"></i>'."\n";
    669         echo '      <h3>'.__('Caching Enabled for 404 Requests?', 'rapid-cache').'</h3>'."\n";
    670         echo '      <p>'.sprintf(__('When this is set to <code>No</code>, %1$s will ignore all 404 requests and no cache file will be served. While this is fine for most site owners, caching the 404 page on a high-traffic site may further reduce server load. When this is set to <code>Yes</code>, %1$s will cache the 404 page (see <a href="https://codex.wordpress.org/Creating_an_Error_404_Page" target="_blank">Creating an Error 404 Page</a>) and then serve that single cache file to all future 404 requests.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
    671         echo '      <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][cache_404_requests]">'."\n";
    672         echo '            <option value="0"'.selected($this->plugin->options['cache_404_requests'], '0', false).'>'.__('No, do NOT cache (or serve a cache file) for 404 requests.', 'rapid-cache').'</option>'."\n";
    673         echo '            <option value="1"'.selected($this->plugin->options['cache_404_requests'], '1', false).'>'.__('Yes, I would like to cache the 404 page and serve the cached file for 404 requests.', 'rapid-cache').'</option>'."\n";
    674         echo '         </select></p>'."\n";
    675         echo '      <p class="info">'.sprintf(__('<strong>How does %1$s cache 404 requests?</strong> %1$s will create a special cache file (<code>----404----.html</code>, see Advanced Tip below) for the first 404 request and then <a href="http://www.php.net/manual/en/function.symlink.php" target="_blank">symlink</a> future 404 requests to this special cache file. That way you don\'t end up with lots of 404 cache files that all contain the same thing (the contents of the 404 page). Instead, you\'ll have one 404 cache file and then several symlinks (i.e., references) to that 404 cache file.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
    676         echo '      <p class="info">'.__('<strong>Advanced Tip:</strong> The default 404 cache filename (<code>----404----.html</code>) is designed to minimize the chance of a collision with a cache file for a real page with the same name. However, if you want to override this default and define your own 404 cache filename, you can do so by adding <code>define(\'RAPID_CACHE_404_CACHE_FILENAME\', \'your-404-cache-filename\');</code> to your <code>wp-config.php</code> file (note that the <code>.html</code> extension should be excluded when defining a new filename).', 'rapid-cache').'</p>'."\n";
    677         echo '   </div>'."\n";
    678 
    679         echo '</div>'."\n";
    680 
    681         /* ----------------------------------------------------------------------------------------- */
    682 
    683         echo '<div class="plugin-menu-page-panel">'."\n";
    684 
    685         echo '   <a href="#" class="plugin-menu-page-panel-heading">'."\n";
    686         echo '      <i class="si si-feed"></i> '.__('Feed Caching', 'rapid-cache')."\n";
    687         echo '   </a>'."\n";
    688 
    689         echo '   <div class="plugin-menu-page-panel-body clearfix">'."\n";
    690         echo '      <i class="si si-question-circle si-4x" style="float:right; margin: 0 0 0 25px;"></i>'."\n";
    691         echo '      <h3>'.__('Caching Enabled for RSS, RDF, Atom Feeds?', 'rapid-cache').'</h3>'."\n";
    692         echo '      <p>'.__('This should almost ALWAYS be set to <code>No</code>. UNLESS, you\'re sure that you want to cache your feeds. If you use a web feed management provider like Google® Feedburner and you set this option to <code>Yes</code>, you may experience delays in the detection of new posts. <strong>NOTE:</strong> If you do enable this, it is highly recommended that you also enable automatic Feed Clearing too. Please see the section above: "Automatic Cache Clearing". Find the sub-section titled: "Auto-Clear RSS/RDF/ATOM Feeds".', 'rapid-cache').'</p>'."\n";
    693         echo '      <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][feeds_enable]" class="-no-if-enabled">'."\n";
    694         echo '            <option value="0"'.selected($this->plugin->options['feeds_enable'], '0', false).'>'.__('No, do NOT cache (or serve a cache file) when displaying a feed.', 'rapid-cache').'</option>'."\n";
    695         echo '            <option value="1"'.selected($this->plugin->options['feeds_enable'], '1', false).'>'.__('Yes, I would like to cache feed URLs.', 'rapid-cache').'</option>'."\n";
    696         echo '         </select></p>'."\n";
    697         echo '      <p class="info">'.__('<strong>Note:</strong> This option affects all feeds served by WordPress, including the site feed, the site comment feed, post-specific comment feeds, author feeds, search feeds, and category and tag feeds. See also: <a href="http://codex.wordpress.org/WordPress_Feeds" target="_blank">WordPress Feeds</a>.', 'rapid-cache').'</p>'."\n";
    698         echo '   </div>'."\n";
    699 
    700         echo '</div>'."\n";
    701 
    702         /* ----------------------------------------------------------------------------------------- */
    703 
    704         $exclude_hosts_option_enable = is_multisite() &&
    705             ((defined('SUBDOMAIN_INSTALL') && SUBDOMAIN_INSTALL) || $this->plugin->canConsiderDomainMapping());
    706 
    707         if ($this->plugin->applyWpFilters(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_exclude_hosts_option_enable', $exclude_hosts_option_enable)) {
    708             echo '<div class="plugin-menu-page-panel">'."\n";
    709 
    710             echo '   <a href="#" class="plugin-menu-page-panel-heading">'."\n";
    711             echo '      <i class="si si-ban"></i> '.__('Host Exclusions', 'rapid-cache')."\n";
    712             echo '   </a>'."\n";
    713 
    714             echo '   <div class="plugin-menu-page-panel-body clearfix">'."\n";
    715             echo '      <h3>'.__('Don\'t Cache These Special Host Exclusion Patterns?', 'rapid-cache').'</h3>'."\n";
    716             echo '      <p>'.__('If there are specific domains that should not be cached, you can enter them here so they are excluded automatically. The easiest way to exclude a host is to enter the full domain name on a line of it\'s own in the field below, e.g., <code>site1.example.com</code>.', 'rapid-cache').'</p>'."\n";
    717             echo '      <p>'.__('This field also supports <a href ="https://github.com/megaoptim/rapid-cache/wiki/Watered-Down-Regex-Syntax" target="_blank" style="text-decoration:none;">Watered-Down Regex</a> syntax, which means that you can also exclude a pattern like: <code>*.example.com</code> or <code>*.example.*</code>. So for instance, if you wanted to exclude all child sites and only cache pages on the Main Site of a Network installation, you could exclude all sub-domains using: <code>*.mynetwork.com</code>. That excludes all sub-domains, but not <code>mynetwork.com</code> by itself.', 'rapid-cache').'</p>'."\n";
    718 
    719             echo '      <p><textarea name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][exclude_hosts]" rows="5" spellcheck="false" class="monospace">'.format_to_edit($this->plugin->options['exclude_hosts']).'</textarea></p>'."\n";
    720 
    721             echo '      <p class="info">'.__('<strong>Note:</strong> please remember that your entries here should be formatted as a line-delimited list; e.g., one exclusion pattern per line.', 'rapid-cache').'</p>'."\n";
    722 
    723             echo '   </div>'."\n";
    724             echo '</div>'."\n";
    725         }
    726 
    727         /* ----------------------------------------------------------------------------------------- */
    728 
    729         echo '<div class="plugin-menu-page-panel">'."\n";
    730 
    731         echo '   <a href="#" class="plugin-menu-page-panel-heading">'."\n";
    732         echo '      <i class="si si-ban"></i> '.__('URI Exclusions', 'rapid-cache')."\n";
    733         echo '   </a>'."\n";
    734 
    735         echo '   <div class="plugin-menu-page-panel-body clearfix">'."\n";
    736         echo '      <h3>'.__('Don\'t Cache These Special URI Exclusion Patterns?', 'rapid-cache').'</h3>'."\n";
    737         echo '      <p>'.__('Sometimes there are certain cases where a particular file, or a particular group of files, should never be cached. This is where you will enter those if you need to (one per line). Searches are performed against the <a href="https://gist.github.com/jaswsinc/338b6eb03a36c048c26f" target="_blank" style="text-decoration:none;"><code>REQUEST_URI</code></a>; i.e., <code>/path/?query</code> (caSe insensitive). So, don\'t put in full URLs here, just word fragments found in the file path (or query string) is all you need, excluding the http:// and domain name. A wildcard <code>*</code> character can also be used when necessary; e.g., <code>/category/abc-followed-by-*</code> (where <code>*</code> = 0 or more characters that are NOT a slash <code>/</code>). Other special characters include: <code>**</code> = 0 or more characters of any kind, including <code>/</code> slashes; <code>^</code> = beginning of the string; <code>$</code> = end of the string. To learn more about this syntax, please see <a href ="https://github.com/megaoptim/rapid-cache/wiki/Watered-Down-Regex-Syntax" target="_blank">this KB article</a>.', 'rapid-cache').'</p>'."\n";
    738         echo '      <p><textarea name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][exclude_uris]" rows="5" spellcheck="false" class="monospace">'.format_to_edit($this->plugin->options['exclude_uris']).'</textarea></p>'."\n";
    739 
    740         echo '      <p class="info">'.__('<strong>Tip:</strong> let\'s use this example URL: <code>http://www.example.com/post/example-post-123</code>. To exclude this URL, you would put this line into the field above: <code>/post/example-post-123</code>. Or, you could also just put in a small fragment, like: <code>example</code> or <code>example-*-123</code> and that would exclude any URI containing that word fragment.', 'rapid-cache').'</p>'."\n";
    741         echo '      <p class="info">'.__('<strong>Note:</strong> please remember that your entries here should be formatted as a line-delimited list; e.g., one exclusion pattern per line.', 'rapid-cache').'</p>'."\n";
    742         if (is_multisite() && defined('SUBDOMAIN_INSTALL') && !SUBDOMAIN_INSTALL) {
    743             echo '      <p class="info">'.__('<strong>Multisite Network w/ Sub-Directories:</strong> You can also use URI Exclusion Patterns to exclude specific sites from being cached, e.g., <code>/site1/*</code>.', 'rapid-cache').'</p>'."\n";
    744         }
    745         echo '   </div>'."\n";
    746 
    747         echo '</div>'."\n";
    748 
    749         /* ----------------------------------------------------------------------------------------- */
    750 
    751         echo '<div class="plugin-menu-page-panel">'."\n";
    752 
    753         echo '   <a href="#" class="plugin-menu-page-panel-heading">'."\n";
    754         echo '      <i class="si si-ban"></i> '.__('HTTP Referrer Exclusions', 'rapid-cache')."\n";
    755         echo '   </a>'."\n";
    756 
    757         echo '   <div class="plugin-menu-page-panel-body clearfix">'."\n";
    758         echo '      <h3>'.__('Don\'t Cache These Special HTTP Referrer Exclusion Patterns?', 'rapid-cache').'</h3>'."\n";
    759         echo '      <p>'.__('Sometimes there are special cases where a particular referring URL (or referring domain) that sends you traffic; or even a particular group of referring URLs or domains that send you traffic; should result in a page being loaded on your site that is NOT from the cache (and that resulting page should never be cached). This is where you will enter those if you need to (one per line). Searches are performed against the <a href="http://www.php.net//manual/en/reserved.variables.server.php" target="_blank" style="text-decoration:none;"><code>HTTP_REFERER</code></a> (caSe insensitive). A wildcard <code>*</code> character can also be used when necessary; e.g., <code>*.domain.com</code> (where <code>*</code> = 0 or more characters that are NOT a slash <code>/</code>). Other special characters include: <code>**</code> = 0 or more characters of any kind, including <code>/</code> slashes; <code>^</code> = beginning of the string; <code>$</code> = end of the string. To learn more about this syntax, please see <a href ="https://github.com/megaoptim/rapid-cache/wiki/Watered-Down-Regex-Syntax" target="_blank">this KB article</a>.', 'rapid-cache').'</p>'."\n";
    760         echo '      <p><textarea name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][exclude_refs]" rows="5" spellcheck="false" class="monospace">'.format_to_edit($this->plugin->options['exclude_refs']).'</textarea></p>'."\n";
    761         echo '      <p class="info">'.__('<strong>Tip:</strong> let\'s use this example URL: <code>http://www.referring-domain.com/search/?q=search+terms</code>. To exclude this referring URL, you could put this line into the field above: <code>www.referring-domain.com</code>. Or, you could also just put in a small fragment, like: <code>/search/</code> or <code>q=*</code>; and that would exclude any referrer containing that word fragment.', 'rapid-cache').'</p>'."\n";
    762         echo '      <p class="info">'.__('<strong>Note:</strong> please remember that your entries here should be formatted as a line-delimited list; e.g., one exclusion pattern per line.', 'rapid-cache').'</p>'."\n";
    763         echo '   </div>'."\n";
    764 
    765         echo '</div>'."\n";
    766 
    767         /* ----------------------------------------------------------------------------------------- */
    768 
    769         echo '<div class="plugin-menu-page-panel">'."\n";
    770 
    771         echo '   <a href="#" class="plugin-menu-page-panel-heading">'."\n";
    772         echo '      <i class="si si-ban"></i> '.__('User-Agent Exclusions', 'rapid-cache')."\n";
    773         echo '   </a>'."\n";
    774 
    775         echo '   <div class="plugin-menu-page-panel-body clearfix">'."\n";
    776         echo '      <h3>'.__('Don\'t Cache These Special User-Agent Exclusion Patterns?', 'rapid-cache').'</h3>'."\n";
    777         echo '      <p>'.__('Sometimes there are special cases when a particular user-agent (e.g., a specific browser or a specific type of device); should be shown a page on your site that is NOT from the cache (and that resulting page should never be cached). This is where you will enter those if you need to (one per line). Searches are performed against the <a href="http://www.php.net//manual/en/reserved.variables.server.php" target="_blank" style="text-decoration:none;"><code>HTTP_USER_AGENT</code></a> (caSe insensitive). A wildcard <code>*</code> character can also be used when necessary; e.g., <code>Android *; Chrome/* Mobile</code> (where <code>*</code> = 0 or more characters that are NOT a slash <code>/</code>). Other special characters include: <code>**</code> = 0 or more characters of any kind, including <code>/</code> slashes; <code>^</code> = beginning of the string; <code>$</code> = end of the string. To learn more about this syntax, please see <a href ="https://github.com/megaoptim/rapid-cache/wiki/Watered-Down-Regex-Syntax" target="_blank">this KB article</a>.', 'rapid-cache').'</p>'."\n";
    778         echo '      <p><textarea name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][exclude_agents]" rows="5" spellcheck="false" class="monospace">'.format_to_edit($this->plugin->options['exclude_agents']).'</textarea></p>'."\n";
    779         echo '      <p class="info">'.sprintf(__('<strong>Tip:</strong> if you wanted to exclude iPhones put this line into the field above: <code>iPhone;*AppleWebKit</code>. Or, you could also just put in a small fragment, like: <code>iphone</code>; and that would exclude any user-agent containing that word fragment. Note, this is just an example. With a default installation of %1$s, there is no compelling reason to exclude iOS devices (or any mobile device for that matter).', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
    780         echo '      <p class="info">'.__('<strong>Note:</strong> please remember that your entries here should be formatted as a line-delimited list; e.g., one exclusion pattern per line.', 'rapid-cache').'</p>'."\n";
    781         echo '   </div>'."\n";
    782 
    783         echo '</div>'."\n";
    784 
    785         /* ----------------------------------------------------------------------------------------- */
    786 
    787         if (MEGAOPTIM_RAPID_CACHE_IS_PRO || $this->plugin->isProPreview()) {
    788             echo '<div class="plugin-menu-page-panel'.(!MEGAOPTIM_RAPID_CACHE_IS_PRO ? ' pro-preview' : '').'">'."\n";
    789 
    790             echo '   <a href="#" class="plugin-menu-page-panel-heading" data-pro-version-only="'.(!MEGAOPTIM_RAPID_CACHE_IS_PRO ? __('pro version only', 'rapid-cache') : '').'">'."\n";
    791             echo '      <i class="si si-sitemap"></i> '.__('Auto-Cache Engine', 'rapid-cache')."\n";
    792             echo '   </a>'."\n";
    793 
    794             echo '   <div class="plugin-menu-page-panel-body clearfix">'."\n";
    795             echo '      <i class="si si-question-circle si-4x" style="float:right; margin: 0 0 0 25px;"></i>'."\n";
    796             echo '      <h3>'.__('Enable the Auto-Cache Engine?', 'rapid-cache').'</h3>'."\n";
    797             echo '      <p>'.sprintf(__('After using %1$s for awhile (or any other page caching plugin, for that matter); it becomes obvious that at some point (based on your configured Expiration Time) %1$s has to refresh itself. It does this by ditching its cached version of a page, reloading the database-driven content, and then recreating the cache with the latest data. This is a never ending regeneration cycle that is based entirely on your configured Expiration Time.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
    798             echo '      <p>'.__('Understanding this, you can see that 99% of your visitors are going to receive a lightning fast response from your server. However, there will always be around 1% of your visitors that land on a page for the very first time (before it\'s been cached), or land on a page that needs to have its cache regenerated, because the existing cache has become outdated. We refer to this as a <em>First-Come Slow-Load Issue</em>. Not a huge problem, but if you\'re optimizing your site for every ounce of speed possible, the Auto-Cache Engine can help with this. The Auto-Cache Engine has been designed to combat this issue by taking on the responsibility of being that first visitor to a page that has not yet been cached, or has an expired cache. The Auto-Cache Engine is powered, in part, by <a href="http://codex.wordpress.org/Category:WP-Cron_Functions" target="_blank">WP-Cron</a> (already built into WordPress). The Auto-Cache Engine runs at 15-minute intervals via WP-Cron. It also uses the <a href="http://core.trac.wordpress.org/browser/trunk/wp-includes/http.php" target="_blank">WP_Http</a> class, which is also built into WordPress already.', 'rapid-cache').'</p>'."\n";
    799             echo '      <p>'.__('The Auto-Cache Engine obtains its list of URLs to auto-cache, from two different sources. It can read an <a href="http://wordpress.org/extend/plugins/google-sitemap-generator/" target="_blank">XML Sitemap</a> and/or a list of specific URLs that you supply. If you supply both sources, it will use both sources collectively. The Auto-Cache Engine takes ALL of your other configuration options into consideration too, including your Expiration Time, as well as any cache exclusion rules.', 'rapid-cache').'</p>'."\n";
    800             echo '      <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][auto_cache_enable]" data-target=".-auto-cache-options">'."\n";
    801             echo '            <option value="0"'.(!MEGAOPTIM_RAPID_CACHE_IS_PRO ? '' : selected($this->plugin->options['auto_cache_enable'], '0', false)).'>'.__('No, leave the Auto-Cache Engine disabled please.', 'rapid-cache').'</option>'."\n";
    802             echo '            <option value="1"'.(!MEGAOPTIM_RAPID_CACHE_IS_PRO ? ' selected' : selected($this->plugin->options['auto_cache_enable'], '1', false)).'>'.__('Yes, I want the Auto-Cache Engine to keep pages cached automatically.', 'rapid-cache').'</option>'."\n";
    803             echo '         </select></p>'."\n";
    804 
    805             echo '      <hr />'."\n";
    806 
    807             echo '      <div class="plugin-menu-page-panel-if-enabled -auto-cache-options">'."\n";
    808             echo '         <h3>'.__('XML Sitemap URL (or an XML Sitemap Index)', 'rapid-cache').'</h3>'."\n";
    809             echo '         <table style="width:100%;"><tr><td style="width:1px; font-weight:bold; white-space:pre;">'.esc_html(home_url('/')).'</td><td><input type="text" name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][auto_cache_sitemap_url]" value="'.esc_attr($this->plugin->options['auto_cache_sitemap_url']).'" /></td></tr></table>'."\n";
    810             if (is_multisite()) {
    811                 echo '      <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][auto_cache_ms_children_too]">'."\n";
    812                 echo '            <option value="0"'.selected($this->plugin->options['auto_cache_ms_children_too'], '0', false).'>'.__('All URLs in this network are in the sitemap for the main site.', 'rapid-cache').'</option>'."\n";
    813                 echo '            <option value="1"'.selected($this->plugin->options['auto_cache_ms_children_too'], '1', false).'>'.__('Using the path I\'ve given, look for blog-specific sitemaps in each child blog also.', 'rapid-cache').'</option>'."\n";
    814                 echo '         </select></p>'."\n";
    815                 echo '      <p class="info" style="display:block; margin-top:0;">'.sprintf(__('<strong>↑</strong> If enabled here, each child blog can be auto-cached too. %1$s will dynamically change the leading <code>%2$s</code> as necessary; for each child blog in the network. %1$s supports both sub-directory &amp; sub-domain networks, including domain mapping plugins. For more information about how the Auto-Cache Engine caches child blogs, see <a href="#" target="_blank">this article</a>.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME), esc_html(home_url('/'))).'</p>'."\n";
    816             }
    817             echo '         <hr />'."\n";
    818 
    819             echo '         <h3>'.__('And/Or; a List of URLs to Auto-Cache (One Per Line)', 'rapid-cache').'</h3>'."\n";
    820             echo '         <p><textarea name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][auto_cache_other_urls]" rows="5" spellcheck="false" class="monospace">'.format_to_edit($this->plugin->options['auto_cache_other_urls']).'</textarea></p>'."\n";
    821             echo '         <p class="info" style="display:block; margin-top:-5px;">'.__('<strong>Note:</strong> Wildcards are NOT supported here. If you are going to supply a list of URLs above, each line must contain one full URL for the Auto-Cache Engine to auto-cache. If you have many URLs, we recommend using an <a href="https://en.wikipedia.org/wiki/Sitemaps" target="_blank">XML Sitemap</a>.', 'rapid-cache').'</p>'."\n";
    822 
    823             echo '         <hr />'."\n";
    824 
    825             echo '         <h3>'.__('Auto-Cache Delay Timer (in Milliseconds)', 'rapid-cache').'</h3>'."\n";
    826             echo '         <p>'.__('As the Auto-Cache Engine runs through each URL, you can tell it to wait X number of milliseconds between each connection that it makes. It is strongly suggested that you DO have some small delay here. Otherwise, you run the risk of hammering your own web server with multiple repeated connections whenever the Auto-Cache Engine is running. This is especially true on very large sites; where there is the potential for hundreds of repeated connections as the Auto-Cache Engine goes through a long list of URLs. Adding a delay between each connection will prevent the Auto-Cache Engine from placing a heavy load on the processor that powers your web server. A value of <code>500</code> milliseconds is suggested here (half a second). If you experience problems, you can bump this up a little at a time, in increments of <code>500</code> milliseconds; until you find a happy place for your server. <em>Please note that <code>1000</code> milliseconds = <code>1</code> full second.</em>', 'rapid-cache').'</p>'."\n";
    827             echo '         <p><input type="text" name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][auto_cache_delay]" value="'.esc_attr($this->plugin->options['auto_cache_delay']).'" /></p>'."\n";
    828 
    829             echo '         <hr />'."\n";
    830 
    831             echo '         <h3>'.__('Auto-Cache User-Agent String', 'rapid-cache').'</h3>'."\n";
    832             echo '         <table style="width:100%;"><tr><td><input type="text" name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][auto_cache_user_agent]" value="'.esc_attr($this->plugin->options['auto_cache_user_agent']).'" /></td><td style="width:1px; font-weight:bold; white-space:pre;">; '.esc_html(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.' '.MEGAOPTIM_RAPID_CACHE_VERSION).'</td></tr></table>'."\n";
    833             echo '         <p class="info" style="display:block;">'.__('This is how the Auto-Cache Engine identifies itself when connecting to URLs. See <a href="http://en.wikipedia.org/wiki/User_agent" target="_blank">User Agent</a> in the Wikipedia.', 'rapid-cache').'</p>'."\n";
    834             echo '      </div>'."\n";
    835             echo '   </div>'."\n";
    836 
    837             echo '</div>'."\n";
    838         }
    839         /* ----------------------------------------------------------------------------------------- */
    840 
    841         if (MEGAOPTIM_RAPID_CACHE_IS_PRO || $this->plugin->isProPreview()) {
    842             echo '<div class="plugin-menu-page-panel'.(!MEGAOPTIM_RAPID_CACHE_IS_PRO ? ' pro-preview' : '').'">'."\n";
    843 
    844             echo '   <a href="#" class="plugin-menu-page-panel-heading" data-pro-version-only="'.(!MEGAOPTIM_RAPID_CACHE_IS_PRO ? __('pro version only', 'rapid-cache') : '').'">'."\n";
    845             echo '      <i class="si si-html5"></i> '.__('HTML Compression', 'rapid-cache')."\n";
    846             echo '   </a>'."\n";
    847 
    848             echo '   <div class="plugin-menu-page-panel-body clearfix">'."\n";
    849             echo '      <i class="si si-question-circle si-4x" style="float:right; margin: 0 0 0 25px;"></i>'."\n";
    850             echo '      <h3>'.__('Enable WebSharks™ HTML Compression?', 'rapid-cache').'</h3>'."\n";
    851             if (is_plugin_active('autoptimize/autoptimize.php')) {
    852                 echo '      <p class="warning">'.__('<strong>Autoptimize + Rapid Cache:</strong> Rapid Cache has detected that you are running the Autoptimize plugin. Autoptimize and the HTML Compressor feature of Rapid Cache are both designed to compress HTML, CSS, and JavaScript. Enabling the HTML Compressor alongside Autoptimize may result in unexpected behavior. If you\'re happy with Autoptimize, you can leave the HTML Compressor disabled. All other Rapid Cache features run great alongside Autoptimize.', 'rapid-cache').' <i class="si si-smile-o"></i></p>';
    853             }
    854             echo '      <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][htmlc_enable]" data-target=".-htmlc-options">'."\n";
    855             echo '            <option value="0"'.(!MEGAOPTIM_RAPID_CACHE_IS_PRO ? '' : selected($this->plugin->options['htmlc_enable'], '0', false)).'>'.__('No, do NOT compress HTML/CSS/JS code at runtime.', 'rapid-cache').'</option>'."\n";
    856             echo '            <option value="1"'.(!MEGAOPTIM_RAPID_CACHE_IS_PRO ? ' selected' : selected($this->plugin->options['htmlc_enable'], '1', false)).'>'.__('Yes, I want to compress HTML/CSS/JS for blazing fast speeds.', 'rapid-cache').'</option>'."\n";
    857             echo '         </select></p>'."\n";
    858             echo '      <hr />'."\n";
    859             echo '      <div class="plugin-menu-page-panel-if-enabled -htmlc-options">'."\n";
    860             echo '         <h3>'.__('HTML Compression Options', 'rapid-cache').'</h3>'."\n";
    861             echo '         <p>'.__('You can <a href="https://github.com/websharks/html-compressor" target="_blank">learn more about all of these options here</a>.', 'rapid-cache').'</p>'."\n";
    862             echo '         <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][htmlc_compress_combine_head_body_css]" autocomplete="off">'."\n";
    863             echo '               <option value="1"'.selected($this->plugin->options['htmlc_compress_combine_head_body_css'], '1', false).'>'.__('Yes, combine CSS from &lt;head&gt; and &lt;body&gt; into fewer files.', 'rapid-cache').'</option>'."\n";
    864             echo '               <option value="0"'.selected($this->plugin->options['htmlc_compress_combine_head_body_css'], '0', false).'>'.__('No, do not combine CSS from &lt;head&gt; and &lt;body&gt; into fewer files.', 'rapid-cache').'</option>'."\n";
    865             echo '            </select></p>'."\n";
    866             echo '         <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][htmlc_compress_css_code]" autocomplete="off">'."\n";
    867             echo '               <option value="1"'.selected($this->plugin->options['htmlc_compress_css_code'], '1', false).'>'.__('Yes, compress the code in any unified CSS files.', 'rapid-cache').'</option>'."\n";
    868             echo '               <option value="0"'.selected($this->plugin->options['htmlc_compress_css_code'], '0', false).'>'.__('No, do not compress the code in any unified CSS files.', 'rapid-cache').'</option>'."\n";
    869             echo '            </select></p>'."\n";
    870             echo '         <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][htmlc_compress_combine_head_js]" autocomplete="off">'."\n";
    871             echo '               <option value="1"'.selected($this->plugin->options['htmlc_compress_combine_head_js'], '1', false).'>'.__('Yes, combine JS from &lt;head&gt; into fewer files.', 'rapid-cache').'</option>'."\n";
    872             echo '               <option value="0"'.selected($this->plugin->options['htmlc_compress_combine_head_js'], '0', false).'>'.__('No, do not combine JS from &lt;head&gt; into fewer files.', 'rapid-cache').'</option>'."\n";
    873             echo '            </select></p>'."\n";
    874             echo '         <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][htmlc_compress_combine_footer_js]" autocomplete="off">'."\n";
    875             echo '               <option value="1"'.selected($this->plugin->options['htmlc_compress_combine_footer_js'], '1', false).'>'.__('Yes, combine JS footer scripts into fewer files.', 'rapid-cache').'</option>'."\n";
    876             echo '               <option value="0"'.selected($this->plugin->options['htmlc_compress_combine_footer_js'], '0', false).'>'.__('No, do not combine JS footer scripts into fewer files.', 'rapid-cache').'</option>'."\n";
    877             echo '            </select></p>'."\n";
    878             echo '         <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][htmlc_compress_combine_remote_css_js]" autocomplete="off">'."\n";
    879             echo '               <option value="1"'.selected($this->plugin->options['htmlc_compress_combine_remote_css_js'], '1', false).'>'.__('Yes, combine CSS/JS from remote resources too.', 'rapid-cache').'</option>'."\n";
    880             echo '               <option value="0"'.selected($this->plugin->options['htmlc_compress_combine_remote_css_js'], '0', false).'>'.__('No, do not combine CSS/JS from remote resources.', 'rapid-cache').'</option>'."\n";
    881             echo '            </select></p>'."\n";
    882             echo '         <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][htmlc_compress_js_code]" autocomplete="off">'."\n";
    883             echo '               <option value="1"'.selected($this->plugin->options['htmlc_compress_js_code'], '1', false).'>'.__('Yes, compress the code in any unified JS files.', 'rapid-cache').'</option>'."\n";
    884             echo '               <option value="0"'.selected($this->plugin->options['htmlc_compress_js_code'], '0', false).'>'.__('No, do not compress the code in any unified JS files.', 'rapid-cache').'</option>'."\n";
    885             echo '            </select></p>'."\n";
    886             echo '         <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][htmlc_compress_inline_js_code]" autocomplete="off">'."\n";
    887             echo '               <option value="1"'.selected($this->plugin->options['htmlc_compress_inline_js_code'], '1', false).'>'.__('Yes, compress inline JavaScript snippets.', 'rapid-cache').'</option>'."\n";
    888             echo '               <option value="0"'.selected($this->plugin->options['htmlc_compress_inline_js_code'], '0', false).'>'.__('No, do not compress inline JavaScript snippets.', 'rapid-cache').'</option>'."\n";
    889             echo '            </select></p>'."\n";
    890             echo '         <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][htmlc_compress_html_code]" autocomplete="off">'."\n";
    891             echo '               <option value="1"'.selected($this->plugin->options['htmlc_compress_html_code'], '1', false).'>'.__('Yes, compress (remove extra whitespace) in the final HTML code too.', 'rapid-cache').'</option>'."\n";
    892             echo '               <option value="0"'.selected($this->plugin->options['htmlc_compress_html_code'], '0', false).'>'.__('No, do not compress the final HTML code.', 'rapid-cache').'</option>'."\n";
    893             echo '            </select></p>'."\n";
    894             echo '         <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][htmlc_amp_exclusions_enable]" autocomplete="off">'."\n";
    895             echo '               <option value="1"'.selected($this->plugin->options['htmlc_amp_exclusions_enable'], '1', false).'>'.__('Yes, auto-detect AMP (Accelerated Mobile Pages) and selectively disable incompatible features.', 'rapid-cache').'</option>'."\n";
    896             echo '               <option value="0"'.selected($this->plugin->options['htmlc_amp_exclusions_enable'], '0', false).'>'.__('No, do not auto-detect AMP (Accelerated Mobile Pages) and selectively disable incompatible features', 'rapid-cache').'</option>'."\n";
    897             echo '            </select></p>'."\n";
    898             echo '         <hr />'."\n";
    899             echo '         <h3>'.__('CSS Exclusion Patterns?', 'rapid-cache').'</h3>'."\n";
    900             echo '         <p>'.__('Sometimes there are special cases when a particular CSS file should NOT be consolidated or compressed in any way. This is where you will enter those if you need to (one per line). Searches are performed against the <code>&lt;link href=&quot;&quot;&gt;</code> value, and also against the contents of any inline <code>&lt;style&gt;</code> tags (caSe insensitive). A wildcard <code>*</code> character can also be used when necessary; e.g., <code>xy*-framework</code> (where <code>*</code> = 0 or more characters that are NOT a slash <code>/</code>). Other special characters include: <code>**</code> = 0 or more characters of any kind, including <code>/</code> slashes; <code>^</code> = beginning of the string; <code>$</code> = end of the string. To learn more about this syntax, please see <a href ="https://github.com/megaoptim/rapid-cache/wiki/Watered-Down-Regex-Syntax" target="_blank">this KB article</a>.', 'rapid-cache').'</p>'."\n";
    901             echo '         <p><textarea name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][htmlc_css_exclusions]" rows="5" spellcheck="false" class="monospace">'.format_to_edit($this->plugin->options['htmlc_css_exclusions']).'</textarea></p>'."\n";
    902             echo '         <p class="info" style="display:block;">'.__('<strong>Note:</strong> please remember that your entries here should be formatted as a line-delimited list; e.g., one exclusion pattern per line.', 'rapid-cache').'</p>'."\n";
    903             echo '         <h3>'.__('JavaScript Exclusion Patterns?', 'rapid-cache').'</h3>'."\n";
    904             echo '         <p>'.__('Sometimes there are special cases when a particular JS file should NOT be consolidated or compressed in any way. This is where you will enter those if you need to (one per line). Searches are performed against the <code>&lt;script src=&quot;&quot;&gt;</code> value, and also against the contents of any inline <code>&lt;script&gt;</code> tags (caSe insensitive). A wildcard <code>*</code> character can also be used when necessary; e.g., <code>xy*-framework</code> (where <code>*</code> = 0 or more characters that are NOT a slash <code>/</code>). Other special characters include: <code>**</code> = 0 or more characters of any kind, including <code>/</code> slashes; <code>^</code> = beginning of the string; <code>$</code> = end of the string. To learn more about this syntax, please see <a href ="https://github.com/megaoptim/rapid-cache/wiki/Watered-Down-Regex-Syntax" target="_blank">this KB article</a>.', 'rapid-cache').'</p>'."\n";
    905             echo '         <p><textarea name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][htmlc_js_exclusions]" rows="5" spellcheck="false" class="monospace">'.format_to_edit($this->plugin->options['htmlc_js_exclusions']).'</textarea></p>'."\n";
    906             echo '         <p class="info" style="display:block;">'.__('<strong>Note:</strong> please remember that your entries here should be formatted as a line-delimited list; e.g., one exclusion pattern per line.', 'rapid-cache').'</p>'."\n";
    907             echo '         <h3>'.__('URI Exclusions for HTML Compressor?', 'rapid-cache').'</h3>'."\n";
    908             echo '         <p>'.__('When you enable HTML Compression above, you may want to prevent certain pages on your site from being cached by the HTML Compressor. This is where you will enter those if you need to (one per line). Searches are performed against the <a href="https://gist.github.com/jaswsinc/338b6eb03a36c048c26f" target="_blank" style="text-decoration:none;"><code>REQUEST_URI</code></a>; i.e., <code>/path/?query</code> (caSe insensitive). So, don\'t put in full URLs here, just word fragments found in the file path (or query string) is all you need, excluding the http:// and domain name. A wildcard <code>*</code> character can also be used when necessary; e.g., <code>/category/abc-followed-by-*</code> (where <code>*</code> = 0 or more characters that are NOT a slash <code>/</code>). Other special characters include: <code>**</code> = 0 or more characters of any kind, including <code>/</code> slashes; <code>^</code> = beginning of the string; <code>$</code> = end of the string. To learn more about this syntax, please see <a href ="https://github.com/megaoptim/rapid-cache/wiki/Watered-Down-Regex-Syntax" target="_blank">this KB article</a>.', 'rapid-cache').'</p>'."\n";
    909             echo '         <p><textarea name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][htmlc_uri_exclusions]" rows="5" spellcheck="false" class="monospace">'.format_to_edit($this->plugin->options['htmlc_uri_exclusions']).'</textarea></p>'."\n";
    910             echo '         <p class="info">'.__('<strong>Tip:</strong> let\'s use this example URL: <code>http://www.example.com/post/example-post-123</code>. To exclude this URL, you would put this line into the field above: <code>/post/example-post-123</code>. Or, you could also just put in a small fragment, like: <code>example</code> or <code>example-*-123</code> and that would exclude any URI containing that word fragment.', 'rapid-cache').'</p>'."\n";
    911             echo '         <p class="info">'.__('<strong>Note:</strong> please remember that your entries here should be formatted as a line-delimited list; e.g., one exclusion pattern per line.', 'rapid-cache').'</p>'."\n";
    912             echo '         <hr />'."\n";
    913             echo '         <h3>'.__('HTML Compression Cache Expiration', 'rapid-cache').'</h3>'."\n";
    914             echo '         <p><input type="text" name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][htmlc_cache_expiration_time]" value="'.esc_attr($this->plugin->options['htmlc_cache_expiration_time']).'" /></p>'."\n";
    915             echo '         <p class="info" style="display:block;">'.__('<strong>Tip:</strong> the value that you specify here MUST be compatible with PHP\'s <a href="http://php.net/manual/en/function.strtotime.php" target="_blank" style="text-decoration:none;"><code>strtotime()</code></a> function. Examples: <code>2 hours</code>, <code>7 days</code>, <code>6 months</code>, <code>1 year</code>.', 'rapid-cache').'</p>'."\n";
    916             echo '         <p>'.sprintf(__('<strong>Note:</strong> This does NOT impact the overall cache expiration time that you configure with %1$s. It only impacts the sub-routines provided by the HTML Compressor. In fact, this expiration time is mostly irrelevant. The HTML Compressor uses an internal checksum, and it also checks <code>filemtime()</code> before using an existing cache file. The HTML Compressor class also handles the automatic cleanup of your cache directories to keep it from growing too large over time. Therefore, unless you have VERY little disk space there is no reason to set this to a lower value (even if your site changes dynamically quite often). If anything, you might like to increase this value which could help to further reduce server load. You can <a href="https://github.com/websharks/HTML-Compressor" target="_blank">learn more here</a>. We recommend setting this value to at least double that of your overall %1$s expiration time.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
    917             echo '      </div>'."\n";
    918             echo '   </div>'."\n";
    919 
    920             echo '</div>'."\n";
    921         }
    922 
    923         /* ----------------------------------------------------------------------------------------- */
    924 
    925         if ($this->plugin->isApache() || $this->plugin->isProPreview()) {
    926             echo '<div class="plugin-menu-page-panel'.(!MEGAOPTIM_RAPID_CACHE_IS_PRO && $this->plugin->isProPreview() ? ' pro-preview' : '').'">'."\n";
    927 
    928             echo '   <a href="#" class="plugin-menu-page-panel-heading" data-additional-pro-features="'.(!MEGAOPTIM_RAPID_CACHE_IS_PRO && $this->plugin->isProPreview() ? __('additional pro features', 'rapid-cache') : '').'">'."\n";
    929             echo '      <i class="si si-server"></i> '.__('Apache Optimizations', 'rapid-cache')."\n";
    930             echo '   </a>'."\n";
    931 
    932             echo '   <div class="plugin-menu-page-panel-body clearfix">'."\n";
    933             echo '      <img src="'.esc_attr($this->plugin->url('/assets/images/apache.png')).'" class="screenshot" />'."\n";
    934             echo '      <h3>'.__('Apache Performance Tuning (Optional; Highly Recommended)', 'rapid-cache').'</h3>'."\n";
    935             echo '      <p>'.__('You don\'t need to use an <code>.htaccess</code> file to enjoy the performance enhancements provided by this plugin; caching is handled automatically by WordPress/PHP alone. That being said, if you want to take advantage of additional speed enhancements by optimizing the Apache web server to achieve maximize performance (and we do recommend this), then you WILL need an <code>.htaccess</code> file to accomplish that part.', 'rapid-cache').'</p>'."\n";
    936             echo '      <p>'.__('WordPress itself uses the <code>.htaccess</code> file to create Apache rewrite rules when you enable fancy Permalinks, so there\'s a good chance you already have an <code>.htaccess</code> file. The options below allow for additional performance tuning using recommendations provided by Rapid Cache.', 'rapid-cache').'</p>'."\n";
    937             echo '      <p>'.__('When you enable one of the options below, Rapid Cache will attempt to automatically insert the appropriate configuration into your <code>.htaccess</code> file (or remove it automatically if you are disabling an option). If Rapid Cache is unable to update the file, or if you would prefer to add the configuration yourself, the recommended configuration to add to the file can be viewed at the bottom of each option.', 'rapid-cache').'</p>'."\n";
    938             echo '              <p class="info" style="display:block;">'.__('<strong>Note:</strong> The <code>.htaccess</code> file is parsed by the web server directly, before WordPress is even loaded. For that reason, if something goes wrong in the file you can end up with a broken site. We recommend creating a backup of your current <code>.htaccess</code> file before making any modifications.', 'rapid-cache').'</p>'."\n";
    939             echo '      <hr />'."\n";
    940             echo '      <h3>'.__('Enable GZIP Compression?', 'rapid-cache').'</h3>'."\n";
    941             echo '      <p>'.__('<a href="https://bit.ly/3jUtUD1" target="_blank">GZIP compression</a> is highly recommended. It\'s not uncommon to achieve compression rates as high as 70-90%, which is a huge savings in the amount of data that needs to be transferred with each visit to your site.', 'rapid-cache').'</p>'."\n";
    942             echo '      <p>'.sprintf(__('%1$s fully supports GZIP compression on its output. However, it does not handle GZIP compression directly like some caching plugins. We purposely left GZIP compression out of this plugin because GZIP compression is something that should really be enabled at the Apache level or inside your <code>php.ini</code> file. GZIP compression can be used for things like JavaScript and CSS files as well, so why bother turning it on for only WordPress-generated pages when you can enable GZIP at the server level and cover all the bases!', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
    943             echo '      <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][htaccess_gzip_enable]" data-target=".-htaccess-gzip-enable-options">'."\n";
    944             echo '            <option value="0"'.selected($this->plugin->options['htaccess_gzip_enable'], '0', false).'>'.__('No, do NOT enable GZIP Compression (or I\'ll update my configuration manually; see below)', 'rapid-cache').'</option>'."\n";
    945             echo '            <option value="1"'.selected($this->plugin->options['htaccess_gzip_enable'], '1', false).'>'.__('Yes, enable GZIP Compression (recommended)', 'rapid-cache').'</option>'."\n";
    946             echo '         </select></p>'."\n";
    947             echo '      <p>'.__('Or, you can update your configuration manually: [<a href="#" data-toggle-target=".'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'-apache-optimizations--gzip-configuration').'"><i class="si si-eye"></i> .htaccess configuration <i class="si si-eye"></i></a>]', 'rapid-cache').'</p>'."\n";
    948             echo '      <div class="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'-apache-optimizations--gzip-configuration').'" style="display:none; margin-top:1em;">'."\n";
    949             echo '        <p>'.__('<strong>To enable GZIP compression:</strong> Create or edit the <code>.htaccess</code> file in your WordPress installation directory and add the following lines to the top:', 'rapid-cache').'</p>'."\n";
    950             echo '        <pre class="code"><code>'.esc_html($this->plugin->fillReplacementCodes(file_get_contents(MEGAOPTIM_RAPID_CACHE_PATH.'stubs/htaccess/gzip-enable.txt'))).'</code></pre>'."\n";
    951             echo '        <p class="info" style="display:block;">'.__('<strong>Or</strong>, if your server is missing <code>mod_deflate</code>/<code>mod_filter</code>; open your <code>php.ini</code> file and add this line: <a href="http://php.net/manual/en/zlib.configuration.php" target="_blank" style="text-decoration:none;"><code>zlib.output_compression = on</code></a>', 'rapid-cache').'</p>'."\n";
    952             echo '      </div>'."\n";
    953 
    954             if ((!MEGAOPTIM_RAPID_CACHE_IS_PRO && $this->plugin->isApache()) && !$this->plugin->isProPreview()) {
    955                 echo '      <hr />'."\n";
    956                 echo '      <p class="warning" style="display:block;">'.sprintf(__('<a href="%1$s">Enable the Pro Preview</a> to see <strong>Leverage Browser Caching</strong>, <strong>Enforce Canonical URLs</strong>, and more!', 'rapid-cache'), esc_attr(add_query_arg(urlencode_deep(['page' => MEGAOPTIM_RAPID_CACHE_GLOBAL_NS, MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_pro_preview' => '1']), self_admin_url('/admin.php')))).'</p>'."\n";
    957             }
    958             if (MEGAOPTIM_RAPID_CACHE_IS_PRO || $this->plugin->isProPreview()) {
    959                 echo '      <hr />'."\n";
    960                 echo '      <h3 data-pro-version-only="'.(!MEGAOPTIM_RAPID_CACHE_IS_PRO ? __('pro version only', 'rapid-cache') : '').'">'.__('Leverage Browser Caching?', 'rapid-cache').'</h3>'."\n";
    961                 echo '      <p>'.__('<a href="https://bit.ly/3lNT8ou" target="_blank">Browser Caching</a> is highly recommended. When loading a single page, downloading all of the resources for that page may require multiple roundtrips between the browser and server, which delays processing and may block rendering of page content. This also incurs data costs for the visitor. With browser caching, your server tells the visitor\'s browser that it is allowed to cache static resources for a certain amount of time (Google recommends 1 week and that\'s what Rapid Cache uses).', 'rapid-cache').'</p>'."\n";
    962                 echo '      <p>'.__('In WordPress, \'Page Caching\' is all about server-side performance (reducing the amount of time it takes the server to generate the page content). With Rapid Cache installed, you\'re drastically reducing page generation time. However, you can make a visitor\'s experience ​<em>even faster</em>​ when you leverage browser caching too. When this option is enabled, the visitor\'s browser will cache static resources from each page and reuse those cached resources on subsequent page loads. In this way, future visits to the same page will not require additional connections to your site to download static resources that the visitor\'s browser has already cached.', 'rapid-cache').'</p>'."\n";
    963                 echo '      <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][htaccess_browser_caching_enable]" data-target=".-htaccess-browser-caching-enable-options">'."\n";
    964                 echo '            <option value="0"'.(!MEGAOPTIM_RAPID_CACHE_IS_PRO ? '' : selected($this->plugin->options['htaccess_browser_caching_enable'], '0', false)).'>'.__('No, do NOT enable Browser Caching (or I\'ll update my configuration manually; see below)', 'rapid-cache').'</option>'."\n";
    965                 echo '            <option value="1"'.(!MEGAOPTIM_RAPID_CACHE_IS_PRO ? 'selected' : selected($this->plugin->options['htaccess_browser_caching_enable'], '1', false)).'>'.__('Yes, enable Browser Caching for static resources (recommended)', 'rapid-cache').'</option>'."\n";
    966                 echo '         </select></p>'."\n";
    967                 echo '      <p>'.__('Or, you can update your configuration manually: [<a href="#" data-toggle-target=".'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'-apache-optimizations--leverage-browser-caching').'"><i class="si si-eye"></i> .htaccess configuration <i class="si si-eye"></i></a>]', 'rapid-cache').'</p>'."\n";
    968                 echo '      <div class="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'-apache-optimizations--leverage-browser-caching').'" style="display:none; margin-top:1em;">'."\n";
    969                 echo '        <p>'.__('<strong>To enable Browser Caching:</strong> Create or edit the <code>.htaccess</code> file in your WordPress installation directory and add the following lines to the top:', 'rapid-cache').'</p>'."\n";
    970                 echo '        <pre class="code"><code>'.esc_html($this->plugin->fillReplacementCodes(file_get_contents(MEGAOPTIM_RAPID_CACHE_PATH.'stubs/htaccess/browser-caching-enable.txt'))).'</code></pre>'."\n";
    971                 echo '      </div>'."\n";
    972             }
    973             if (MEGAOPTIM_RAPID_CACHE_IS_PRO || $this->plugin->isProPreview()) {
    974                 echo '      <hr />'."\n";
    975                 echo '      <h3 data-pro-version-only="'.(!MEGAOPTIM_RAPID_CACHE_IS_PRO ? __('pro version only', 'rapid-cache') : '').'">'.__('Enforce an Exact Hostname?', 'rapid-cache').'</h3>'."\n";
    976                 echo '      <p>'.sprintf(__('By enforcing an exact hostname you avoid duplicate cache files, which saves disk space and improves cache performance. For example, if a bot or crawler accesses your site using your server\'s IP address instead of using your domain name (e.g., <code>http://123.456.789/path</code>), this results in duplicate cache files, because the host was an IP address. The \'host\' being an important factor in any cache storage system. The same would be true if a visitor attempted to access your site using a made-up sub-domain; e.g., <code>http://foo.bar.%1$s/path</code>. This sort of thing can be avoided by explicitly enforcing an exact hostname in the request. One that matches exactly what you\'ve configured in <strong>WordPress Settings → General</strong>.', 'rapid-cache'), esc_html(parse_url(network_home_url(), PHP_URL_HOST))).'</p>'."\n";
    977                 echo '      <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][htaccess_enforce_exact_host_name]" data-target=".-htaccess-enforce-exact-host-name-options">'."\n";
    978                 echo '            <option value="0"'.(!MEGAOPTIM_RAPID_CACHE_IS_PRO ? '' : selected($this->plugin->options['htaccess_enforce_exact_host_name'], '0', false)).'>'.__('No, do NOT enforce an exact hostname (or I\'ll update my configuration manually; see below)', 'rapid-cache').'</option>'."\n";
    979                 echo '            <option value="1"'.(!MEGAOPTIM_RAPID_CACHE_IS_PRO ? 'selected' : selected($this->plugin->options['htaccess_enforce_exact_host_name'], '1', false)).'>'.sprintf(__('Yes, enforce the exact hostname: %1$s', 'rapid-cache'), esc_html(parse_url(network_home_url(), PHP_URL_HOST))).'</option>'."\n";
    980                 echo '         </select></p>'."\n";
    981                 echo '      <p>'.__('Or, you can update your configuration manually: [<a href="#" data-toggle-target=".'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'-apache-optimizations--enforce-exact-host-name').'"><i class="si si-eye"></i> .htaccess configuration <i class="si si-eye"></i></a>]', 'rapid-cache').'</p>'."\n";
    982                 echo '      <div class="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'-apache-optimizations--enforce-exact-host-name').'" style="display:none; margin-top:1em;">'."\n";
    983                 echo '        <p>'.__('<strong>To enforce an exact hostname:</strong> Create or edit the <code>.htaccess</code> file in your WordPress installation directory and add the following lines to the top:', 'rapid-cache').'</p>'."\n";
    984                 echo '        <pre class="code"><code>'.esc_html($this->plugin->fillReplacementCodes(file_get_contents(MEGAOPTIM_RAPID_CACHE_PATH.'stubs/htaccess/enforce-exact-host-name.txt'))).'</code></pre>'."\n";
    985                 echo '      </div>'."\n";
    986             }
    987             if ((MEGAOPTIM_RAPID_CACHE_IS_PRO && !empty($GLOBALS['wp_rewrite']->permalink_structure)) || $this->plugin->isProPreview()) {
    988                 echo '      <hr />'."\n";
    989                 echo '      <h3 data-pro-version-only="'.(!MEGAOPTIM_RAPID_CACHE_IS_PRO ? __('pro version only', 'rapid-cache') : '').'">'.__('Enforce Canonical URLs?', 'rapid-cache').'</h3>'."\n";
    990                 echo '      <p>'.__('Permalinks (URLs) leading to Posts/Pages on your site (based on your WordPress Permalink Settings) '.($GLOBALS['wp_rewrite']->use_trailing_slashes ? 'require a <code>.../trailing-slash/</code>' : 'do not require a <code>.../trailing-slash</code>').'. Ordinarily, WordPress enforces this by redirecting a request for '.($GLOBALS['wp_rewrite']->use_trailing_slashes ? '<code>.../something</code>' : '<code>.../something/</code>').', to '.($GLOBALS['wp_rewrite']->use_trailing_slashes ? '<code>.../something/</code>' : '<code>.../something</code>').', thereby forcing the final location to match your Permalink configuration. However, whenever you install a plugin like Rapid Cache, much of WordPress (including this automatic redirection) is out of the picture when the cached copy of a page is being served. So enabling this option will add rules to your <code>.htaccess</code> file that make Apache aware of your WordPess Permalink configuration. Apache can do what WordPress normally would, only much more efficiently.', 'rapid-cache').'</p>'."\n";
    991                 echo '      <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][htaccess_enforce_canonical_urls]" data-target=".-htaccess-enforce-canonical-urls-options">'."\n";
    992                 echo '            <option value="0"'.(!MEGAOPTIM_RAPID_CACHE_IS_PRO ? '' : selected($this->plugin->options['htaccess_enforce_canonical_urls'], '0', false)).'>'.__('No, do NOT enforce canonical URLs (or I\'ll update my configuration manually; see below)', 'rapid-cache').'</option>'."\n";
    993                 echo '            <option value="1"'.(!MEGAOPTIM_RAPID_CACHE_IS_PRO ? 'selected' : selected($this->plugin->options['htaccess_enforce_canonical_urls'], '1', false)).'>'.__('Yes, enforce canonical URLs (recommended)', 'rapid-cache').'</option>'."\n";
    994                 echo '         </select></p>'."\n";
    995                 echo '      <p>'.__('Or, you can update your configuration manually: [<a href="#" data-toggle-target=".'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'-apache-optimizations--enforce-cononical-urls').'"><i class="si si-eye"></i> .htaccess configuration <i class="si si-eye"></i></a>]', 'rapid-cache').'</p>'."\n";
    996                 echo '      <div class="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'-apache-optimizations--enforce-cononical-urls').'" style="display:none; margin-top:1em;">'."\n";
    997                 echo '        <p>'.__('<strong>To enforce Canonical URLs:</strong> Create or edit the <code>.htaccess</code> file in your WordPress installation directory and add the following lines to the top:', 'rapid-cache').'</p>'."\n";
    998                 if ($GLOBALS['wp_rewrite']->use_trailing_slashes) {
    999                     echo '        <pre class="code"><code>'.esc_html($this->plugin->fillReplacementCodes(file_get_contents(MEGAOPTIM_RAPID_CACHE_PATH.'stubs/htaccess/canonical-urls-ts-enable.txt'))).'</code></pre>'."\n";
    1000                 } else {
    1001                     echo '        <pre class="code"><code>'.esc_html($this->plugin->fillReplacementCodes(file_get_contents(MEGAOPTIM_RAPID_CACHE_PATH.'stubs/htaccess/canonical-urls-no-ts-enable.txt'))).'</code></pre>'."\n";
    1002                 }
    1003                 echo '      </div>'."\n";
    1004             }
    1005             if ((MEGAOPTIM_RAPID_CACHE_IS_PRO && $this->plugin->options['cdn_enable']) || $this->plugin->isProPreview()) {
    1006                 echo '      <hr />'."\n";
    1007                 echo '      <h3 data-pro-version-only="'.(!MEGAOPTIM_RAPID_CACHE_IS_PRO ? __('pro version only', 'rapid-cache') : '').'">'.__('Send Access-Control-Allow-Origin Header?', 'rapid-cache').'</h3>'."\n";
    1008                 if ($this->plugin->options['cdn_enable'] && !$this->plugin->options['htaccess_access_control_allow_origin']) {
    1009                     echo '        <p class="warning" style="display:block;">'.__('<strong>Warning:</strong> Send Access-Control-Allow-Origin Header has been disabled below but <strong>Rapid Cache → Plugin Options → Static CDN Filters</strong> are enabled. We recommend configuring your server to send the <code>Access-Control-Allow-Origin</code> header to avoid <a href="#" target="_blank">CORS errors</a> when a CDN is configured.', 'rapid-cache').'</p>'."\n";
    1010                 }
    1011                 echo '      <p>'.__('If you are using Static CDN Filters to load resources for your site from another domain, it\'s important that your server sends an <code>Access-Control-Allow-Origin</code> header to prevent Cross Origin Resource Sharing (CORS) errors. This option is enabled automatically when you enable Static CDN Filters. For more information, see <a href="#" target="_blank">this article</a>.', 'rapid-cache').'</p>'."\n";
    1012                 echo '      <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][htaccess_access_control_allow_origin]" data-target=".-htaccess-access-control-allow-origin-options">'."\n";
    1013                 echo '            <option value="0"'.(!MEGAOPTIM_RAPID_CACHE_IS_PRO ? '' : selected($this->plugin->options['htaccess_access_control_allow_origin'], '0', false)).'>'.__('No, do NOT send the Access-Control-Allow-Origin header (or I\'ll update my configuration manually; see below)', 'rapid-cache').'</option>'."\n";
    1014                 echo '            <option value="1"'.(!MEGAOPTIM_RAPID_CACHE_IS_PRO ? 'selected' : selected($this->plugin->options['htaccess_access_control_allow_origin'], '1', false)).'>'.__('Yes, send the Access-Control-Allow-Origin header (recommended for Static CDN Filters)', 'rapid-cache').'</option>'."\n";
    1015                 echo '         </select></p>'."\n";
    1016                 echo '      <p>'.__('Or, you can update your configuration manually: [<a href="#" data-toggle-target=".'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'-apache-optimizations--access-control-allow-origin').'"><i class="si si-eye"></i> .htaccess configuration <i class="si si-eye"></i></a>]', 'rapid-cache').'</p>'."\n";
    1017                 echo '      <div class="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'-apache-optimizations--access-control-allow-origin').'" style="display:none; margin-top:1em;">'."\n";
    1018                 echo '        <p>'.__('<strong>To send the Access-Control-Allow-Origin header:</strong> Create or edit the <code>.htaccess</code> file in your WordPress installation directory and add the following lines to the top:', 'rapid-cache').'</p>'."\n";
    1019                 echo '        <pre class="code"><code>'.esc_html($this->plugin->fillReplacementCodes(file_get_contents(MEGAOPTIM_RAPID_CACHE_PATH.'stubs/htaccess/access-control-allow-origin-enable.txt'))).'</code></pre>'."\n";
    1020                 echo '      </div>'."\n";
    1021             }
    1022             echo '   </div>'."\n";
    1023             echo '</div>'."\n";
    1024         }
    1025 
    1026         /* ----------------------------------------------------------------------------------------- */
    1027 
    1028         if (MEGAOPTIM_RAPID_CACHE_IS_PRO || $this->plugin->isProPreview()) {
    1029             echo '<div class="plugin-menu-page-panel'.(!MEGAOPTIM_RAPID_CACHE_IS_PRO ? ' pro-preview' : '').'">'."\n";
    1030 
    1031             echo '   <a href="#" class="plugin-menu-page-panel-heading" data-pro-version-only="'.(!MEGAOPTIM_RAPID_CACHE_IS_PRO ? __('pro version only', 'rapid-cache') : '').'">'."\n";
    1032             echo '      <i class="si si-octi-versions"></i> '.__('Dynamic Version Salt', 'rapid-cache')."\n";
    1033             echo '   </a>'."\n";
    1034 
    1035             echo '   <div class="plugin-menu-page-panel-body clearfix">'."\n";
    1036             echo '      <img src="'.esc_attr($this->plugin->url('/assets/images/salt.png')).'" class="screenshot" />'."\n";
    1037             echo '      <h3>'.__('<i class="si si-flask"></i> <span style="display:inline-block; padding:5px; border-radius:3px; background:#FFFFFF; color:#354913;"><span style="font-weight:bold; font-size:80%;">GEEK ALERT</span></span> This is for VERY advanced users only...', 'rapid-cache').'</h3>'."\n";
    1038             echo '      <p>'.sprintf(__('<em>Note: Understanding the %1$s <a href="https://github.com/megaoptim/rapid-cache/wiki/What-is-the-Branched-Cache-Structure" target="_blank">Branched Cache Structure</a> is a prerequisite to understanding how Dynamic Version Salts are added to the mix.</em>', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
    1039             echo '      <p>'.__('A Version Salt gives you the ability to dynamically create multiple variations of the cache, and those dynamic variations will be served on subsequent visits; e.g., if a visitor has a specific cookie (of a certain value) they will see pages which were cached with that version (i.e., w/ that Version Salt: the value of the cookie). A Version Salt can really be anything.', 'rapid-cache').'</p>'."\n";
    1040             echo '      <p>'.__('A Version Salt can be a single variable like <code>$_COOKIE[\'my_cookie\']</code>, or it can be a combination of multiple variables, like <code>$_COOKIE[\'my_cookie\'].$_COOKIE[\'my_other_cookie\']</code>. (When using multiple variables, please separate them with a dot, as shown in the example.)', 'rapid-cache').'</p>'."\n";
    1041             echo '      <p>'.__('Experts could even use PHP ternary expressions that evaluate into something. For example: <code>((preg_match(\'/iPhone/i\', $_SERVER[\'HTTP_USER_AGENT\'])) ? \'iPhones\' : \'\')</code>. This would force a separate version of the cache to be created for iPhones (e.g., <code>PROTOCOL.HOST.URI[...]v/iPhones.html</code>).', 'rapid-cache').'</p>'."\n";
    1042             echo '      <p>'.__('For more documentation, please see <a href="#" target="_blank">Dynamic Version Salts</a>.', 'rapid-cache').'</p>'."\n";
    1043             echo '      <hr />'."\n";
    1044             echo '      <h3>'.sprintf(__('Create a Dynamic Version Salt For %1$s? &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-size:90%%; opacity:0.5;">150%% OPTIONAL</span>', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</h3>'."\n";
    1045             echo '      <table style="width:100%;"><tr><td style="width:1px; font-weight:bold; white-space:pre;">PROTOCOL.HOST.URI.v.</td><td><input type="text" name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][version_salt]" value="'.esc_attr($this->plugin->options['version_salt']).'" class="monospace" placeholder="$_COOKIE[\'my_cookie\']" /></td><td style="width:1px; font-weight:bold; white-space:pre;"></td></tr></table>'."\n";
    1046             echo '      <p class="info" style="display:block;">'.__('<a href="http://php.net/manual/en/language.variables.superglobals.php" target="_blank">Super Globals</a> work here; <a href="http://codex.wordpress.org/Editing_wp-config.php#table_prefix" target="_blank"><code>$GLOBALS[\'table_prefix\']</code></a> is a popular one.<br />Or, perhaps a PHP Constant defined in <code>/wp-config.php</code>; such as <code>WPLANG</code> or <code>DB_HOST</code>.', 'rapid-cache').'</p>'."\n";
    1047             echo '      <p class="notice" style="display:block;">'.__('<strong>Important:</strong> your Version Salt is scanned for PHP syntax errors via <a href="http://phpcodechecker.com/" target="_blank"><code>phpCodeChecker.com</code></a>. If errors are found, you\'ll receive a notice in the Dashboard.', 'rapid-cache').'</p>'."\n";
    1048             echo '      <p class="info" style="display:block;">'.__('If you\'ve enabled a separate cache for each user (optional) that\'s perfectly OK. A Version Salt works with user caching too.', 'rapid-cache').'</p>'."\n";
    1049             echo '   </div>'."\n";
    1050 
    1051             echo '</div>'."\n";
    1052         }
    1053         /* ----------------------------------------------------------------------------------------- */
    1054 
    1055         echo '<div class="plugin-menu-page-panel">'."\n";
    1056 
    1057         echo '   <a href="#" class="plugin-menu-page-panel-heading">'."\n";
    1058         echo '      <i class="si si-octi-plug"></i> '.__('Theme/Plugin Developers', 'rapid-cache')."\n";
    1059         echo '   </a>'."\n";
    1060 
    1061         echo '   <div class="plugin-menu-page-panel-body clearfix">'."\n";
    1062         echo '      <i class="si si-puzzle-piece si-4x" style="float:right; margin: 0 0 0 25px;"></i>'."\n";
    1063         echo '      <h3>'.__('Developing a Theme or Plugin for WordPress?', 'rapid-cache').'</h3>'."\n";
    1064 
    1065         echo '      <p>'.sprintf(__('<strong>Tip:</strong> %1$s can be disabled temporarily. If you\'re a theme/plugin developer, you can set a flag within your PHP code to disable the cache engine at runtime. Perhaps on a specific page, or in a specific scenario.</p><p>In your PHP script, set: <code>$_SERVER[\'RAPID_CACHE_ALLOWED\'] = FALSE;</code> or <code>define(\'RAPID_CACHE_ALLOWED\', FALSE)</code>. %1$s is also compatible with: <code>define(\'DONOTCACHEPAGE\', TRUE)</code>. It does\'t matter where or when you define one of these, because %1$s is the last thing to run before script execution ends.</p><p>Check the <a href="https://github.com/megaoptim/rapid-cache/wiki/Developer-Hooks" target="_blank">Developer hooks</a>, <a target="_blank" href="https://github.com/megaoptim/rapid-cache/wiki/Clearing-the-Cache-Dynamically">Clearing the Cache Dynamically</a> or our <a target="_blank" href="https://github.com/megaoptim/rapid-cache/wiki">wiki</a> for more information.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
    1066         echo '   </div>'."\n";
    1067 
    1068         echo '</div>'."\n";
    1069 
    1070         /* ----------------------------------------------------------------------------------------- */
    1071 
    1072         echo '<div class="plugin-menu-page-panel">'."\n";
    1073 
    1074         echo '   <a href="#" class="plugin-menu-page-panel-heading">'."\n";
    1075         echo '      <i class="si si-arrow-circle-o-up"></i> '.__('Import/Export/Migrate', 'rapid-cache')."\n";
    1076         echo '   </a>'."\n";
    1077 
    1078         echo '   <div class="plugin-menu-page-panel-body clearfix">'."\n";
    1079         echo '      <i class="si si-arrow-circle-o-up si-4x" style="float:right; margin: 0 0 0 25px;"></i>'."\n";
    1080         echo '      <h3>'.sprintf(__('Import Options from Another %1$s Installation?', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</h3>'."\n";
    1081         echo '      <p>'.sprintf(__('Upload your <code>options.json</code> file and click "Save All Changes" below. The options provided by your import file will override any that exist currently.', 'rapid-cache')).'</p>'."\n";
    1082         echo '      <p><input type="file" name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[import_options]" /></p>'."\n";
    1083         echo '      <hr />'."\n";
    1084         echo '      <h3>'.sprintf(__('Export Existing Options from this %1$s Installation?', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</h3>'."\n";
    1085         echo '      <p>'.sprintf(__('Download your existing options and import them all into another %1$s installation; saves time on future installs.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
    1086         echo '      <p><button type="button" class="plugin-menu-page-export-options"'.// Exports existing options from this installation.
    1087              '         data-action="'.esc_attr(add_query_arg(urlencode_deep(['page' => MEGAOPTIM_RAPID_CACHE_GLOBAL_NS, '_wpnonce' => wp_create_nonce(), MEGAOPTIM_RAPID_CACHE_GLOBAL_NS => ['exportOptions' => '1']]), self_admin_url('/admin.php'))).'">'.
    1088              '         <i class="si si-arrow-circle-o-down"></i> '.__('Export', 'rapid-cache').'</button></p>'."\n";
    1089 
    1090         if(get_option(MEGAOPTIM_RAPID_CACHE_OLD_GLOBAL_NS.'_options')) {
    1091             $_confirm = __('Are you sure that you want to copy the old options from Comet Cache? This will overwrite your current options and will not be possible to revert.');
    1092             $action_migrate_purge = esc_attr(add_query_arg(urlencode_deep(['page' => MEGAOPTIM_RAPID_CACHE_GLOBAL_NS, '_wpnonce' => wp_create_nonce(), MEGAOPTIM_RAPID_CACHE_GLOBAL_NS => ['migrateFromLegacy' => '1'], 'purgeLegacy' => 1]), self_admin_url('/admin.php')));
    1093             $action_migrate_normal = esc_attr(add_query_arg(urlencode_deep(['page' => MEGAOPTIM_RAPID_CACHE_GLOBAL_NS, '_wpnonce' => wp_create_nonce(), MEGAOPTIM_RAPID_CACHE_GLOBAL_NS => ['migrateFromLegacy' => '1']]), self_admin_url('/admin.php')));
    1094             $action_migrate_default = $action_migrate_normal;
    1095             echo '     <hr />'."\n";
    1096             echo '     <h3>'.sprintf(__('Migration from %s', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_OLD_NAME)).'</h3>'."\n";
    1097             echo '     <p>'.sprintf(__('We detected that you had a previous install of %s on your site. Click on the button to preserve the options.', 'rapid-cache'), '<strong>'.esc_html(MEGAOPTIM_RAPID_CACHE_OLD_NAME).'</strong>').'</p>'."\n";
    1098             echo '     <p>'."\n";
    1099             echo '     <p><input type="checkbox" class="plugin-delete-legacy-data">'.sprintf(__('Do you want to delete %s plugin options data after migration?', 'rapid-cache'), MEGAOPTIM_RAPID_CACHE_OLD_NAME).'</p>';
    1100             echo '     <button type="button" class="plugin-action-migrate plugin-menu-page-export-options"'.// Exports existing options from this installation.
    1101                  '        data-confirmation="'.$_confirm.'" '.
    1102                  '        data-action="'.$action_migrate_default.'" '.
    1103                  '        data-action-purge="'.$action_migrate_purge.'" '.
    1104                  '        data-action-normal="'.$action_migrate_normal.'">'.
    1105                  '        <i class="si si-copy"></i> '.__('Migrate', 'rapid-cache').'</button></p>'."\n";
    1106         }
    1107 
    1108         echo '   </div>'."\n";
    1109 
    1110         echo '</div>'."\n";
    1111         /* ----------------------------------------------------------------------------------------- */
    1112 
    1113         echo '<div class="plugin-menu-page-save">'."\n";
    1114         echo '   <button type="submit">'.__('Save All Changes', 'rapid-cache').' <i class="si si-save"></i></button>'."\n";
    1115         echo '</div>'."\n";
    1116 
    1117         /* ----------------------------------------------------------------------------------------- */
    1118 
    1119         echo '</div>'."\n";
    1120         echo '</form>';
    1121     }
     18    /**
     19     * Constructor.
     20     *
     21     * @since 1.0.0
     22     */
     23    public function __construct()
     24    {
     25        parent::__construct(); // Parent constructor.
     26
     27        echo '<form id="plugin-menu-page" class="plugin-menu-page" method="post" enctype="multipart/form-data" autocomplete="off"'.
     28             ' action="'.esc_attr(add_query_arg(urlencode_deep(['page' => MEGAOPTIM_RAPID_CACHE_GLOBAL_NS, '_wpnonce' => wp_create_nonce()]), self_admin_url('/admin.php'))).'">'."\n";
     29
     30        /* ----------------------------------------------------------------------------------------- */
     31
     32        echo '<div class="plugin-menu-page-heading">'."\n";
     33
     34        if (is_multisite()) {
     35            echo '<button type="button" class="plugin-menu-page-wipe-cache" style="float:right; margin-left:15px;" title="'.esc_attr(__('Wipe Cache (Start Fresh); clears the cache for all sites in this network at once!', 'rapid-cache')).'"'.
     36                 '  data-action="'.esc_attr(add_query_arg(urlencode_deep(['page' => MEGAOPTIM_RAPID_CACHE_GLOBAL_NS, '_wpnonce' => wp_create_nonce(), MEGAOPTIM_RAPID_CACHE_GLOBAL_NS => ['wipeCache' => '1']]), self_admin_url('/admin.php'))).'">'.
     37                 '  '.__('Wipe', 'rapid-cache').' <img src="'.esc_attr($this->plugin->url('/assets/images/wipe.png')).'" style="width:16px; height:16px; display:inline-block;" /></button>'."\n";
     38        }
     39        echo '   <button type="button" class="plugin-menu-page-clear-cache" style="float:right;" title="'.esc_attr(__('Clear Cache (Start Fresh)', 'rapid-cache').((is_multisite()) ? __('; affects the current site only.', 'rapid-cache') : '')).'"'.
     40             '      data-action="'.esc_attr(add_query_arg(urlencode_deep(['page' => MEGAOPTIM_RAPID_CACHE_GLOBAL_NS, '_wpnonce' => wp_create_nonce(), MEGAOPTIM_RAPID_CACHE_GLOBAL_NS => ['clearCache' => '1']]), self_admin_url('/admin.php'))).'">'.
     41             '      '.__('Clear', 'rapid-cache').' <img src="'.esc_attr($this->plugin->url('/assets/images/clear.png')).'" style="width:16px; height:16px; display:inline-block;" /></button>'."\n";
     42
     43        echo '   <button type="button" class="plugin-menu-page-restore-defaults"'.// Restores default options.
     44             '      data-confirmation="'.esc_attr(__('Restore default plugin options? You will lose all of your current settings! Are you absolutely sure about this?', 'rapid-cache')).'"'.
     45             '      data-action="'.esc_attr(add_query_arg(urlencode_deep(['page' => MEGAOPTIM_RAPID_CACHE_GLOBAL_NS, '_wpnonce' => wp_create_nonce(), MEGAOPTIM_RAPID_CACHE_GLOBAL_NS => ['restoreDefaultOptions' => '1']]), self_admin_url('/admin.php'))).'">'.
     46             '      '.__('Restore', 'rapid-cache').' <i class="si si-ambulance"></i></button>'."\n";
     47
     48        echo '   <div class="plugin-menu-page-panel-togglers" title="'.esc_attr(__('All Panels', 'rapid-cache')).'">'."\n";
     49        echo '      <button type="button" class="plugin-menu-page-panels-open"><i class="si si-chevron-down"></i></button>'."\n";
     50        echo '      <button type="button" class="plugin-menu-page-panels-close"><i class="si si-chevron-up"></i></button>'."\n";
     51        echo '   </div>'."\n";
     52
     53        echo '  <div class="plugin-menu-page-support-links">'."\n";
     54        echo '      <a href="'.esc_attr('https://github.com/megaoptim/rapid-cache/wiki').'" target="_blank"><i class="si si-book"></i> '.__('Wiki', 'rapid-cache').'</a>'."\n";
     55        echo '      <a href="'.esc_attr('https://megaoptim.com/blog/category/rapid-cache/').'" target="_blank"><i class="si si-rss-square"></i> '.__('Blog', 'rapid-cache').'</a>'."\n";
     56        echo '      <a href="'.esc_attr('https://github.com/megaoptim/rapid-cache/wiki/Report-Issue').'" target="_blank"><i class="si si-ticket"></i> '.__('Report Issue', 'rapid-cache').'</a>'."\n";
     57        echo '   </div>'."\n";
     58
     59        echo '<div class="plugin-menu-page-version">'."\n";
     60        echo    sprintf(__('%1$s v%2$s', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME), esc_html(MEGAOPTIM_RAPID_CACHE_VERSION))."\n";
     61        echo    '(<a href="'.esc_attr('https://wordpress.org/plugins/rapid-cache/#developers').'" target="_blank">'.__('changelog', 'rapid-cache').'</a>)'."\n";
     62        echo '</div>'."\n";
     63        echo '    <img src="'.$this->plugin->url('/assets/images/options-logo.png').'" alt="'.esc_attr(__('Plugin Options', 'rapid-cache')).'" />'."\n";
     64
     65        echo '<div style="clear:both;"></div>'."\n";
     66
     67        echo '</div>'."\n";
     68
     69        /* ----------------------------------------------------------------------------------------- */
     70
     71        echo '<hr />'."\n";
     72
     73        /* ----------------------------------------------------------------------------------------- */
     74
     75        if (!empty($_REQUEST[MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_updated'])) {
     76            echo '<div class="plugin-menu-page-notice notice">'."\n";
     77            echo '   <i class="si si-thumbs-up"></i> '.__('Options updated successfully.', 'rapid-cache')."\n";
     78            echo '</div>'."\n";
     79        }
     80        if (!empty($_REQUEST[MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_restored'])) {
     81            echo '<div class="plugin-menu-page-notice notice">'."\n";
     82            echo '   <i class="si si-thumbs-up"></i> '.__('Default options successfully restored.', 'rapid-cache')."\n";
     83            echo '</div>'."\n";
     84        }
     85        if (!empty($_REQUEST[MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_migrated'])) {
     86            echo '<div class="plugin-menu-page-notice notice">'."\n";
     87            echo '   <i class="si si-thumbs-up"></i> '.sprintf(__('Legacy %s options preserved successfully!', 'rapid-cache'), '<strong>'.MEGAOPTIM_RAPID_CACHE_OLD_NAME.'</strong>')."\n";
     88            echo '</div>'."\n";
     89        }
     90        if (!empty($_REQUEST[MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_cache_wiped'])) {
     91            echo '<div class="plugin-menu-page-notice notice">'."\n";
     92            echo '   <img src="'.esc_attr($this->plugin->url('/assets/images/wipe.png')).'" /> '.__('Cache wiped across all sites; re-creation will occur automatically over time.', 'rapid-cache')."\n";
     93            echo '</div>'."\n";
     94        }
     95        if (!empty($_REQUEST[MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_cache_cleared'])) {
     96            echo '<div class="plugin-menu-page-notice notice">'."\n";
     97            if (is_multisite() && is_main_site()) {
     98                echo '<img src="'.esc_attr($this->plugin->url('/assets/images/clear.png')).'" /> '.__('Cache cleared for main site; re-creation will occur automatically over time.', 'rapid-cache')."\n";
     99            } else {
     100                echo '<img src="'.esc_attr($this->plugin->url('/assets/images/clear.png')).'" /> '.__('Cache cleared for this site; re-creation will occur automatically over time.', 'rapid-cache')."\n";
     101            }
     102            echo '</div>'."\n";
     103        }
     104        if (!empty($_REQUEST[MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_wp_htaccess_add_failure'])) {
     105            echo '<div class="plugin-menu-page-notice error">'."\n";
     106            echo '   <i class="si si-thumbs-down"></i> '.sprintf(__('Failed to update your <code>/.htaccess</code> file automatically. Most likely a permissions error. Please make sure it has permissions <code>644</code> or higher (perhaps <code>666</code>). Once you\'ve done this, please try saving the %1$s options again.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME))."\n";
     107            echo '</div>'."\n";
     108        }
     109        if (!empty($_REQUEST[MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_wp_htaccess_remove_failure'])) {
     110            echo '<div class="plugin-menu-page-notice error">'."\n";
     111            echo '   <i class="si si-thumbs-down"></i> '.sprintf(__('Failed to update your <code>/.htaccess</code> file automatically. Most likely a permissions error. Please make sure it has permissions <code>644</code> or higher (perhaps <code>666</code>). Once you\'ve done this, please try saving the %1$s options again.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME))."\n";
     112            echo '</div>'."\n";
     113        }
     114        if (!empty($_REQUEST[MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_wp_htaccess_nginx_notice'])) {
     115            echo '<div class="plugin-menu-page-notice error">'."\n";
     116            echo '   <i class="si si-thumbs-down"></i> '.__('It appears that your server is running NGINX and does not support <code>.htaccess</code> rules. Please <a href="https://github.com/megaoptim/rapid-cache/wiki/Recommended-Nginx-Configuration-for-Rapid-Cache" target="_new">update your server configuration manually</a>. If you\'ve already updated your NGINX configuration, you can safely <a href="https://github.com/megaoptim/rapid-cache/wiki/How-to-disable-the-Nginx-htaccess-notice" target="_new">ignore this message</a>.', 'rapid-cache')."\n";
     117            echo '</div>'."\n";
     118        }
     119        if (!empty($_REQUEST[MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_wp_config_wp_cache_add_failure'])) {
     120            echo '<div class="plugin-menu-page-notice error">'."\n";
     121            echo '   <i class="si si-thumbs-down"></i> '.__('Failed to update your <code>/wp-config.php</code> file automatically. Please add the following line to your <code>/wp-config.php</code> file (right after the opening <code>&lt;?php</code> tag; on it\'s own line). <pre class="code"><code>define( \'WP_CACHE\', true );</code></pre>', 'rapid-cache')."\n";
     122            echo '</div>'."\n";
     123        }
     124        if (!empty($_REQUEST[MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_wp_config_wp_cache_remove_failure'])) {
     125            echo '<div class="plugin-menu-page-notice error">'."\n";
     126            echo '   <i class="si si-thumbs-down"></i> '.__('Failed to update your <code>/wp-config.php</code> file automatically. Please remove the following line from your <code>/wp-config.php</code> file, or set <code>WP_CACHE</code> to a <code>FALSE</code> value. <pre class="code"><code>define( \'WP_CACHE\', true );</code></pre>', 'rapid-cache')."\n";
     127            echo '</div>'."\n";
     128        }
     129        if (!empty($_REQUEST[MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_advanced_cache_add_failure'])) {
     130            echo '<div class="plugin-menu-page-notice error">'."\n";
     131            if ($_REQUEST[MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_advanced_cache_add_failure'] === 'advanced-cache') {
     132                echo '<i class="si si-thumbs-down"></i> '.sprintf(__('Failed to update your <code>/wp-content/advanced-cache.php</code> file. Cannot write file: <code>%1$s/%2$s-advanced-cache</code>. Please be sure this directory exists (and that it\'s writable): <code>%1$s</code>. Please use directory permissions <code>755</code> or higher (perhaps <code>777</code>). Once you\'ve done this, please try again.', 'rapid-cache'), esc_html($this->plugin->cacheDir()), esc_html(mb_strtolower(MEGAOPTIM_RAPID_CACHE_SHORT_NAME)))."\n";
     133            } else {
     134                echo '<i class="si si-thumbs-down"></i> '.__('Failed to update your <code>/wp-content/advanced-cache.php</code> file. Most likely a permissions error. Please create an empty file here: <code>/wp-content/advanced-cache.php</code> (just an empty PHP file, with nothing in it); give it permissions <code>644</code> or higher (perhaps <code>666</code>). Once you\'ve done this, please try again.', 'rapid-cache')."\n";
     135            }
     136            echo '</div>'."\n";
     137        }
     138        if (!empty($_REQUEST[MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_advanced_cache_remove_failure'])) {
     139            echo '<div class="plugin-menu-page-notice error">'."\n";
     140            echo '   <i class="si si-thumbs-down"></i> '.__('Failed to remove your <code>/wp-content/advanced-cache.php</code> file. Most likely a permissions error. Please delete (or empty the contents of) this file: <code>/wp-content/advanced-cache.php</code>.', 'rapid-cache')."\n";
     141            echo '</div>'."\n";
     142        }
     143        if (!empty($_REQUEST[MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_ua_info_dir_population_failure'])) {
     144            echo '<div class="plugin-menu-page-notice error">'."\n";
     145            echo '   <i class="si si-thumbs-down"></i> '.sprintf(__('Failed to populate User-Agent detection files for Mobile-Adaptive Mode. User-Agent detection files are pulled from a remote location so you\'ll always have the most up-to-date information needed for accurate detection. However, it appears the remote source of this information is currently unvailable. Please wait 15 minutes, then try saving your %1$s options again.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME))."\n";
     146            echo '</div>'."\n";
     147        }
     148        if (!$this->plugin->options['enable']) {
     149            echo '<div class="plugin-menu-page-notice warning">'."\n";
     150            echo '   <i class="si si-warning"></i> '.sprintf(__('%1$s is currently disabled; please review options below.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME))."\n";
     151            echo '</div>'."\n";
     152        }
     153        /* ----------------------------------------------------------------------------------------- */
     154
     155        echo '<div class="plugin-menu-page-body">'."\n";
     156
     157        /* ----------------------------------------------------------------------------------------- */
     158
     159        echo '<h2 class="plugin-menu-page-section-heading">'.
     160             '  '.__('Basic Configuration (Required)', 'rapid-cache').
     161             '  <small><span>'.sprintf(__('Review these basic options and %1$s will be ready-to-go!', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</span></small>'.
     162             '</h2>';
     163
     164        /* --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
     165
     166        echo '<div class="plugin-menu-page-panel">'."\n";
     167
     168        echo '   <a href="#" class="plugin-menu-page-panel-heading'.((!$this->plugin->options['enable']) ? ' open' : '').'">'."\n";
     169        echo '      <i class="si si-enty-gauge"></i> '.__('Enable/Disable', 'rapid-cache')."\n";
     170        echo '   </a>'."\n";
     171
     172        echo '   <div class="plugin-menu-page-panel-body'.((!$this->plugin->options['enable']) ? ' open' : '').' clearfix">'."\n";
     173        echo '      <p class="speed"><img src="'.esc_attr($this->plugin->url('/assets/images/tach.png')).'" style="float:right; width:100px; margin-left:1em;" />'.sprintf(__('%1$s = SPEED<em>!!</em>', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
     174        echo '      <p><label class="switch-primary"><input type="radio" name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][enable]" value="1"'.checked($this->plugin->options['enable'], '1', false).' /> '.sprintf(__('Yes, enable %1$s', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).' <i class="si si-magic si-flip-horizontal"></i></label> &nbsp;&nbsp;&nbsp; <label><input type="radio" name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][enable]" value="0"'.checked($this->plugin->options['enable'], '0', false).' /> '.__('No, disable.', 'rapid-cache').'</label></p>'."\n";
     175        echo '      <p class="info" style="font-family:\'Georgia\', serif; font-size:110%; margin-top:1.5em;">'.sprintf(__('<strong>HUGE Time-Saver:</strong> Approx. 95%% of all WordPress sites running %1$s, simply enable it here; and that\'s it :-) <strong>No further configuration is necessary (really).</strong> All of the other options (down below) are already tuned for the BEST performance on a typical WordPress installation. Simply enable %1$s here and click "Save All Changes". If you get any warnings please follow the instructions given. Otherwise, you\'re good <i class="si si-smile-o"></i>. This plugin is designed to run just fine like it is. Take it for a spin right away; you can always fine-tune things later if you deem necessary.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
     176        echo '      <hr />'."\n";
     177        echo '      <img src="'.esc_attr($this->plugin->url('/assets/images/source-code-ss.png')).'" class="screenshot" />'."\n";
     178        echo '      <h3>'.sprintf(__('How Can I Tell %1$s is Working?', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</h3>'."\n";
     179        echo '      <p>'.sprintf(__('First of all, please make sure that you\'ve enabled %1$s here; then scroll down to the bottom of this page and click "Save All Changes". All of the other options (below) are already pre-configured for typical usage. Feel free to skip them all for now. You can go back through all of these later and fine-tune things the way you like them.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
     180        echo '      <p>'.sprintf(__('Once %1$s has been enabled, <strong>you\'ll need to log out (and/or clear browser cookies)</strong>. By default, cache files are NOT served to visitors who are logged-in, and that includes you too ;-) Cache files are NOT served to recent comment authors either. If you\'ve commented (or replied to a comment lately); please clear your browser cookies before testing.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
     181        echo '      <p>'.sprintf(__('<strong>To verify that %1$s is working</strong>, navigate your site like a normal visitor would. Right-click on any page (choose View Source), then scroll to the very bottom of the document. At the bottom, you\'ll find comments that show %1$s stats and information. You should also notice that page-to-page navigation is <i class="si si-flash"></i> <strong>lightning fast</strong> now that %1$s is running; and it gets faster over time!', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
     182        echo '      <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][debugging_enable]" class="-no-if-enabled">'."\n";
     183        echo '            <option value="1"'.selected($this->plugin->options['debugging_enable'], '1', false).'>'.__('Yes, enable notes in the source code so I can see it\'s working (recommended).', 'rapid-cache').'</option>'."\n";
     184        echo '            <option value="2"'.selected($this->plugin->options['debugging_enable'], '2', false).'>'.__('Yes, enable notes in the source code AND show debugging details (not recommended for production).', 'rapid-cache').'</option>'."\n";
     185        echo '            <option value="0"'.selected($this->plugin->options['debugging_enable'], '0', false).'>'.__('No, I don\'t want my source code to contain any of these notes.', 'rapid-cache').'</option>'."\n";
     186        echo '         </select></p>'."\n";
     187        echo '   </div>'."\n";
     188
     189        echo '</div>'."\n";
     190
     191        /* ----------------------------------------------------------------------------------------- */
     192
     193        echo '<div class="plugin-menu-page-panel">'."\n";
     194
     195        echo '   <a href="#" class="plugin-menu-page-panel-heading">'."\n";
     196        echo '      <i class="si si-shield"></i> '.__('Plugin Deletion Safeguards', 'rapid-cache')."\n";
     197        echo '   </a>'."\n";
     198
     199        echo '   <div class="plugin-menu-page-panel-body clearfix">'."\n";
     200        echo '      <i class="si si-shield si-4x" style="float:right; margin: 0 0 0 25px;"></i>'."\n";
     201        echo '      <h3>'.__('Uninstall on Plugin Deletion; or Safeguard Options?', 'rapid-cache').'</h3>'."\n";
     202        echo '      <p>'.sprintf(__('<strong>Tip:</strong> By default, if you delete %1$s using the plugins menu in WordPress, nothing is lost. However, if you want to completely uninstall %1$s you should set this to <code>Yes</code> and <strong>THEN</strong> deactivate &amp; delete %1$s from the plugins menu in WordPress. This way %1$s will erase your options for the plugin, erase directories/files created by the plugin, remove the <code>advanced-cache.php</code> file, terminate CRON jobs, etc. It erases itself from existence completely.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
     203        echo '      <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][uninstall_on_deletion]">'."\n";
     204        echo '            <option value="0"'.selected($this->plugin->options['uninstall_on_deletion'], '0', false).'>'.__('Safeguard my options and the cache (recommended).', 'rapid-cache').'</option>'."\n";
     205        echo '            <option value="1"'.selected($this->plugin->options['uninstall_on_deletion'], '1', false).'>'.sprintf(__('Yes, uninstall (completely erase) %1$s on plugin deletion.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</option>'."\n";
     206        echo '         </select></p>'."\n";
     207        echo '   </div>'."\n";
     208
     209        echo '</div>'."\n";
     210
     211        /* ----------------------------------------------------------------------------------------- */
     212
     213        echo '<h2 class="plugin-menu-page-section-heading">'.
     214             '  '.__('Advanced Configuration (All Optional)', 'rapid-cache').
     215             '  <small>'.__('Recommended for advanced site owners only; already pre-configured for most WP installs.', 'rapid-cache').'</small>'.
     216             '</h2>';
     217
     218        /* --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
     219
     220        echo '<div class="plugin-menu-page-panel">'."\n";
     221
     222        echo '   <a href="#" class="plugin-menu-page-panel-heading">'."\n";
     223        echo '      <i class="si si-server"></i> '.__('Automatic Cache Clearing', 'rapid-cache')."\n";
     224        echo '   </a>'."\n";
     225
     226        echo '   <div class="plugin-menu-page-panel-body clearfix">'."\n";
     227
     228        echo '      <h3>'.__('Clearing the Cache Automatically', 'rapid-cache').'</h3>'."\n";
     229        echo '      <img src="'.esc_attr($this->plugin->url('/assets/images/auto-clear-ss.png')).'" class="screenshot" />'."\n";
     230        echo '      <p>'.sprintf(__('This is built into the %1$s plugin; i.e., this functionality is "always on". If you edit a Post/Page (or delete one), %1$s will automatically clear the cache file(s) associated with that content. This way a new updated version of the cache will be created automatically the next time this content is accessed. Simple updates like this occur each time you make changes in the Dashboard, and %1$s will notify you of these as they occur. %1$s monitors changes to Posts (of any kind, including Pages), Categories, Tags, Links, Themes (even Users), and more.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
     231        echo '      <hr />'."\n";
     232        echo '      <h3>'.__('Primary Page Options', 'rapid-cache').'</h3>'."\n";
     233
     234        echo '      <h4 style="margin-bottom:0;">'.__('Auto-Clear Designated "Home Page" Too?', 'rapid-cache').'</h4>'."\n";
     235        echo '      <p style="margin-top:2px;">'.sprintf(__('On many sites, the Home Page (aka: the Front Page) offers an archive view of all Posts (or even Pages). Therefore, if a single Post/Page is changed in some way; and %1$s clears/resets the cache for a single Post/Page, would you like %1$s to also clear any existing cache files for the "Home Page"?', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
     236        echo '      <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][cache_clear_home_page_enable]" class="-no-if-enabled">'."\n";
     237        echo '            <option value="1"'.selected($this->plugin->options['cache_clear_home_page_enable'], '1', false).'>'.__('Yes, if any single Post/Page is cleared/reset; also clear the "Home Page".', 'rapid-cache').'</option>'."\n";
     238        echo '            <option value="0"'.selected($this->plugin->options['cache_clear_home_page_enable'], '0', false).'>'.__('No, my Home Page does not provide a list of Posts/Pages; e.g., this is not necessary.', 'rapid-cache').'</option>'."\n";
     239        echo '         </select></p>'."\n";
     240        echo '      <h4 style="margin-bottom:0;">'.__('Auto-Clear Designated "Posts Page" Too?', 'rapid-cache').'</h4>'."\n";
     241        echo '      <p style="margin-top:2px;">'.sprintf(__('On many sites, the Posts Page (aka: the Blog Page) offers an archive view of all Posts (or even Pages). Therefore, if a single Post/Page is changed in some way; and %1$s clears/resets the cache for a single Post/Page, would you like %1$s to also clear any existing cache files for the "Posts Page"?', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
     242        echo '      <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][cache_clear_posts_page_enable]" class="-no-if-enabled">'."\n";
     243        echo '            <option value="1"'.selected($this->plugin->options['cache_clear_posts_page_enable'], '1', false).'>'.__('Yes, if any single Post/Page is cleared/reset; also clear the "Posts Page".', 'rapid-cache').'</option>'."\n";
     244        echo '            <option value="0"'.selected($this->plugin->options['cache_clear_posts_page_enable'], '0', false).'>'.__('No, I don\'t use a separate Posts Page; e.g., my Home Page IS my Posts Page.', 'rapid-cache').'</option>'."\n";
     245        echo '         </select></p>'."\n";
     246
     247        echo '      <hr />'."\n";
     248        echo '      <h3>'.__('Author, Archive, and Tag/Term Options', 'rapid-cache').'</h3>'."\n";
     249
     250        echo '      <h4 style="margin-bottom:0;">'.__('Auto-Clear "Author Page" Too?', 'rapid-cache').'</h4>'."\n";
     251        echo '      <p style="margin-top:2px;">'.sprintf(__('On many sites, each author has a related "Author Page" that offers an archive view of all posts associated with that author. Therefore, if a single Post/Page is changed in some way; and %1$s clears/resets the cache for a single Post/Page, would you like %1$s to also clear any existing cache files for the related "Author Page"?', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
     252        echo '      <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][cache_clear_author_page_enable]" class="-no-if-enabled">'."\n";
     253        echo '            <option value="1"'.selected($this->plugin->options['cache_clear_author_page_enable'], '1', false).'>'.__('Yes, if any single Post/Page is cleared/reset; also clear the "Author Page".', 'rapid-cache').'</option>'."\n";
     254        echo '            <option value="0"'.selected($this->plugin->options['cache_clear_author_page_enable'], '0', false).'>'.__('No, my site doesn\'t use multiple authors and/or I don\'t have any "Author Page" archive views.', 'rapid-cache').'</option>'."\n";
     255        echo '         </select></p>'."\n";
     256
     257        echo '      <h4 style="margin-bottom:0;">'.__('Auto-Clear "Category Archives" Too?', 'rapid-cache').'</h4>'."\n";
     258        echo '      <p style="margin-top:2px;">'.sprintf(__('On many sites, each post is associated with at least one Category. Each category then has an archive view that contains all the posts within that category. Therefore, if a single Post/Page is changed in some way; and %1$s clears/resets the cache for a single Post/Page, would you like %1$s to also clear any existing cache files for the associated Category archive views?', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
     259        echo '      <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][cache_clear_term_category_enable]" class="-no-if-enabled">'."\n";
     260        echo '            <option value="1"'.selected($this->plugin->options['cache_clear_term_category_enable'], '1', false).'>'.__('Yes, if any single Post/Page is cleared/reset; also clear the associated Category archive views.', 'rapid-cache').'</option>'."\n";
     261        echo '            <option value="0"'.selected($this->plugin->options['cache_clear_term_category_enable'], '0', false).'>'.__('No, my site doesn\'t use Categories and/or I don\'t have any Category archive views.', 'rapid-cache').'</option>'."\n";
     262        echo '         </select></p>'."\n";
     263
     264        echo '      <h4 style="margin-bottom:0;">'.__('Auto-Clear "Tag Archives" Too?', 'rapid-cache').'</h4>'."\n";
     265        echo '      <p style="margin-top:2px;">'.sprintf(__('On many sites, each post may be associated with at least one Tag. Each tag then has an archive view that contains all the posts assigned that tag. Therefore, if a single Post/Page is changed in some way; and %1$s clears/resets the cache for a single Post/Page, would you like %1$s to also clear any existing cache files for the associated Tag archive views?', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
     266        echo '      <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][cache_clear_term_post_tag_enable]" class="-no-if-enabled">'."\n";
     267        echo '            <option value="1"'.selected($this->plugin->options['cache_clear_term_post_tag_enable'], '1', false).'>'.__('Yes, if any single Post/Page is cleared/reset; also clear the associated Tag archive views.', 'rapid-cache').'</option>'."\n";
     268        echo '            <option value="0"'.selected($this->plugin->options['cache_clear_term_post_tag_enable'], '0', false).'>'.__('No, my site doesn\'t use Tags and/or I don\'t have any Tag archive views.', 'rapid-cache').'</option>'."\n";
     269        echo '         </select></p>'."\n";
     270
     271        echo '      <h4 style="margin-bottom:0;">'.__('Auto-Clear "Date-Based Archives" Too?', 'rapid-cache').'</h4>'."\n";
     272        echo '      <p style="margin-top:2px;">'.sprintf(__('Date-Based Archives allow visitors to browse Posts by the year, month, or day they were originally published. If a single Post (of any type) is changed in some way; and %1$s clears/resets the cache for that Post, would you like %1$s to also clear any existing cache files for Dated-Based Archives that match the publication time?', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
     273        echo '      <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][cache_clear_date_archives_enable]" class="-no-if-enabled">'."\n";
     274        echo '            <option value="1"'.selected($this->plugin->options['cache_clear_date_archives_enable'], '1', false).'>'.__('Yes, if any single Post is cleared/reset, also clear the associated Date archive views.', 'rapid-cache').'</option>'."\n";
     275        echo '            <option value="2"'.selected($this->plugin->options['cache_clear_date_archives_enable'], '2', false).'>'.__('Yes, but only clear the associated Day and Month archive views.', 'rapid-cache').'</option>'."\n";
     276        echo '            <option value="3"'.selected($this->plugin->options['cache_clear_date_archives_enable'], '3', false).'>'.__('Yes, but only clear the associated Day archive view.', 'rapid-cache').'</option>'."\n";
     277        echo '            <option value="0"'.selected($this->plugin->options['cache_clear_date_archives_enable'], '0', false).'>'.__('No, don\'t clear any associated Date archive views.', 'rapid-cache').'</option>'."\n";
     278        echo '         </select></p>'."\n";
     279
     280        echo '      <h4 style="margin-bottom:0;">'.__('Auto-Clear "Custom Term Archives" Too?', 'rapid-cache').'</h4>'."\n";
     281        echo '      <p style="margin-top:2px;">'.sprintf(__('Most sites do not use any custom Terms so it should be safe to leave this disabled. However, if your site uses custom Terms and they have their own Term archive views, you may want to clear those when the associated post is cleared. Therefore, if a single Post/Page is changed in some way; and %1$s clears/resets the cache for a single Post/Page, would you like %1$s to also clear any existing cache files for the associated Tag archive views?', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
     282        echo '      <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][cache_clear_term_other_enable]" class="-no-if-enabled">'."\n";
     283        echo '            <option value="1"'.selected($this->plugin->options['cache_clear_term_other_enable'], '1', false).'>'.__('Yes, if any single Post/Page is cleared/reset; also clear any associated custom Term archive views.', 'rapid-cache').'</option>'."\n";
     284        echo '            <option value="0"'.selected($this->plugin->options['cache_clear_term_other_enable'], '0', false).'>'.__('No, my site doesn\'t use any custom Terms and/or I don\'t have any custom Term archive views.', 'rapid-cache').'</option>'."\n";
     285        echo '         </select></p>'."\n";
     286
     287        echo '      <h4 style="margin-bottom:0;">'.__('Auto-Clear "Custom Post Type Archives" Too?', 'rapid-cache').'</h4>'."\n";
     288        echo '      <p style="margin-top:2px;">'.sprintf(__('Most sites do not use any Custom Post Types so it should be safe to disable this option. However, if your site uses Custom Post Types and they have their own Custom Post Type archive views, you may want to clear those when any associated post is cleared. Therefore, if a single Post with a Custom Post Type is changed in some way; and %1$s clears/resets the cache for that post, would you like %1$s to also clear any existing cache files for the associated Custom Post Type archive views?', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
     289        echo '      <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][cache_clear_custom_post_type_enable]" class="-no-if-enabled">'."\n";
     290        echo '            <option value="1"'.selected($this->plugin->options['cache_clear_custom_post_type_enable'], '1', false).'>'.__('Yes, if any single Post with a Custom Post Type is cleared/reset; also clear any associated Custom Post Type archive views.', 'rapid-cache').'</option>'."\n";
     291        echo '            <option value="0"'.selected($this->plugin->options['cache_clear_custom_post_type_enable'], '0', false).'>'.__('No, my site doesn\'t use any Custom Post Types and/or I don\'t have any Custom Post Type archive views.', 'rapid-cache').'</option>'."\n";
     292        echo '         </select></p>'."\n";
     293
     294        echo '      <hr />'."\n";
     295        echo '      <h3>'.__('Feed-Related Options', 'rapid-cache').'</h3>'."\n";
     296
     297        echo '      <h4 style="margin-bottom:0;">'.__('Auto-Clear "RSS/RDF/ATOM Feeds" Too?', 'rapid-cache').'</h4>'."\n";
     298        echo '      <p style="margin-top:2px;">'.sprintf(__('If you enable Feed Caching (below), this can be quite handy. If enabled, when you update a Post/Page, approve a Comment, or make other changes where %1$s can detect that certain types of Feeds should be cleared to keep your site up-to-date, then %1$s will do this for you automatically. For instance, the blog\'s master feed, the blog\'s master comments feed, feeds associated with comments on a Post/Page, term-related feeds (including mixed term-related feeds), author-related feeds, etc. Under various circumstances (i.e., as you work in the Dashboard) these can be cleared automatically to keep your site up-to-date.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
     299        echo '      <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][cache_clear_xml_feeds_enable]" class="-no-if-enabled">'."\n";
     300        echo '            <option value="1"'.selected($this->plugin->options['cache_clear_xml_feeds_enable'], '1', false).'>'.__('Yes, automatically clear RSS/RDF/ATOM Feeds from the cache when certain changes occur.', 'rapid-cache').'</option>'."\n";
     301        echo '            <option value="0"'.selected($this->plugin->options['cache_clear_xml_feeds_enable'], '0', false).'>'.__('No, I don\'t have Feed Caching enabled, or I prefer not to automatically clear Feeds.', 'rapid-cache').'</option>'."\n";
     302        echo '         </select></p>'."\n";
     303
     304        echo '      <hr />'."\n";
     305        echo '      <h3>'.__('Sitemap-Related Options', 'rapid-cache').'</h3>'."\n";
     306
     307        echo '      <h4 style="margin-bottom:0;">'.__('Auto-Clear "XML Sitemaps" Too?', 'rapid-cache').'</h4>'."\n";
     308        echo '      <p style="margin-top:2px;">'.sprintf(__('If you\'re generating XML Sitemaps with a plugin like <a href="http://wordpress.org/plugins/google-sitemap-generator/" target="_blank">Google XML Sitemaps</a>, you can tell %1$s to automatically clear the cache of any XML Sitemaps whenever it clears a Post/Page. Note: This does NOT clear the XML Sitemap itself of course, only the cache. The point being, to clear the cache and allow changes to a Post/Page to be reflected by a fresh copy of your XML Sitemap; sooner rather than later.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
     309        echo '      <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][cache_clear_xml_sitemaps_enable]" data-target=".-cache-clear-xml-sitemap-patterns">'."\n";
     310        echo '            <option value="1"'.selected($this->plugin->options['cache_clear_xml_sitemaps_enable'], '1', false).'>'.__('Yes, if any single Post/Page is cleared/reset; also clear the cache for any XML Sitemaps.', 'rapid-cache').'</option>'."\n";
     311        echo '            <option value="0"'.selected($this->plugin->options['cache_clear_xml_sitemaps_enable'], '0', false).'>'.__('No, my site doesn\'t use any XML Sitemaps and/or I prefer NOT to clear the cache for XML Sitemaps.', 'rapid-cache').'</option>'."\n";
     312        echo '         </select></p>'."\n";
     313        echo '      <div class="plugin-menu-page-panel-if-enabled -cache-clear-xml-sitemap-patterns">'."\n";
     314        echo '          <p>'.__('<strong style="font-size:110%;">XML Sitemap Patterns (one per line):</strong> A default value of <code>/sitemap**.xml</code> covers all XML Sitemaps for most installations. However, you may customize this further if you deem necessary. Please list one pattern per line. XML Sitemap Pattern searches are performed against the <a href="https://gist.github.com/jaswsinc/338b6eb03a36c048c26f" target="_blank">REQUEST_URI</a>. A wildcard <code>**</code> (double asterisk) can be used when necessary; e.g., <code>/sitemap**.xml</code>. Note that <code>**</code> = 0 or more characters of any kind, including <code>/</code> slashes. <code>*</code> (a single asterisk) means 0 or more characters that are NOT a slash <code>/</code>. Your patterns must match from beginning to end; i.e., the special chars: <code>^</code> (beginning of string) and <code>$</code> (end of the string) are always on for these patterns (i.e., applied internally). For that reason, if you want to match part of a URI, use <code>**</code> to match anything before and/or after the fragment you\'re searching for. For example, <code>**/sitemap**.xml</code> will match any URI containing <code>/sitemap</code> (anywhere), so long as the URI also ends with <code>.xml</code>. On the other hand, <code>/sitemap*.xml</code> will only match URIs that begin with <code>/sitemap</code>, and it will only match URIs ending in <code>.xml</code> in that immediate directory — bypassing any inside nested sub-directories. To learn more about this syntax, please see <a href="https://github.com/megaoptim/rapid-cache/wiki/Watered-Down-Regex-Syntax" target="_blank">this KB article</a>.', 'rapid-cache').'</p>'."\n";
     315        echo '          <p><textarea name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][cache_clear_xml_sitemap_patterns]" rows="5" spellcheck="false" class="monospace">'.format_to_edit($this->plugin->options['cache_clear_xml_sitemap_patterns']).'</textarea></p>'."\n";
     316        if (is_multisite()) {
     317            echo '      <p class="info" style="display:block; margin-top:-15px;">'.__('In a Multisite Network, each child blog (whether it be a sub-domain, a sub-directory, or a mapped domain); will automatically change the leading <code>http://[sub.]domain/[sub-directory]</code> used in pattern matching. In short, there is no need to add sub-domains or sub-directories for each child blog in these patterns. Please include only the <a href="https://gist.github.com/jaswsinc/338b6eb03a36c048c26f" target="_blank">REQUEST_URI</a> (i.e., the path) which leads to the XML Sitemap on all child blogs in the network.', 'rapid-cache').'</p>'."\n";
     318        }
     319        echo '      </div>' . "\n";
     320        echo '      <hr />' . "\n";
     321        echo '      <h3>' . __( 'Misc. Auto-Clear Options', 'rapid-cache' ) . '</h3>' . "\n";
     322        echo '      <h4 style="margin-bottom:0;">' . __( 'Auto-Clear Custom URL Patterns Too?', 'rapid-cache' ) . '</h4>' . "\n";
     323        echo '      <p style="margin-top:2px;">' . sprintf( __( '<strong>Auto-Clear Custom URL Patterns (one per line):</strong> When you update a Post/Page, approve a Comment, etc., %1$s will detect that a Post/Page cache should be cleared to keep your site up-to-date. When this occurs, %1$s can also clear a list of custom URLs that you enter here. Please list one URL per line. A wildcard <code>*</code> character can be used when necessary; e.g., <code>https://example.com/category/abc/**</code>. Note that <code>**</code> (double asterisk) means 0 or more characters of any kind, including <code>/</code> slashes. <code>*</code> (a single asterisk) means 0 or more characters that are NOT a slash <code>/</code>. Your patterns must match from beginning to end; i.e., the special chars: <code>^</code> (beginning of string) and <code>$</code> (end of the string) are always on for these patterns (i.e., applied internally). For that reason, if you want to match part of a URL, use <code>**</code> to match anything before and/or after the fragment you\'re searching for. For example, <code>https://**/category/abc/**</code> will find all URLs containing <code>/category/abc/</code> (anywhere); whereas <code>https://*/category/abc/*</code> will match URLs on any domain, but the path must then begin with <code>/category/abc/</code> and the pattern will only match paths in that immediate directory — bypassing any additional paths in sub-directories. To learn more about this syntax, please see <a href="https://github.com/megaoptim/rapid-cache/wiki/Watered-Down-Regex-Syntax" target="_blank">this KB article</a>.', 'rapid-cache' ), esc_html( MEGAOPTIM_RAPID_CACHE_NAME ) ) . '</p>' . "\n";
     324        echo '      <p><textarea name="' . esc_attr( MEGAOPTIM_RAPID_CACHE_GLOBAL_NS ) . '[saveOptions][cache_clear_urls]" spellcheck="false" wrap="off" rows="5">' . format_to_edit( $this->plugin->options['cache_clear_urls'] ) . '</textarea></p>' . "\n";
     325        echo '      <p class="info" style="display:block;">' . __( '<strong>Note:</strong> Relative URLs (e.g., <code>/name-of-post</code>) should NOT be used. Each entry above should start with <code>http://</code> or <code>https://</code> and include a fully qualified domain name (or wildcard characters in your pattern that will match the domain).', 'rapid-cache' ) . '</p>' . "\n";
     326        echo '   </div>' . "\n";
     327
     328        echo '</div>'."\n";
     329
     330        /* ----------------------------------------------------------------------------------------- */
     331
     332        echo '<div class="plugin-menu-page-panel">'."\n";
     333
     334        echo '   <a href="#" class="plugin-menu-page-panel-heading">'."\n";
     335        echo '      <i class="si si-folder-open"></i> '.__('Cache Directory', 'rapid-cache')."\n";
     336        echo '   </a>'."\n";
     337
     338        echo '   <div class="plugin-menu-page-panel-body clearfix">'."\n";
     339        echo '      <h3>'.__('Base Cache Directory (Must be Writable; i.e., <a href="https://wordpress.org/support/article/changing-file-permissions/" target="_blank">Permissions</a> <code>755</code> or Higher)', 'rapid-cache').'</h3>'."\n";
     340        echo '      <p>'.sprintf(__('This is where %1$s will store the cached version of your site. If you\'re not sure how to deal with directory permissions, don\'t worry too much about this. If there is a problem, %1$s will let you know about it. By default, this directory is created by %1$s and the permissions are setup automatically. In most cases there is nothing more you need to do.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
     341        echo '      <table style="width:100%;"><tr><td style="width:1px; font-weight:bold; white-space:pre;">'.esc_html(WP_CONTENT_DIR).'/</td><td><input type="text" name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][base_dir]" value="'.esc_attr($this->plugin->options['base_dir']).'" /></td><td style="width:1px; font-weight:bold; white-space:pre;">/</td></tr></table>'."\n";
     342        echo '   </div>'."\n";
     343
     344        echo '</div>'."\n";
     345
     346        /* ----------------------------------------------------------------------------------------- */
     347
     348        echo '<div class="plugin-menu-page-panel">'."\n";
     349
     350        echo '   <a href="#" class="plugin-menu-page-panel-heading">'."\n";
     351        echo '      <i class="si si-clock-o"></i> '.__('Cache Expiration Time', 'rapid-cache')."\n";
     352        echo '   </a>'."\n";
     353
     354        echo '   <div class="plugin-menu-page-panel-body clearfix">'."\n";
     355        echo '      <i class="si si-clock-o si-4x" style="float:right; margin: 0 0 0 25px;"></i>'."\n";
     356        echo '      <h3>'.__('Automatic Expiration Time (Max Age)', 'rapid-cache').'</h3>'."\n";
     357        echo '      <p>'.__('If you don\'t update your site much, you could set this to <code>6 months</code> and optimize everything even further. The longer the Cache Expiration Time is, the greater your performance gain. Alternatively, the shorter the Expiration Time, the fresher everything will remain on your site. A default value of <code>7 days</code> (recommended); is a good conservative middle-ground.', 'rapid-cache').'</p>'."\n";
     358        echo '      <p>'.sprintf(__('Keep in mind that your Expiration Time is only one part of the big picture. %1$s will also clear the cache automatically as changes are made to the site (i.e., you edit a post, someone comments on a post, you change your theme, you add a new navigation menu item, etc., etc.). Thus, your Expiration Time is really just a fallback; e.g., the maximum amount of time that a cache file could ever possibly live.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
     359        echo '      <p>'.sprintf(__('All of that being said, you could set this to just <code>60 seconds</code> and you would still see huge differences in speed and performance. If you\'re just starting out with %1$s (perhaps a bit nervous about old cache files being served to your visitors); you could set this to something like <code>30 minutes</code> and experiment with it while you build confidence in %1$s. It\'s not necessary to do so, but many site owners have reported this makes them feel like they\'re more-in-control when the cache has a short expiration time. All-in-all, it\'s a matter of preference <i class="si si-smile-o"></i>.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
     360        echo '      <p><input type="text" name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][cache_max_age]" value="'.esc_attr($this->plugin->options['cache_max_age']).'" /></p>'."\n";
     361        echo '      <p class="info">'.__('<strong>Tip:</strong> the value that you specify here MUST be compatible with PHP\'s <a href="http://php.net/manual/en/function.strtotime.php" target="_blank" style="text-decoration:none;"><code>strtotime()</code></a> function. Examples: <code>30 seconds</code>, <code>2 hours</code>, <code>7 days</code>, <code>6 months</code>, <code>1 year</code>.', 'rapid-cache').'</p>'."\n";
     362        echo '      <p class="info">'.sprintf(__('<strong>Note:</strong> %1$s will never serve a cache file that is older than what you specify here (even if one exists in your cache directory; stale cache files are never used). In addition, a WP Cron job will automatically cleanup your cache directory (once per hour); purging expired cache files periodically. This prevents a HUGE cache from building up over time, creating a potential storage issue.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
     363
     364        echo '      <hr />'."\n";
     365
     366        echo '      <h3>'.__('Cache Cleanup Schedule', 'rapid-cache').'</h3>'."\n";
     367        echo '      <p>'.sprintf(__('If you have an extremely large site and you lower the default Cache Expiration Time of <code>7 days</code>, expired cache files can build up more quickly. By default, %1$s cleans up expired cache files via <a href="https://codex.wordpress.org/Category:WP-Cron_Functions" target="_blank">WP Cron</a> at an <code>hourly</code> interval, but you can tell %1$s to use a custom Cache Cleanup Schedule below to run the cleanup process more or less frequently, depending on your specific needs.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
     368        echo '      <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][cache_cleanup_schedule]">'."\n";
     369        foreach (wp_get_schedules() as $_wp_cron_schedule_key => $_wp_cron_schedule) {
     370            echo '       <option value="'.esc_attr($_wp_cron_schedule_key).'"'.selected($this->plugin->options['cache_cleanup_schedule'], $_wp_cron_schedule_key, false).'>'.esc_html($_wp_cron_schedule['display']).'</option>'."\n";
     371        } // This builds the list of options using WP_Cron schedules configured for this WP installation.
     372        unset($_wp_cron_schedule_key, $_wp_cron_schedule);
     373        echo '      </select></p>'."\n";
     374
     375        echo '   </div>'."\n";
     376
     377        echo '</div>'."\n";
     378
     379        /* ----------------------------------------------------------------------------------------- */
     380
     381        echo '<div class="plugin-menu-page-panel">'."\n";
     382
     383        echo '   <a href="#" class="plugin-menu-page-panel-heading">'."\n";
     384        echo '      <i class="si si-sitemap"></i> '.__('Cache Preloading', 'rapid-cache')."\n";
     385        echo '   </a>'."\n";
     386
     387        echo '   <div class="plugin-menu-page-panel-body clearfix">'."\n";
     388        echo '      <i class="si si-question-circle si-4x" style="float:right; margin: 0 0 0 25px;"></i>'."\n";
     389        echo '      <h3>'.__('Enable the Auto-Cache Engine?', 'rapid-cache').'</h3>'."\n";
     390        echo '      <p>'.sprintf(__('After using %1$s for awhile (or any other page caching plugin, for that matter); it becomes obvious that at some point (based on your configured Expiration Time) %1$s has to refresh itself. It does this by ditching its cached version of a page, reloading the database-driven content, and then recreating the cache with the latest data. This is a never ending regeneration cycle that is based entirely on your configured Expiration Time.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
     391        echo '      <p>'.__('Understanding this, you can see that 99% of your visitors are going to receive a lightning fast response from your server. However, there will always be around 1% of your visitors that land on a page for the very first time (before it\'s been cached), or land on a page that needs to have its cache regenerated, because the existing cache has become outdated. We refer to this as a <em>First-Come Slow-Load Issue</em>. Not a huge problem, but if you\'re optimizing your site for every ounce of speed possible, the Auto-Cache Engine can help with this. The Auto-Cache Engine has been designed to combat this issue by taking on the responsibility of being that first visitor to a page that has not yet been cached, or has an expired cache. The Auto-Cache Engine is powered, in part, by <a href="http://codex.wordpress.org/Category:WP-Cron_Functions" target="_blank">WP-Cron</a> (already built into WordPress). The Auto-Cache Engine runs at 15-minute intervals via WP-Cron. It also uses the <a href="http://core.trac.wordpress.org/browser/trunk/wp-includes/http.php" target="_blank">WP_Http</a> class, which is also built into WordPress already.', 'rapid-cache').'</p>'."\n";
     392        echo '      <p>'.__('The Auto-Cache Engine obtains its list of URLs to auto-cache, from two different sources. It can read an <a href="http://wordpress.org/extend/plugins/google-sitemap-generator/" target="_blank">XML Sitemap</a> and/or a list of specific URLs that you supply. If you supply both sources, it will use both sources collectively. The Auto-Cache Engine takes ALL of your other configuration options into consideration too, including your Expiration Time, as well as any cache exclusion rules.', 'rapid-cache').'</p>'."\n";
     393        echo '      <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][auto_cache_enable]" data-target=".-auto-cache-options">'."\n";
     394        echo '            <option value="0"'.(selected($this->plugin->options['auto_cache_enable'], '0', false)).'>'.__('No, leave the Auto-Cache Engine disabled please.', 'rapid-cache').'</option>'."\n";
     395        echo '            <option value="1"'.(selected($this->plugin->options['auto_cache_enable'], '1', false)).'>'.__('Yes, I want the Auto-Cache Engine to keep pages cached automatically.', 'rapid-cache').'</option>'."\n";
     396        echo '         </select></p>'."\n";
     397
     398        echo '      <hr />'."\n";
     399
     400        echo '      <div class="plugin-menu-page-panel-if-enabled -auto-cache-options">'."\n";
     401        echo '         <h3>'.__('XML Sitemap URL (or an XML Sitemap Index)', 'rapid-cache').'</h3>'."\n";
     402        echo '         <table style="width:100%;"><tr><td style="width:1px; font-weight:bold; white-space:pre;">'.esc_html(home_url('/')).'</td><td><input type="text" name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][auto_cache_sitemap_url]" value="'.esc_attr($this->plugin->options['auto_cache_sitemap_url']).'" /></td></tr></table>'."\n";
     403        if (is_multisite()) {
     404            echo '      <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][auto_cache_ms_children_too]">'."\n";
     405            echo '            <option value="0"'.selected($this->plugin->options['auto_cache_ms_children_too'], '0', false).'>'.__('All URLs in this network are in the sitemap for the main site.', 'rapid-cache').'</option>'."\n";
     406            echo '            <option value="1"'.selected($this->plugin->options['auto_cache_ms_children_too'], '1', false).'>'.__('Using the path I\'ve given, look for blog-specific sitemaps in each child blog also.', 'rapid-cache').'</option>'."\n";
     407            echo '         </select></p>'."\n";
     408            echo '      <p class="info" style="display:block; margin-top:0;">'.sprintf(__('<strong>↑</strong> If enabled here, each child blog can be auto-cached too. %1$s will dynamically change the leading <code>%2$s</code> as necessary; for each child blog in the network. %1$s supports both sub-directory &amp; sub-domain networks, including domain mapping plugins. For more information about how the Auto-Cache Engine caches child blogs, see <a href="#" target="_blank">this article</a>.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME), esc_html(home_url('/'))).'</p>'."\n";
     409        }
     410        echo '         <hr />'."\n";
     411
     412        echo '         <h3>'.__('And/Or; a List of URLs to Auto-Cache (One Per Line)', 'rapid-cache').'</h3>'."\n";
     413        echo '         <p><textarea name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][auto_cache_other_urls]" rows="5" spellcheck="false" class="monospace">'.format_to_edit($this->plugin->options['auto_cache_other_urls']).'</textarea></p>'."\n";
     414        echo '         <p class="info" style="display:block; margin-top:-5px;">'.__('<strong>Note:</strong> Wildcards are NOT supported here. If you are going to supply a list of URLs above, each line must contain one full URL for the Auto-Cache Engine to auto-cache. If you have many URLs, we recommend using an <a href="https://en.wikipedia.org/wiki/Sitemaps" target="_blank">XML Sitemap</a>.', 'rapid-cache').'</p>'."\n";
     415
     416        echo '         <hr />'."\n";
     417
     418        echo '         <h3>'.__('Auto-Cache Delay Timer (in Milliseconds)', 'rapid-cache').'</h3>'."\n";
     419        echo '         <p>'.__('As the Auto-Cache Engine runs through each URL, you can tell it to wait X number of milliseconds between each connection that it makes. It is strongly suggested that you DO have some small delay here. Otherwise, you run the risk of hammering your own web server with multiple repeated connections whenever the Auto-Cache Engine is running. This is especially true on very large sites; where there is the potential for hundreds of repeated connections as the Auto-Cache Engine goes through a long list of URLs. Adding a delay between each connection will prevent the Auto-Cache Engine from placing a heavy load on the processor that powers your web server. A value of <code>500</code> milliseconds is suggested here (half a second). If you experience problems, you can bump this up a little at a time, in increments of <code>500</code> milliseconds; until you find a happy place for your server. <em>Please note that <code>1000</code> milliseconds = <code>1</code> full second.</em>', 'rapid-cache').'</p>'."\n";
     420        echo '         <p><input type="text" name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][auto_cache_delay]" value="'.esc_attr($this->plugin->options['auto_cache_delay']).'" /></p>'."\n";
     421
     422        echo '         <hr />'."\n";
     423
     424        echo '         <h3>'.__('Auto-Cache User-Agent String', 'rapid-cache').'</h3>'."\n";
     425        echo '         <table style="width:100%;"><tr><td><input type="text" name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][auto_cache_user_agent]" value="'.esc_attr($this->plugin->options['auto_cache_user_agent']).'" /></td><td style="width:1px; font-weight:bold; white-space:pre;">; '.esc_html(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.' '.MEGAOPTIM_RAPID_CACHE_VERSION).'</td></tr></table>'."\n";
     426        echo '         <p class="info" style="display:block;">'.__('This is how the Auto-Cache Engine identifies itself when connecting to URLs. See <a href="http://en.wikipedia.org/wiki/User_agent" target="_blank">User Agent</a> in the Wikipedia.', 'rapid-cache').'</p>'."\n";
     427        echo '      </div>'."\n";
     428        echo '   </div>'."\n";
     429
     430        echo '</div>'."\n";
     431
     432        /* ----------------------------------------------------------------------------------------- */
     433
     434        echo '<div class="plugin-menu-page-panel">'."\n";
     435
     436        echo '   <a href="#" class="plugin-menu-page-panel-heading">'."\n";
     437        echo '      <i class="si si-octi-tach"></i> '.__('Client-Side Cache', 'rapid-cache')."\n";
     438        echo '   </a>'."\n";
     439
     440        echo '   <div class="plugin-menu-page-panel-body clearfix">'."\n";
     441        echo '      <i class="si si-desktop si-4x" style="float:right; margin: 0 0 0 25px;"></i>'."\n";
     442        echo '      <h3>'.__('Allow Double-Caching In The Client-Side Browser?', 'rapid-cache').'</h3>'."\n";
     443        echo '      <p>'.__('Recommended setting: <code>No</code> (for membership sites, very important). Otherwise, <code>Yes</code> would be better (if users do NOT log in/out of your site).', 'rapid-cache').'</p>'."\n";
     444        echo '      <p>'.__('<strong>This option is NOT the same as "Leverage Browser Caching"</strong>, which refers to the caching of static resources in the browser (e.g., images, CSS, JS). This Client-Side Cache option is different in that it controls the caching of <em>page content</em> in the browser, i.e., the caching of HTML content generated by PHP itself, which is generally NOT static. If you\'re looking to Leverage Browser Caching for static resources (highly recommended), see the <strong>Apache Optimizations</strong> panel below.', 'rapid-cache').'</p>'."\n";
     445        echo '      <p>'.sprintf(__('%1$s handles content delivery through its ability to communicate with a browser using PHP. If you allow a browser to (cache) the caching system itself, you are momentarily losing some control; and this can have a negative impact on users that see more than one version of your site; e.g., one version while logged-in, and another while NOT logged-in. For instance, a user may log out of your site, but upon logging out they report seeing pages on the site which indicate they are STILL logged in (even though they\'re not — that\'s bad). This can happen if you allow a client-side cache, because their browser may cache web pages they visited while logged into your site which persist even after logging out. Sending no-cache headers will work to prevent this issue.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
     446        echo '      <p>'.__('All of that being said, if all you care about is blazing fast speed and users don\'t log in/out of your site (only you do); you can safely set this to <code>Yes</code> (recommended in this case). Allowing a client-side browser cache will improve speed and reduce outgoing bandwidth when this option is feasible.', 'rapid-cache').'</p>'."\n";
     447        echo '      <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][allow_client_side_cache]" data-toggle="enable-disable" data-target=".-client-side-cache-options">'."\n";
     448        echo '            <option value="0"'.selected($this->plugin->options['allow_client_side_cache'], '0', false).'>'.__('No, prevent a client-side browser cache of dynamic page content (safest option).', 'rapid-cache').'</option>'."\n";
     449        echo '            <option value="1"'.selected($this->plugin->options['allow_client_side_cache'], '1', false).'>'.__('Yes, I will allow a client-side browser cache of pages on the site.', 'rapid-cache').'</option>'."\n";
     450        echo '         </select></p>'."\n";
     451        echo '      <p class="info">'.__('<strong>Tip:</strong> Setting this to <code>No</code> is highly recommended when running a membership plugin like <a href="http://wordpress.org/plugins/s2member/" target="_blank">s2Member</a> (as one example). In fact, many plugins like s2Member will send <a href="http://codex.wordpress.org/Function_Reference/nocache_headers" target="_blank">nocache_headers()</a> on their own, so your configuration here will likely be overwritten when you run such plugins (which is better anyway). In short, if you run a membership plugin, you should NOT allow a client-side browser cache.', 'rapid-cache').'</p>'."\n";
     452        echo '      <p class="info">'.__('<strong>Tip:</strong> Setting this to <code>No</code> will NOT impact static content; e.g., CSS, JS, images, or other media. This setting pertains only to dynamic PHP scripts which produce content generated by WordPress.', 'rapid-cache').'</p>'."\n";
     453        echo '      <p class="info">'.sprintf(__('<strong>Advanced Tip:</strong> if you have this set to <code>No</code>, but you DO want to allow a few special URLs to be cached by the browser; you can add this parameter to your URL <code>?%2$sABC=1</code>. This tells %1$s that it\'s OK for the browser to cache that particular URL. In other words, the <code>%2$sABC=1</code> parameter tells %1$s NOT to send no-cache headers to the browser.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME), esc_html(mb_strtolower(MEGAOPTIM_RAPID_CACHE_NAME))).'</p>'."\n";
     454        echo '      <hr />'."\n";
     455        echo '      <div class="plugin-menu-page-panel-if-enabled -client-side-cache-options">'."\n";
     456        echo '        <h3>'.__('Exclusion Patterns for Client-Side Caching', 'rapid-cache').'</h3>'."\n";
     457        echo '        <p>'.__('When you enable Client-Side Caching above, you may want to prevent certain pages on your site from being cached by a client-side browser. This is where you will enter those if you need to (one per line). Searches are performed against the <a href="https://gist.github.com/jaswsinc/338b6eb03a36c048c26f" target="_blank" style="text-decoration:none;"><code>REQUEST_URI</code></a>; i.e., <code>/path/?query</code> (caSe insensitive). So, don\'t put in full URLs here, just word fragments found in the file path (or query string) is all you need, excluding the http:// and domain name. A wildcard <code>*</code> character can also be used when necessary; e.g., <code>/category/abc-followed-by-*</code> (where <code>*</code> = 0 or more characters that are NOT a slash <code>/</code>). Other special characters include: <code>**</code> = 0 or more characters of any kind, including <code>/</code> slashes; <code>^</code> = beginning of the string; <code>$</code> = end of the string. To learn more about this syntax, please see <a href ="https://github.com/megaoptim/rapid-cache/wiki/Watered-Down-Regex-Syntax" target="_blank">this KB article</a>.', 'rapid-cache').'</p>'."\n";
     458        echo '        <p><textarea name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][exclude_client_side_uris]" rows="5" spellcheck="false" class="monospace">'.format_to_edit($this->plugin->options['exclude_client_side_uris']).'</textarea></p>'."\n";
     459        echo '        <p class="info">'.__('<strong>Tip:</strong> let\'s use this example URL: <code>http://www.example.com/post/example-post-123</code>. To exclude this URL, you would put this line into the field above: <code>/post/example-post-123</code>. Or, you could also just put in a small fragment, like: <code>example</code> or <code>example-*-123</code> and that would exclude any URI containing that word fragment.', 'rapid-cache').'</p>'."\n";
     460        echo '        <p class="info">'.__('<strong>Note:</strong> please remember that your entries here should be formatted as a line-delimited list; e.g., one exclusion pattern per line.', 'rapid-cache').'</p>'."\n";
     461        echo '      </div>'."\n";
     462        echo '   </div>'."\n";
     463
     464        echo '</div>'."\n";
     465
     466        /* --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
     467        if ( $this->plugin->functionIsPossible( 'opcache_reset' ) ) {
     468
     469            echo '<div class="plugin-menu-page-panel">' . "\n";
     470
     471            echo '   <a href="#" class="plugin-menu-page-panel-heading">' . "\n";
     472            echo '      <i class="si si-code"></i> ' . __( 'OPcache Control', 'rapid-cache' ) . "\n";
     473            echo '   </a>' . "\n";
     474
     475            echo '   <div class="plugin-menu-page-panel-body clearfix">' . "\n";
     476
     477            echo '  <h3>' . __( 'Clear the <a href="https://github.com/megaoptim/rapid-cache/wiki/OPcache-Control" target="_blank">PHP OPcache</a> Too?', 'rapid-cache' ) . '</h3>' . "\n";
     478            echo '  <p>' . sprintf( __( 'If you clear the cache manually, do you want %1$s to clear the PHP OPcache too? This is not necessary, but if you want a truly clean start, this will clear all PHP files in the server\'s opcode cache also. Note: If you don\'t already know what the PHP OPcache is, it is suggested that you leave this disabled. It really is not necessary. This is just an added feature for advanced users.', 'rapid-cache' ), 'Rapid Cache' ) . '</p>' . "\n";
     479            echo '  <p><select name="' . esc_attr( MEGAOPTIM_RAPID_CACHE_GLOBAL_NS ) . '[saveOptions][cache_clear_opcache_enable]" class="-no-if-enabled">' . "\n";
     480            echo '      <option value="0"' . selected( $this->plugin->options['cache_clear_opcache_enable'], '0', false ) . '>' . __( 'No, I don\'t use the PHP OPcache extension; or, I don\'t want the opcode cache cleared.', 'rapid-cache' ) . '</option>' . "\n";
     481            echo '      <option value="1"' . selected( $this->plugin->options['cache_clear_opcache_enable'], '1', false ) . '>' . __( 'Yes, if the PHP OPcache extension is enabled, also clear the entire PHP opcode cache.', 'rapid-cache' ) . '</option>' . "\n";
     482            echo '  </select></p>' . "\n";
     483
     484            echo '   </div>' . "\n";
     485
     486            echo '</div>' . "\n";
     487        }
     488
     489        /* ----------------------------------------------------------------------------------------- */
     490        echo '<div class="plugin-menu-page-panel">'."\n";
     491
     492        echo '   <a href="#" class="plugin-menu-page-panel-heading">'."\n";
     493        echo '      <i class="si si-octi-organization"></i> '.__('Users Cache', 'rapid-cache')."\n";
     494        echo '   </a>'."\n";
     495
     496        echo '   <div class="plugin-menu-page-panel-body clearfix">'."\n";
     497        echo '      <i class="si si-group si-4x" style="float:right; margin: 0 0 0 25px;"></i>'."\n";
     498        echo '      <h3>'.__('Caching Enabled for Logged-In Users &amp; Comment Authors?', 'rapid-cache').'</h3>'."\n";
     499        echo '      <p>'.__('This should almost always be set to <code>No</code>. Most sites don\'t cache content generated while a user is logged-in. Doing so could result in a cache of dynamic content generated specifically for a particular user, where the content being cached may contain details that pertain only to the user that was logged-in when the cache was generated. In short, don\'t turn this on unless you know what you\'re doing. Note also that most sites get most (sometimes all) of their traffic from users who <em>are not</em> logged-in. When a user <em>is</em> logged-in, disabling the cache is generally a good idea because a logged-in user has a session open with your site. The content they view should remain very dynamic in this scenario.', 'rapid-cache').'</p>'."\n";
     500        echo '      <i class="si si-sitemap si-4x" style="float:right; margin: 0 0 0 25px;"></i>'."\n";
     501        echo '      <p>'.sprintf(__('<strong>Exception (Membership Sites):</strong> If you run a site with many users and the majority of your traffic comes from users who <em>are</em> logged-in, choose: <code>Yes (maintain separate cache)</code>. %1$s will operate normally, but when a user is logged-in the cache is user-specific. %1$s will intelligently refresh the cache when/if a user submits a form on your site with the GET or POST method. Or, if you make changes to their account (or another plugin makes changes to their account); including user <a href="http://codex.wordpress.org/Function_Reference/update_user_option" target="_blank">option</a>|<a href="http://codex.wordpress.org/Function_Reference/update_user_meta" target="_blank">meta</a> additions, updates &amp; deletions too. However, please note that enabling this feature (i.e., user-specific cache entries) will eat up much more disk space. That being said, the benefits of this feature for most sites will outweigh the disk overhead; i.e., it\'s not an issue in most cases. In other words, unless you\'re short on disk space, or you have thousands of users, the disk overhead is neglible.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
     502        echo '      <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][when_logged_in]" data-toggle="enable-disable" data-enabled-strings="1,postload" data-target=".-logged-in-users-options">'."\n";
     503        echo '            <option value="0" '.selected($this->plugin->options['when_logged_in']).'>'.__('No, do NOT cache; or serve a cache file when a user is logged-in (safest option).', 'rapid-cache').'</option>'."\n";
     504        echo '            <option value="postload"'.(selected($this->plugin->options['when_logged_in'], 'postload', false)).'>'.__('Yes, and maintain a separate cache for each user (recommended for membership sites).', 'rapid-cache').'</option>'."\n";
     505        if ($this->plugin->options['when_logged_in'] === '1' || get_site_option(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_when_logged_in_was_1')) {
     506            update_site_option(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_when_logged_in_was_1', '1');
     507            echo '            <option value="1"'.selected($this->plugin->options['when_logged_in'], '1', false).'>'.__('Yes, but DON\'T maintain a separate cache for each user (I know what I\'m doing).', 'rapid-cache').'</option>'."\n";
     508        }
     509        echo '         </select></p>'."\n";
     510        if ($this->plugin->options['when_logged_in'] === '1' && $this->plugin->applyWpFilters(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_when_logged_in_no_admin_bar', true)) {
     511            echo '<p class="warning">'.sprintf(__('<strong>Warning:</strong> Whenever you enable caching for logged-in users (without a separate cache for each user), the WordPress Admin Bar <em>must</em> be disabled to prevent one user from seeing another user\'s details in the Admin Bar. <strong>Given your current configuration, %1$s will automatically hide the WordPress Admin Bar on the front-end of your site.</strong>', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
     512        }
     513        echo '      <p class="info">'.sprintf(__('<strong>Note:</strong> %1$s includes comment authors as part of it\'s logged-in user check. This way comment authors will be able to see updates to comment threads immediately. And, so that any dynamically-generated messages displayed by your theme will work as intended. In short, %1$s thinks of a comment author as a logged-in user, even though technically they are not. Users who gain access to password-protected Posts/Pages are also considered by the logged-in user check.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
     514
     515        echo '      <hr />'."\n";
     516
     517        echo '      <div class="plugin-menu-page-panel-if-enabled -logged-in-users-options">'."\n";
     518        echo '        <h3>'.__('Cache Pages Containing Nonce Values in Markup?', 'rapid-cache').'</h3>'."\n";
     519        echo '        <p>'.sprintf(__('This should almost always be set to <code>Yes</code>. WordPress injects Nonces (<a href="https://developer.wordpress.org/themes/theme-security/using-nonces/" target="_blank" rel="external">numbers used once</a>) into the markup on any given page that a logged-in user lands on. These Nonce values are generally used to improve security when actions are taken by a user; e.g., posting a form or clicking a link that performs an action. If you set this to <code>No</code>, any page containing an Nonce will bypass the cache and be served dynamically (a performance hit). Even the Admin Bar in WordPress injects Nonce values. That\'s reason enough to leave this at the default value of <code>Yes</code>; i.e., so Nonce values in the markup don\'t result in a cache bypass. In short, don\'t set this to <code>No</code> unless you know what you\'re doing.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
     520        echo '        <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][cache_nonce_values_when_logged_in]">'."\n";
     521        echo '           <option value="1"'.selected($this->plugin->options['cache_nonce_values_when_logged_in'], '1', false).'>'.__('Yes, for logged-in users, intelligently cache pages containing Nonce values (recommended).', 'rapid-cache').'</option>'."\n";
     522        echo '           <option value="0"'.selected($this->plugin->options['cache_nonce_values_when_logged_in'], '0', false).'>'.__('No, for logged-in users, refuse to cache pages containing Nonce values.', 'rapid-cache').'</option>'."\n";
     523        echo '           </select></p>'."\n";
     524        echo '        <p class="info">'.sprintf(__('<strong>Note:</strong> Nonce values in WordPress have a limited lifetime. They can expire just 12 hours after they were first generated. For this reason, %1$s will automatically force cache files containing Nonce values to expire once they are 12+ hours old; i.e., a new request for an expired page containing Nonce values will be rebuilt automatically, generating new Nonces that will continue to operate as expected. This rule is enforced no matter what your overall Cache Expiration Time is set to.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
     525        echo '      </div>'."\n";
     526        echo '   </div>'."\n";
     527        echo '</div>'."\n";
     528        /* ----------------------------------------------------------------------------------------- */
     529
     530        echo '<div class="plugin-menu-page-panel">'."\n";
     531
     532        echo '   <a href="#" class="plugin-menu-page-panel-heading">'."\n";
     533        echo '      <i class="si si-question-circle"></i> '.__('GET Requests', 'rapid-cache')."\n";
     534        echo '   </a>'."\n";
     535
     536        echo '   <div class="plugin-menu-page-panel-body clearfix">'."\n";
     537
     538        echo '      <i class="si si-question-circle si-4x" style="float:right; margin: 0 0 0 25px;"></i>'."\n";
     539        echo '      <h3>'.__('Caching Enabled for GET (Query String) Requests?', 'rapid-cache').'</h3>'."\n";
     540        echo '      <p>'.__('This should almost always be set to <code>No</code>. UNLESS, you\'re using unfriendly Permalinks; i.e., if all of your URLs contain a query string (like <code>?p=123</code>). In such a case, you should set this option to <code>Yes</code>. However, it\'s better to update your Permalink options and use friendly Permalinks, which also optimizes your site for search engines. Again, if you\'re using friendly Permalinks (recommended) you can leave this at the default value of <code>No</code>.', 'rapid-cache').'</p>'."\n";
     541        echo '      <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][get_requests]">'."\n";
     542        echo '            <option value="0"'.selected($this->plugin->options['get_requests'], '0', false).'>'.__('No, do NOT cache (or serve a cache file) when a query string is present.', 'rapid-cache').'</option>'."\n";
     543        echo '            <option value="1"'.selected($this->plugin->options['get_requests'], '1', false).'>'.__('Yes, I would like to cache URLs that contain a query string.', 'rapid-cache').'</option>'."\n";
     544        echo '         </select></p>'."\n";
     545        echo '      <p class="info">'.sprintf(__('<strong>Advanced Tip:</strong> If you are not caching GET requests (recommended), but you <em>do</em> want to allow some special URLs that include query string parameters to be cached, you can add this special parameter to any URL <code>?%2$sAC=1</code>. This tells %1$s that it\'s OK to cache that particular URL, even though it contains query string arguments. If you <em>are</em> caching GET requests and you want to force %1$s to <em>not</em> cache a specific request, you can add this special parameter to any URL <code>?%2$sAC=0</code>.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME), esc_html(mb_strtolower(MEGAOPTIM_RAPID_CACHE_SHORT_NAME))).'</p>'."\n";
     546        echo '      <p style="font-style:italic;">'.__('<strong>Other Request Types:</strong> POST requests (i.e., forms with <code>method=&quot;post&quot;</code>) are always excluded from the cache, which is the way it should be. Any <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html" target="_blank">POST/PUT/DELETE</a> request should never, ever be cached. CLI and self-serve requests are also excluded from the cache automatically. A CLI request is one that comes from the command line; commonly used by CRON jobs and other automated routines. A self-serve request is an HTTP connection established from your site, to your site. For instance, a WP Cron job, or any other HTTP request that is spawned not by a user, but by the server itself.', 'rapid-cache').'</p>'."\n";
     547
     548        echo '<div>'."\n";
     549        echo    '<hr />'."\n";
     550        echo    '<h3>'.__('List of GET Variable Names to Ignore', 'rapid-cache').'</h3>'."\n";
     551        echo    '<p>'.__('You can enter one variable name per line. Each of the variable names that you list here will be ignored entirely; i.e., not considered when caching any given page, and not considered when serving any page that is already cached. For example, many sites use Google Analytics and there are <a href="https://support.google.com/analytics/answer/1033863?hl=en" target="_blank" rel="external">GET request variables used by Google Analytics</a>, which are read by client-side JavaScript only. Those GET variables can be ignored altogether when it comes to the cache algorithm — speeding up your site even further.', 'rapid-cache').'</p>'."\n";
     552        echo    '<p><textarea name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][ignore_get_request_vars]" rows="5" spellcheck="false" class="monospace">'.format_to_edit($this->plugin->options['ignore_get_request_vars']).'</textarea></p>'."\n";
     553        echo    '<p style="font-style:italic;">'.__('A wildcard <code>*</code> character can also be used when necessary; e.g., <code>utm_*</code> (where <code>*</code> = 0 or more characters that are NOT a slash <code>/</code>). To learn more about this syntax, please see <a href ="https://github.com/megaoptim/rapid-cache/wiki/Watered-Down-Regex-Syntax" target="_blank">this KB article</a>.', 'rapid-cache').'</p>'."\n";
     554        echo '</div>'."\n";
     555
     556        echo '   </div>'."\n";
     557
     558        echo '</div>'."\n";
     559
     560        /* ----------------------------------------------------------------------------------------- */
     561
     562        echo '<div class="plugin-menu-page-panel">'."\n";
     563
     564        echo '   <a href="#" class="plugin-menu-page-panel-heading">'."\n";
     565        echo '      <i class="si si-chain-broken"></i> '.__('404 Requests', 'rapid-cache')."\n";
     566        echo '   </a>'."\n";
     567
     568        echo '   <div class="plugin-menu-page-panel-body clearfix">'."\n";
     569        echo '      <i class="si si-question-circle si-4x" style="float:right; margin: 0 0 0 25px;"></i>'."\n";
     570        echo '      <h3>'.__('Caching Enabled for 404 Requests?', 'rapid-cache').'</h3>'."\n";
     571        echo '      <p>'.sprintf(__('When this is set to <code>No</code>, %1$s will ignore all 404 requests and no cache file will be served. While this is fine for most site owners, caching the 404 page on a high-traffic site may further reduce server load. When this is set to <code>Yes</code>, %1$s will cache the 404 page (see <a href="https://codex.wordpress.org/Creating_an_Error_404_Page" target="_blank">Creating an Error 404 Page</a>) and then serve that single cache file to all future 404 requests.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
     572        echo '      <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][cache_404_requests]">'."\n";
     573        echo '            <option value="0"'.selected($this->plugin->options['cache_404_requests'], '0', false).'>'.__('No, do NOT cache (or serve a cache file) for 404 requests.', 'rapid-cache').'</option>'."\n";
     574        echo '            <option value="1"'.selected($this->plugin->options['cache_404_requests'], '1', false).'>'.__('Yes, I would like to cache the 404 page and serve the cached file for 404 requests.', 'rapid-cache').'</option>'."\n";
     575        echo '         </select></p>'."\n";
     576        echo '      <p class="info">'.sprintf(__('<strong>How does %1$s cache 404 requests?</strong> %1$s will create a special cache file (<code>----404----.html</code>, see Advanced Tip below) for the first 404 request and then <a href="http://www.php.net/manual/en/function.symlink.php" target="_blank">symlink</a> future 404 requests to this special cache file. That way you don\'t end up with lots of 404 cache files that all contain the same thing (the contents of the 404 page). Instead, you\'ll have one 404 cache file and then several symlinks (i.e., references) to that 404 cache file.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
     577        echo '      <p class="info">'.__('<strong>Advanced Tip:</strong> The default 404 cache filename (<code>----404----.html</code>) is designed to minimize the chance of a collision with a cache file for a real page with the same name. However, if you want to override this default and define your own 404 cache filename, you can do so by adding <code>define(\'RAPID_CACHE_404_CACHE_FILENAME\', \'your-404-cache-filename\');</code> to your <code>wp-config.php</code> file (note that the <code>.html</code> extension should be excluded when defining a new filename).', 'rapid-cache').'</p>'."\n";
     578        echo '   </div>'."\n";
     579
     580        echo '</div>'."\n";
     581
     582        /* ----------------------------------------------------------------------------------------- */
     583
     584        echo '<div class="plugin-menu-page-panel">'."\n";
     585
     586        echo '   <a href="#" class="plugin-menu-page-panel-heading">'."\n";
     587        echo '      <i class="si si-feed"></i> '.__('Feed Caching', 'rapid-cache')."\n";
     588        echo '   </a>'."\n";
     589
     590        echo '   <div class="plugin-menu-page-panel-body clearfix">'."\n";
     591        echo '      <i class="si si-question-circle si-4x" style="float:right; margin: 0 0 0 25px;"></i>'."\n";
     592        echo '      <h3>'.__('Caching Enabled for RSS, RDF, Atom Feeds?', 'rapid-cache').'</h3>'."\n";
     593        echo '      <p>'.__('This should almost ALWAYS be set to <code>No</code>. UNLESS, you\'re sure that you want to cache your feeds. If you use a web feed management provider like Google® Feedburner and you set this option to <code>Yes</code>, you may experience delays in the detection of new posts. <strong>NOTE:</strong> If you do enable this, it is highly recommended that you also enable automatic Feed Clearing too. Please see the section above: "Automatic Cache Clearing". Find the sub-section titled: "Auto-Clear RSS/RDF/ATOM Feeds".', 'rapid-cache').'</p>'."\n";
     594        echo '      <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][feeds_enable]" class="-no-if-enabled">'."\n";
     595        echo '            <option value="0"'.selected($this->plugin->options['feeds_enable'], '0', false).'>'.__('No, do NOT cache (or serve a cache file) when displaying a feed.', 'rapid-cache').'</option>'."\n";
     596        echo '            <option value="1"'.selected($this->plugin->options['feeds_enable'], '1', false).'>'.__('Yes, I would like to cache feed URLs.', 'rapid-cache').'</option>'."\n";
     597        echo '         </select></p>'."\n";
     598        echo '      <p class="info">'.__('<strong>Note:</strong> This option affects all feeds served by WordPress, including the site feed, the site comment feed, post-specific comment feeds, author feeds, search feeds, and category and tag feeds. See also: <a href="http://codex.wordpress.org/WordPress_Feeds" target="_blank">WordPress Feeds</a>.', 'rapid-cache').'</p>'."\n";
     599        echo '   </div>'."\n";
     600
     601        echo '</div>'."\n";
     602
     603        /* ----------------------------------------------------------------------------------------- */
     604
     605        $exclude_hosts_option_enable = is_multisite() &&
     606                                       ((defined('SUBDOMAIN_INSTALL') && SUBDOMAIN_INSTALL) || $this->plugin->canConsiderDomainMapping());
     607
     608        if ($this->plugin->applyWpFilters(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_exclude_hosts_option_enable', $exclude_hosts_option_enable)) {
     609            echo '<div class="plugin-menu-page-panel">'."\n";
     610
     611            echo '   <a href="#" class="plugin-menu-page-panel-heading">'."\n";
     612            echo '      <i class="si si-ban"></i> '.__('Host Exclusions', 'rapid-cache')."\n";
     613            echo '   </a>'."\n";
     614
     615            echo '   <div class="plugin-menu-page-panel-body clearfix">'."\n";
     616            echo '      <h3>'.__('Don\'t Cache These Special Host Exclusion Patterns?', 'rapid-cache').'</h3>'."\n";
     617            echo '      <p>'.__('If there are specific domains that should not be cached, you can enter them here so they are excluded automatically. The easiest way to exclude a host is to enter the full domain name on a line of it\'s own in the field below, e.g., <code>site1.example.com</code>.', 'rapid-cache').'</p>'."\n";
     618            echo '      <p>'.__('This field also supports <a href ="https://github.com/megaoptim/rapid-cache/wiki/Watered-Down-Regex-Syntax" target="_blank" style="text-decoration:none;">Watered-Down Regex</a> syntax, which means that you can also exclude a pattern like: <code>*.example.com</code> or <code>*.example.*</code>. So for instance, if you wanted to exclude all child sites and only cache pages on the Main Site of a Network installation, you could exclude all sub-domains using: <code>*.mynetwork.com</code>. That excludes all sub-domains, but not <code>mynetwork.com</code> by itself.', 'rapid-cache').'</p>'."\n";
     619
     620            echo '      <p><textarea name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][exclude_hosts]" rows="5" spellcheck="false" class="monospace">'.format_to_edit($this->plugin->options['exclude_hosts']).'</textarea></p>'."\n";
     621
     622            echo '      <p class="info">'.__('<strong>Note:</strong> please remember that your entries here should be formatted as a line-delimited list; e.g., one exclusion pattern per line.', 'rapid-cache').'</p>'."\n";
     623
     624            echo '   </div>'."\n";
     625            echo '</div>'."\n";
     626        }
     627
     628        /* ----------------------------------------------------------------------------------------- */
     629
     630        echo '<div class="plugin-menu-page-panel">'."\n";
     631
     632        echo '   <a href="#" class="plugin-menu-page-panel-heading">'."\n";
     633        echo '      <i class="si si-ban"></i> '.__('Cache Exclusions', 'rapid-cache')."\n";
     634        echo '   </a>'."\n";
     635
     636        echo '   <div class="plugin-menu-page-panel-body clearfix">'."\n";
     637        echo '      <h3>'.__('Don\'t Cache These Special URI Exclusion Patterns?', 'rapid-cache').'</h3>'."\n";
     638        echo '      <p>'.__('Sometimes there are certain cases where a particular file, or a particular group of files, should never be cached. This is where you will enter those if you need to (one per line). Searches are performed against the <a href="https://gist.github.com/jaswsinc/338b6eb03a36c048c26f" target="_blank" style="text-decoration:none;"><code>REQUEST_URI</code></a>; i.e., <code>/path/?query</code> (caSe insensitive). So, don\'t put in full URLs here, just word fragments found in the file path (or query string) is all you need, excluding the http:// and domain name. A wildcard <code>*</code> character can also be used when necessary; e.g., <code>/category/abc-followed-by-*</code> (where <code>*</code> = 0 or more characters that are NOT a slash <code>/</code>). Other special characters include: <code>**</code> = 0 or more characters of any kind, including <code>/</code> slashes; <code>^</code> = beginning of the string; <code>$</code> = end of the string. To learn more about this syntax, please see <a href ="https://github.com/megaoptim/rapid-cache/wiki/Watered-Down-Regex-Syntax" target="_blank">this KB article</a>.', 'rapid-cache').'</p>'."\n";
     639        echo '      <p><textarea name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][exclude_uris]" rows="5" spellcheck="false" class="monospace">'.format_to_edit($this->plugin->options['exclude_uris']).'</textarea></p>'."\n";
     640
     641        echo '      <p class="info">'.__('<strong>Tip:</strong> let\'s use this example URL: <code>http://www.example.com/post/example-post-123</code>. To exclude this URL, you would put this line into the field above: <code>/post/example-post-123</code>. Or, you could also just put in a small fragment, like: <code>example</code> or <code>example-*-123</code> and that would exclude any URI containing that word fragment.', 'rapid-cache').'</p>'."\n";
     642        echo '      <p class="info">'.__('<strong>Note:</strong> please remember that your entries here should be formatted as a line-delimited list; e.g., one exclusion pattern per line.', 'rapid-cache').'</p>'."\n";
     643        if (is_multisite() && defined('SUBDOMAIN_INSTALL') && !SUBDOMAIN_INSTALL) {
     644            echo '      <p class="info">'.__('<strong>Multisite Network w/ Sub-Directories:</strong> You can also use URI Exclusion Patterns to exclude specific sites from being cached, e.g., <code>/site1/*</code>.', 'rapid-cache').'</p>'."\n";
     645        }
     646
     647        echo '   <hr/>'."\n";
     648
     649        echo '      <h3>'.__('Don\'t Cache These Special HTTP Referrer Exclusion Patterns?', 'rapid-cache').'</h3>'."\n";
     650        echo '      <p>'.__('Sometimes there are special cases where a particular referring URL (or referring domain) that sends you traffic; or even a particular group of referring URLs or domains that send you traffic; should result in a page being loaded on your site that is NOT from the cache (and that resulting page should never be cached). This is where you will enter those if you need to (one per line). Searches are performed against the <a href="http://www.php.net//manual/en/reserved.variables.server.php" target="_blank" style="text-decoration:none;"><code>HTTP_REFERER</code></a> (caSe insensitive). A wildcard <code>*</code> character can also be used when necessary; e.g., <code>*.domain.com</code> (where <code>*</code> = 0 or more characters that are NOT a slash <code>/</code>). Other special characters include: <code>**</code> = 0 or more characters of any kind, including <code>/</code> slashes; <code>^</code> = beginning of the string; <code>$</code> = end of the string. To learn more about this syntax, please see <a href ="https://github.com/megaoptim/rapid-cache/wiki/Watered-Down-Regex-Syntax" target="_blank">this KB article</a>.', 'rapid-cache').'</p>'."\n";
     651        echo '      <p><textarea name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][exclude_refs]" rows="5" spellcheck="false" class="monospace">'.format_to_edit($this->plugin->options['exclude_refs']).'</textarea></p>'."\n";
     652        echo '      <p class="info">'.__('<strong>Tip:</strong> let\'s use this example URL: <code>http://www.referring-domain.com/search/?q=search+terms</code>. To exclude this referring URL, you could put this line into the field above: <code>www.referring-domain.com</code>. Or, you could also just put in a small fragment, like: <code>/search/</code> or <code>q=*</code>; and that would exclude any referrer containing that word fragment.', 'rapid-cache').'</p>'."\n";
     653        echo '      <p class="info">'.__('<strong>Note:</strong> please remember that your entries here should be formatted as a line-delimited list; e.g., one exclusion pattern per line.', 'rapid-cache').'</p>'."\n";
     654
     655
     656        echo '   <hr/>'."\n";
     657
     658        echo '      <h3>'.__('Don\'t Cache These Special User-Agent Exclusion Patterns?', 'rapid-cache').'</h3>'."\n";
     659        echo '      <p>'.__('Sometimes there are special cases when a particular user-agent (e.g., a specific browser or a specific type of device); should be shown a page on your site that is NOT from the cache (and that resulting page should never be cached). This is where you will enter those if you need to (one per line). Searches are performed against the <a href="http://www.php.net//manual/en/reserved.variables.server.php" target="_blank" style="text-decoration:none;"><code>HTTP_USER_AGENT</code></a> (caSe insensitive). A wildcard <code>*</code> character can also be used when necessary; e.g., <code>Android *; Chrome/* Mobile</code> (where <code>*</code> = 0 or more characters that are NOT a slash <code>/</code>). Other special characters include: <code>**</code> = 0 or more characters of any kind, including <code>/</code> slashes; <code>^</code> = beginning of the string; <code>$</code> = end of the string. To learn more about this syntax, please see <a href ="https://github.com/megaoptim/rapid-cache/wiki/Watered-Down-Regex-Syntax" target="_blank">this KB article</a>.', 'rapid-cache').'</p>'."\n";
     660        echo '      <p><textarea name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][exclude_agents]" rows="5" spellcheck="false" class="monospace">'.format_to_edit($this->plugin->options['exclude_agents']).'</textarea></p>'."\n";
     661        echo '      <p class="info">'.sprintf(__('<strong>Tip:</strong> if you wanted to exclude iPhones put this line into the field above: <code>iPhone;*AppleWebKit</code>. Or, you could also just put in a small fragment, like: <code>iphone</code>; and that would exclude any user-agent containing that word fragment. Note, this is just an example. With a default installation of %1$s, there is no compelling reason to exclude iOS devices (or any mobile device for that matter).', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
     662        echo '      <p class="info">'.__('<strong>Note:</strong> please remember that your entries here should be formatted as a line-delimited list; e.g., one exclusion pattern per line.', 'rapid-cache').'</p>'."\n";
     663
     664
     665        echo '   </div>'."\n";
     666
     667        echo '</div>'."\n";
     668
     669        /* ----------------------------------------------------------------------------------------- */
     670
     671        if ($this->plugin->isApache()) {
     672            echo '<div class="plugin-menu-page-panel">'."\n";
     673
     674            echo '   <a href="#" class="plugin-menu-page-panel-heading">'."\n";
     675            echo '      <i class="si si-server"></i> '.__('Apache Optimizations', 'rapid-cache')."\n";
     676            echo '   </a>'."\n";
     677
     678            echo '   <div class="plugin-menu-page-panel-body clearfix">'."\n";
     679            echo '      <img src="'.esc_attr($this->plugin->url('/assets/images/apache.png')).'" class="screenshot" />'."\n";
     680            echo '      <h3>'.__('Apache Performance Tuning (Optional; Highly Recommended)', 'rapid-cache').'</h3>'."\n";
     681            echo '      <p>'.__('You don\'t need to use an <code>.htaccess</code> file to enjoy the performance enhancements provided by this plugin; caching is handled automatically by WordPress/PHP alone. That being said, if you want to take advantage of additional speed enhancements by optimizing the Apache web server to achieve maximize performance (and we do recommend this), then you WILL need an <code>.htaccess</code> file to accomplish that part.', 'rapid-cache').'</p>'."\n";
     682            echo '      <p>'.__('WordPress itself uses the <code>.htaccess</code> file to create Apache rewrite rules when you enable fancy Permalinks, so there\'s a good chance you already have an <code>.htaccess</code> file. The options below allow for additional performance tuning using recommendations provided by Rapid Cache.', 'rapid-cache').'</p>'."\n";
     683            echo '      <p>'.__('When you enable one of the options below, Rapid Cache will attempt to automatically insert the appropriate configuration into your <code>.htaccess</code> file (or remove it automatically if you are disabling an option). If Rapid Cache is unable to update the file, or if you would prefer to add the configuration yourself, the recommended configuration to add to the file can be viewed at the bottom of each option.', 'rapid-cache').'</p>'."\n";
     684            echo '              <p class="info" style="display:block;">'.__('<strong>Note:</strong> The <code>.htaccess</code> file is parsed by the web server directly, before WordPress is even loaded. For that reason, if something goes wrong in the file you can end up with a broken site. We recommend creating a backup of your current <code>.htaccess</code> file before making any modifications.', 'rapid-cache').'</p>'."\n";
     685            echo '      <hr />'."\n";
     686            echo '      <h3>'.__('Enable GZIP Compression?', 'rapid-cache').'</h3>'."\n";
     687            echo '      <p>'.__('<a href="https://bit.ly/3jUtUD1" target="_blank">GZIP compression</a> is highly recommended. It\'s not uncommon to achieve compression rates as high as 70-90%, which is a huge savings in the amount of data that needs to be transferred with each visit to your site.', 'rapid-cache').'</p>'."\n";
     688            echo '      <p>'.sprintf(__('%1$s fully supports GZIP compression on its output. However, it does not handle GZIP compression directly like some caching plugins. We purposely left GZIP compression out of this plugin because GZIP compression is something that should really be enabled at the Apache level or inside your <code>php.ini</code> file. GZIP compression can be used for things like JavaScript and CSS files as well, so why bother turning it on for only WordPress-generated pages when you can enable GZIP at the server level and cover all the bases!', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
     689            echo '      <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][htaccess_gzip_enable]" data-target=".-htaccess-gzip-enable-options">'."\n";
     690            echo '            <option value="0"'.selected($this->plugin->options['htaccess_gzip_enable'], '0', false).'>'.__('No, do NOT enable GZIP Compression (or I\'ll update my configuration manually; see below)', 'rapid-cache').'</option>'."\n";
     691            echo '            <option value="1"'.selected($this->plugin->options['htaccess_gzip_enable'], '1', false).'>'.__('Yes, enable GZIP Compression (recommended)', 'rapid-cache').'</option>'."\n";
     692            echo '         </select></p>'."\n";
     693            echo '      <p>'.__('Or, you can update your configuration manually: [<a href="#" data-toggle-target=".'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'-apache-optimizations--gzip-configuration').'"><i class="si si-eye"></i> .htaccess configuration <i class="si si-eye"></i></a>]', 'rapid-cache').'</p>'."\n";
     694            echo '      <div class="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'-apache-optimizations--gzip-configuration').'" style="display:none; margin-top:1em;">'."\n";
     695            echo '        <p>'.__('<strong>To enable GZIP compression:</strong> Create or edit the <code>.htaccess</code> file in your WordPress installation directory and add the following lines to the top:', 'rapid-cache').'</p>'."\n";
     696            echo '        <pre class="code"><code>'.esc_html($this->plugin->fillReplacementCodes(file_get_contents(MEGAOPTIM_RAPID_CACHE_PATH.'stubs/htaccess/gzip-enable.txt'))).'</code></pre>'."\n";
     697            echo '        <p class="info" style="display:block;">'.__('<strong>Or</strong>, if your server is missing <code>mod_deflate</code>/<code>mod_filter</code>; open your <code>php.ini</code> file and add this line: <a href="http://php.net/manual/en/zlib.configuration.php" target="_blank" style="text-decoration:none;"><code>zlib.output_compression = on</code></a>', 'rapid-cache').'</p>'."\n";
     698            echo '      </div>'."\n";
     699
     700            echo '      <hr />'."\n";
     701            echo '      <h3>'.__('Leverage Browser Caching?', 'rapid-cache').'</h3>'."\n";
     702            echo '      <p>'.__('<a href="https://bit.ly/3lNT8ou" target="_blank">Browser Caching</a> is highly recommended. When loading a single page, downloading all of the resources for that page may require multiple roundtrips between the browser and server, which delays processing and may block rendering of page content. This also incurs data costs for the visitor. With browser caching, your server tells the visitor\'s browser that it is allowed to cache static resources for a certain amount of time (Google recommends 1 week and that\'s what Rapid Cache uses).', 'rapid-cache').'</p>'."\n";
     703            echo '      <p>'.__('In WordPress, \'Page Caching\' is all about server-side performance (reducing the amount of time it takes the server to generate the page content). With Rapid Cache installed, you\'re drastically reducing page generation time. However, you can make a visitor\'s experience ​<em>even faster</em>​ when you leverage browser caching too. When this option is enabled, the visitor\'s browser will cache static resources from each page and reuse those cached resources on subsequent page loads. In this way, future visits to the same page will not require additional connections to your site to download static resources that the visitor\'s browser has already cached.', 'rapid-cache').'</p>'."\n";
     704            echo '      <p><select name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[saveOptions][htaccess_browser_caching_enable]" data-target=".-htaccess-browser-caching-enable-options">'."\n";
     705            echo '            <option value="0"'.(selected($this->plugin->options['htaccess_browser_caching_enable'], '0', false)).'>'.__('No, do NOT enable Browser Caching (or I\'ll update my configuration manually; see below)', 'rapid-cache').'</option>'."\n";
     706            echo '            <option value="1"'.(selected($this->plugin->options['htaccess_browser_caching_enable'], '1', false)).'>'.__('Yes, enable Browser Caching for static resources (recommended)', 'rapid-cache').'</option>'."\n";
     707            echo '         </select></p>'."\n";
     708            echo '      <p>'.__('Or, you can update your configuration manually: [<a href="#" data-toggle-target=".'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'-apache-optimizations--leverage-browser-caching').'"><i class="si si-eye"></i> .htaccess configuration <i class="si si-eye"></i></a>]', 'rapid-cache').'</p>'."\n";
     709            echo '      <div class="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'-apache-optimizations--leverage-browser-caching').'" style="display:none; margin-top:1em;">'."\n";
     710            echo '        <p>'.__('<strong>To enable Browser Caching:</strong> Create or edit the <code>.htaccess</code> file in your WordPress installation directory and add the following lines to the top:', 'rapid-cache').'</p>'."\n";
     711            echo '        <pre class="code"><code>'.esc_html($this->plugin->fillReplacementCodes(file_get_contents(MEGAOPTIM_RAPID_CACHE_PATH.'stubs/htaccess/browser-caching-enable.txt'))).'</code></pre>'."\n";
     712            echo '      </div>'."\n";
     713
     714            echo '   </div>'."\n";
     715            echo '</div>'."\n";
     716        }
     717
     718        /* ----------------------------------------------------------------------------------------- */
     719
     720        echo '<div class="plugin-menu-page-panel">'."\n";
     721
     722        echo '   <a href="#" class="plugin-menu-page-panel-heading">'."\n";
     723        echo '      <i class="si si-octi-plug"></i> '.__('Theme/Plugin Developers', 'rapid-cache')."\n";
     724        echo '   </a>'."\n";
     725
     726        echo '   <div class="plugin-menu-page-panel-body clearfix">'."\n";
     727        echo '      <i class="si si-puzzle-piece si-4x" style="float:right; margin: 0 0 0 25px;"></i>'."\n";
     728        echo '      <h3>'.__('Developing a Theme or Plugin for WordPress?', 'rapid-cache').'</h3>'."\n";
     729
     730        echo '      <p>'.sprintf(__('<strong>Tip:</strong> %1$s can be disabled temporarily. If you\'re a theme/plugin developer, you can set a flag within your PHP code to disable the cache engine at runtime. Perhaps on a specific page, or in a specific scenario.</p><p>In your PHP script, set: <code>$_SERVER[\'RAPID_CACHE_ALLOWED\'] = FALSE;</code> or <code>define(\'RAPID_CACHE_ALLOWED\', FALSE)</code>. %1$s is also compatible with: <code>define(\'DONOTCACHEPAGE\', TRUE)</code>. It does\'t matter where or when you define one of these, because %1$s is the last thing to run before script execution ends.</p><p>Check the <a href="https://github.com/megaoptim/rapid-cache/wiki/Developer-Hooks" target="_blank">Developer hooks</a>, <a target="_blank" href="https://github.com/megaoptim/rapid-cache/wiki/Clearing-the-Cache-Dynamically">Clearing the Cache Dynamically</a> or our <a target="_blank" href="https://github.com/megaoptim/rapid-cache/wiki">wiki</a> for more information.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
     731        echo '   </div>'."\n";
     732
     733        echo '</div>'."\n";
     734
     735        /* ----------------------------------------------------------------------------------------- */
     736
     737        echo '<div class="plugin-menu-page-panel">'."\n";
     738
     739        echo '   <a href="#" class="plugin-menu-page-panel-heading">'."\n";
     740        echo '      <i class="si si-arrow-circle-o-up"></i> '.__('Import/Export/Migrate', 'rapid-cache')."\n";
     741        echo '   </a>'."\n";
     742
     743        echo '   <div class="plugin-menu-page-panel-body clearfix">'."\n";
     744        echo '      <i class="si si-arrow-circle-o-up si-4x" style="float:right; margin: 0 0 0 25px;"></i>'."\n";
     745        echo '      <h3>'.sprintf(__('Import Options from Another %1$s Installation?', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</h3>'."\n";
     746        echo '      <p>'.sprintf(__('Upload your <code>options.json</code> file and click "Save All Changes" below. The options provided by your import file will override any that exist currently.', 'rapid-cache')).'</p>'."\n";
     747        echo '      <p><input type="file" name="'.esc_attr(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS).'[import_options]" /></p>'."\n";
     748        echo '      <hr />'."\n";
     749        echo '      <h3>'.sprintf(__('Export Existing Options from this %1$s Installation?', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</h3>'."\n";
     750        echo '      <p>'.sprintf(__('Download your existing options and import them all into another %1$s installation; saves time on future installs.', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME)).'</p>'."\n";
     751        echo '      <p><button type="button" class="plugin-menu-page-export-options"'.// Exports existing options from this installation.
     752             '         data-action="'.esc_attr(add_query_arg(urlencode_deep(['page' => MEGAOPTIM_RAPID_CACHE_GLOBAL_NS, '_wpnonce' => wp_create_nonce(), MEGAOPTIM_RAPID_CACHE_GLOBAL_NS => ['exportOptions' => '1']]), self_admin_url('/admin.php'))).'">'.
     753             '         <i class="si si-arrow-circle-o-down"></i> '.__('Export', 'rapid-cache').'</button></p>'."\n";
     754
     755        if(get_option(MEGAOPTIM_RAPID_CACHE_OLD_GLOBAL_NS.'_options')) {
     756            $_confirm = __('Are you sure that you want to copy the old options from Comet Cache? This will overwrite your current options and will not be possible to revert.');
     757            $action_migrate_purge = esc_attr(add_query_arg(urlencode_deep(['page' => MEGAOPTIM_RAPID_CACHE_GLOBAL_NS, '_wpnonce' => wp_create_nonce(), MEGAOPTIM_RAPID_CACHE_GLOBAL_NS => ['migrateFromLegacy' => '1'], 'purgeLegacy' => 1]), self_admin_url('/admin.php')));
     758            $action_migrate_normal = esc_attr(add_query_arg(urlencode_deep(['page' => MEGAOPTIM_RAPID_CACHE_GLOBAL_NS, '_wpnonce' => wp_create_nonce(), MEGAOPTIM_RAPID_CACHE_GLOBAL_NS => ['migrateFromLegacy' => '1']]), self_admin_url('/admin.php')));
     759            $action_migrate_default = $action_migrate_normal;
     760            echo '     <hr />'."\n";
     761            echo '     <h3>'.sprintf(__('Migration from %s', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_OLD_NAME)).'</h3>'."\n";
     762            echo '     <p>'.sprintf(__('We detected that you had a previous install of %s on your site. Click on the button to preserve the options.', 'rapid-cache'), '<strong>'.esc_html(MEGAOPTIM_RAPID_CACHE_OLD_NAME).'</strong>').'</p>'."\n";
     763            echo '     <p>'."\n";
     764            echo '     <p><input type="checkbox" class="plugin-delete-legacy-data">'.sprintf(__('Do you want to delete %s plugin options data after migration?', 'rapid-cache'), MEGAOPTIM_RAPID_CACHE_OLD_NAME).'</p>';
     765            echo '     <button type="button" class="plugin-action-migrate plugin-menu-page-export-options"'.// Exports existing options from this installation.
     766                 '        data-confirmation="'.$_confirm.'" '.
     767                 '        data-action="'.$action_migrate_default.'" '.
     768                 '        data-action-purge="'.$action_migrate_purge.'" '.
     769                 '        data-action-normal="'.$action_migrate_normal.'">'.
     770                 '        <i class="si si-copy"></i> '.__('Migrate', 'rapid-cache').'</button></p>'."\n";
     771        }
     772
     773        echo '   </div>'."\n";
     774
     775        echo '</div>'."\n";
     776        /* ----------------------------------------------------------------------------------------- */
     777
     778        echo '<div class="plugin-menu-page-save">'."\n";
     779        echo '   <button type="submit">'.__('Save All Changes', 'rapid-cache').' <i class="si si-save"></i></button>'."\n";
     780        echo '</div>'."\n";
     781
     782        /* ----------------------------------------------------------------------------------------- */
     783
     784        echo '</div>'."\n";
     785        echo '</form>';
     786    }
    1122787}
  • rapid-cache/trunk/includes/src/Classes/Plugin.php

    r2500432 r3027335  
    99namespace MegaOptim\RapidCache\Classes;
    1010
    11 use MegaOptim\RapidCache\Classes;
    1211use MegaOptim\RapidCache\Traits;
    1312
     
    2221    use Traits\Plugin\ActionUtils;
    2322    use Traits\Plugin\AdminBarUtils;
     23    use Traits\Plugin\AutoCacheUtils;
    2424    use Traits\Plugin\BbPressUtils;
    2525    use Traits\Plugin\CleanupUtils;
     
    5151    use Traits\Plugin\WcpTransientUtils;
    5252    use Traits\Plugin\WcpUpdaterUtils;
    53     use Traits\Plugin\WcpUtils;
     53    use Traits\Plugin\WcpUrlUtils;
     54    use Traits\Plugin\WcpUtils;
    5455    use Traits\Plugin\WcpWooCommerceUtils;
    5556    /*[/.build.php-auto-generate-use-Traits]*/
     
    6364     */
    6465    public $enable_hooks = true;
    65 
    66     /**
    67      * Pro-only option keys.
    68      *
    69      * @since 1.0.0
    70      *
    71      * @type array Pro-only option keys.
    72      */
    73     public $pro_only_option_keys = [];
    7466
    7567    /**
     
    177169        load_plugin_textdomain(MEGAOPTIM_RAPID_CACHE_SLUG); // Text domain.
    178170
    179         $this->pro_only_option_keys = [
    180             'cache_max_age_disable_if_load_average_is_gte',
    181 
    182             'change_notifications_enable',
    183 
    184             'cache_clear_admin_bar_options_enable',
    185             'cache_clear_admin_bar_roles_caps',
    186 
    187             'cache_clear_cdn_enable',
    188             'cache_clear_opcache_enable',
    189             'cache_clear_s2clean_enable',
    190             'cache_clear_eval_code',
    191             'cache_clear_urls',
    192 
    193             'ignore_get_request_vars',
    194             'cache_nonce_values_when_logged_in',
    195 
    196             'when_logged_in',
    197 
    198             'version_salt',
    199             'mobile_adaptive_salt',
    200             'mobile_adaptive_salt_enable',
    201             'ua_info_last_data_update',
    202 
    203             'htmlc_enable',
    204             'htmlc_css_exclusions',
    205             'htmlc_js_exclusions',
    206             'htmlc_uri_exclusions',
    207             'htmlc_cache_expiration_time',
    208             'htmlc_compress_combine_head_body_css',
    209             'htmlc_compress_combine_head_js',
    210             'htmlc_compress_combine_footer_js',
    211             'htmlc_compress_combine_remote_css_js',
    212             'htmlc_compress_inline_js_code',
    213             'htmlc_compress_css_code',
    214             'htmlc_compress_js_code',
    215             'htmlc_compress_html_code',
    216             'htmlc_amp_exclusions_enable',
    217             'htmlc_when_logged_in',
    218 
    219             'auto_cache_enable',
    220             'auto_cache_max_time',
    221             'auto_cache_delay',
    222             'auto_cache_sitemap_url',
    223             'auto_cache_ms_children_too',
    224             'auto_cache_other_urls',
    225             'auto_cache_user_agent',
    226 
    227             'htaccess_browser_caching_enable',
    228             'htaccess_enforce_exact_host_name',
    229             'htaccess_enforce_canonical_urls',
    230             'htaccess_access_control_allow_origin',
    231 
    232             'cdn_enable',
    233             'cdn_host',
    234             'cdn_hosts',
    235             'cdn_invalidation_var',
    236             'cdn_invalidation_counter',
    237             'cdn_over_ssl',
    238             'cdn_when_logged_in',
    239             'cdn_whitelisted_extensions',
    240             'cdn_blacklisted_extensions',
    241             'cdn_whitelisted_uri_patterns',
    242             'cdn_blacklisted_uri_patterns',
    243 
    244             'stats_enable',
    245             'stats_admin_bar_enable',
    246             'stats_admin_bar_roles_caps',
    247 
    248             'dir_stats_history_days',
    249             'dir_stats_refresh_time',
    250             'dir_stats_auto_refresh_max_resources',
    251 
    252             'pro_update_check',
    253             'pro_update_check_stable',
    254             'last_pro_update_check',
    255 
    256             'latest_pro_version',
    257             'latest_pro_package',
    258 
    259             'pro_update_username',
    260             'pro_update_password',
    261 
    262             'pro_auto_update_enable',
    263 
    264             'last_pro_stats_log',
    265         ];
    266171        $this->default_options = [
    267172            /* Core/systematic plugin options. */
     
    293198            /* Related to cache clearing. */
    294199
    295             'change_notifications_enable' => '1', // `0|1`.
    296 
    297             'cache_clear_admin_bar_enable'         => '1', // `0|1`.
    298             'cache_clear_admin_bar_options_enable' => '1', // `0|1|2`.
    299             'cache_clear_admin_bar_roles_caps'     => '', // Comma-delimited list of roles/caps.
    300 
    301             'cache_clear_cdn_enable'        => '0', // `0|1`.
    302200            'cache_clear_opcache_enable'    => '0', // `0|1`.
    303             'cache_clear_s2clean_enable'    => '0', // `0|1`.
    304             'cache_clear_eval_code'         => '', // PHP code.
    305201            'cache_clear_urls'              => '', // Line-delimited list of URLs.
    306202            'cache_clear_transients_enable' => '0', // `0|1`
     
    358254            'ua_info_last_data_update'    => '0', // Timestamp.
    359255
    360             /* Related to HTML compressor. */
    361 
    362             'htmlc_enable' => '0', // Enable HTML compression?
    363 
    364             'htmlc_css_exclusions' => "id='rs-plugin-settings-inline-css'", // Empty string or line-delimited patterns.
    365             // This defaults to an exclusion rule that handles compatibility with RevSlider. See: <https://github.com/websharks/rapid-cache/issues/614>
    366 
    367             'htmlc_js_exclusions'         => '.php?', // Empty string or line-delimited patterns.
    368             'htmlc_uri_exclusions'        => '', // Empty string or line-delimited patterns.
    369             'htmlc_cache_expiration_time' => '14 days', // `strtotime()` compatible.
    370 
    371             'htmlc_compress_combine_head_body_css' => '1', // `0|1`.
    372             'htmlc_compress_combine_head_js'       => '1', // `0|1`.
    373             'htmlc_compress_combine_footer_js'     => '1', // `0|1`.
    374             'htmlc_compress_combine_remote_css_js' => '1', // `0|1`.
    375             'htmlc_compress_inline_js_code'        => '1', // `0|1`.
    376             'htmlc_compress_css_code'              => '1', // `0|1`.
    377             'htmlc_compress_js_code'               => '1', // `0|1`.
    378             'htmlc_compress_html_code'             => '1', // `0|1`.
    379             'htmlc_amp_exclusions_enable'          => '1', // `0|1`.
    380             'htmlc_when_logged_in'                 => '0', // `0|1`; enable when logged in?
    381 
    382256            /* Related to auto-cache engine. */
    383257
     
    394268            'htaccess_browser_caching_enable'      => '0', // `0|1`; enable browser caching?
    395269            'htaccess_gzip_enable'                 => '0', // `0|1`; enable GZIP compression?
    396             'htaccess_enforce_exact_host_name'     => '0', // `0|1`; enforce exact hostname?
    397             'htaccess_enforce_canonical_urls'      => '0', // `0|1`; enforce canonical URLs?
    398             'htaccess_access_control_allow_origin' => '0', // `0|1`; send Access-Control-Allow-Origin header?
    399 
    400             /* Related to CDN functionality. */
    401 
    402             'cdn_enable' => '0', // `0|1`; enable CDN filters?
    403 
    404             'cdn_host'  => '', // e.g., `d1v41qemfjie0l.cloudfront.net`
    405             'cdn_hosts' => '', // e.g., line-delimited list of CDN hosts.
    406 
    407             'cdn_invalidation_var'     => 'iv', // A query string variable name.
    408             'cdn_invalidation_counter' => '1', // Current version counter.
    409 
    410             'cdn_over_ssl'       => '0', // `0|1`; enable SSL compat?
    411             'cdn_when_logged_in' => '0', // `0|1`; enable when logged in?
    412 
    413             'cdn_whitelisted_extensions' => '', // Whitelisted extensions.
    414             // This is a comma-delimited list. Delimiters may include of these: `[|;,\s]`.
    415             // Defaults to all extensions supported by the WP media library; i.e. `wp_get_mime_types()`.
    416 
    417             'cdn_blacklisted_extensions' => '', // Blacklisted extensions.
    418             // This is a comma-delimited list. Delimiters may include of these: `[|;,\s]`.
    419 
    420             'cdn_whitelisted_uri_patterns' => '', // A line-delimited list of inclusion patterns.
    421             // Wildcards `*` are supported here. Matched against local file URIs.
    422 
    423             'cdn_blacklisted_uri_patterns' => '', // A line-delimited list of exclusion patterns.
    424             // Wildcards `*` are supported here. Matched against local file URIs.
    425 
    426             /* Related to statistics/charts. */
    427 
    428             'stats_enable'               => is_multisite() && wp_is_large_network() ? '0' : '1',
    429             'stats_admin_bar_enable'     => '1', // `0|1`; enable stats in admin bar?
    430             'stats_admin_bar_roles_caps' => '', // Comma-delimited list of roles/caps.
    431 
    432             'dir_stats_auto_refresh_max_resources' => '1500', // Don't use cache if less than this.
    433             'dir_stats_refresh_time'               => '15 minutes', // `strtotime()` compatible.
    434             'dir_stats_history_days'               => '30', // Numeric; number of days.
    435 
    436             /* Related to automatic pro updates. */
    437 
    438             'pro_update_check'        => '1', // `0|1`; enable?
    439             'pro_update_check_stable' => '1', // `0` for beta/RC checks.
    440             'last_pro_update_check'   => '0', // Timestamp.
    441 
    442             'latest_pro_version' => MEGAOPTIM_RAPID_CACHE_VERSION, // Latest version.
    443             'latest_pro_package' => '', // Latest package URL.
    444 
    445             'pro_update_username' => '', // Username.
    446             'pro_update_password' => '', // Password or license key.
    447 
    448             'pro_auto_update_enable' => '0', // `0|1`; enable?
    449 
    450             /* Related to stats logging. */
    451 
    452             'last_pro_stats_log' => '0', // Timestamp.
    453270
    454271            /* Related to uninstallation routines. */
     
    478295        add_action('wp_loaded', [$this, 'actions']);
    479296
     297        add_action('admin_init', [$this, 'autoCacheMaybeClearPrimaryXmlSitemapError']);
     298        add_action('admin_init', [$this, 'autoCacheMaybeClearPhpReqsError']);
     299
    480300        add_action('admin_bar_menu', [$this, 'adminBarMenu']);
    481301        add_action('wp_head', [$this, 'adminBarMetaTags'], 0);
     
    555375            add_filter('cron_schedules', [$this, 'extendCronSchedules']);
    556376            add_action('_cron_'.MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_cleanup', [$this, 'cleanupCache']);
     377            add_action('_cron_'.MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_auto_cache', [$this, 'autoCache']);
    557378        }
    558379
  • rapid-cache/trunk/includes/src/Traits/Ac/AbortUtils.php

    r2380046 r3027335  
    77 * @copyright 2016 WP Sharks (https://wpsharks.com/)
    88 */
     9
    910namespace MegaOptim\RapidCache\Traits\Ac;
    1011
    11 use MegaOptim\RapidCache\Classes;
    12 
    13 trait AbortUtils
    14 {
    15     /**
    16      * Ignores user aborts; when/if the Auto-Cache Engine is running.
    17      *
    18      * @since 1.0.0
    19      */
    20     public function maybeIgnoreUserAbort()
    21     {
    22        
    23     }
     12trait AbortUtils {
     13    /**
     14     * Ignores user aborts; when/if the Auto-Cache Engine is running.
     15     *
     16     * @since 1.0.0
     17     */
     18    public function maybeIgnoreUserAbort() {
     19        if ( $this->isAutoCacheEngine() ) {
     20            ignore_user_abort( true );
     21        }
     22    }
    2423}
  • rapid-cache/trunk/includes/src/Traits/Ac/NcDebugUtils.php

    r2380046 r3027335  
    3333    {
    3434        if (!RAPID_CACHE_DEBUGGING_ENABLE) {
    35             return; // Nothing to do.
     35            return null; // Nothing to do.
    3636        }
    3737        $reason = (string) $reason;
    3838        if (!($reason_code = (string) $reason_code)) {
    39             return; // Not applicable.
     39            return null; // Not applicable.
    4040        }
    4141        $this->debug_info = ['reason_code' => $reason_code, 'reason' => $reason];
     42
     43        return null;
    4244    }
    4345
  • rapid-cache/trunk/includes/src/Traits/Ac/ObUtils.php

    r2380046 r3027335  
    3939     */
    4040    public $host_base_dir_tokens = '';
    41    
     41
    4242
    4343    /**
     
    130130     *       This method serves existing (fresh) cache files. It is also responsible
    131131     *       for beginning the process of collecting the output buffer.
     132     *
     133     * @return mixed
    132134     */
    133135    public function maybeStartOutputBuffering()
    134136    {
    135         if (strcasecmp(PHP_SAPI, 'cli') === 0) {
     137        if (strcasecmp(PHP_SAPI, 'cli') === 0) {
    136138            return $this->maybeSetDebugInfo($this::NC_DEBUG_PHP_SAPI_CLI);
    137139        }
     
    151153            return $this->maybeSetDebugInfo($this::NC_DEBUG_DONOTCACHEPAGE_CONSTANT);
    152154        }
    153         if (isset($_SERVER['DONOTCACHEPAGE'])) {
     155        if (isset($_SERVER['DONOTCACHEPAGE'])) {
    154156            return $this->maybeSetDebugInfo($this::NC_DEBUG_DONOTCACHEPAGE_SERVER_VAR);
    155157        }
     
    163165            return $this->maybeSetDebugInfo($this::NC_DEBUG_AC_GET_VAR);
    164166        }
    165         if ($this->isUncacheableRequestMethod()) {
     167        if ($this->isUncacheableRequestMethod()) {
    166168            return $this->maybeSetDebugInfo($this::NC_DEBUG_UNCACHEABLE_REQUEST);
    167169        }
    168170        if (isset($_SERVER['SERVER_ADDR']) && $this->currentIp() === $_SERVER['SERVER_ADDR']) {
    169             if ((!MEGAOPTIM_RAPID_CACHE_IS_PRO || !$this->isAutoCacheEngine()) && !$this->isLocalhost()) {
     171            if ((!$this->isAutoCacheEngine()) && !$this->isLocalhost()) {
    170172                return $this->maybeSetDebugInfo($this::NC_DEBUG_SELF_SERVE_REQUEST);
    171173            } // Don't trip on requests by the auto-cache engine.
     
    174176            return $this->maybeSetDebugInfo($this::NC_DEBUG_FEED_REQUEST);
    175177        }
    176         if (preg_match('/\/(?:wp\-[^\/]+|xmlrpc)\.php(?:[?]|$)/ui', $_SERVER['REQUEST_URI'])) {
     178        if (preg_match('/\/(?:wp\-[^\/]+|xmlrpc)\.php(?:[?]|$)/ui', $_SERVER['REQUEST_URI'])) {
    177179            return $this->maybeSetDebugInfo($this::NC_DEBUG_WP_SYSTEMATICS);
    178180        }
     
    183185            return $this->maybeSetDebugInfo($this::NC_DEBUG_MS_FILES);
    184186        }
    185         if ((!MEGAOPTIM_RAPID_CACHE_IS_PRO || !RAPID_CACHE_WHEN_LOGGED_IN) && $this->isLikeUserLoggedIn()) {
     187        if (!RAPID_CACHE_WHEN_LOGGED_IN && $this->isLikeUserLoggedIn()) {
    186188            return $this->maybeSetDebugInfo($this::NC_DEBUG_IS_LIKE_LOGGED_IN_USER);
    187189        }
    188         if (!RAPID_CACHE_GET_REQUESTS && $this->requestContainsUncacheableQueryVars()) {
     190        if (!RAPID_CACHE_GET_REQUESTS && $this->requestContainsUncacheableQueryVars()) {
    189191            return $this->maybeSetDebugInfo($this::NC_DEBUG_GET_REQUEST_QUERIES);
    190192        }
    191         if (!empty($_REQUEST['preview'])) { // Don't cache previews under any circumstance.
     193        if (!empty($_REQUEST['preview'])) { // Don't cache previews under any circumstance.
    192194            return $this->maybeSetDebugInfo($this::NC_DEBUG_PREVIEW);
    193195        }
     
    198200            return $this->maybeSetDebugInfo($this::NC_DEBUG_EXCLUDED_URIS);
    199201        }
    200         if (RAPID_CACHE_EXCLUDE_AGENTS && !empty($_SERVER['HTTP_USER_AGENT']) && (!MEGAOPTIM_RAPID_CACHE_IS_PRO || !$this->isAutoCacheEngine())) {
    201             if (preg_match(RAPID_CACHE_EXCLUDE_AGENTS, $_SERVER['HTTP_USER_AGENT'])) {
     202        if (RAPID_CACHE_EXCLUDE_AGENTS && !empty($_SERVER['HTTP_USER_AGENT']) || (!$this->isAutoCacheEngine())) {
     203            if (!empty($_SERVER['HTTP_USER_AGENT']) && preg_match(RAPID_CACHE_EXCLUDE_AGENTS, $_SERVER['HTTP_USER_AGENT'])) {
    202204                return $this->maybeSetDebugInfo($this::NC_DEBUG_EXCLUDED_AGENTS);
    203205            } // Don't trip on requests by the auto-cache engine.
     
    221223        $this->version_salt = $this->applyFilters(get_class($this).'__version_salt', $this->version_salt);
    222224        $this->version_salt = $this->applyFilters(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_version_salt', $this->version_salt);
     225        $this->version_salt = $this->applyWpFilters(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_version_salt', $this->version_salt);
    223226
    224227        $this->cache_path = $this->buildCachePath($this->protocol.$this->host_token.$_SERVER['REQUEST_URI'], '', $this->version_salt);
     
    233236        $this->nonce_cache_max_age = strtotime('-12 hours'); // Initialize; based on a fixed expiration time.
    234237
    235 
    236         if (MEGAOPTIM_RAPID_CACHE_IS_PRO && RAPID_CACHE_WHEN_LOGGED_IN === 'postload' && $this->isLikeUserLoggedIn()) {
     238        if (defined('RAPID_CACHE_WHEN_LOGGED_IN') && RAPID_CACHE_WHEN_LOGGED_IN === 'postload' && $this->isLikeUserLoggedIn()) {
    237239            $this->postload['when_logged_in'] = true; // Enable postload check.
    238240        } elseif (is_file($this->cache_file) && ($this->cache_max_age_disabled || filemtime($this->cache_file) >= $this->cache_max_age)) {
     
    313315            return (bool) $this->maybeSetDebugInfo($this::NC_DEBUG_REST_REQUEST_CONSTANT);
    314316        }
    315         if ((!MEGAOPTIM_RAPID_CACHE_IS_PRO || !RAPID_CACHE_WHEN_LOGGED_IN) && $this->is_user_logged_in) {
     317        if ((!defined('RAPID_CACHE_WHEN_LOGGED_IN') || !RAPID_CACHE_WHEN_LOGGED_IN) && $this->is_user_logged_in) {
    316318            return (bool) $this->maybeSetDebugInfo($this::NC_DEBUG_IS_LOGGED_IN_USER);
    317319        }
    318         if ((!MEGAOPTIM_RAPID_CACHE_IS_PRO || !RAPID_CACHE_WHEN_LOGGED_IN) && $this->isLikeUserLoggedIn()) {
     320        if ((!defined('RAPID_CACHE_WHEN_LOGGED_IN') || !RAPID_CACHE_WHEN_LOGGED_IN) && $this->isLikeUserLoggedIn()) {
    319321            return (bool) $this->maybeSetDebugInfo($this::NC_DEBUG_IS_LIKE_LOGGED_IN_USER);
    320322        }
    321         if (!RAPID_CACHE_CACHE_NONCE_VALUES && preg_match('/\b(?:_wpnonce|akismet_comment_nonce)\b/u', $cache)) {
    322             if (MEGAOPTIM_RAPID_CACHE_IS_PRO && RAPID_CACHE_WHEN_LOGGED_IN && $this->isLikeUserLoggedIn()) {
     323        if (!RAPID_CACHE_CACHE_NONCE_VALUES && preg_match('/\b(?:'.implode('|', $this->getPossibleNonceKeys()).')\b/u', $cache)) {
     324            if (defined('RAPID_CACHE_WHEN_LOGGED_IN') && RAPID_CACHE_WHEN_LOGGED_IN && $this->isLikeUserLoggedIn()) {
    323325                if (!RAPID_CACHE_CACHE_NONCE_VALUES_WHEN_LOGGED_IN) {
    324326                    return (bool) $this->maybeSetDebugInfo($this::NC_DEBUG_IS_LOGGED_IN_USER_NONCE);
     
    387389            $DebugNotes->addLineBreak();
    388390
    389             if (MEGAOPTIM_RAPID_CACHE_IS_PRO && RAPID_CACHE_WHEN_LOGGED_IN && $this->user_token) {
     391            if (defined('RAPID_CACHE_WHEN_LOGGED_IN') && RAPID_CACHE_WHEN_LOGGED_IN && $this->user_token) {
    390392                $DebugNotes->add(__('Cache File User Token', 'rapid-cache'), $this->user_token);
    391393            }
    392             if (MEGAOPTIM_RAPID_CACHE_IS_PRO && RAPID_CACHE_MOBILE_ADAPTIVE_SALT_ENABLE && RAPID_CACHE_MOBILE_ADAPTIVE_SALT && $this->mobile_adaptive_salt) {
     394            if (defined('RAPID_CACHE_MOBILE_ADAPTIVE_SALT_ENABLE') && RAPID_CACHE_MOBILE_ADAPTIVE_SALT_ENABLE && defined('RAPID_CACHE_MOBILE_ADAPTIVE_SALT') && RAPID_CACHE_MOBILE_ADAPTIVE_SALT && $this->mobile_adaptive_salt) {
    393395                // Note: Not using `$this->mobile_adaptive_salt` here. Instead, generating a human readable variation.
    394396                $DebugNotes->add(__('Cache File for Mobile Device', 'rapid-cache'), $this->fillUaTokens(RAPID_CACHE_MOBILE_ADAPTIVE_SALT, false));
     
    404406            $DebugNotes->addLineBreak();
    405407
    406             $DebugNotes->add(__('Cache File Generated Via', 'rapid-cache'), MEGAOPTIM_RAPID_CACHE_IS_PRO && $this->isAutoCacheEngine() ? __('Auto-Cache Engine', 'rapid-cache') : __('HTTP request', 'rapid-cache'));
     408            $DebugNotes->add(__('Cache File Generated Via', 'rapid-cache'), $this->isAutoCacheEngine() ? __('Auto-Cache Engine', 'rapid-cache') : __('HTTP request', 'rapid-cache'));
    407409            $DebugNotes->add(__('Cache File Generated On', 'rapid-cache'), date('M jS, Y @ g:i a T'));
    408410            $DebugNotes->add(__('Cache File Generated In', 'rapid-cache'), sprintf(__('%1$s seconds', 'rapid-cache'), $total_time));
     
    410412            $DebugNotes->addLineBreak();
    411413
    412             if (MEGAOPTIM_RAPID_CACHE_IS_PRO && RAPID_CACHE_WHEN_LOGGED_IN && $this->cache_max_age < $this->nonce_cache_max_age && preg_match('/\b(?:_wpnonce|akismet_comment_nonce)\b/u', $cache)) {
     414            if ((defined('RAPID_CACHE_WHEN_LOGGED_IN') && RAPID_CACHE_WHEN_LOGGED_IN) && $this->cache_max_age < $this->nonce_cache_max_age && preg_match('/\b(?:'.implode('|', $this->getPossibleNonceKeys()).')\b/u', $cache)) {
    413415                $DebugNotes->add(__('Cache File Expires Early', 'rapid-cache'), __('yes, due to nonce in markup', 'rapid-cache'));
    414416                $DebugNotes->add(__('Cache File Expires On', 'rapid-cache'), date('M jS, Y @ g:i a T', $time + ($time - $this->nonce_cache_max_age)));
     
    438440        throw new \Exception(sprintf(__('%1$s: failed to write cache file for: `%2$s`; possible permissions issue (or race condition), please check your cache directory: `%3$s`.', 'rapid-cache'), MEGAOPTIM_RAPID_CACHE_NAME, $_SERVER['REQUEST_URI'], RAPID_CACHE_DIR));
    439441    }
     442
     443    /**
     444     * Returns all possible nonce keys
     445     *
     446     * @since 1.2.0
     447     *
     448     * @return string[]
     449     */
     450    protected function getPossibleNonceKeys() {
     451        return $this->applyWpFilters( MEGAOPTIM_RAPID_CACHE_GLOBAL_NS . '_possible_nonce_keys', [
     452            '_wpnonce',
     453            'akismet_comment_nonce',
     454            'rest_nonce',
     455        ] );
     456    }
    440457}
  • rapid-cache/trunk/includes/src/Traits/Ac/PostloadUtils.php

    r2380046 r3027335  
    9090    public $is_maintenance = false;
    9191
     92    /**
     93     * Calculated user token; applicable w/ user postload enabled.
     94     *
     95     * @since 1.2.0
     96     *
     97     * @type string|int An MD5 hash token; or a specific WP user ID.
     98     */
     99    public $user_token = '';
     100
    92101    /**
    93102     * Array of data targeted at the postload phase.
     
    98107     */
    99108    public $postload = [
    100        
    101         'filter_status_header' => true,
    102         'wp_main_query'        => true,
    103         'set_debug_info'       => RAPID_CACHE_DEBUGGING_ENABLE,
     109        'invalidate_when_logged_in' => false,
     110        'when_logged_in'            => false,
     111        'filter_status_header'      => true,
     112        'wp_main_query'             => true,
     113        'set_debug_info'            => RAPID_CACHE_DEBUGGING_ENABLE,
    104114    ];
    105115
    106    
    107 
    108    
    109 
    110    
    111 
    112    
     116    /**
     117     * Sets a flag for possible invalidation upon certain actions in the postload phase.
     118     *
     119     * @since 1.2.0
     120     */
     121    public function maybePostloadInvalidateWhenLoggedIn()
     122    {
     123        if (!defined('RAPID_CACHE_WHEN_LOGGED_IN') || RAPID_CACHE_WHEN_LOGGED_IN !== 'postload') {
     124            return; // Nothing to do in this case.
     125        }
     126        if (is_admin()) {
     127            return; // No invalidations.
     128        }
     129        if (!$this->isLikeUserLoggedIn()) {
     130            return; // Nothing to do.
     131        }
     132        if (!empty($_REQUEST[MEGAOPTIM_RAPID_CACHE_GLOBAL_NS])) {
     133            return; // Plugin action.
     134        }
     135        if ($this->isPostPutDeleteRequest() || $this->isUncacheableRequestMethod()) {
     136            $this->postload['invalidate_when_logged_in'] = true;
     137        } elseif (!RAPID_CACHE_GET_REQUESTS && $this->requestContainsUncacheableQueryVars()) {
     138            $this->postload['invalidate_when_logged_in'] = true;
     139        }
     140    }
     141
     142    /**
     143     * Invalidates cache files for a user (if applicable).
     144     *
     145     * @since 1.2.0
     146     */
     147    public function maybeInvalidateWhenLoggedInPostload()
     148    {
     149        if (!defined('RAPID_CACHE_WHEN_LOGGED_IN') || RAPID_CACHE_WHEN_LOGGED_IN !== 'postload') {
     150            return; // Nothing to do in this case.
     151        }
     152        if (empty($this->postload['invalidate_when_logged_in'])) {
     153            return; // Nothing to do in this case.
     154        }
     155        if (!($this->user_token = $this->userToken())) {
     156            return; // Nothing to do in this case.
     157        }
     158        if ($this->applyWpFilters(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_invalidate_when_logged_in_postload', true) === false) {
     159            return; // Nothing to do in this case (disabled via filter).
     160        }
     161        $regex = $this->assembleCachePathRegex('', '.*?\.u\/'.preg_quote($this->user_token, '/').'[.\/]');
     162        $this->wipeFilesFromCacheDir($regex); // Wipe matching files.
     163    }
     164
     165    /**
     166     * Starts output buffering in the postload phase (i.e. a bit later);
     167     *    when/if user caching is enabled; and if applicable.
     168     *
     169     * @since 1.2.0
     170     *
     171     * @return void
     172     */
     173    public function maybeStartObWhenLoggedInPostload()
     174    {
     175        if (!defined('RAPID_CACHE_WHEN_LOGGED_IN') || RAPID_CACHE_WHEN_LOGGED_IN !== 'postload') {
     176            return; // Nothing to do in this case.
     177        }
     178        if (empty($this->postload['when_logged_in'])) {
     179            return; // Nothing to do in this case.
     180        }
     181        if (!($this->user_token = $this->userToken())) {
     182            if (!$this->user_login_cookie_expired_or_invalid) {
     183                return $this->maybeSetDebugInfo(self::NC_DEBUG_NO_USER_TOKEN);
     184            }
     185        }
     186        $this->cache_path = $this->buildCachePath($this->protocol.$this->host_token.$_SERVER['REQUEST_URI'], $this->user_token, $this->version_salt);
     187        $this->cache_file = RAPID_CACHE_DIR.'/'.$this->cache_path; // Now considering a user token.
     188
     189        if (is_file($this->cache_file) && ($this->cache_max_age_disabled || filemtime($this->cache_file) >= $this->cache_max_age)) {
     190            list($headers, $cache) = explode('<!--headers-->', file_get_contents($this->cache_file), 2);
     191
     192            if (filemtime($this->cache_file) < $this->nonce_cache_max_age && preg_match('/\b(?:_wpnonce|akismet_comment_nonce)\b/u', $cache)) {
     193                ob_start([$this, 'outputBufferCallbackHandler']); // This ignores `cache_max_age_disabled` in favor of better security.
     194            } else {
     195                $headers_list = $this->headersList(); // Headers that are enqueued already.
     196
     197                foreach (unserialize($headers) as $_header) {
     198                    if (!in_array($_header, $headers_list, true) && mb_stripos($_header, 'last-modified:') !== 0) {
     199                        header($_header); // Only cacheable/safe headers are stored in the cache.
     200                    }
     201                } // unset($_header); // Just a little housekeeping.
     202
     203                if (RAPID_CACHE_DEBUGGING_ENABLE && $this->isHtmlXmlDoc($cache)) {
     204                    $total_time = number_format(microtime(true) - $this->timer, 5, '.', '');
     205
     206                    $DebugNotes = new Classes\Notes();
     207
     208                    $DebugNotes->add(__('Loaded via Cache On', 'rapid-cache'), date('M jS, Y @ g:i a T'));
     209                    $DebugNotes->add(__('Loaded via Cache In', 'rapid-cache'), sprintf(__('%1$s seconds', 'rapid-cache'), $total_time));
     210
     211                    $cache .= "\n\n".$DebugNotes->asHtmlComments();
     212                }
     213                exit($cache); // Exit with cache contents.
     214            }
     215        } else {
     216            ob_start([$this, 'outputBufferCallbackHandler']);
     217        }
     218    }
    113219
    114220    /**
  • rapid-cache/trunk/includes/src/Traits/Plugin/ActionUtils.php

    r2380046 r3027335  
    77 * @copyright 2016 WP Sharks (https://wpsharks.com/)
    88 */
     9
    910namespace MegaOptim\RapidCache\Traits\Plugin;
    1011
    1112use MegaOptim\RapidCache\Classes;
    1213
    13 trait ActionUtils
    14 {
    15     /**
    16      * Plugin action handler.
    17      *
    18      * @since 1.0.0
    19      *
    20      * @attaches-to `wp_loaded` hook.
    21      */
    22     public function actions()
    23     {
    24         if (!empty($_REQUEST[MEGAOPTIM_RAPID_CACHE_GLOBAL_NS])) {
    25             new Classes\Actions();
    26         }
    27        
    28     }
     14trait ActionUtils {
     15    /**
     16     * Plugin action handler.
     17     *
     18     * @since 1.0.0
     19     *
     20     * @attaches-to `wp_loaded` hook.
     21     */
     22    public function actions() {
     23        if ( ! empty( $_REQUEST[ MEGAOPTIM_RAPID_CACHE_GLOBAL_NS ] ) ) {
     24            new Classes\Actions();
     25        }
     26
     27        if ( ! empty( $_REQUEST[ MEGAOPTIM_RAPID_CACHE_GLOBAL_NS . '_auto_cache_cron' ] ) ) {
     28            $this->autoCache();
     29            exit();
     30        }
     31
     32    }
    2933}
  • rapid-cache/trunk/includes/src/Traits/Plugin/AdminBarUtils.php

    r2500432 r3027335  
    1414     * Showing admin bar.
    1515     *
    16      * @param bool $feature Check something specific?
     16     * @param  bool  $feature Check something specific?
    1717     *
    1818     * @return bool True if showing.
     
    3030            switch ( $feature ) {
    3131                case 'cache_wipe':
    32                     $showing = $this->options['cache_clear_admin_bar_enable'] && $is_multisite;
     32                    $showing &= $is_multisite;
    3333                    break;
    3434                case 'cache_clear':
    3535                default: // Default case handler.
    36                     $showing = ( $this->options['cache_clear_admin_bar_enable'] && $is_multisite )
    37                                || ( $this->options['cache_clear_admin_bar_enable'] && ( ! $is_multisite || ! is_network_admin() || $this->isMenuPage( MEGAOPTIM_RAPID_CACHE_GLOBAL_NS . '*' ) ) );
     36                    $showing = $is_multisite
     37                               || ( ! $is_multisite || ! is_network_admin() || $this->isMenuPage( MEGAOPTIM_RAPID_CACHE_GLOBAL_NS . '*' ) );
    3838                    break;
    3939            }
     
    6868     */
    6969    public function adminBarMenu( \WP_Admin_Bar &$wp_admin_bar ) {
     70
    7071        if ( ! $this->adminBarShowing() ) {
    7172            return; // Nothing to do.
     
    8889        if ( $this->adminBarShowing( 'cache_clear' ) ) {
    8990
    90             if ( ( $cache_clear_options_showing = $this->adminBarShowing( 'cache_clear_options' ) ) ) {
     91            if ( ( $this->adminBarShowing( 'cache_clear_options' ) ) ) {
    9192                $cache_clear_options = '<li class="-home-url-only"><a href="#" title="' . __( 'Clear the Home Page cache', 'rapid-cache' ) . '">' . __( 'Home Page', 'rapid-cache' ) . '</a></li>';
    9293                if ( ! is_admin() ) {
     
    102103            } else {
    103104                $cache_clear_options = ''; // Empty in this default case.
    104             }
    105 
    106             if ( $cache_clear_options && $this->options['cache_clear_admin_bar_options_enable'] === '2' ) {
    107                 $wp_admin_bar->add_menu(
    108                     [
    109                         'parent' => 'top-secondary',
    110                         'id'     => MEGAOPTIM_RAPID_CACHE_GLOBAL_NS . '-clear-options',
    111                         'title'  => '',
    112                         'href'   => '#',
    113                         'meta'   => [
    114                             'title'    => __( 'Clear Options', 'rapid-cache' ),
    115                             'class'    => '-clear-options',
    116                             'tabindex' => - 1,
    117                         ],
    118                     ]
    119                 );
    120                 $wp_admin_bar->add_group(
    121                     [
    122                         'parent' => MEGAOPTIM_RAPID_CACHE_GLOBAL_NS . '-clear-options',
    123                         'id'     => MEGAOPTIM_RAPID_CACHE_GLOBAL_NS . '-clear-options-wrapper',
    124                         'meta'   => [
    125                             'class' => '-wrapper',
    126                         ],
    127                     ]
    128                 );
    129                 $wp_admin_bar->add_menu(
    130                     [
    131                         'parent' => MEGAOPTIM_RAPID_CACHE_GLOBAL_NS . '-clear-options-wrapper',
    132                         'id'     => MEGAOPTIM_RAPID_CACHE_GLOBAL_NS . '-clear-options-container',
    133                         'title'  => '<div class="-label">' .
    134                                     '   <span class="-text">' . __( 'Clear Cache', 'rapid-cache' ) . '</span>' .
    135                                     '</div>' .
    136                                     '<ul class="-options">' .
    137                                     '   ' . $cache_clear_options .
    138                                     '</ul>' .
    139                                     '<div class="-spacer"></div>',
    140                         'meta'   => [
    141                             'class'    => '-container',
    142                             'tabindex' => - 1,
    143                         ],
    144                     ]
    145                 );
    146105            }
    147106
     
    161120                ]
    162121            );
    163             if ( $cache_clear_options && $this->options['cache_clear_admin_bar_options_enable'] === '1' ) {
     122            if ( $cache_clear_options ) {
    164123                $wp_admin_bar->add_group(
    165124                    [
     
    207166            'currentUserHasCap'        => current_user_can( $this->cap ),
    208167            'currentUserHasNetworkCap' => current_user_can( $this->network_cap ),
    209             'htmlCompressorEnabled'    => (bool) $this->options['htmlc_enable'],
    210168            'ajaxURL'                  => site_url( '/wp-load.php', is_ssl() ? 'https' : 'http' ),
    211169            'i18n'                     => [
  • rapid-cache/trunk/includes/src/Traits/Plugin/CronUtils.php

    r2380046 r3027335  
    4747            || $this->options['crons_setup_on_wp_with_schedules'] !== sha1(serialize(wp_get_schedules()))
    4848            || !wp_next_scheduled('_cron_'.MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_cleanup')
    49            
     49            || !wp_next_scheduled('_cron_'.MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_auto_cache')
     50
    5051        ) {
    51             wp_clear_scheduled_hook('_cron_'.MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_cleanup');
    52             wp_schedule_event(time() + 60, $this->options['cache_cleanup_schedule'], '_cron_'.MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_cleanup');
     52            wp_clear_scheduled_hook( '_cron_' . MEGAOPTIM_RAPID_CACHE_GLOBAL_NS . '_cleanup' );
     53            wp_schedule_event( time() + 60, $this->options['cache_cleanup_schedule'], '_cron_' . MEGAOPTIM_RAPID_CACHE_GLOBAL_NS . '_cleanup' );
    5354
    54            
     55            wp_clear_scheduled_hook( '_cron_' . MEGAOPTIM_RAPID_CACHE_GLOBAL_NS . '_auto_cache' );
     56            wp_schedule_event( time() + 60, 'every15m', '_cron_' . MEGAOPTIM_RAPID_CACHE_GLOBAL_NS . '_auto_cache' );
    5557
    5658            $this->updateOptions(
  • rapid-cache/trunk/includes/src/Traits/Plugin/HtaccessUtils.php

    r2380046 r3027335  
    3232     */
    3333    public $options_with_htaccess_rules = [
    34         'cdn_enable',
    3534        'htaccess_browser_caching_enable',
    3635        'htaccess_gzip_enable',
    37         'htaccess_enforce_canonical_urls',
    3836    ];
    3937
     
    9290                    } // ↑ Only if GZIP is enabled at this time.
    9391                    break;
     92                case 'browser-caching-enable.txt':
     93                    if ($this->options['htaccess_browser_caching_enable']) {
     94                        $template_blocks .= $_template_file_contents."\n\n";
     95                    } // ↑ Only if browser caching is enabled at this time.
     96                    break;
    9497
    9598               
  • rapid-cache/trunk/includes/src/Traits/Plugin/InstallUtils.php

    r2380046 r3027335  
    2626        if (defined('WP_CLI') && WP_CLI) {
    2727            $this->updateOptions(['enable' => '1']);
    28         }
    29         if (MEGAOPTIM_RAPID_CACHE_IS_PRO && (!$this->options['pro_update_username'] || !$this->options['pro_update_password'])) {
    30             $configure_pro_updater_url = add_query_arg(urlencode_deep(['page' => MEGAOPTIM_RAPID_CACHE_GLOBAL_NS, MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_configure_pro_updater' => 1]), network_admin_url('/admin.php')).'#'.MEGAOPTIM_RAPID_CACHE_SLUG.'-configure-pro-updater';
    31             $this->enqueueMainNotice('<form method="post" action="'.esc_url($configure_pro_updater_url).'" style="margin:.5em 0;">'.sprintf(__('<strong>IMPORTANT:</strong> To be notified when a new version of %1$s is available, please &nbsp; %2$s', 'rapid-cache'), esc_html(MEGAOPTIM_RAPID_CACHE_NAME), '<button type="submit" class="button" style="vertical-align:middle;">'.__('Configure Pro Update Credentials', 'rapid-cache').'</button>').'</form>', ['class' => 'notice notice-info', 'push_to_top' => true, 'persistent' => true, 'persistent_key' => 'configure-pro-updater', 'dismissable' => true]);
    3228        }
    3329        if (!$this->options['welcomed'] && !$this->options['enable']) {
  • rapid-cache/trunk/includes/src/Traits/Plugin/MenuPageUtils.php

    r2380046 r3027335  
    5353                'currentUserHasCap'        => current_user_can($this->cap),
    5454                'currentUserHasNetworkCap' => current_user_can($this->network_cap),
    55                 'htmlCompressorEnabled'    => (bool) $this->options['htmlc_enable'],
    5655                'ajaxURL'                  => site_url('/wp-load.php', is_ssl() ? 'https' : 'http'),
    5756                'emptyStatsCountsImageUrl' => $this->url('/assets/images/stats-fc-empty.png'),
  • rapid-cache/trunk/includes/src/Traits/Plugin/OptionUtils.php

    r2380536 r3027335  
    7979    public function updateOptions(array $options, $intersect = true)
    8080    {
    81         if (!MEGAOPTIM_RAPID_CACHE_IS_PRO) { // Do not save Pro option keys.
    82             $options = array_diff_key($options, $this->pro_only_option_keys);
    83         }
    84         if (!empty($options['base_dir']) && $options['base_dir'] !== $this->options['base_dir']) {
     81        if (!empty($options['base_dir']) && $options['base_dir'] !== $this->options['base_dir']) {
    8582            $this->tryErasingAllFilesDirsIn($this->wpContentBaseDirTo(''));
    86         }
    87         if (MEGAOPTIM_RAPID_CACHE_IS_PRO && !empty($options['pro_update_username']) && !empty($options['pro_update_password'])) {
    88             $this->dismissMainNotice('configure-pro-updater');
    8983        }
    9084        $this->options = array_merge($this->default_options, $this->options, $options);
     
    156150                $query_args[MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_advanced_cache_add_failure'] = $add_advanced_cache === null ? 'advanced-cache' : '1';
    157151            }
     152            if ($this->plugin->options['mobile_adaptive_salt_enable'] && !$this->plugin->maybePopulateUaInfoDirectory()) {
     153                $query_args[MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_ua_info_dir_population_failure'] = '1';
     154            }
    158155
    159156            if ( ! $this->plugin->options['auto_cache_enable']) {
  • rapid-cache/trunk/includes/src/Traits/Plugin/WcpAuthorUtils.php

    r2380046 r3027335  
    8282            $counter += $_author_counter; // Add to overall counter.
    8383
    84             if ($_author_counter && $enqueued_notices < 100 && is_admin() && (!MEGAOPTIM_RAPID_CACHE_IS_PRO || $this->options['change_notifications_enable'])) {
     84            if ($_author_counter && $enqueued_notices < 100 && is_admin()) {
    8585                $this->enqueueNotice(sprintf(__('Found %1$s in the cache for Author Page: <code>%2$s</code>; auto-clearing.', 'rapid-cache'), esc_html($this->i18nFiles($_author_counter)), esc_html($_author['display_name'])), ['combinable' => true]);
    8686                ++$enqueued_notices; // Increment enqueued notices counter.
     
    145145            $counter += $_author_counter; // Add to overall counter.
    146146
    147             if ($_author_counter && $enqueued_notices < 100 && is_admin() && (!MEGAOPTIM_RAPID_CACHE_IS_PRO || $this->options['change_notifications_enable'])) {
     147            if ($_author_counter && $enqueued_notices < 100 && is_admin()) {
    148148                $this->enqueueNotice(sprintf(__('Found %1$s in the cache for Author Page: <code>%2$s</code>; auto-clearing.', 'rapid-cache'), esc_html($this->i18nFiles($_author_counter)), esc_html($_author['display_name'])), ['combinable' => true]);
    149149                ++$enqueued_notices; // Increment enqueued notices counter.
  • rapid-cache/trunk/includes/src/Traits/Plugin/WcpDateArchiveUtils.php

    r2380046 r3027335  
    8989            $counter += $_url_counter; // Add to overall counter.
    9090
    91             if ($_url_counter && $enqueued_notices < 100 && is_admin() && (!MEGAOPTIM_RAPID_CACHE_IS_PRO || $this->options['change_notifications_enable'])) {
     91            if ($_url_counter && $enqueued_notices < 100 && is_admin()) {
    9292                $this->enqueueNotice(sprintf(__('Found %1$s in the cache for %2$s; auto-clearing.', 'rapid-cache'), esc_html($this->i18nFiles($_url_counter)), esc_html($_label)), ['combinable' => true]);
    9393                ++$enqueued_notices; // Increment enqueued notices counter.
  • rapid-cache/trunk/includes/src/Traits/Plugin/WcpFeedUtils.php

    r2380046 r3027335  
    118118        } // unset($_i, $_variation_regex_frags, $_regex); // Housekeeping.
    119119
    120         if ($counter && is_admin() && (!MEGAOPTIM_RAPID_CACHE_IS_PRO || $this->options['change_notifications_enable'])) {
     120        if ($counter && is_admin()) {
    121121            $this->enqueueNotice(sprintf(__('Found %1$s in the cache, for XML feeds of type: <code>%2$s</code>; auto-clearing.', 'rapid-cache'), esc_html($this->i18nFiles($counter)), esc_html($type)), ['combinable' => true]);
    122122        }
  • rapid-cache/trunk/includes/src/Traits/Plugin/WcpHomeBlogUtils.php

    r2380046 r3027335  
    4646        $counter += $this->clearFilesFromHostCacheDir($regex);
    4747
    48         if ($counter && is_admin() && (!MEGAOPTIM_RAPID_CACHE_IS_PRO || $this->options['change_notifications_enable'])) {
     48        if ($counter && is_admin()) {
    4949            $this->enqueueNotice(sprintf(__('Found %1$s in the cache for the designated "Home Page"; auto-clearing.', 'rapid-cache'), esc_html($this->i18nFiles($counter))), ['combinable' => true]);
    5050        }
     
    104104        $counter += $this->clearFilesFromHostCacheDir($regex);
    105105
    106         if ($counter && is_admin() && (!MEGAOPTIM_RAPID_CACHE_IS_PRO || $this->options['change_notifications_enable'])) {
     106        if ($counter && is_admin()) {
    107107            $this->enqueueNotice(sprintf(__('Found %1$s in the cache for the designated "Posts Page"; auto-clearing.', 'rapid-cache'), esc_html($this->i18nFiles($counter))), ['combinable' => true]);
    108108        }
  • rapid-cache/trunk/includes/src/Traits/Plugin/WcpOpcacheUtils.php

    r2380046 r3027335  
    2727    {
    2828        $counter = 0; // Initialize counter.
    29 
    30         if ($maybe && !$this->options['cache_clear_opcache_enable']) {
    31             return $counter; // Not enabled at this time.
    32         }
     29        if ($maybe && !$this->options['cache_clear_opcache_enable']) {
     30            return $counter; // Not enabled at this time.
     31        }
    3332        if (!$this->functionIsPossible('opcache_reset')) {
    3433            return $counter; // Not possible.
  • rapid-cache/trunk/includes/src/Traits/Plugin/WcpPostTypeUtils.php

    r2380046 r3027335  
    6969        $counter += $this->clearFilesFromHostCacheDir($regex);
    7070
    71         if ($counter && is_admin() && (!MEGAOPTIM_RAPID_CACHE_IS_PRO || $this->options['change_notifications_enable'])) {
     71        if ($counter && is_admin()) {
    7272            $this->enqueueNotice(sprintf(__('Found %1$s in the cache for Custom Post Type: <code>%2$s</code>; auto-clearing.', 'rapid-cache'), esc_html($this->i18nFiles($counter)), esc_html($custom_post_type_name)), ['combinable' => true]);
    7373        }
  • rapid-cache/trunk/includes/src/Traits/Plugin/WcpPostUtils.php

    r2380046 r3027335  
    9797        $counter += $this->clearFilesFromHostCacheDir($regex);
    9898
    99         if ($counter && is_admin() && (!MEGAOPTIM_RAPID_CACHE_IS_PRO || $this->options['change_notifications_enable'])) {
     99        if ($counter && is_admin()) {
    100100            $this->enqueueNotice(sprintf(__('Found %1$s in the cache for %2$s ID: <code>%3$s</code>; auto-clearing.', 'rapid-cache'), esc_html($this->i18nFiles($counter)), esc_html($post_type_singular_name), esc_html($post_id)), ['combinable' => true]);
    101101        }
     
    109109        $counter += $this->autoClearPostTermsCache($post_id, $force);
    110110        $counter += $this->autoClearDateArchiveCache($post_id, $force);
    111         $counter += $this->autoClearCustomPostTypeArchiveCache($post_id);
    112        
     111        $counter += $this->autoClearCustomPostTypeArchiveCache($post_id);
     112        $counter += $this->autoClearUrlsCache();
    113113
    114114        if ($post_type !== 'page' && ($parent_post_id = wp_get_post_parent_id($post_id))) {
  • rapid-cache/trunk/includes/src/Traits/Plugin/WcpSitemapUtils.php

    r2380046 r3027335  
    5252        $counter += $this->clearFilesFromHostCacheDir($regex);
    5353
    54         if ($counter && is_admin() && (!MEGAOPTIM_RAPID_CACHE_IS_PRO || $this->options['change_notifications_enable'])) {
     54        if ($counter && is_admin()) {
    5555            $this->enqueueNotice(sprintf(__('Found %1$s in the cache for XML sitemaps; auto-clearing.', 'rapid-cache'), esc_html($this->i18nFiles($counter))), ['combinable' => true]);
    5656        }
    5757        return $counter;
    5858    }
     59
    5960}
  • rapid-cache/trunk/includes/src/Traits/Plugin/WcpTermUtils.php

    r2380046 r3027335  
    138138            $counter += $_term_counter; // Add to overall counter.
    139139
    140             if ($_term_counter && $enqueued_notices < 100 && is_admin() && (!MEGAOPTIM_RAPID_CACHE_IS_PRO || $this->options['change_notifications_enable'])) {
     140            if (($_term_counter && $enqueued_notices < 100 && is_admin())) {
    141141                $this->enqueueNotice(sprintf(__('Found %1$s in the cache for %2$s: <code>%3$s</code>; auto-clearing.', 'rapid-cache'), esc_html($this->i18nFiles($_term_counter)), esc_html($_term['taxonomy_label']), esc_html($_term['term_name'])), ['combinable' => true]);
    142142                ++$enqueued_notices; // Increment enqueued notices counter.
  • rapid-cache/trunk/includes/src/Traits/Plugin/WcpTransientUtils.php

    r2500432 r3027335  
    109109    }
    110110}
    111 /*[/pro]*/
  • rapid-cache/trunk/includes/src/Traits/Plugin/WcpUpdaterUtils.php

    r2380046 r3027335  
    99namespace MegaOptim\RapidCache\Traits\Plugin;
    1010
    11 use MegaOptim\RapidCache\Classes;
    1211
    1312trait WcpUpdaterUtils
  • rapid-cache/trunk/includes/src/Traits/Plugin/WcpUtils.php

    r2380046 r3027335  
    128128
    129129        $this->doWpAction(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_purge_cache', $counter);
    130        
     130
    131131        return $counter;
    132132    }
     
    200200        $counter += $this->wipeCache();
    201201
    202         if ($counter && is_admin() && (!MEGAOPTIM_RAPID_CACHE_IS_PRO || $this->options['change_notifications_enable'])) {
     202        if ( $this->isChangeNotificationEnabled($counter) ) {
    203203            $this->enqueueNotice(sprintf(__('Detected significant changes that require a full wipe of the cache. Found %1$s in the cache; auto-wiping.', 'rapid-cache'), esc_html($this->i18nFiles($counter))), ['combinable' => true]);
    204204        }
     
    246246        $counter += $this->clearCache();
    247247
    248         if ($counter && is_admin() && (!MEGAOPTIM_RAPID_CACHE_IS_PRO || $this->options['change_notifications_enable'])) {
     248        if ( $this->isChangeNotificationEnabled($counter) ) {
    249249            $this->enqueueNotice(sprintf(__('Detected important site changes that affect the entire cache. Found %1$s in the cache for this site; auto-clearing.', 'rapid-cache'), esc_html($this->i18nFiles($counter))), ['combinable' => true]);
    250250        }
     
    280280        $counter += $this->purgeCache();
    281281
    282         if ($counter && is_admin() && (!MEGAOPTIM_RAPID_CACHE_IS_PRO || $this->options['change_notifications_enable'])) {
     282        if ( $this->isChangeNotificationEnabled($counter) ) {
    283283            $this->enqueueNotice(sprintf(__('Detected important site changes. Found %1$s in the cache for this site that were expired; auto-purging.', 'rapid-cache'), esc_html($this->i18nFiles($counter))), ['combinable' => true]);
    284284        }
     
    314314        $counter += $this->wurgeCache();
    315315
    316         if ($counter && is_admin() && (!MEGAOPTIM_RAPID_CACHE_IS_PRO || $this->options['change_notifications_enable'])) {
     316        if ( $this->isChangeNotificationEnabled($counter) ) {
    317317            $this->enqueueNotice(sprintf(__('Detected important site changes. Found %1$s in the cache that were expired; auto-purging.', 'rapid-cache'), esc_html($this->i18nFiles($counter))), ['combinable' => true]);
    318318        }
     
    334334        $is_disabled = (boolean) $this->applyWpFilters(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_disable_auto_wipe_cache_routines', false);
    335335
    336         if ($is_disabled && is_admin() && (!MEGAOPTIM_RAPID_CACHE_IS_PRO || $this->options['change_notifications_enable'])) {
     336        if ( $this->isChangeNotificationEnabled($is_disabled) ) {
    337337            $this->enqueueMainNotice(
    338338                '<img src="'.esc_attr($this->url('/assets/images/clear.png')).'" style="float:left; margin:0 10px 0 0; border:0;" />'.
     
    357357        $is_disabled = (boolean) $this->applyWpFilters(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_disable_auto_clear_cache_routines', false);
    358358
    359         if ($is_disabled && is_admin() && (!MEGAOPTIM_RAPID_CACHE_IS_PRO || $this->options['change_notifications_enable'])) {
     359        if ( $this->isChangeNotificationEnabled($is_disabled) ) {
    360360            $this->enqueueMainNotice(
    361361                '<img src="'.esc_attr($this->url('/assets/images/clear.png')).'" style="float:left; margin:0 10px 0 0; border:0;" />'.
     
    380380        $is_disabled = (boolean) $this->applyWpFilters(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_disable_auto_purge_cache_routines', false);
    381381
    382         if ($is_disabled && is_admin() && (!MEGAOPTIM_RAPID_CACHE_IS_PRO || $this->options['change_notifications_enable'])) {
     382        if ( $this->isChangeNotificationEnabled($is_disabled) ) {
    383383            $this->enqueueMainNotice(
    384384                '<img src="'.esc_attr($this->url('/assets/images/clear.png')).'" style="float:left; margin:0 10px 0 0; border:0;" />'.
     
    388388        return $is_disabled;
    389389    }
     390
     391    /**
     392     * Is change notification enabled
     393     * @param $is_disabled
     394     *
     395     * @return bool
     396     */
     397    protected function isChangeNotificationEnabled( $is_disabled ) {
     398        if ( $is_disabled && is_admin() ) {
     399            return true;
     400        }
     401        return false;
     402    }
    390403}
  • rapid-cache/trunk/includes/src/Traits/Shared/ConditionalUtils.php

    r2500432 r3027335  
    171171    }
    172172
    173     /**
    174      * Are we in a LOCALHOST environment?
    175      *
    176      * @since 1.0.0
    177      *
    178      * @return bool True if we are in a LOCALHOST environment.
    179      */
    180     public function isLocalhost()
    181     {
    182         if (($is = &$this->staticKey(__FUNCTION__)) !== null) {
    183             return $is; // Already cached this.
    184         }
    185         if (defined('LOCALHOST')) {
    186             return $is = (bool) LOCALHOST;
    187         } elseif (preg_match('/\b(?:localhost|127\.0\.0\.1)\b/ui', $this->hostToken())) {
    188             return $is = true;
    189         }
    190         return $is = false;
    191     }
    192 
    193    
     173    /**
     174     * Are we in a LOCALHOST environment?
     175     *
     176     * @return bool True if we are in a LOCALHOST environment.
     177     * @since 1.0.0
     178     *
     179     */
     180    public function isLocalhost() {
     181        if ( ( $is = &$this->staticKey( __FUNCTION__ ) ) !== null ) {
     182            return $is; // Already cached this.
     183        }
     184
     185        if ( defined( 'LOCALHOST' ) ) {
     186            $is = (bool) LOCALHOST;
     187        } elseif ( defined( 'RAPID_CACHE_LOCALHOST' ) ) {
     188            $is = (bool) RAPID_CACHE_LOCALHOST;
     189        } elseif ( preg_match( '/\b(?:localhost|127\.0\.0\.1)\b/ui', $this->hostToken() ) ) {
     190            $is = true;
     191        } else {
     192            $is = false;
     193        }
     194
     195        $is = $this->applyWpFilters( MEGAOPTIM_RAPID_CACHE_GLOBAL_NS . '_is_localhost', $is );
     196
     197        return $is;
     198    }
     199
     200    /**
     201     * Is the current request for the Auto-Cache Engine?
     202     *
     203     * @since 1.2.0
     204     *
     205     * @return bool True if the current request is for the Auto-Cache Engine.
     206     */
     207    public function isAutoCacheEngine()
     208    {
     209        if (($is = &$this->staticKey(__FUNCTION__)) !== null) {
     210            return $is; // Already cached this.
     211        }
     212        if (!empty($_SERVER['HTTP_USER_AGENT']) && mb_stripos($_SERVER['HTTP_USER_AGENT'], MEGAOPTIM_RAPID_CACHE_GLOBAL_NS) !== false) {
     213            return $is = true;
     214        }
     215        return $is = false;
     216    }
    194217
    195218    /**
  • rapid-cache/trunk/includes/src/Traits/Shared/FsUtils.php

    r2380046 r3027335  
    3838        if (mb_strpos($dir_file, ':' !== false)) {
    3939            if (preg_match('/^(?P<drive_letter>[a-zA-Z])\:[\/\\\\]/u', $dir_file)) {
    40                 $dir_file = preg_replace_callback('/^(?P<drive_letter>[a-zA-Z])\:[\/\\\\]/u', create_function('$m', 'return mb_strtoupper($m[0]);'), $dir_file);
     40                $dir_file = preg_replace_callback('/^(?P<drive_letter>[a-zA-Z])\:[\/\\\\]/u', array($this, 'sanitizePathForDriveLetter'), $dir_file);
    4141            }
    4242        }
     
    4949        return $dir_file; // Normalized now.
    5050    }
     51
     52    /**
     53     * Sanitizes path for drive letter
     54     * @param $m
     55     *
     56     * @return array|false|string|string[]|null
     57     */
     58    public function sanitizePathForDriveLetter($m) {
     59        return function_exists('mb_strtoupper') ? mb_strtoupper($m[0]) : strtoupper($m[0]);
     60    }
    5161
    5262    /**
  • rapid-cache/trunk/includes/src/Traits/Shared/IpAddrUtils.php

    r2380046 r3027335  
    77 * @copyright 2016 WP Sharks (https://wpsharks.com/)
    88 */
     9
    910namespace MegaOptim\RapidCache\Traits\Shared;
    1011
    1112use MegaOptim\RapidCache\Classes;
    1213
    13 trait IpAddrUtils
    14 {
    15     /**
    16      * Get the current visitor's real IP address.
    17      *
    18      * @since 1.0.0
    19      *
    20      * @return string Real IP address, else `unknown` on failure.
    21      *
    22      * @note This supports both IPv4 and IPv6 addresses.
    23      * @note See my tests against this here: http://3v4l.org/fVWUp
    24      */
    25     public function currentIp()
    26     {
    27         if (!is_null($ip = &$this->staticKey('currentIp'))) {
    28             return $ip; // Already cached this.
    29         }
    30         $sources = [
    31             'HTTP_CF_CONNECTING_IP',
    32             'HTTP_CLIENT_IP',
    33             'HTTP_X_FORWARDED_FOR',
    34             'HTTP_X_FORWARDED',
    35             'HTTP_X_CLUSTER_CLIENT_IP',
    36             'HTTP_FORWARDED_FOR',
    37             'HTTP_FORWARDED',
    38             'HTTP_VIA',
    39             'REMOTE_ADDR',
    40         ];
    41         $sources = $this->applyFilters(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'\\share::current_ip_sources', $sources);
    42         $sources = $this->applyFilters(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_current_ip_sources', $sources);
     14trait IpAddrUtils {
     15    /**
     16     * Get the current visitor's real IP address.
     17     *
     18     * @return string Real IP address, else `unknown` on failure.
     19     *
     20     * @note This supports both IPv4 and IPv6 addresses.
     21     * @note See my tests against this here: http://3v4l.org/fVWUp
     22     * @since 1.0.0
     23     *
     24     */
     25    public function currentIp() {
     26        if ( ! is_null( $ip = &$this->staticKey( 'currentIp' ) ) ) {
     27            return $ip; // Already cached this.
     28        }
    4329
    44         $prioritize_remote_addr = false; // Off by default; can be filtered however.
    45         $prioritize_remote_addr = $this->applyFilters(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'\\share::current_ip_prioritize_remote_addr', $prioritize_remote_addr);
    46         $prioritize_remote_addr = $this->applyFilters(MEGAOPTIM_RAPID_CACHE_GLOBAL_NS.'_current_ip_prioritize_remote_addr', $prioritize_remote_addr);
     30        if ( defined( 'RAPID_CACHE_CURRENT_CLIENT_IP' ) ) {
     31            $ip = RAPID_CACHE_CURRENT_CLIENT_IP;
     32        }
    4733
    48         if (!empty($_SERVER['REMOTE_ADDR']) && $prioritize_remote_addr) {
    49             if (($_valid_public_ip = $this->validPublicIp((string) $_SERVER['REMOTE_ADDR']))) {
    50                 return $ip = $_valid_public_ip;
    51             }
    52             unset($_valid_public_ip); // Housekeeping.
    53         }
    54         foreach ($sources as $_key => $_source) {
    55             if (!empty($_SERVER[$_source])) {
    56                 if (($_valid_public_ip = $this->validPublicIp((string) $_SERVER[$_source]))) {
    57                     return $ip = $_valid_public_ip;
    58                 }
    59             }
    60             unset($_key, $_source, $_valid_public_ip); // Housekeeping.
    61         }
    62         if (!empty($_SERVER['REMOTE_ADDR'])) {
    63             return $ip = mb_strtolower((string) $_SERVER['REMOTE_ADDR']);
    64         }
    65         return $ip = 'unknown'; // Not possible.
    66     }
     34        if ( is_null( $ip ) ) {
     35            $sources = [
     36                'HTTP_CF_CONNECTING_IP',
     37                'HTTP_CLIENT_IP',
     38                'HTTP_X_FORWARDED_FOR',
     39                'HTTP_X_FORWARDED',
     40                'HTTP_X_CLUSTER_CLIENT_IP',
     41                'HTTP_FORWARDED_FOR',
     42                'HTTP_FORWARDED',
     43                'HTTP_VIA',
     44                'REMOTE_ADDR',
     45            ];
     46            $sources = $this->applyFilters( MEGAOPTIM_RAPID_CACHE_GLOBAL_NS . '\\share::current_ip_sources', $sources );
     47            $sources = $this->applyFilters( MEGAOPTIM_RAPID_CACHE_GLOBAL_NS . '_current_ip_sources', $sources );
    6748
    68     /**
    69      * Gets a valid/public IP address.
    70      *
    71      * @since 1.0.0
    72      *
    73      * @param string $list_of_possible_ips A single IP, or a comma-delimited list of IPs.
    74      *
    75      * @return string A valid/public IP address (if one is found), else an empty string.
    76      *
    77      * @note This supports both IPv4 and IPv6 addresses.
    78      * @note See my tests against this here: http://3v4l.org/fVWUp
    79      */
    80     public function validPublicIp($list_of_possible_ips)
    81     {
    82         if (!$list_of_possible_ips || !is_string($list_of_possible_ips)) {
    83             return ''; // Empty or invalid data.
    84         }
    85         if (!($list_of_possible_ips = trim($list_of_possible_ips))) {
    86             return ''; // Not possible; i.e., empty string.
    87         }
    88         foreach (preg_split('/[\s;,]+/', $list_of_possible_ips, -1, PREG_SPLIT_NO_EMPTY) as $_key => $_possible_ip) {
    89             if (($_valid_public_ip = filter_var(mb_strtolower($_possible_ip), FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE))) {
    90                 return $_valid_public_ip; // A valid public IPv4 or IPv6 address.
    91             }
    92         }
    93         unset($_key, $_possible_ip, $_valid_public_ip); // Housekeeping.
     49            $prioritize_remote_addr = false; // Off by default; can be filtered however.
     50            $prioritize_remote_addr = $this->applyFilters( MEGAOPTIM_RAPID_CACHE_GLOBAL_NS . '\\share::current_ip_prioritize_remote_addr', $prioritize_remote_addr );
     51            $prioritize_remote_addr = $this->applyFilters( MEGAOPTIM_RAPID_CACHE_GLOBAL_NS . '_current_ip_prioritize_remote_addr', $prioritize_remote_addr );
    9452
    95         return ''; // Default return value.
    96     }
     53            if ( ! empty( $_SERVER['REMOTE_ADDR'] ) && $prioritize_remote_addr ) {
     54                $_valid_public_ip = $this->validPublicIp( (string) $_SERVER['REMOTE_ADDR'] );
     55                if ( $_valid_public_ip ) {
     56                    $ip = $_valid_public_ip;
     57                }
     58                unset( $_valid_public_ip ); // Housekeeping.
     59            }
     60        }
     61
     62        if ( is_null( $ip ) ) {
     63            foreach ( $sources as $_key => $_source ) {
     64                if ( ! empty( $_SERVER[ $_source ] ) ) {
     65                    $_valid_public_ip = $this->validPublicIp( (string) $_SERVER[ $_source ] );
     66                    if ( $_valid_public_ip ) {
     67                        $ip = $_valid_public_ip;
     68                    }
     69                }
     70            }
     71        }
     72
     73        if ( is_null( $ip ) ) {
     74            if ( ! empty( $_SERVER['REMOTE_ADDR'] ) ) {
     75                $ip = mb_strtolower( (string) $_SERVER['REMOTE_ADDR'] );
     76            } else {
     77                $ip = 'unknown';
     78            }
     79        }
     80
     81        $ip = $this->applyWpFilters( MEGAOPTIM_RAPID_CACHE_GLOBAL_NS . '_current_client_ip', $ip );
     82        return $ip;
     83    }
     84
     85    /**
     86     * Gets a valid/public IP address.
     87     *
     88     * @param  string  $list_of_possible_ips  A single IP, or a comma-delimited list of IPs.
     89     *
     90     * @return string A valid/public IP address (if one is found), else an empty string.
     91     *
     92     * @note This supports both IPv4 and IPv6 addresses.
     93     * @note See my tests against this here: http://3v4l.org/fVWUp
     94     * @since 1.0.0
     95     *
     96     */
     97    public function validPublicIp( $list_of_possible_ips ) {
     98        if ( ! $list_of_possible_ips || ! is_string( $list_of_possible_ips ) ) {
     99            return ''; // Empty or invalid data.
     100        }
     101        if ( ! ( $list_of_possible_ips = trim( $list_of_possible_ips ) ) ) {
     102            return ''; // Not possible; i.e., empty string.
     103        }
     104        foreach ( preg_split( '/[\s;,]+/', $list_of_possible_ips, - 1, PREG_SPLIT_NO_EMPTY ) as $_key => $_possible_ip ) {
     105            if ( ( $_valid_public_ip = filter_var( mb_strtolower( $_possible_ip ), FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE ) ) ) {
     106                return $_valid_public_ip; // A valid public IPv4 or IPv6 address.
     107            }
     108        }
     109        unset( $_key, $_possible_ip, $_valid_public_ip ); // Housekeeping.
     110
     111        return ''; // Default return value.
     112    }
    97113}
  • rapid-cache/trunk/includes/src/Traits/Shared/TokenUtils.php

    r2380046 r3027335  
    1313trait TokenUtils
    1414{
    15    
     15    /**
     16     * A simple utility flag.
     17     *
     18     * @since 1.2.0
     19     *
     20     * @type bool `TRUE` if expired or invalid.
     21     */
     22    public $user_login_cookie_expired_or_invalid = false;
    1623
    1724    /**
     
    6168            }
    6269        }
     70        $token = $this->applyWpFilters( MEGAOPTIM_RAPID_CACHE_GLOBAL_NS . '_host_token', $token );
    6371        return $token;
    6472    }
     
    304312    }
    305313
     314    /**
     315     * Produces a token based on the current user.
     316     *
     317     * @since 1.2.0.
     318     *
     319     * @return string Produces a token based on the current user;
     320     *                else an empty string if that's not possible to do.
     321     *
     322     * @note The return value of this function is cached to reduce overhead on repeat calls.
     323     *
     324     * @note This routine may trigger a flag which indicates that the current user was logged-in at some point,
     325     *    but now the login cookie can no longer be validated by WordPress; i.e. they are NOT actually logged in any longer.
     326     *    See {@link $user_login_cookie_expired_or_invalid}
     327     *
     328     * @warning Do NOT call upon this method until WordPress reaches it's cache postload phase.
     329     */
     330    public function userToken()
     331    {
     332        if (!is_null($token = &$this->staticKey('userToken'))) {
     333            return $token; // Already cached this.
     334        }
     335
     336        if ($this->functionIsPossible('wp_validate_auth_cookie')) {
     337            if (($user_id = (integer) wp_validate_auth_cookie('', 'logged_in'))) {
     338                return $token = (string) $user_id; // A real user in this case.
     339            } elseif (!empty($_COOKIE['wordpress_logged_in_'.COOKIEHASH])) {
     340                $this->user_login_cookie_expired_or_invalid = true;
     341            }
     342        }
     343        if (!empty($_COOKIE['comment_author_email_'.COOKIEHASH])) {
     344            return $token = md5(mb_strtolower(stripslashes((string) $_COOKIE['comment_author_email_'.COOKIEHASH])));
     345        } elseif (!empty($_COOKIE['wp-postpass_'.COOKIEHASH])) {
     346            return $token = md5(stripslashes((string) $_COOKIE['wp-postpass_'.COOKIEHASH]));
     347        } elseif (defined('SID') && SID) {
     348            return $token = preg_replace('/[^a-z0-9]/ui', '', (string) SID);
     349        }
     350        return $token = '';
     351    }
    306352   
    307353}
  • rapid-cache/trunk/includes/stub.php

    r2500432 r3027335  
    2222define('MEGAOPTIM_RAPID_CACHE_SLUG', 'rapid-cache');
    2323define('MEGAOPTIM_RAPID_CACHE_OLD_SLUG', 'rapid-cache');
    24 define('MEGAOPTIM_RAPID_CACHE_VERSION', '1.1.0');
     24define('MEGAOPTIM_RAPID_CACHE_VERSION', '1.2.0');
    2525define('MEGAOPTIM_RAPID_CACHE_PATH', dirname(__DIR__).DIRECTORY_SEPARATOR);
    2626define('MEGAOPTIM_RAPID_CACHE_PLUGIN_FILE', MEGAOPTIM_RAPID_CACHE_PATH.MEGAOPTIM_RAPID_CACHE_SLUG.'.php');
  • rapid-cache/trunk/includes/utils/helpers.php

    r2380046 r3027335  
    99
    1010use MegaOptim\RapidCache as Plugin;
    11 
    12 /**
    13  * Postload event handler; overrides core WP function.
    14  *
    15  * @since 1.0.0
    16  *
    17  * @note See `/wp-settings.php` around line #226.
    18  */
    19 function rapidcache_postload_cache()
    20 {
    21     $GLOBAL_NS      = MEGAOPTIM_RAPID_CACHE_GLOBAL_NS;
    22     $advanced_cache = $GLOBALS[$GLOBAL_NS.'_advanced_cache'];
    23 
    24     if (!$advanced_cache->is_running) {
    25         return; // Not applicable.
    26     }
    27     $advanced_cache->doWpAction('before_'.$GLOBAL_NS.'_'.__FUNCTION__, get_defined_vars());
    28 
    29     if (!empty($advanced_cache->postload['filter_status_header'])) {
    30         $advanced_cache->maybeFilterStatusHeaderPostload();
    31     }
    32     if (!empty($advanced_cache->postload['set_debug_info'])) {
    33         $advanced_cache->maybeSetDebugInfoPostload();
    34     }
    35     if (!empty($advanced_cache->postload['wp_main_query'])) {
    36         add_action('wp', [$advanced_cache, 'wpMainQueryPostload'], PHP_INT_MAX);
    37     }
    38     $advanced_cache->doWpAction('after_'.$GLOBAL_NS.'_'.__FUNCTION__, get_defined_vars());
    39     $advanced_cache->doWpAction($GLOBAL_NS.'_'.__FUNCTION__.'_complete', get_defined_vars());
    40 }
    41 
    4211
    4312/**
  • rapid-cache/trunk/rapid-cache.php

    r2500432 r3027335  
    33Plugin Name: Rapid Cache
    44Plugin URI: https://megaoptim.com/tools/rapid-cache
    5 Description: Rapid Cache is fork of Commet Cache and advanced WordPress caching plugin inspired by simplicity
     5Description: Rapid Cache is a fork of Comet Cache, an advanced WordPress caching plugin inspired by simplicity
    66Author: MegaOptim
    77Author URI: https://megaoptim.com
    8 Version: 1.1.0
     8Version: 1.2.0
    99Text Domain: rapid-cache
    1010Domain Path: /languages
  • rapid-cache/trunk/readme.txt

    r2500432 r3027335  
    11=== Rapid Cache ===
    22
    3 Stable tag: 1.1.0
     3Stable tag: 1.2.0
    44Requires at least: 4.2
    5 Tested up to: 5.7
     5Tested up to: 6.4
    66Text Domain: rapid-cache
    77License: GPLv2 or later
     
    99Author: MegaOptim
    1010Author URI: https://megaoptim.com/rapid-cache
    11 Contributors: megaoptim,darkog
     11Contributors: megaoptim, darkog
    1212Tags: cache, speed, performance, fast, caching, advanced cache, static, client-side cache, rss cache, feed cache, gzip compression, page cache
    1313
     
    237237
    238238== Changelog ==
     239
     240= 1.2.0 =
     241Release date: January 26th, 2024
     242- New: Compatibility with PHP 8.3
     243- New: Compatibility with WordPress 6.4
     244- New: Cache Preloading with CRON
     245- New: Option to cache logged-in users
     246- New: Version cache salt filter - `rapid_cache_version_salt`
     247- New: Reorganized settings
     248- Fix: Fixes various PHP warnings
    239249
    240250= 1.1.0 =
  • rapid-cache/trunk/stubs/advanced-cache.x-php

    r2380046 r3027335  
    4141}
    4242
     43if (defined('WP_DEBUG') && WP_DEBUG) {
     44    if ((include_once(dirname(RAPID_CACHE_PLUGIN_FILE).'/includes/utils/wp-cache-postload.php')) === false) {
     45        return; // Unable to find postload function(s). Fail softly w/ PHP warning.
     46    }
     47} elseif ((@include_once(dirname(RAPID_CACHE_PLUGIN_FILE).'/includes/utils/wp-cache-postload.php')) === false) {
     48    return; // Unable to find postload function(s). Fail softly.
     49}
     50
    4351if (!defined('RAPID_CACHE_PRO')) {
    4452    /*
     
    145153}
    146154
     155if (!defined('RAPID_CACHE_WHEN_LOGGED_IN')) {
     156    /*
     157     * Cache logged-in users?
     158     *
     159     * @since 1.2.0
     160     *
     161     * @var string|integer|boolean A boolean-ish value; e.g. `1` or `0`; or `postload`.
     162     */
     163    define('RAPID_CACHE_WHEN_LOGGED_IN', '%%RAPID_CACHE_WHEN_LOGGED_IN%%');
     164}
     165
    147166if (!defined('RAPID_CACHE_DIR')) {
    148167    /*
  • rapid-cache/trunk/stubs/htaccess/browser-caching-enable.txt

    r2380046 r3027335  
    11# Enable browser caching.
    2 FileETag mtime size
    3 
    4 <IfModule expires_module>
    5   ExpiresActive on
    6   ExpiresDefault "access plus 1 week"
     2<IfModule mod_expires.c>
     3    ExpiresActive On
     4    ExpiresByType text/css A31536000
     5    ExpiresByType text/x-component A31536000
     6    ExpiresByType application/x-javascript A31536000
     7    ExpiresByType application/javascript A31536000
     8    ExpiresByType text/javascript A31536000
     9    ExpiresByType text/x-js A31536000
     10    ExpiresByType video/asf A31536000
     11    ExpiresByType video/avi A31536000
     12    ExpiresByType image/bmp A31536000
     13    ExpiresByType application/java A31536000
     14    ExpiresByType video/divx A31536000
     15    ExpiresByType application/msword A31536000
     16    ExpiresByType application/vnd.ms-fontobject A31536000
     17    ExpiresByType application/x-msdownload A31536000
     18    ExpiresByType image/gif A31536000
     19    ExpiresByType application/x-gzip A31536000
     20    ExpiresByType image/x-icon A31536000
     21    ExpiresByType image/jpeg A31536000
     22    ExpiresByType image/webp A31536000
     23    ExpiresByType application/json A31536000
     24    ExpiresByType application/vnd.ms-access A31536000
     25    ExpiresByType audio/midi A31536000
     26    ExpiresByType video/quicktime A31536000
     27    ExpiresByType audio/mpeg A31536000
     28    ExpiresByType video/mp4 A31536000
     29    ExpiresByType video/mpeg A31536000
     30    ExpiresByType video/webm A31536000
     31    ExpiresByType application/vnd.ms-project A31536000
     32    ExpiresByType application/x-font-otf A31536000
     33    ExpiresByType application/vnd.ms-opentype A31536000
     34    ExpiresByType application/vnd.oasis.opendocument.database A31536000
     35    ExpiresByType application/vnd.oasis.opendocument.chart A31536000
     36    ExpiresByType application/vnd.oasis.opendocument.formula A31536000
     37    ExpiresByType application/vnd.oasis.opendocument.graphics A31536000
     38    ExpiresByType application/vnd.oasis.opendocument.presentation A31536000
     39    ExpiresByType application/vnd.oasis.opendocument.spreadsheet A31536000
     40    ExpiresByType application/vnd.oasis.opendocument.text A31536000
     41    ExpiresByType audio/ogg A31536000
     42    ExpiresByType application/pdf A31536000
     43    ExpiresByType image/png A31536000
     44    ExpiresByType application/vnd.ms-powerpoint A31536000
     45    ExpiresByType audio/x-realaudio A31536000
     46    ExpiresByType image/svg+xml A31536000
     47    ExpiresByType application/x-shockwave-flash A31536000
     48    ExpiresByType application/x-tar A31536000
     49    ExpiresByType image/tiff A31536000
     50    ExpiresByType application/x-font-ttf A31536000
     51    ExpiresByType application/vnd.ms-opentype A31536000
     52    ExpiresByType audio/wav A31536000
     53    ExpiresByType audio/wma A31536000
     54    ExpiresByType application/vnd.ms-write A31536000
     55    ExpiresByType application/font-woff A31536000
     56    ExpiresByType application/font-woff2 A31536000
     57    ExpiresByType application/vnd.ms-excel A31536000
     58    ExpiresByType application/zip A31536000
    759</IfModule>
Note: See TracChangeset for help on using the changeset viewer.