Comet Cache - Version 161221

Version Description

= v160416 =

Requires WordPress v4.2+.

Download this release

Release Info

Developer raamdev
Plugin Icon 128x128 Comet Cache
Version 161221
Comparing to
See all releases

Code changes from version 161119 to 161221

CHANGELOG.md DELETED
@@ -1,697 +0,0 @@
1
- = v161119 =
2
-
3
- - **Bug Fix:** Avoid browser autocomplete in configuration fields by adding `autocomplete="off"` to all form tags in Comet Cache menu pages. See [Issue #832](https://github.com/websharks/comet-cache/issues/832).
4
- - **Bug Fix:** Fixed a broken link to the [Static CDN Filters tutorial for MaxCDN integration](http://cometcache.com/r/static-cdn-filters-maxcdn/). Props @kristineds. See [Issue #842](https://github.com/websharks/comet-cache/issues/842).
5
- - **Bug Fix:** Multisite installations inside a subdirectory were broken by Apache Optimizations via `.htaccess` in some scenarios. Fixed in this release. See [Issue #798](https://github.com/websharks/comet-cache/issues/798).
6
- - **Bug Fix:** Don't enqueue `Chart.js` unnecessarily in lite version of the software. See [Issue #830](https://github.com/websharks/comet-cache/issues/830).
7
- - **Bug Fix:** Enhancing WooCommerce integration by listening to the `woocommerce_product_set_stock_status` hook in addition to the `woocommerce_product_set_stock` hook. See [Issue #674](https://github.com/websharks/comet-cache/issues/674).
8
- - **Bug Fix** (Pro): Automatically dismiss any persistent update notifications whenever a new version of the software is recompiled; i.e., don't continue to show an upgrade notice whenever the software has just been updated by a site owner. See [Issue #806](https://github.com/websharks/comet-cache/issues/806).
9
- - **Enhancement:** This version enhances the HTML comments left in the source code (HTML Debug Notes). When debug notes are enabled (i.e., HTML comments) they are now broken down into key/value pairs and tabulated for a cleaner display and easier debugging. See [Issue #790](https://github.com/websharks/comet-cache/issues/790).
10
- - **Performance Enhancement:** For sites configured to allow query string variables into the cache, those variables are now sorted by key name internally to avoid duplicate cache files; i.e., whenever the order of query string variables changes from request to another, but with the same exact values. In short, Comet Cache now knows how to serve the same underlying cache file; i.e., from a previous request that may have had the same query string, just in a slightly different order. See [Issue #639](https://github.com/websharks/comet-cache/issues/639).
11
- - **UI Enhancement:** The Comet Cache UI is now fully Responsive with an improved UI on laptop and mobile devices. Props @renzms. See [Issue #699](https://github.com/websharks/comet-cache/issues/699).
12
- - **UI Enhancement:** This release improves the toggle link that allows you to see additional details whenever Comet Cache automatically clears more than one facet of the cache. See [Issue #837](https://github.com/websharks/comet-cache/issues/837) and [Issue #831](https://github.com/websharks/comet-cache/issues/831).
13
- - **UI Enhancement** (Pro): Following improvements to the update API in a previous release of Comet Cache that made it possible to update both the lite and pro versions of the software through normal WordPress update mechanisms, this release removes some clutter from the menu pages for Comet Cache. In short, now that we have a tighter integration with WordPress core, it's no longer necessary for Comet Cache to display update notifications in a custom way. See [Issue #829](https://github.com/websharks/comet-cache/issues/829).
14
- - **UI Enhancement** (Pro): On pro version activation, display a notice that reminds site owners to configure their Pro Update Credentials so they'll be notified by WordPress about new versions of the pro software. See [Issue #477](https://github.com/websharks/comet-cache/issues/477).
15
- - **New Pro Feature:** In the pro version it is now possible to define a list of GET request variable names that should be ignored entirely by Comet Cache. See: **Dashboard → Comet Cache → Plugin Options → GET Requests → List of GET Variable Names to Ignore**. As an example, this new feature makes it possible for site owners to pass query string variables associated with Google Analytics (i.e., `utm_*` variable names) without incurring a cache performance hit. See [Issue #639](https://github.com/websharks/comet-cache/issues/639).
16
- - **Nonce Support** (Pro): In the pro version, when logged-in user caching is enabled, Comet Cache is now capable of intelligently caching pages that contain Nonce values ([numbers used once](https://cometcache.com/r/numbers-used-once-nonce/)). This allows for pages containing the WordPress Admin Bar to be cached without issue. It also improves compatibility with plugins like bbPress and BuddyPress, resulting in better performance and faster speeds for logged-in users. See [Issue #793](https://github.com/websharks/comet-cache/issues/793).
17
- - **RevSlider Compat.:** This release includes a built-in exclusion rule for the HTML Compressor to allow for improved compatibility with the popular RevSlider plugin for WordPress. The new built-in exclusion rule looks for and automatically bypasses an important style tag that must be preserved for the RevSlider plugin to work in all scenarios; i.e., `<style id='rs-plugin-settings-inline-css'`. See [Issue #614](https://github.com/websharks/comet-cache/issues/614).
18
- - **i18n Compat.** (Lite): This release makes all pro preview labels translatable by moving the labels that were previously defined in CSS only into HTML attribute values. See [Issue #808](https://github.com/websharks/comet-cache/issues/808).
19
-
20
- = v160917 =
21
-
22
- - **New Feature** (Lite): The Clear Cache button is now available in the Admin Toolbar for the Lite version of Comet Cache.
23
- - **New Feature** (Pro): Comet Cache Pro is now fully compatible with [WordPress Automatic Background Updates](https://codex.wordpress.org/Configuring_Automatic_Background_Updates#Plugin_.26_Theme_Updates_via_Filter). If you enable automatic background updates for plugins, and you save valid Comet Cache Pro License Credentials in the _Comet Cache Pro → Plugin Options → Update Credentials_ panel, you will automatically receive Pro plugin updates. Props @jaswsinc. See [Issue #289](https://github.com/websharks/comet-cache/issues/289).
24
- - **Bug Fix**: In some scenarios Comet Cache might produce a false-positive "Warning: mkdir(): File exists" message when checking if the cache directory exists. Comet Cache now calls `clearstatcache()` and uses `file_exists()` instead of `is_dir()` to help make this check more robust. See [Issue #786](https://github.com/websharks/comet-cache/issues/786).
25
- - **Bug Fix**: Fixed a bug where the Comet Cache PHP requirements check would fail and produce a fatal error when upgrading from a version of Comet Cache that did not require an extension that is now required by newer releases. This would occur when, for example, the required PHP `mbstring` extension was missing. Props @jaswsinc for finding the bug. See [Issue #817](https://github.com/websharks/comet-cache/issues/817).
26
- - **Bug Fix**: Fixed a bug where upgrading from v160521 would result in the Client-Side Cache option being reset to the default (disabled). If you enabled the Client-Side Cache at some point, now is a good time to double-check that it's still enabled. This bug fix also improves the reliability of all version upgrade routines that Comet Cache runs during upgrades. See [Issue #807](https://github.com/websharks/comet-cache/issues/807).
27
- - **Compatibility / Bug Fix**: The automatic Clear Cache routines that cleared the entire cache automatically whenever _WordPress Dashboard → Settings → General_ was updated, were being too aggressive and not taking into consideration other plugins that might also be using the same `options-general.php` URL. As a result, the entire cache was being unnecessarily cleared when the settings for those other plugins were saved. Props to @futtta from Autoptimize for reporting. See [Issue #825](https://github.com/websharks/comet-cache/issues/825).
28
- - **UI Enhancement:** Adjusted option page font styles for WordPress v4.6 to better match existing style. See [Issue #271](https://github.com/websharks/comet-cache-pro/pull/271).
29
- - **ManageWP Compatibility** (Pro): Comet Cache Pro is now compatible with ManageWP, a service that allows remote management of multiple WordPress sites. Comet Cache Pro Plugin Updates will now appear in the ManageWP dashboard and, assuming you have saved valid license credentials in _Dashboard → Comet Cache Pro → Plugin Options → Update Credentials_, you will be able to upgrade Comet Cache Pro remotely from the ManageWP Dashboard. Props @jaswsinc. See [Issue #465](https://github.com/websharks/comet-cache/issues/465).
30
- - **InfiniteWP Compatibility** (Pro): Comet Cache Pro is now compatible with InfiniteWP, an application that allows you to manage multiple WordPress sites from a single location. Comet Cache Pro Plugin Updates will now appear in the InfiniteWP dashboard and, assuming you have saved valid license credentials in _Dashboard → Comet Cache Pro → Plugin Options → Update Credentials_, you will be able to upgrade Comet Cache Pro remotely from the InfiniteWP Dashboard. See [Issue #394](https://github.com/websharks/comet-cache/issues/394).
31
- - **Rewritten Pro Plugin Updater**: The Comet Cache Pro Plugin Updater has been redesigned to use the built-in WordPress plugin updater system. When a Comet Cache Pro update is available, it now appears in the WordPress Updates section and in the Plugins list, like other WordPress plugins and can be updated normally like other WordPress plugins, as long as you have saved valid Comet Cache Pro license details in the new "Update Credentials" options panel. Props @jaswsinc. See [Issue #272](https://github.com/websharks/comet-cache-pro/issues/272).
32
- - **Code Style**: The `WP_CACHE` line that gets inserted into the `wp-config.php` file to enable caching now follows the [WordPress PHP Code Standards](https://make.wordpress.org/core/handbook/best-practices/coding-standards/php/). Props @szepeviktor. See [Issue #799](https://github.com/websharks/comet-cache/pull/799).
33
- - **Compatibility** (Pro): When the Autoptimize plugin is active, the Comet Cache Pro HTML Compressor panel now shows a friendly notice explaining that both the HTML Compressor and Autoptimize should not be enabled at the same time because they both address the same performance improvements. The rest of Comet Cache works great alongside Autoptimize and whether you use the HTML Compressor or Autoptimize is a matter of preference. Props to @futtta from Autoptimize for the continued collaboration.
34
-
35
- = v160709 =
36
-
37
- - **Bug Fix** (Pro): Fixed a bug in the Auto-Cache Engine that was introduced by the previous release (v160706). The bug produced an error whenever the Auto-Cache Engine ran: "PHP Fatal error: Call to undefined method applyWpFilters()". This had no visible affect on the front-end of the site or in the WordPress Dashboard, but it prevented the Auto-Cache Engine from working behind the scenes. Props @Peter-FB for reporting. See [Issue #795](https://github.com/websharks/comet-cache/issues/795).
38
-
39
- = v160706 =
40
-
41
- - **New Feature! Apache Optimizations.** This release includes a completely new option panel for Apache Performance Tuning. Current options for Apache tuning include GZIP Compression, Leverage Browser Caching, Enforce Canonical URLs, and Send Access-Control-Allow-Origin Header (for Static CDN Filters). These options automatically add or remove from your `.htaccess` file the appropriate configuration based on the options you enable or disable (all options are disabled by default, so your `.htaccess` file is not modified unless you say so). If you prefer to update your `.htaccess` file manually, the necessary configuration can be viewed beneath each option. Props @jaswsinc, @renzms. See [Issue #789](https://github.com/websharks/comet-cache/issues/789).
42
- - **New Feature!** A new "Enable GZIP Compression" option has been added to the new Apache Optimizations panel. This option will automatically add the appropriate configuration to your `.htaccess` file to enable GZIP compression. This option is disabled by default. The old "GZIP Compression" panel has been removed in favor of the new option inside Apache Optimizations. Props @renzms, @jaswsinc. See [Issue #764](https://github.com/websharks/comet-cache/issues/764).
43
- - **New Feature!** Multisite Host Exclusion Patterns. It's now possible to exclude entire sites from the cache in a Multisite Network environment. Domain mapping is also supported! See _Comet Cache → Plugin Options → Host Exclusion Patterns_. If you're running a Multisite Network with Sub-Directories, you can exclude sites using the existing URI Exclusion Patterns feature. Props @kristineds. See [Issue #754](https://github.com/websharks/comet-cache/issues/754).
44
- - **New Feature (Pro)!** A new "Leverage Browser Caching" option has been added to the new Apache Optimizations panel. This option will automatically add the appropriate configuration to your `.htaccess` file to enable Browser Caching. This option is disabled by default. Props @renzms, @jaswsinc. See [Issue #764](https://github.com/websharks/comet-cache/issues/764).
45
- - **New Feature (Pro)!** A new "Enforce Canonical URLs" option has been added to the new Apache Optimizations panel. This options adds the appropriate `.htaccess` code to enforce the correct canonical URLs according to your WordPress Permalink settings (Comet Cache detects if the Permalink Structure ends with a trailing slash, or without a trailing slash). Props @renzms, @jaswsinc. See [Issue #554](https://github.com/websharks/comet-cache/issues/554).
46
- - **Bug Fix**: In some scenarios the Cron Event that cleans up expired cache files (`_cron_comet_cache_cleanup`) would never run, or the Next Run time would constantly reset to 1 minute away from running every time a page was reloaded. We suspect this is a race condition and in attempt to work around this issue we now skip all of our Cron-related checks if Cron is currently in the middle of running a process. Props @xberg and @lkraav for help reporting. See [Issue #653](https://github.com/websharks/comet-cache/issues/653).
47
- - **Bug Fix**: If your site uses aliased domains, Comet Cache now properly considers all possible domain variations when it clears the cache on WP Standard installations. Props @kristineds, @jaswsinc, @yoffe, and @VR51. See [Issue #608](https://github.com/websharks/comet-cache/issues/608).
48
- - **Bug Fix** (Pro): Fixed a bug where Comet Cache would appear to prevent WordPress from redirecting Permalinks that don't include a trailing slash, to the URL that does include a trailing slash. This was due to the fact that Comet Cache loads very early on (for caching purposes) and as a result the WordPress `redirect_canonical()` function never gets run. This was fixed by adding an option to the new Apache Optimizations panel that allows you to Enforce Canonical URLs. Props @renzms, @jaswsinc. See [Issue #554](https://github.com/websharks/comet-cache/issues/554).
49
- - **UX Bug Fix** (Pro): If you had your WordPress Dashboard login details saved by your browser, the browser autofill would automatically fill in the Pro Plugin Updater fields with those details, which then needed to be replaced with your actual Pro license details. The browser autofill has been disabled for those fields (tested in Chrome, Firefox, and Safari). Props @renzms. See [Issue #741](https://github.com/websharks/comet-cache/issues/741).
50
- - **Enhancement**: Added links the Options Page for the Comet Cache [Twitter](http://twitter.com/cometcache) and [Facebook](http://facebook.com/cometcache) accounts. Props @renzms. [Issue #771](https://github.com/websharks/comet-cache/issues/771).
51
- - **Enhancement:** Added full support for UTF-8 (multibyte strings). This release adds full support for UTF-8 throughout the Comet Cache codebase, greatly enhancing Comet Cache's ability to deal with file paths and URLs that may contain UTF-8 characters. Props @jaswsinc. [Issue #703](https://github.com/websharks/comet-cache/issues/703).
52
- - **UI Enhancements**: Improved the Logged-In Users and the Client-Side Caching options panels to dim additional options when the feature is disabled. Additionally, the "Enable HTML Compression for Logged-In Users?" option has been relocated from the HTML Compressor option panel to the more appropriate Logged-In Users option panel. See [Issue #768](https://github.com/websharks/comet-cache/issues/768).
53
- - **UX Enhancement**: Improved the inline docs for Auto-Clear List of Custom URLs to clarify that full URLs must be provided. Props @renzms. See [Issue #781](https://github.com/websharks/comet-cache/issues/781).
54
- - **Enhancement** (Pro): The Pro Plugin Updater has been improved to allow for better compatibility with hosting platforms that use Apache's ModSecurity. In some cases, site owners were seeing a 404 error when attempting to update the Pro version using the Pro Plugin updater because certain ModSecurity rules were blocking the Pro Updater requests. The Pro Plugin Updater now uses WP Transients to store the necessary metadata, which works around the issue with ModSecurity. Props to @seozones for reporting and @jaswsinc for help fixing this. [Issue #416](https://github.com/websharks/comet-cache/issues/416).
55
- - **Enhancement** (Pro): When Static CDN Filters are enabled, it's now possible to disable the automatic insertion of rules into your `.htaccess` file that are designed to prevent issues with [CORS](https://cometcache.com/kb-article/what-are-cross-origin-request-blocked-errors/). See _Apache Optimizations → Send Access-Control-Allow-Origin Header?_ See [Issue #787](https://github.com/websharks/comet-cache/issues/787).
56
- - **Enhancement** (Pro): The HTML Notes added to the bottom of a cached page now specify if the page was cached as the result of an HTTP Request or if it was cached by the Auto-Cache Engine. Props @kristineds. See [Issue #292](https://github.com/websharks/comet-cache/issues/292).
57
- - **Enhancement** (Pro): The Auto-Cache Engine now supports a fallback to cURL using the WP HTTP API. If your PHP configuration has `allow_fopen_url=0`, the Auto-Cache Engine will use the fallback to download the XML Sitemap and parse it from a temporary file. If you want to force the use of this fallback even when `allow_fopen_url=1`, you can use [a filter](https://github.com/websharks/comet-cache/issues/440#issuecomment-228338371). See [Issue #440](https://github.com/websharks/comet-cache/issues/440).
58
- - **UI Enhancement** (Pro): A second button has been added to the bottom of the Pro Plugin Updater page that allows you to "Save and Update Comet Cache Pro" in one step. Props @renzms. See [Issue #741](https://github.com/websharks/comet-cache/issues/741).
59
- - **UI Enhancement** (Pro): The "Cache Stats" button in Admin Bar is now linked to the Cache Stats page. Instead of hovering over the button and then clicking "More Info" inside the popup panel, you can now just click the "Cache Stats" button to go directly to the Cache Stats page. Props @Presskopp, @renzms. See [Issue #780](https://github.com/websharks/comet-cache/issues/780).
60
- - **Comment Mail Compatibility:** Improved compatibility with the Comment Mail plugin by automatically clearing the cache whenever Comment Mail options are changed. Many of the Comment Mail options affect front-end portions of the site, so it's important that the cache is cleared whenever Comment Mail options change. See [Comment Mail Issue #278](https://github.com/websharks/comment-mail/issues/278#issuecomment-225994050).
61
- - **PHP Compatibility:** Improved compatibility back to PHP 5.2 (the lowest version allowed by WordPress). Comet Cache still requires PHP 5.4+, but if you install Comet Cache on a site running PHP 5.2, it will now fail gracefully with a Dashboard notice indicating PHP 5.4+ is required, instead of producing a fatal error. See [Issue #784](https://github.com/websharks/comet-cache/issues/784).
62
- - **WP-CLI Compatibility**: Fixed a bug with deactivating Comet Cache using WP-CLI. Doing so was producing a "Invalid argument; host token empty!" error message. This has been resolved. Props @MarioKnight @jaswsinc @renzms. See [Issue #728](https://github.com/websharks/comet-cache/issues/728).
63
- - Renamed `COMET_CACHE_ALLOW_BROWSER_CACHE` constant to `COMET_CACHE_ALLOW_CLIENT_SIDE_CACHE`. Backwards compatibility has been maintained.
64
- - Renamed `allow_browser_cache` plugin option to `allow_client_side_cache`.
65
-
66
- = v160521 =
67
-
68
- - **Bug Fix**: Fixed a bug that, in some scenarios, resulted in "PHP Fatal error: Undefined class constant 'CACHE_PATH_NO_PATH_INDEX'". This also affected the Cache Statistics feature (Comet Cache Pro), resulting in a blank panel when hovering over the Cache Stats button in the menu bar. See [Issue #752](https://github.com/websharks/comet-cache/issues/752).
69
- - **Bug Fix**: When the PHP OPCache extension is active, the OPCache is now cleared when a WordPress plugin is upgraded, activated, or deactivated. This works around an issue that could produce a fatal error when the PHP OPCache contains cached PHP code that conflicts with new PHP code introduced by an update. See [Issue #740](https://github.com/websharks/comet-cache/issues/740).
70
- - **Enhancement** (Pro): It's now possible to disable the WordPress Admin Toolbar when Logged-In User Caching is enabled with a new option in _Comet Cache → Plugin Options → Logged-In Users → Disable the Admin Toolbar for Logged-In Users & Comment Authors?_ Props @renzms and @KTS915. See [Issue #690](https://github.com/websharks/comet-cache/issues/690).
71
- - **Enhancement**: The the option to automatically clear the cache for Custom Term Archive Views (see _Comet Cache → Plugin Options → Automatic Cache Clearing → Auto-Clear "Custom Term Archives" Too?_) is now enabled by default. This feature was previously disabled by default, which lead to confusion about why those cache files were not being cleared automatically when a Custom Post Type with a Custom Term Archive View was being used. Props @renzms. See [Issue #693](https://github.com/websharks/comet-cache/issues/693).
72
- - **Enhancement** (Pro): A new filter allows overriding the default behavior to clear the user cache upon login and logout when caching for Logged-In Users is enabled. See [this article](https://cometcache.com/r/kb-article-how-can-i-prevent-the-user-cache-from-being-cleared-upon-login-or-logout/) for details. Props @KTS915. See [Issue #756](https://github.com/websharks/comet-cache/issues/756).
73
-
74
- = v160417 =
75
-
76
- - **Bug Fix**: Fixed a "PHP Fatal error: Undefined class constant 'CACHE_PATH_NO_SCHEME'" introduced by the previous release (v160416). This issue only affected sites where Feed Caching was enabled (_Comet Cache → Plugin Options → RSS, RDF, and Atom Feeds_). Props to MassimoD and @emanwebdev for reporting. See [Issue #739](https://github.com/websharks/comet-cache/issues/739).
77
-
78
- = v160416 =
79
-
80
- - **Enhancement**: Several PHP 5.4+ enhancements, most notably a conversion from PHP Closures to PHP Traits. See [Issue #635](https://github.com/websharks/comet-cache/issues/635).
81
- - **Enhancement**: Dashboard notices generated by Comet Cache now use the WordPress-style dismiss button to keep things consistent. See [Issue #719](https://github.com/websharks/comet-cache/issues/719).
82
- - **Enhancement**: Dashboard notices generated by Comet Cache are now compacted into a single notice that can be expanded to view details. This helps reduce the number of messages that appear when, for example, a Post is published or updated and several cache files are automatically cleared. Instead of showing a separate notice for each type of cache file that was cleared, a single notice is shown with a link to toggle the details. See [Issue #118](https://github.com/websharks/comet-cache/issues/118).
83
- - **Enhancement** (Pro): Improved the way the Auto-Cache Engine figures out the URL scheme (`http` vs `https`) that should be used when fetching the XML Sitemap. Instead of forcing `http`, whatever scheme is configured with the Home URL is now used. See [Issue #715](https://github.com/websharks/comet-cache/issues/715).
84
- - **Enhancement** (Pro): The Pro Plugin Updater page now includes a "Save All Changes" button at the bottom, allowing you to save changes to the updater configuration without actually running the plugin updater. Props @bridgeport @NoahjChampion @1wdtv. See [Issue #681](https://github.com/websharks/comet-cache/issues/681).
85
- - **Bug Fix**: Fixed a duplicated row of links on the Pro Plugin Updater page. See [Issue #696](https://github.com/websharks/comet-cache/issues/696).
86
- - **Bug Fix**: Fixed an issue where some browsers would report "Failed to parse SourceMap" errors in their console when browsing the Comet Cache Options page. This was related to `sourceMappingURL` comments in the minified JS/CSS files that were intended for development purposes. Props to @1wdtv for reporting. See [#732](https://github.com/websharks/comet-cache/issues/732).
87
- - **Bug Fix**: Fixed a UI bug in the Pro Preview that was causing the Manual Cache Clearing panel to not appear as part of the Pro Preview. Props @renzms. See [Issue #711](https://github.com/websharks/comet-cache/issues/711).
88
- - **Bug Fix** (Pro): Fixed a bug related to the Pro Updater where some users who had migrated from ZenCache Pro to Comet Cache Pro were seeing an invalid new version message. Props @renzms @jaswsinc. See [Issue #727](https://github.com/websharks/comet-cache/issues/727)
89
- - **Bug Fix** (Pro): Fixed a bug with the Pro Plugin Updater that resulted in "Unknown error. Please wait 15 minutes and try again." when attempting to update Comet Cache Pro. The issue affected sites on servers running an old version of cURL (< v7.36) and/or an old version of OpenSSL, which made them unable to connect to the Comet Cache Pro update server. The Pro Plugin Updater now attempts to connect to a secondary update server that is more compatible with older versions of cURL and OpenSSL. See [Issue #678](https://github.com/websharks/comet-cache/issues/678).
90
- - **Hooks/Filters**: Comet Cache now hooks into `plugins_loaded` instead of `after_setup_theme` when calling its own setup routine. This improves integration with other plugins that may be expecting the Comet Cache API functions to be available after `plugins_loaded`. Props to Frank Goossens (@futtta) from Autoptimize for helping with this. See [Issue #716](https://github.com/websharks/comet-cache/issues/716).
91
- - **Compatibility**: Fixed a compatibility issue for some themes and plugins that were using old AC Plugin code designed to work with Quick Cache. This fix adds some backwards compatibility support for Quick Cache, but note that the first release of Comet Cache dropped support for Quick Cache backwards compatibility in favor of ZenCache backwards compatibility. See [Issue #710](https://github.com/websharks/comet-cache/issues/710).
92
- - **Compatibility: Query Monitor.** The Query Monitor plugin was reporting false-positive errors indicating that many Comet Cache methods did not exist. This was due to how the Comet Cache codebase was utilizing PHP Closures, which Query Monitor had a hard time handling. The codebase has been refactored to use PHP Traits instead of Closures and now the Query Monitor plugin has no problem recognizing Comet Cache methods. Props to @NoahjChampion for reporting. See [Issue #686](https://github.com/websharks/comet-cache/issues/686).
93
- - **Compatibility: WP-CLI.** When installing Comet Cache via WP-CLI, Comet Cache is now automatically enabled. There's no need to manually enable Comet Cache from within the plugin options after installing. Props @jaswsinc. See [Issue #464](https://github.com/websharks/comet-cache/issues/464).
94
- - **Required WordPress Version is now v4.2.** The minimum required WordPress version has been bumped from v4.1 to v4.2. See [Issue #706](https://github.com/websharks/comet-cache/issues/706).
95
-
96
- = v160227 =
97
-
98
- - **Bug Fix**: Fixed a ZenCache Backwards Compatibility bug that was preventing calls to `$GLOBALS['zencache']` from working properly with Comet Cache. See [Issue #689](https://github.com/websharks/comet-cache/issues/689)
99
- - **Bug Fix**: Fixed a ZenCache Backwards Compatibility bug that was preventing `ZENCACHE_ALLOWED` from working properly with Comet Cache. See [Issue #683](https://github.com/websharks/comet-cache/issues/683).
100
- - **Bug Fix**: Fixed a Quick Cache Backwards Compatibility bug that was preventing calls to `$GLOBALS['quick_cache']` from working properly with Comet Cache. Props to @Kedakai for reporting. See [Issue #691](https://github.com/websharks/comet-cache/issues/691).
101
- - **Bug Fix** (Pro): Fixed an Auto-Cache Engine bug that was preventing the Auto-Cache Engine from generating cached pages. Props @digitalhexcode for reporting. See [Issue #679](https://github.com/websharks/comet-cache/issues/679).
102
- - **Enhancement**: Improved the way Comet Cache handles file locking in an effort to improve compatibility with various environments. There were reports of issues with PHP FPM/FastCGI and this release attempts to address those. See [Issue #671](https://github.com/websharks/comet-cache/issues/671)
103
- - **Enhancement** (Pro): A new HTML Compression option allows you to define whether or not HTML Compression should be enabled for Logged-In users (when Logged-In User caching is enabled). See **Comet Cache → Plugin Options → HTML Compression → Enable HTML Compression for Logged-In Users?**. Props @renzms. See [Issue #650](https://github.com/websharks/comet-cache/issues/650).
104
- - **Accelerated Mobile Pages (AMP) Compatibility**: Added full support for Accelerated Mobile Pages via the [AMP plugin](https://wordpress.org/plugins/amp/). Comet Cache now works great alongside the AMP plugin. AMP-generated pages will be cached and those cache files will be intelligently cleared when necessary to keep things up-to-date. See [Issue #688](https://github.com/websharks/comet-cache/issues/688).
105
-
106
- = v160223.1 =
107
-
108
- - **Bug Fix**: Fixes PHP Fatal Error when upgrading from Comet Cache v160211.
109
-
110
- = v160223 =
111
-
112
- - **Announcement: After March 1st, 2016 Comet Cache will require PHP Multibyte String support.** The `mbstring` extension provides Multibyte String support to PHP and is required to properly handle UTF-8 characters, which many sites now use. Without Multibyte String support, caching will be unstable. For that reason we are requiring the `mbstring` extension to improve reliability when caching and to prevent your site from experiencing unforeseen issues in the future..
113
- - **Bug Fix (Multisite)**: Fixed a bug where when Comet Cache was Network Activated the plugin settings link would show up in the plugins list for the Main Site and would lead to a 404 error. The settings link is now only shown when viewing the plugins list from the Network Admin. Props @jaswsinc. See [Issue #675](https://github.com/websharks/zencache/issues/675).
114
- - **Enhancement**: Added support-related links to the plugin options page. Props @renzms. See [Issue #612](https://github.com/websharks/zencache/issues/612#issuecomment-186827661).
115
-
116
- = v160222 =
117
-
118
- - **Announcement: ZenCache is changing its name to Comet Cache!** Learn more about this upcoming change [here](https://cometcache.com/r/announcing-comet-cache-formerly-zencache/).
119
- - **Announcement: This version of ZenCache requires PHP 5.4+.** As announced in the previous release, the minimum PHP version required to run ZenCache / Comet Cache has changed to PHP 5.4+ as of December 1st, 2015. Please see announcement with further details: [New Minimum PHP Version: PHP 5.4](http://zencache.com/r/new-minimum-php-version-php-5-4/)
120
- - **Announcement: This version of ZenCache does not support the PHP APC Extension**. As announced in the previous release, ZenCache / Comet Cache no longer runs with the PHP APC extension enabled as of December 1st, 2015. Please see announcement with further details: [PHP APC Extension No Longer Supported](http://zencache.com/r/php-apc-extension-no-longer-supported/)
121
- - **Announcement: After March 1st, 2016 ZenCache / Comet Cache will require PHP Multibyte String support.** The `mbstring` extension provides Multibyte String support to PHP and is required to properly handle UTF-8 characters, which many sites now use. Without Multibyte String support, caching will be unstable. For that reason we are requiring the `mbstring` extension to improve reliability when caching and to prevent your site from experiencing unforeseen issues in the future.
122
- - **Announcement: Restructured Codebase**. The entire ZenCache Lite codebase has been restructured to improve performance, enhance flexibility, and make it easier to build in new features! This release of ZenCache Lite has been built from the ZenCache Pro codebase, which is more polished and up-to-date. This release includes many changes and improvements that were released as part of ZenCache Pro releases over the past 6 months and are now being included in the Lite version. See the full changelog below for a complete list of changes.
123
- - **New Feature!** A new watered-down Regular Expression syntax is now supported in several existing ZenCache features, including XML Sitemap Patterns, URI Exclusion Patterns, HTTP Referrer Exclusion Patterns, and User-Agent Exclusion Patterns. (It is also supported in the Pro-only Custom URLs to Auto-Clear, and the HTML Compressor CSS Exclusion Patterns and JavaScript Exclusion Patterns.) This new syntax greatly increases the power and flexibility of each of these features and makes things possible like the much-requested ability to Auto-Clear the Home Page or Posts Page of a site whenever a post cache is cleared. For more information on this new watered-down Regular Expression syntax, [this KB Article](http://zencache.com/r/watered-down-regex-syntax/). Props @kristineds @jaswsinc. See [Issue #191](https://github.com/websharks/zencache/issues/191).
124
- - **Bug Fix**: Fixed a bug with clearing cache files for paginated pages where the `pagination_base` had been changed from the default `page` to something else (e.g., a translated string). The WP Rewrite API is now used to include `pagination_base` and `comments_pagination_base` when building paths to cache files to determine which cache files should be cleared. Props @renzms. See [Issue #607](https://github.com/websharks/zencache/issues/607).
125
- - **Bug Fix**: This release attempts to resolve reports of Error 500 and Internal Server Error issues when running with PHP 5.6 + OPcache. Instead of clearing the entire Opcode cache whenever the plugin options are saved, we only invalidate the `advanced-cache.php` file, which is rebuilt each time you update your configuration options. Props @jaswsinc. Also props to @MarioKnight and @CotswoldPhoto for helping us narrow this down. See [Issue #624](https://github.com/websharks/zencache/issues/624).
126
- - **Bug Fix**: Fixed an issue where a PHP Notice was generated when an inactive WordPress component was being upgraded. This issue did not have any adverse affect on the site, but this fix resolves the issue so that the notice won't appear in PHP logs. See [Issue #589](https://github.com/websharks/zencache/issues/589).
127
- - **Bug Fix**: Fixed a bug where a commented-out `WP_CACHE` definition in `wp-config.php` (such as what WP Super Cache leaves behind) was being incorrectly ignored and resulted in caching being silently disabled. Props @davidfavor. See [Issue #591](https://github.com/websharks/zencache/issues/591).
128
- - **Bug Fix**: Fixed a bug where in some scenarios a page might not be cached due to a stray `AUTH_COOKIE` or `SECURE_AUTH_COOKIE` cookie, even when the user is not logged in. Props @jaswsinc @renzms. See [Issue #592](https://github.com/websharks/zencache/issues/592).
129
- - **Bug Fix**: Fixed an issue related to a popular NGINX server configuration (`try_files $uri $uri/ /index.php?q=$uri&$args;`) that was preventing the entire site from being cached. ZenCache disables caching by default for all requests that include a query string (see _Dashboard → ZenCache → Plugin Options → GET Requests_) and this particular NGINX configuration passes _all_ requests to WordPress with a `?q=` query variable, which was resulting in ZenCache disabling caching on all pages. This release implements better detection for NGINX and works around this scenario. Props @jaswsinc. See [Issue #561](https://github.com/websharks/zencache/issues/561).
130
- - **Bug Fix**: Fixed a bug where, in some rare cases, `wp-config.php` would end up with two `WP_CACHE` definitions. Props @jaswsinc. See [Issue #509](https://github.com/websharks/zencache/issues/509).
131
- - **Bug Fix**: Saving a Post as a Draft was incorrectly purging XML Sitemap cache files. Props @jaswsinc. See [Issue #368](https://github.com/websharks/zencache/issues/368).
132
- - **Bug Fix**: Fixed a bug in the Dynamic Version Salt filter that was generating PHP notices and warnings. See [Issue #522](https://github.com/websharks/zencache/issues/522).
133
- - **Bug Fix**: Fixed an issue with backwards compatibility that was preventing some AC Plugins from working properly. See [Issue #514](https://github.com/websharks/zencache/issues/514).
134
- - **Bug Fix**: Fixed a bug where saving a Post/Page as a Draft as a user with an Editor role would unnecessarily clear the Home Page cache. See [Issue #625](https://github.com/websharks/zencache/issues/625).
135
- - **Multisite Bug Fix**: Fixed a bug where the Clear Cache button wouldn't clear Child-Site Logged-In User Home Page cache files on WordPress Multisite Networks. Props @jaswsinc. See [Issue #409](https://github.com/websharks/zencache/issues/409)
136
- - **Multisite Bug Fix**: Fixed a bug where the Home Page cache was not clearing on Child Sites in a Multisite Network. Props @jaswsinc. See [Issue #409](https://github.com/websharks/zencache/issues/409)
137
- - **Multisite Bug Fix**: Fixed a bug with 404 Request caching on Multisite Networks where ZenCache Pro was not considering that each child blog in a multisite network will have its own 404 error page. Props @jaswsinc. See [Issue #539](https://github.com/websharks/zencache/issues/539).
138
- - **Multisite Bug Fix**: Fixed a bug where clearing the cache from the main site of a multisite network, when there are child blogs in sub-directories, resulted in all child blogs being cleared from the cache, not just the main site as would be expected. This has been resolved and only the main site is cleared when clicking the Clear Cache button. Note that the Wipe Cache button can still be used to clear the cache for all sites in a Multisite Network. Props @jaswsinc. See [Issue #540](https://github.com/websharks/zencache/issues/540).
139
- - **Multisite Bug Fix**: Fixed a bug where Wiping the cache on a multisite network resulted in the very next page view being cached incorrectly. Props @jaswsinc. See [Issue #541](https://github.com/websharks/zencache/issues/541).
140
- - **Multisite Bug Fix**: Fixed a bug where when ZenCache was Network Activated the plugin settings link would show up in the plugins list for the Main Site and would lead to a 404 error. The settings link is now only shown when viewing the plugins list from the Network Admin. Props @jaswsinc. See [Issue #675](https://github.com/websharks/zencache/issues/675).
141
- - **Enhancement**: Added support-related links to the plugin options page. Props @renzms. See [Issue #612](https://github.com/websharks/zencache/issues/612#issuecomment-186827661).
142
- - **Enhancement**: It's now possible to override the ZenCache Nonce exclusion globally (dangerous) or only for Logged-In Users (safer). Please see [this article](http://zencache.com/r/kb-article-what-are-wordpress-nonces-and-why-are-they-not-cache-compatible/) for full details. [Issue #637](https://github.com/websharks/zencache/issues/637).
143
- - **Enhancement**: Improved WP Cron-related configuration and validation of custom cron schedules. See [PR #197](https://github.com/websharks/zencache-pro/pull/197).
144
- - **Enhancement**: ZenCache now clears the cache whenever a WordPress plugin is activated or deactivated. Many WordPress plugins change content on the front-end of the site, so this enhancement ensures that an old cache file is never served to visitors. If you want to disable this automatic behavior, see [this article](http://zencache.com/kb-article/how-do-i-prevent-zencache-from-clearing-the-cache-upon-plugin-activation-or-deactivation/). Props @renzms. See [Issue #424](https://github.com/websharks/zencache/issues/424).
145
- - **Enhancement**: When activating ZenCache for the first time, a new Dashboard message now includes a helpful link to the options page to enable caching and review the options. Props @kristineds. See [Issue #112](https://github.com/websharks/zencache/issues/112).
146
- - **Enhancement**: The automatic Cache Cleanup schedule that cleans up (deletes) expired/stale cache files has been changed from once every day to once every hour. Running the cleanup hourly makes ZenCache smarter when configured in certain ways and saves disk space. Props @kristineds. See [Issue #472](https://github.com/websharks/zencache/issues/472).
147
- - **Enhancement**: When the Cache Directory location is changed, ZenCache now cleans up the old Cache Directory and any old cache files instead of leaving them behind. Props @clavaque @renzms. See [Issue #580](https://github.com/websharks/zencache/issues/580).
148
- - **Enhancement**: Added a new API Function that allows a site owner to clear the cache for a specific URL via `zencache::clearUrl($url);`. See [this article](http://zencache.com/kb-article/clearing-the-cache-dynamically/#toc-988085ad) for further details. Props @kristineds. See [Issue #590](https://github.com/websharks/zencache/issues/590).
149
- - **Enhancement**: Improved the HTML Notes generated by ZenCache when s2Member (a membership plugin for WordPress) is specifically disabling caching. s2Member automatically disables caching on certain pages that are required to remain dynamic. The HTML Notes generated by ZenCache now explain when this is happening. Props @renzms. See [Issue #504](https://github.com/websharks/zencache/issues/504).
150
- - **Enhancement**: Manual Cache Clearing options have now been separated from Automatic Cache Clearing options inside the ZenCache Plugin Options to improve the differentiation between these.
151
- - **Enhancement**: New icons in the ZenCache Plugin Options help improve the visual representation of each panel.
152
- - **Enhancement**: The installed plugin version is now shown at the top of the ZenCache Options Page. Props @renzms. See [Issue #502](https://github.com/websharks/zencache/issues/502).
153
- - **Enhancement**: New transition in/out effects on the Cache Cleared Dashboard notifications. Props @jaswsinc. See [Issue #538](https://github.com/websharks/zencache/issues/538).
154
- - **Enhancement**: Improved compatibility with any Custom Post Type that uses hierarchies. Props @jaswsinc.
155
- - **Akismet Compatibility:** ZenCache no longer caches pages that contain `akismet_comment_nonce` in the markup. This ensures that a page that contains a time-sensitive `nonce` value does not get cached. Props @kristineds and @jaswsinc. See [Issue #601](https://github.com/websharks/zencache/issues/601).
156
- - **Akismet Compatibility:** ZenCache now automatically disables the Akismet Comment Nonce using [the `akismet_comment_nonce` filter](https://github.com/git-mirror/wordpress-akismet/blob/2.5.6/akismet.php#L333), which improves compatibility between Akismet and the page caching functionality provided by ZenCache. This ensures that pages do not contain time-sensitive `nonce` values that should not be cached. If you'd like to revert this behavior, please see [this article](http://zencache.com/kb-article/how-do-i-prevent-zencache-from-disabling-the-akismet-comment-nonce/). Props @kristineds and @jaswsinc. See [Issue #601](https://github.com/websharks/zencache/issues/601).
157
- - **Akismet Compatibility**: Fixed a bug with Akismet compatibility where ZenCache was not properly disabling the Akismet Comment Nonce, which resulted in pages being unnecessarily excluded from the cache due to the presence of the `akismet_comment_nonce` in the markup. Props @Kalfer. See [Issue #642](https://github.com/websharks/zencache/issues/642).
158
- - **WooCommerce Compatibility:** This release improves compatibility with the WooCommerce Product Stock feature. When the Product Stock changes, ZenCache will now clear the cache file for the associated Product to ensure that the stock quantity that appears on the site remains up-to-date. See [Issue #597](https://github.com/websharks/zencache/issues/597).
159
- - **Multisite Domain Mapping Compatibility**: ZenCache is now fully compatible with the [WordPress MU Domain Mapping plugin](https://wordpress.org/plugins/wordpress-mu-domain-mapping/), including Multisite Networks using domain mapping on top-level domains, sub-domains, and sub-directories. Multiple variations of each site spread across an unlimited number of domain mappings and/or the original blog domain/path is also supported. All Pro-only features, including the Auto-Cache Engine, Static CDN Filters, and HTML Compression, are also now compatible with domain mapping. Props @jaswsinc. See [Issue #339](https://github.com/websharks/zencache/issues/339).
160
- - **bbPress Compatibility**: This release greatly improves compatibility with bbPress. Events like creating a new Forum, creating a new Topic, and posting a reply to a Topic (including threaded replies), now properly clear the necessary cache files to ensure that cached bbPress pages remain up-to-date. Props @jaswsinc. See [Issue #168](https://github.com/websharks/zencache/issues/168).
161
- - **bbPress Compatibility:** This release improves compatibility with bbPress when ZenCache Logged-In User caching is enabled. In this scenario, bbPress may generate links for Admins that contain time-sensitive `_wpnonce` values which could expire if cached and result in certain admin-related actions failing. ZenCache no longer caches pages that contain `_wpnonce` in the markup. This ensures that pages containing time-sensitive `nonce` values are not cached. Props @kristineds, @jaswsinc, and @clavaque. See [Issue #601](https://github.com/websharks/zencache/issues/601).
162
- - **New Pro Features:** This release updates the Pro Preview to include several new Pro features that have been added over the past 6 months, including the ability to clear the PHP OPCache whenever manually clearing the cache (_ZenCache Options → Manual Cache Clearing → Clear the PHP OPCache Too?_), clear the CDN Cache whenever manually clearing the cache (_ZenCache Options → Manual Cache Clearing → CDN Cache Clear the CDN Cache Too?_), disable cache expiration if the server load average is high (_ZenCache Options → Cache Expiration Time → Disable Cache Expiration If Server Load Average is High_), the ability to specify which WordPress Roles/Capabilities are allowed to clear the cache from the WordPress Admin bar (_ZenCache Options → Manual Cache Clearing → Also allow others to clear the cache from their Admin Bar?_), a completely new Cache Statistics feature that allows you to monitor the health and status of your cache (_ZenCache → Stats / Charts_), the ability to specify a list of Custom URLs whose cache files should be cleared whenever ZenCache detects that a Post/Page cache should be cleared (_ZenCache Options → Automatic Cache Clearing → Misc. Auto-Clear Options → Auto-Clear a List of Custom URLs Too?_), a new menu of Clear Cache options in the Admin Bar that allows you to clear the cache for just the Home Page, the Current URL, a Specific URL, PHP's OPCache, or the CDN Cache (_ZenCache Options → Plugin Options → Manual Cache Clearing_), the ability to customize the Cache Cleanup Schedule and set your own schedule (_ZenCache Options → Manual Cache Clearing → Cache Cleanup Schedule_), the ability to configure the Pro Plugin Updater to check for Beta versions, an option to clear Expired WordPress Transients, and URI Exclusion Patterns for Client-Side Caching.
163
-
164
- = v160211 =
165
-
166
- **Announcing Comet Cache, formerly ZenCache!**
167
-
168
- We are very excited to announce the release of [Comet Cache](http://cometcache.com), an advanced WordPress caching plugin inspired by simplicity. Comet Cache is the successor to ZenCache (and Quick Cache before that), a very popular WordPress caching plugin that has been downloaded over 1 million times and has won acclaim for its speed, simplicity, and ease of configuration. [Read the full announcement here](https://cometcache.com/r/announcing-comet-cache-formerly-zencache/).
169
-
170
- = v160103 =
171
-
172
- - **Bug Fix**: Fixed an issue that was unexpectedly producing "Failed to update your /.htaccess file" error messages. The `.htaccess` routines are now more intelligent and take into consideration which plugin options are enabled and which options require updating the `.htaccess` file. This also improves performance by avoiding unnecessary read/writes to the `.htaccess` file. Props @patdumond. See [Issue #641](https://github.com/websharks/zencache/issues/641).
173
- - **Bug Fix**: When `allow_url_fopen` is disabled via the PHP configuration, the Auto-Cache Engine is unable to read the XML Sitemap and was silently failing with only PHP Warning in the PHP error log. The Auto-Cache Engine currently requires [PHP URL-aware fopen wrappers](http://zencache.com/r/allow_url_fopen/). A new Dashboard notice displays an error message when `allow_url_fopen` is disabled and prevents the Auto-Cache Engine from attempting to run. See [Issue #644](https://github.com/websharks/zencache/issues/644).
174
- - **Bug Fix**: Fixed an Auto-Cache Engine bug that was producing false-positive Dashboard errors related to timeouts: "Problematic XML Sitemap URL - WP_Http says: Operation timed out after 5001 milliseconds with 0 bytes received." Due to the way ZenCache was checking the XML Sitemap URL more than necessary, timeouts were more likely to occur. We now only check the URL repeatedly when a failure has been encountered. If the URL is confirmed as working, we don't check the URL again until the Auto-Cache Engine runs (every 15 minutes by default) or until the Plugin Options are saved. If you are still seeing timeout errors after this update, please see [this article](http://zencache.com/kb-article/why-am-i-seeing-auto-cache-engine-timeout-errors/). See [Issue #643](https://github.com/websharks/zencache/issues/643).
175
- - **Bug Fix**: Fixed an Auto-Cache Engine bug where ZenCache would would check both the non-SSL (`http://`) and the SSL (`https://`) version of the XML Sitemap URL when the Site Address was configured to use SSL. See [Issue #643](https://github.com/websharks/zencache/issues/643).
176
- - **Enhancement**: It's now possible to override the ZenCache Nonce exclusion globally (dangerous) or only for Logged-In Users (safer). Please see [this article](http://zencache.com/r/kb-article-what-are-wordpress-nonces-and-why-are-they-not-cache-compatible/) for full details. [Issue #637](https://github.com/websharks/zencache/issues/637).
177
- - **Akismet Compatibility**: Fixed a bug with Akismet compatibility where ZenCache was not properly disabling the Akismet Comment Nonce, which resulted in pages being unnecessarily excluded from the cache due to the presence of the `akismet_comment_nonce` in the markup. Props @Kalfer. See [Issue #642](https://github.com/websharks/zencache/issues/642).
178
-
179
- = v151220 =
180
-
181
- - **New Feature!**: It's now possible to customize the Cache Cleanup Schedule and set your own schedule in _ZenCache → Plugin Options → Manual Cache Clearing → Cache Cleanup Schedule_. ZenCache uses [`wp_get_schedules()`](https://codex.wordpress.org/Function_Reference/wp_get_schedules) when generating the list of available schedules, which makes it possible to create your own custom cron schedule using a plugin like WP Crontrol and use that to define a custom Cache Cleanup Schedule. Props @kristineds. See [Issue #472](https://github.com/websharks/zencache/issues/472).
182
- - **New Feature!** It's now possible to configure the Pro Plugin Updater to check for Beta versions (Release Candidates) of the plugin. See _ZenCache → Plugin Updater → Beta Testers_. We publish Release Candidates a week or so before official releases to allow for additional testing and early preview of upcoming features and bug fixes. If you're not already on our Beta Testers mailing list, you can signup [here](http://zencache.com/r/zencache-beta-testers-list/). Props @kristineds. See [Issue #352](https://github.com/websharks/zencache/issues/352).
183
- - **New Feature!** It's now possible to clear [Expired WordPress Transients](https://codex.wordpress.org/Transients_API) from the Clear Cache Option Menu in the WordPress Admin Bar. The WordPress Transients API has no functionality to automatically clean up expired transients; doing so is left for plugin authors and we've found that very few plugins that use the Transient API actually clean up expired transients properly, which can lead to your database being full of expired transient data that is no longer used. Props @kristineds. See [Issue #459](https://github.com/websharks/zencache/issues/459).
184
- - **New Feature!** Client-Side Caching now includes a new URI Exclusion Patterns for Client-Side Caching, allowing you to exclude specific URIs from being cached by a client-side browser when Client-Side Caching is enabled. Props @renzms. See [Issue #498](https://github.com/websharks/zencache/issues/498).
185
- - **Bug Fix**: Fixed a bug that was generating a "Failed to update your `/.htaccess` file" error message. The routines that update your `.htaccess` file were failing if your `.htaccess` file already contained the word "ZenCache" (case-insensitive). See [Issue #617](https://github.com/websharks/zencache/issues/617) and [Issue #620](https://github.com/websharks/zencache/issues/620).
186
- - **Bug Fix**: Fixed a bug that in some scenarios could cause custom `.htaccess` rules to be lost if your `.htaccess` file was using the exact same comment start and end markers as ZenCache (`# BEGIN ZenCache` and `# END ZenCache`). If you were using those exact same start and end markers, ZenCache was replacing whatever was between them with a copy of the ZenCache `.htaccess` rules. ZenCache now uses a unique marker (`WmVuQ2FjaGU`) to identify its own code blocks inside your `.htaccess` file. See [Issue #620](https://github.com/websharks/zencache/issues/620).
187
- - **Bug Fix**: Fixed a bug with clearing cache files for paginated pages where the `pagination_base` had been changed from the default `page` to something else (e.g., a translated string). The WP Rewrite API is now used to include `pagination_base` and `comments_pagination_base` when building paths to cache files to determine which cache files should be cleared. Props @renzms. See [Issue #607](https://github.com/websharks/zencache/issues/607).
188
- - **Bug Fix**: Fixed a bug with the Static CDN Filters that affected sites using a permalink structure that ended with `.htm` or `.html`. This bug was supposed to be fixed back in v151002 but another bug prevented the fix from working properly. This release fixes the issue once and for all. See [Issue #495](https://github.com/websharks/zencache/issues/495#issuecomment-160324313).
189
- - **Bug Fix**: With Logged-In User caching enabled, there were some scenarios where the user cache was being cleared on every page load when a user was logged in. ZenCache now hooks into `updated_user_metadata` instead of `update_user_metadata` to clear a specific user cache. Props @kristineds. See [Issue #623](https://github.com/websharks/zencache/issues/623).
190
- - **Bug Fix**: Fixed a bug where the Auto-Cache Engine cron event would disappear in some scenarios. Props @patdumond, @MarioKnight. See [Issue #613](https://github.com/websharks/zencache/issues/613).
191
- - **Bug Fix**: ZenCache no longer caches any pages that contain `_wpnonce` in the markup. This ensures that pages containing time-sensitive `nonce` values are not cached. Props @kristineds and @jaswsinc. See [Issue #601](https://github.com/websharks/zencache/issues/601).
192
- - **Bug Fix**: This release attempts to resolve reports of Error 500 and Internal Server Error issues when running with PHP 5.6 + OPcache. Instead of clearing the entire Opcode cache whenever the plugin options are saved, we only invalidate the `advanced-cache.php` file, which is rebuilt each time you update your configuration options. Props @jaswsinc. Also props to @MarioKnight and @CotswoldPhoto for helping us narrow this down. See [Issue #624](https://github.com/websharks/zencache/issues/624).
193
- - **Bug Fix**: Fixed a bug where ZenCache could inadvertently corrupt the `.htaccess` file if it contained invalid UTF-8 characters. This has been fixed by first checking the `.htaccess` file for invalid UTF-8 characters via `wp_check_invalid_utf8()`. See [Issue #633](https://github.com/websharks/zencache/issues/633#issuecomment-165493039).
194
- - **Enhancement**: Improved WP Cron-related configuration and validation of custom cron schedules. See [PR #197](https://github.com/websharks/zencache-pro/pull/197).
195
- - **Enhancement**: ZenCache now clears the cache whenever a WordPress plugin is activated or deactivated. Many WordPress plugins change content on the front-end of the site, so this enhancement ensures that an old cache file is never served to visitors. If you want to disable this automatic behavior, see [this article](http://zencache.com/kb-article/how-do-i-prevent-zencache-from-clearing-the-cache-upon-plugin-activation-or-deactivation/). Props @renzms. See [Issue #424](https://github.com/websharks/zencache/issues/424).
196
- - **Enhancement**: The Auto-Cache Engine diagnostic reporting for XML Sitemap-related errors has been greatly improved. The Dashboard notice now explains exactly what error is occurring when the Auto-Cache Engine attempts to verify that the XML Sitemap exists. Props @jaswsinc. See [Issue #615](https://github.com/websharks/zencache/issues/615) and [Issue #618](https://github.com/websharks/zencache/issues/618).
197
- - **Enhancement**: Auto-Cache Engine XML Sitemap error checking is now more intelligent. When configured, the XML Sitemap URL is now checked upon every `admin_init` to verify that the XML Sitemap is accessible and valid. If a previous error has been fixed, the error message will disappear immediately instead of taking 15 minutes (the Auto-Cache Engine run cycle). See [Issue #616](https://github.com/websharks/zencache/issues/616).
198
- - **Enhancement**: Static CDN Filters are no longer applied by default for Logged-In Users. This was causing some confusion because Logged-In User caching is disabled by default. There is no harm in applying Static CDN Filters to all users (logged-in or not logged-in), in fact we recommend it, however we now disable this functionality by default to avoid confusion. A new option allows you to control this behavior and enable Static CDN Filters for Logged-In users; see _ZenCache → Logged-In Users → Static CDN Filters Enabled for Logged-In Users & Comment Authors?_ Props @kristineds, @lkraav, and @isaumya. See [Issue #486](https://github.com/websharks/zencache/issues/486).
199
- - **Enhancement**: The Static CDN Filters now attempt to obey the `ZENCACHE_ALLOWED` and `DONOTCACHEPAGE` constants so that Static CDN Filters are not applied when caching is disabled. However, due to the way Static CDN Filters are implemented this is not always reliable. If you need to programmatically disable Static CDN Filters, see [this article](http://zencache.com/kb-article/how-do-i-disable-static-cdn-filters-via-php/). See [Issue #628](https://github.com/websharks/zencache/issues/628).
200
- - **Enhancement**: When activating ZenCache for the first time, a new Dashboard message now includes a helpful link to the options page to enable caching and review the options. Props @kristineds. See [Issue #112](https://github.com/websharks/zencache/issues/112).
201
- - **Enhancement**: The automatic Cache Cleanup schedule that cleans up (deletes) expired/stale cache files has been changed from once every day to once every hour. Running the cleanup hourly makes ZenCache smarter when configured in certain ways and saves disk space. Props @kristineds. See [Issue #472](https://github.com/websharks/zencache/issues/472).
202
- - **Enhancement:** The new default value for "Clear the PHP OPcache Too?" when clearing the cache manually is now disabled. Instead of having this option enabled by default, we automatically invalidate only the `advanced-cache.php` file in PHP's opcode cache whenever you update your configuration options, which allows ZenCache to function as expected. That was the most important reason for needing to clear the opcode cache in previous versions. Props @jaswsinc. Also props to @MarioKnight and @CotswoldPhoto for helping us narrow this down. See [Issue #624](https://github.com/websharks/zencache/issues/624).
203
- - **Enhancement**: Improved `.htaccess` utilities so that an exclusive lock is acquired when reading+writing to the file. This helps avoid inadvertently corrupting the `.htaccess` file in scenarios where another process might be reading/writing to it at the same time. See [Issue #633](https://github.com/websharks/zencache/issues/633).
204
- - **Multisite Enhancement**: The Auto-Cache Engine has a new configuration option when running on WP Multisite Networks that allows you to define whether or not the Auto-Cache Engine should look for XML Sitemaps on each of the child blogs. This now defaults to being off; i.e., by default, child blogs are no longer checked. Props @jaswsinc. See [Issue #618](https://github.com/websharks/zencache/issues/618#issuecomment-158695842).
205
- - **Multisite Enhancement**: The Auto-Cache Engine XML Sitemap diagnostic reporting is now always disabled for child blogs and only errors related to a primary sitemap location are displayed on the Dashboard. Props @jaswsinc. See [Issue #618](https://github.com/websharks/zencache/issues/618#issuecomment-158695842).
206
- - **bbPress Compatibility:** This release improves compatibility with bbPress when ZenCache Logged-In User caching is enabled. In this scenario, bbPress may generate links for Admins that contain time-sensitive `_wpnonce` values which could expire if cached and result in certain admin-related actions failing. ZenCache no longer caches pages that contain `_wpnonce` in the markup. This ensures that pages containing time-sensitive `nonce` values are not cached. Props @kristineds, @jaswsinc, and @clavaque. See [Issue #601](https://github.com/websharks/zencache/issues/601).
207
- - **Akismet Compatibility:** ZenCache no longer caches pages that contain `akismet_comment_nonce` in the markup. This ensures that a page that contains a time-sensitive `nonce` value does not get cached. Props @kristineds and @jaswsinc. See [Issue #601](https://github.com/websharks/zencache/issues/601).
208
- - **Akismet Compatibility:** ZenCache now automatically disables the Akismet Comment Nonce using [the `akismet_comment_nonce` filter](https://github.com/git-mirror/wordpress-akismet/blob/2.5.6/akismet.php#L333), which improves compatibility between Akismet and the page caching functionality provided by ZenCache. This ensures that pages do not contain time-sensitive `nonce` values that should not be cached. If you'd like to revert this behavior, please see [this article](http://zencache.com/kb-article/how-do-i-prevent-zencache-from-disabling-the-akismet-comment-nonce/). Props @kristineds and @jaswsinc. See [Issue #601](https://github.com/websharks/zencache/issues/601).
209
- - **WooCommerce Compatibility:** This release improves compatibility with the WooCommerce Product Stock feature. When the Product Stock changes, ZenCache will now clear the cache file for the associated Product to ensure that the stock quantity that appears on the site remains up-to-date. See [Issue #597](https://github.com/websharks/zencache/issues/597).
210
-
211
- = v151114 =
212
-
213
- - **Announcement: The next version of ZenCache will require PHP 5.4+.** As of December 1st, 2015, the minimum PHP version required to run ZenCache will change to PHP 5.4+. This release of ZenCache will be the last version to support PHP 5.3. Please see announcement with further details: [New Minimum PHP Version: PHP 5.4](http://zencache.com/r/new-minimum-php-version-php-5-4/)
214
- - **Announcement: The next version of ZenCache will not support the PHP APC Extension**. As of December 1st, 2015, ZenCache will no longer run with the PHP APC extension enabled. Please see announcement with further details: [PHP APC Extension No Longer Supported](http://zencache.com/r/php-apc-extension-no-longer-supported/)
215
- - **New Feature!** The Clear Cache button in the Admin Bar now includes a sub-menu with several new options for clearing the cache from anywhere on your site. You can clear the cache for just the Home Page, the Current URL, a Specific URL, PHP's OPCache (if active), or the CDN Cache (when Static CDN Filters are configured). This menu comes in two flavors and can be customized (or disabled entirely) inside _ZenCache → Plugin Options → Manual Cache Clearing_. Props @jaswsinc. See [Issue #596](https://github.com/websharks/zencache/issues/596#issuecomment-152786080).
216
- - **New Feature!** It's now possible to specify a list of Custom URLs whose cache files should be cleared whenever you update a Post/Page, approve a Comment, or make other changes where ZenCache detects that a Post/Page cache should be cleared to keep your site up-to-date. See _ZenCache → Plugin Options → Automatic Cache Clearing → Misc. Auto-Clear Options → Auto-Clear a List of Custom URLs Too?_ Props @kristineds. See [Issue #111](https://github.com/websharks/zencache/issues/111).
217
- - **New Feature!** A new watered-down Regular Expression syntax is now supported in several existing ZenCache features, including the new list of Custom URLs to Auto-Clear, URI Exclusion Patterns, HTTP Referrer Exclusion Patterns, User-Agent Exclusion Patterns, and the HTML Compressor CSS Exclusion Patterns and JavaScript Exclusion Patterns. This new syntax greatly increases the power and flexibility of each of these features and makes things possible like the much-requested ability to Auto-Clear the Home Page or Posts Page of a site whenever a post cache is cleared. For more information on this new watered-down Regular Expression syntax, [this KB Article](http://zencache.com/r/watered-down-regex-syntax/). Props @kristineds @jaswsinc. See [Issue #191](https://github.com/websharks/zencache/issues/191).
218
- - **Bug Fix**: Fixed a bug with Static CDN Filters and Cross-Origin Resource Sharing (CORS) that was generating a "Cross-Origin Request Blocked" error. ZenCache will now update the root `.htaccess` file to include a `Header set Access-Control-Allow-Origin "*"` rule for `ttf`, `ttc`, `otf`, `eot`, `woff`, `woff2`, `font.css`, `css`, and `js` files whenever the Static CDN Filters are enabled. This is necessary to avoid "Cross-Origin Request Blocked" errors. Note that if you are already experiencing this error, you should create and configure a new CDN hostname to resolve the issue. In our tests it appears that some CDNs are caching the initial header response received by the server, which means it's necessary to send the `Access-Control-Allow-Origin` header _before_ configuring the Static CDN Filters with a CDN hostname. See [Issue #427](https://github.com/websharks/zencache/issues/427#issuecomment-121774596).
219
- - **Bug Fix**: Removed `eot,ttf,otf,woff` font extensions from the Static CDN Filter Blacklisted Extensions. These were added in a previous release in an attempt to resolve an issue with Cross-Origin Resource Sharing (CORS), however now that the HTML Compressor has been updated to work with Static CDN Filters, the CSS compressed by the HTML Compressor is now served from the CDN. Fonts are most likely to be referenced by CSS, which is static. So when Static CDN Filters are applied, the CSS is getting moved to the CDN and the fonts are then expected to live on the CDN too. By excluding them from the Static CDN Filter, we were creating a problem instead of solving one. This release removes the font extensions from the default Blacklisted Extensions so that fonts can be hosted on the CDN alongside the CSS that references them. See [Issue #427](https://github.com/websharks/zencache/issues/427#issuecomment-121777790).
220
- - **Bug Fix**: Fixed a bug related to updating plugins with WP-CLI on a site that was running ZenCache Pro. While ZenCache Pro updates must still be done through the ZenCache Pro Updater inside the Dashboard, updating other plugins via WP-CLI was generating a harmless ZenCache exception: "Invalid argument; host token empty!". With this fix, ZenCache will properly detect when WP-CLI is running to avoid these errors. Props @MarioKnight @renzms. See [Issue #563](https://github.com/websharks/zencache/issues/563).
221
- - **Bug Fix**: Fixed a bug where post previews were being cached when Logged-In User Caching and GET Request caching were both enabled (both are disabled by default). This release now detects previews in this scenario and excludes those requests from being cached. Props @clavaque @kristineds. See [Issue #583](https://github.com/websharks/zencache/issues/583).
222
- - **Bug Fix**: Fixed an issue where a PHP Notice was generated when an inactive WordPress component was being upgraded. This issue did not have any adverse affect on the site, but this fix resolves the issue so that the notice won't appear in PHP logs. See [Issue #589](https://github.com/websharks/zencache/issues/589).
223
- - **Bug Fix**: Fixed a bug where a commented-out `WP_CACHE` definition in `wp-config.php` (such as what WP Super Cache leaves behind) was being incorrectly ignored and resulted in caching being silently disabled. Props @davidfavor. See [Issue #591](https://github.com/websharks/zencache/issues/591).
224
- - **Bug Fix**: Fixed a bug where in some scenarios a page might not be cached due to a stray `AUTH_COOKIE` or `SECURE_AUTH_COOKIE` cookie, even when the user is not logged in. Props @jaswsinc @renzms. See [Issue #592](https://github.com/websharks/zencache/issues/592).
225
- - **Enhancement**: Excluded several unnecessary files from the plugin zip file that were being used during the build process but were not necessary to run the plugin. Props @bridgeport. See [Issue #579](https://github.com/websharks/zencache/issues/579).
226
- - **Enhancement**: When the Cache Directory location is changed, ZenCache now cleans up the old Cache Directory and any old cache files instead of leaving them behind. Props @clavaque @renzms. See [Issue #580](https://github.com/websharks/zencache/issues/580).
227
- - **Enhancement**: Added a new API Function that allows a site owner to clear the cache for a specific URL via `zencache::clearUrl($url);`. See [this article](http://zencache.com/kb-article/clearing-the-cache-dynamically/#toc-988085ad) for further details. Props @kristineds. See [Issue #590](https://github.com/websharks/zencache/issues/590).
228
- - **Enhancement**: Improved the HTML Notes generated by ZenCache when s2Member (a membership plugin for WordPress) is specifically disabling caching. s2Member automatically disables caching on certain pages that are required to remain dynamic. The HTML Notes generated by ZenCache now explain when this is happening. Props @renzms. See [Issue #504](https://github.com/websharks/zencache/issues/504).
229
- - **Enhancement**: In Logged-In User Caching, the "Yes, but DON'T maintain a separate cache for each user" option has been hidden because this particular option has the potential to create a security issue if not configured properly. If you were already using this option, it will not be hidden and it will continue to work. Otherwise, if you require this particular option you can now enable it using a filter (see [this comment](https://github.com/websharks/zencache/issues/497#issuecomment-146060440)). Props @renzms @jaswsinc. See [Issue #497](https://github.com/websharks/zencache/issues/497).
230
- - **Enhancement**: The Auto-Cache Engine now detects when the configured XML Sitemap is not valid or is unreachable and displays an appropriate notice. Props @kristineds and @jaswsinc. See [Issue #555](https://github.com/websharks/zencache/issues/555).
231
-
232
- = v151004 =
233
-
234
- - **Bug Fix**: Fixed a bug introduced in the previous release that was resulting in a "Fatal error: Using $this when not in object context" for sites running PHP 5.3. (PHP 5.4+ sites were unaffected.) Props @jaswsinc. See [Issue #581](https://github.com/websharks/zencache/issues/581).
235
-
236
- = v151002 =
237
-
238
- - **New Feature!** Cache Statistics is a completely new ZenCache Pro feature that will help site owners better understand their WordPress site cache. An easy-to-access Cache Stats menu button in the Admin Bar is accompanied by a whole new page that shows Current Cache Totals (including total number of cache files and total size of cache on the disk), Current Disk Health (including total disk capacity and total available), Current System Health (including memory usage and load average), and two beautiful Polar Area pie charts that show you both current and historical data on Cache File Counts and Cache File Sizes with a 30-Day High, Current Total, Page Cache total, and HTML Compressor total for each chart. Props to @jaswsinc. See [Issue #83](https://github.com/websharks/zencache/issues/83).
239
- - **New Feature!** It's now possible to specify which WordPress Roles/Capabilities are allowed to clear the cache from the WordPress Admin bar. A new option inside _Dashboard → ZenCache → Plugin Options → Manual Cache Clearing_ allows specifying a comma-delimited list of Roles and/or Capabilities under, "Also allow others to clear the cache from their Admin Bar?". If a user has an allowed Role/Capability, they will see the "Clear Cache" button in their Admin Bar. This feature is also compatible with WordPress Multisite Networks, allowing a Network Administrator to define which Child Site roles should allow a Child Site user to see the "Clear Cache" button for their Child Site. Props @danielmt2k @jaswsinc. See [Issue #68](https://github.com/websharks/zencache/issues/68).
240
- - **New Feature!** It's now possible to "Disable Cache Expiration If Server Load Average is High" (see _Dashboard → ZenCache → Plugin Options → Cache Expiration Time_). This allows you to provide a specific load average that should cause ZenCache to disable cache expiration and help reduce stress on the server; i.e., to avoid generating a new version of the cache while the server is very busy. Props @jaswsinc. See [Issue #347](https://github.com/websharks/zencache/issues/347).
241
- - **New Feature!** It's now possible to manually clear the CDN Cache when Static CDN Filters are enabled. Inside the Static CDN Filters options panel there's a new "Clear CDN Cache" button and there's also a new option ("Clear the CDN Cache Too?") inside _Dashboard → ZenCache → Plugin Options → Manual Cache Clearing_ that allows you to specify whether or not you'd like the CDN Cache to be cleared whenever the "Clear Cache" button is clicked (either from the Admin Bar or from inside the Plugin Options). Props @kristineds @jaswsinc. See [Issue #488](https://github.com/websharks/zencache/issues/488).
242
- - **New Feature!** When your server has the [PHP OPCache Extension](http://zencache.com/r/php-opcache/) installed, ZenCache can now be configured to also clear the PHP opcode cache whenever you clear the cache manually using the ZenCache "Clear Cache" button. See _ZenCache Options → Manual Cache Clearing → Clear the PHP OPCache Too?_ (note that this option only appears if you have the OPCache Extension installed). Props @jaswsinc. See [Issue #489](https://github.com/websharks/zencache/issues/489).
243
- - **Bug Fix**: Fixed an HTML Compressor bug related to CSS pseudo-classes where spaces between the class name and pseudo-class name were being removed when CSS was minified. Props @patdumond @jaswsinc. See [Issue #544](https://github.com/websharks/zencache/issues/544).
244
- - **Bug Fix**: Fixed an HTML Compressor bug related to `<noscript>` tags. The HTML Compressor now makes no adjustments to anything inside `<noscript>` tags, and the same has always been true for IE conditional comments as well. Props @rtrevellyan @jaswsinc. See [Issue #65](https://github.com/websharks/html-compressor/issues/65).
245
- - **Bug Fix**: Fixed an issue related to a popular NGINX server configuration (`try_files $uri $uri/ /index.php?q=$uri&$args;`) that was preventing the entire site from being cached. ZenCache disables caching by default for all requests that include a query string (see _Dashboard → ZenCache → Plugin Options → GET Requests_) and this particular NGINX configuration passes _all_ requests to WordPress with a `?q=` query variable, which was resulting in ZenCache disabling caching on all pages. This release implements better detection for NGINX and works around this scenario. Props @jaswsinc. See [Issue #561](https://github.com/websharks/zencache/issues/561).
246
- - **Bug Fix**: Fixed a bug with the Static CDN Filters that affected sites using a permalink structure that ended with `.htm` or `.html`. Generally, files that end in `.htm` or `.html` are considered static files, hence the reason ZenCache was rewriting URLs with those extensions to point at the configured CDN. However, if a site uses `.htm` or `.html` in their permalink structure, all links to Posts/Pages within the site will appear to be static files when they are in fact dynamic and therefore should not be rewritten. ZenCache now checks the permalink structure and excludes `.htm` and `.html` from the allowed extensions when the permalink structure is using one of these. Props @jaswsinc. See [Issue #495](https://github.com/websharks/zencache/issues/495).
247
- - **Bug Fix**: Fixed an SSL issue with the HTML Compressor that was causing problems in some hosting environments where the hosting server was incorrectly setting `$_SERVER['REQUEST_SCHEME']` to `http` even when the WordPress Site URL and Home URL were set to use `https://`. As a result of this improper server configuration, the combined CSS/JS files generated by the HTML Compressor were being served over HTTP even when a site was configured to use HTTPS. This release applies a workaround for this improper server configuration that no longer looks at `$_SERVER['REQUEST_SCHEME']`. See [Issue #413](https://github.com/websharks/zencache/issues/413) and [Issue #73](https://github.com/websharks/html-compressor/issues/73).
248
- - **Multisite Bug Fix**: Fixed a bug in the Auto-Cache Engine that was resulting in duplicate Cron Jobs being created for each Child Site. The Auto-Cache Engine now only runs from the Main Site in a network, as it should. When the Auto-Cache Engine runs on the Main Site, it will also run for each of the Child Blogs (see [this article](http://zencache.com/r/kb-article-how-does-the-auto-cache-engine-cache-child-blogs-in-a-multisite-network/) for more information). Props @jaswsinc. See [Issue #543](https://github.com/websharks/zencache/issues/543).
249
- - **Enhancement**: Improved HTML Compressor HTTP connection handling, timeouts, protocol, BOM markers, exceptions, `Referer:` and `User-Agent:` headers. Props @LittleBastard77 @jaswsinc. See [Issue #391](https://github.com/websharks/zencache/issues/391) and [Issue #69](https://github.com/websharks/html-compressor/issues/69).
250
- - **Enhancement**: Manual Cache Clearing options have now been separated from Automatic Cache Clearing options inside the ZenCache Plugin Options to improve the differentiation between these.
251
- - **Enhancement**: New icons in the ZenCache Plugin Options help improve the visual representation of each panel.
252
- - **Enhancement**: The installed plugin version is now shown at the top of the ZenCache Options Page. When a newer version of the plugin is available, an "update available" link appears. Props @renzms. See [Issue #502](https://github.com/websharks/zencache/issues/502).
253
- - **Enhancement**: New transition in/out effects on the Cache Cleared Dashboard notifications. Props @jaswsinc. See [Issue #538](https://github.com/websharks/zencache/issues/538).
254
-
255
- = v150821 =
256
-
257
- - **Multisite Domain Mapping Compatibility**: ZenCache Pro is now fully compatible with the [WordPress MU Domain Mapping plugin](https://wordpress.org/plugins/wordpress-mu-domain-mapping/), including Multisite Networks using domain mapping on top-level domains, sub-domains, and sub-directories. Multiple variations of each site spread across an unlimited number of domain mappings and/or the original blog domain/path is also supported. All other features of ZenCache Pro, including the Auto-Cache Engine, Static CDN Filters, and HTML Compression are also now compatible with domain mapping. Props @jaswsinc. See [Issue #339](https://github.com/websharks/zencache/issues/339).
258
- - **bbPress Compatibility**: This release greatly improves compatibility with bbPress. Events like creating a new Forum, creating a new Topic, and posting a reply to a Topic (including threaded replies), now properly clear the necessary cache files to ensure that cached bbPress pages remain up-to-date. Props @jaswsinc. See [Issue #168](https://github.com/websharks/zencache/issues/168).
259
- - **Bug Fix**: Fixed a bug where, in some rare cases, `wp-config.php` would end up with two `WP_CACHE` definitions. Props @jaswsinc. See [Issue #509](https://github.com/websharks/zencache/issues/509).
260
- - **Bug Fix**: Saving a Post as a Draft was incorrectly purging XML Sitemap cache files. Props @jaswsinc. See [Issue #368](https://github.com/websharks/zencache/issues/368).
261
- - **Bug Fix:** The HTML Compressor now strips UTF-8 Byte Order Markers (BOMs) from CSS files generated by preprocessors such as Sass. Files consolidated by the HTML Compressor include an `@charset` rule already, making a BOM unnecessary. In fact, if BOMs are not stripped, some browsers will choke on portions of a consolidated CSS file, because a BOM could potentially appear in the middle of the file; i.e., at the _wrong_ place. Symptoms included mysterious missing styles in portions of the site, fonts not loading at all times, or font-based icons (e.g., FontAwesome) to render mystery glyphs instead of the icons. Props @jaswsinc. See [Issue #52](https://github.com/websharks/html-compressor/issues/52).
262
- - **Bug Fix:** Improved HTML Compressor strict data type comparison when analyzing `$_SERVER` environment variables to detect an `https://` connection URL. We now detect `(integer)443` and `(string)443`. In addition, we can now pick up `$_SERVER['HTTPS']` being any of `1|on|yes|true` (caSe insensitive). Props @jaswsinc. See [Issue #61](https://github.com/websharks/html-compressor/issues/61).
263
- - **Multisite Bug Fix**: Fixed a bug where the Clear Cache button wouldn't clear Child-Site Logged-In User Home Page cache files on WordPress Multisite Networks. Props @jaswsinc. See [Issue #409](https://github.com/websharks/zencache/issues/409)
264
- - **Multisite Bug Fix**: Fixed a bug where the Home Page cache was not clearing on Child Sites in a Multisite Network. Props @jaswsinc. See [Issue #409](https://github.com/websharks/zencache/issues/409)
265
- - **Multisite Bug Fix**: Fixed an issue where the Auto-Cache Engine would fail to auto-cache child blogs in a multisite network whenever the network was being served from a sub-directory. Props @jaswsinc. See [Issue #537](https://github.com/websharks/zencache/issues/537).
266
- - **Multisite Bug Fix**: Fixed a bug with 404 Request caching on Multisite Networks where ZenCache Pro was not considering that each child blog in a multisite network will have its own 404 error page. Props @jaswsinc. See [Issue #539](https://github.com/websharks/zencache/issues/539).
267
- - **Multisite Bug Fix**: Fixed a bug where clearing the cache from the main site of a multisite network, when there are child blogs in sub-directories, resulted in all child blogs being cleared from the cache, not just the main site as would be expected. This has been resolved and only the main site is cleared when clicking the Clear Cache button. Note that the Wipe Cache button can still be used to clear the cache for all sites in a Multisite Network. Props @jaswsinc. See [Issue #540](https://github.com/websharks/zencache/issues/540).
268
- - **Multisite Bug Fix**: Fixed a bug where Wiping the cache on a multisite network resulted in the very next page view being cached incorrectly. Props @jaswsinc. See [Issue #541](https://github.com/websharks/zencache/issues/541).
269
- - **Enhancement**: Improved compatibility with any Custom Post Type that uses hierarchies. Props @jaswsinc.
270
-
271
- = v150716 =
272
-
273
- - **Bug Fix**: Fixed a fatal error that was occurring on some sites after upgrading to v150629. We discovered the fatal error was related to PHP's outdated and buggy APC extension, which is often active on sites running PHP 5.3 and PHP 5.4. We now prevent activation of ZenCache on systems with the APC extension enabled and show a warning message instead. We've written [a KB Article that further explains the APC Extension Warning](http://zencache.com/kb-article/why-does-zencache-show-an-apc-extension-warning/) and offers advice to site owners who are currently running APC. See also [Issue #511](https://github.com/websharks/zencache/issues/511).
274
- - **Bug Fix**: Fixed a bug in the Dynamic Version Salt filter that was generating PHP notices and warnings. See [Issue #522](https://github.com/websharks/zencache/issues/522).
275
- - **Bug Fix**: Fixed an issue with backwards compatibility that was preventing some AC Plugins from working properly. See [Issue #514](https://github.com/websharks/zencache/issues/514).
276
- - **Enhancement**: Added a stats pinger, similar to the WordPress stats collector, that reports the server OS, PHP version, MySQL version, WordPress version, and the ZenCache version, securely and anonymously to WebSharks. See [this KB Article](http://zencache.com/kb-article/what-information-does-zencache-pro-report-to-websharks/) for more information.
277
-
278
- = v150626 =
279
-
280
- - **Restructured Codebase**: The entire ZenCache codebase has been restructured to improve performance, enhance flexibility, and make it easier to build in new features!
281
- - **New Feature!** The free version of ZenCache now supports several new options that were previously only available in the Pro version. You can now toggle the Auto-Clear Cache routines for the Home Page, Posts Page, Author Page, Category Archives, Tag Archives, Custom Term Archives, RSS/RDF/Atom Feeds, and XML Sitemaps. This gives you more control over exactly when ZenCache purges the cache for these parts of your site. See _ZenCache → Plugin Options → Clearing the Cache_ for further details.
282
- - **New Feature!** URI Exclusion Patterns are now available in ZenCache Lite! This previously Pro-only feature is now available in the free version of ZenCache and allows you to exclude a list of URIs from being cached by ZenCache. See _ZenCache → Plugin Options → URI Exclusion Patterns_ for further details.
283
- - **New Feature!** HTTP Referrer Exclusion Patterns are now available in ZenCache Lite! This previously Pro-only feature is now available in the free version of ZenCache and allows you to define a list of referring URLs or domains that send you traffic. When ZenCache sees a request coming from one of those URLs or domains, it will not cache that particular request. See _ZenCache → Plugin Options → HTTP Referrer Exclusion Patterns_ for further details.
284
- - **New Pro Feature!**: HTML Compression now supports compressing JSON (in addition to the already supported HTML, JavaScript, and CSS compression). Props @jaswsinc. See [Issue #469](https://github.com/websharks/zencache/issues/469).
285
- - **New Pro Feature!**: Static CDN Filters now supports multiple CDN hostnames. This allows you to configure more than one CDN hostname, also referred to as Domain Sharding. This makes it possible for site owners to work around web browser concurrency limits, allowing the browser to download many resources simultaneously, which increases overall speed. Props to @isaumya and @jaswsinc. See [Issue #468](https://github.com/websharks/zencache/issues/468).
286
- - **Enhancement** (Pro): Static CDN Filters now includes proper support for WordPress Multisite Networks, including support for subdomains (full support for Domain Mapping coming in the next release). If you're running a WordPress Multisite Network and want to configure a CDN, see [this KB Article](http://zencache.com/kb-article/static-cdn-filters-for-wordpress-multisite-networks/) for further details.
287
- - **Enhancement** (Pro): Static CDN Filters now also apply to any static files that are referenced inside CSS files. Props @jaswsinc. See [Issue #461](https://github.com/websharks/zencache/issues/461).
288
- - **Enhancement**: Completed a major restructure of the entire codebase to improve modularity and dependency management. Props @jaswsinc.
289
- - **Enhancement** (Pro): Static CDN Filters now supports the ability to configure separate CDN hostname(s) for each domain (or subdomain) that you run in a WordPress Multisite Network. Props @jaswsinc. See [Issue #475](https://github.com/websharks/zencache/issues/475).
290
- - **Enhancement** (Pro): Static CDN Filters now support subdomains when ZenCache is running inside a WordPress Multisite Network. Props @jaswsinc. See [Issue #439](https://github.com/websharks/zencache/issues/439).
291
- - **Bug Fix** (Pro): Static CDN Filters were not being applied to the primary site on WP Multisite installations that used subdomains. Props to @isaumya for discovering this bug. See [Issue #470](https://github.com/websharks/zencache/issues/470).
292
-
293
- = v150409 =
294
-
295
- - **Enhancement (includes improved CloudFlare support)**: Improvements to IP address detection, including added support for CloudFlare IP forwarding, multiple IPs in a single header, and the ability to customize the lookup order and/or add/remove sources that are searched when looking for the current IP address. It's also possible to revert to the old IP address detection behavior (see [How do I customize remote IP detection?](http://zencache.com/kb-article/how-do-i-customize-ip-address-detection/)). Props @jaswsinc. [Issue #449](https://github.com/websharks/zencache/pull/449)
296
- - **Enhancement** (Pro): Files being served by the HTML Compressor were being sent without a `Vary: Accept-Encoding` header, which caused some page speed testing services to give a lower rating to sites using ZenCache. ZenCache now ensures this header is sent via an `.htaccess` file inside the HTML Compressor cache directory (requires Apache 2.1+). Props @jaswsinc. [Issue #436](https://github.com/websharks/zencache/issues/436).
297
- - **Enhancement** (Pro): Static CDN Filters now also filter any static resources inside Text Widgets, so that those resources can be cached by your CDN. Props @jaswsinc. [Issue #430](https://github.com/websharks/zencache/issues/430)
298
- - **Enhancement** (Pro): Static CDN Filters now apply to minified and compressed CSS/JS files generated by the HTML Compressor; these files will now be cached by your CDN. Props @jaswsinc. [Issue #429](https://github.com/websharks/zencache/issues/429)
299
- - **Bug Fix**: Fixed a bug related to the Quick Cache migration that resulted in caching being disabled despite ZenCache being enabled. Uninstalling Quick Cache was removing `define('WP_CACHE', TRUE);` from the `wp-config.php` file. ZenCache now makes sure that caching remains enabled after uninstalling Quick Cache during the ZenCache migration process. [Issue #450](https://github.com/websharks/zencache/issues/450).
300
- - **Bug Fix**: Fixed a minor UI issue where the ZenCache Dashboard icon would occasionally flash to a black color when refreshing the Dashboard. Props @jaswsinc. [Issue #453](https://github.com/websharks/zencache/issues/453).
301
- - **Bug Fix**: When ZenCache was running on an installation of PHP with `open_basedir` restrictions applied, calls to `is_dir()` were triggering a PHP Warning while looking for a writable temporary directory. This bug has been fixed. [Issue #456](https://github.com/websharks/zencache/issues/456).
302
- - **Bug Fix**: Fixed a bug where changing the permalink for a published post would result in the cache file for the old permalink being left behind and as a result both the old and the new permalink would be accessible, instead of WordPress redirecting the old permalink to the new one. This has been fixed and ZenCache now properly clears the old cache file when changing the permalink on a published post. [Issue #359](https://github.com/websharks/zencache/issues/359).
303
- - **Bug Fix**: Fixed a bug where transitioning a Published post back to Pending or Draft would not automatically clear the cache file. This resulted in the post remaining accessible on the frontend despite being set as Pending or Draft. ZenCache now properly clears the cache file automatically when transitioning from Published to Pending or Draft, which prevents access to the post as expected. [Issue #441](https://github.com/websharks/zencache/issues/441).
304
- - **Bug Fix** (Pro): Some users reported seeing `Warning: trim() expects parameter 1 to be string`. This was produced by a low-impact bug that has been fixed in this release. [Issue #455](https://github.com/websharks/zencache/issues/455).
305
- - **Bug Fix** (Pro): Some users running the HTML Compressor reported seeing 403 Forbidden errors related to loading the compressed/minified files. This was a permissions-related issue that has been resolved in this release. Props @superian and @jaswsinc. See [Issue #50](https://github.com/websharks/html-compressor/issues/50).
306
- - **Bug Fix** (Pro): Some HTTP requests made by the HTML Compressor to servers configured to reject HTTP requests that don't include a User-Agent were failing. A User-Agent is now always used in all requests. Props @jaswsinc. See [Issue #49](https://github.com/websharks/html-compressor/issues/49).
307
- - **Minimum Required PHP Version Bumped to PHP v5.3.2+:** The minimum PHP version required for ZenCache has been bumped up to PHP v5.3.2+ (from PHP v5.3+). The ZenCache cache locking mechanism, specifically the use of `flock()`, requires behavior introduced in PHP v5.3.2. [Issue #444](https://github.com/websharks/zencache/issues/444).
308
-
309
- = v150314 =
310
-
311
- - **Bug Fix**: Fixed a bug in the Quick Cache back compat. method `\zencache\share\apply_wp_filters()`. It was not passing the ZenCache-filtered value through the Quick Cache back compat. routine. This bug affected sites that had disabled automatic cache clearing routines via a filter.
312
- - **Bug Fix** (Pro): Updated Static CDN Filters whitelist to include font file extensions `eot,ttf,otf,woff`, as site owners may wish to serve fonts with these extensions from the CDN (this would require a custom CORS configuration; see [this article](http://davidwalsh.name/cdn-fonts) for instructions). See [#427](https://github.com/websharks/zencache/issues/427).
313
- - **Bug Fix** (Pro): Updated Static CDN Filters blacklist to exclude font file extensions `eot,ttf,otf,woff` by default, as they require custom CORS configuration to display properly. See [#427](https://github.com/websharks/zencache/issues/427).
314
- - **Bug Fix** (Pro): The Static CDN Filters feature was calling a protected method that was requiring PHP v5.4+ but now the Static CDN Filters feature works with PHP v5.3+. See [#426](https://github.com/websharks/zencache/issues/426).
315
- - **Bug Fix**: Fixed a zero-byte `advanced-cache.php` bug related to migrating from Quick Cache. When you deleted/uninstalled Quick Cache after upgrading to ZenCache, the Quick Cache uninstallation process would empty the `advanced-cache.php` file, resulting in the site no longer being cached, despite ZenCache being active. ZenCache now continuously checks to make sure that `advanced-cache.php` is installed properly. See [#432](https://github.com/websharks/zencache/issues/432).
316
-
317
- = v150218 =
318
-
319
- **Announcing ZenCache, formerly Quick Cache!**
320
-
321
- We are very excited to announce the release of [ZenCache](http://zencache.com), an advanced WordPress caching plugin inspired by simplicity. ZenCache is the successor to Quick Cache, a very popular WordPress caching plugin that has been downloaded over 1 million times and won acclaim for its speed, simplicity, and ease of configuration. [Read the full announcement here](http://zencache.com/announcing-zencache-formerly-quick-cache/).
322
-
323
- ZenCache is an evolution of Quick Cache. It comes with a completely refactored codebase, subtle UI enhancements, internal optimizations; along with full backward compatibility with all previous versions of Quick Cache Lite and Quick Cache Pro. In fact, installing ZenCache on a site that was previously running Quick Cache is a piece of cake! Watch [this video](http://zencache.com/kb-article/how-to-migrate-from-quick-cache-lite-to-zencache-lite/) to learn more. All configuration options are preserved.
324
-
325
- - **New Pro Feature: CDN Integration:** With the announcement and release of ZenCache we are excited to also announce a new, highly-requested feature: Static CDN Filters. This feature allows you to serve some and/or ALL static files on your site from a CDN of your choosing. See also: [Introduction to Static CDN Filters](http://zencache.com/kb-article/introduction-to-static-cdn-filters/).
326
- - **Full Backwards Compatibility with Quick Cache and Quick Cache Pro:** ZenCache is fully backwards compatible with all previous versions of Quick Cache Lite and Quick Cache Pro. Simply install ZenCache and your existing Quick Cache options will preserved by ZenCache.
327
-
328
- = v150129 =
329
-
330
- - **Bug Fix** (Pro): Fixed a bug where the Pro Updater would fail when FTP or SFTP details via the WordPress Dashboard are required to perform updates. Props @jaswsinc. See [#389](https://github.com/websharks/quick-cache/issues/389).
331
- - **Bug Fix**: Several fixes for a stubborn bug related to "Fatal Error: 'Unable to clear dir'" error messages and errors referencing "SplFileInfo::getMTime(): stat failed". Props @jaswsinc. See [#397](https://github.com/websharks/quick-cache/issues/397).
332
- - **Bug Fix** (Pro): Fixed a bug where the `qcAC` variable (used to force-enable/disable GET Request caching) was not respected properly whenever a URL contained a query string and a user was currently logged into the site. Props @jaswsinc. See [#401](https://github.com/websharks/quick-cache/issues/401).
333
-
334
- = v141231 =
335
-
336
- - **Bug Fix**: Addressed another issue related to "Fatal Error: 'Unable to clear dir'" and tmp directories that don't get cleared by Quick Cache. This fix discards iteration references before renaming the tmp directories. Props @jaswsinc. See [#288](https://github.com/websharks/quick-cache/issues/288).
337
- - **Bug Fix**: We have had a few reports of getMTime Stat failing when clearing the cache. This fix clears the Stat Cache before iteration when deleting files from the cache directory. Props @jaswsinc. See [#385](https://github.com/websharks/quick-cache/issues/385).
338
- - **Enhancement**: Added a new filter (`quick_cache\\share_disable_cache_locking`) to allow disabling cache locking. Simply return boolean `TRUE` to this filter to disable cache locking. This may be useful for site owners who are experiencing issues with cache locking on web hosting platforms with filesystems that don't properly support locking. Note that this filter must be applied using an Advanced Cache Plugin (see **Dashboard → Quick Cache → Plugin Options → Theme/Plugin Developers**). See also [#387](https://github.com/websharks/quick-cache/issues/387).
339
- - **Enhancement**: Added a new filter that allows forcing Semaphore cache locking on hosting platforms where `sem_get()` is available and would result in improved performance. Return `sem` to the `quick_cache\\share::cache_lock_lock_type` filter to force Semaphore cache locking, or `flock` to use the default method that uses `flock()`. Note that this filter must be applied using an Advanced Cache Plugin (see **Dashboard → Quick Cache → Plugin Options → Theme/Plugin Developers**). See also [#387](https://github.com/websharks/quick-cache/issues/387).
340
-
341
- = v141205 =
342
-
343
- - **Bug Fix**: Addressed another issue with "Fatal Error: 'Unable to clear dir'" messages by adding new blocking methods for cache lock and unlock, making it so that cache writes (including clearing, purging, wiping) all gain an exclusive lock on the cache directory while work is underway. Props @jaswsinc. See [#288](https://github.com/websharks/quick-cache/issues/288).
344
- - **Bug Fix**: Fixed a Home Page clearing bug that arose in the previous release as the result of an extra leading `\/` in one of our regex patterns. Props @jaswsinc. See [#365](https://github.com/websharks/quick-cache/issues/365).
345
-
346
- = v141110 =
347
-
348
- - **Quick Cache is changing its name to ZenCache!** See [the blog post](http://www.websharks-inc.com/post/quick-cache-is-changing-its-name/) for full details.
349
- - **Enhancement**: All dashboard notices will now include the number of files cleared for each notice. Props @jaswsinc. See [#351](https://github.com/websharks/quick-cache/pull/351).
350
- - **Enhancement**: Quick Cache is now capable of doing atomic clearing/purging/wiping. On a Multisite network, this is now accomplished on a blog-specific basis, without needing to scan the entire network-wide cache directory. This should improve performance considerably on large networks (i.e. those with VERY large cache directories). Props @jaswsinc. See [#288](https://github.com/websharks/quick-cache/issues/288) and [#351](https://github.com/websharks/quick-cache/pull/351).
351
- - **Enhancement**: Added a new class file (`/includes/utils-feed.php`) and refactored the XML feed clearing routine. With these utilities in place, the `auto_clear_xml_feeds_cache()` method is now much easier to deal with and comprehend. Props @jaswsinc. See [#351](https://github.com/websharks/quick-cache/pull/351).
352
- - **Enhancement**: Quick Cache now scans each scheme sub-directory, i.e. `/http/` and `/https/`, separately to help break apart what was previously a much larger directory scan for sites that serve pages over both schemes. This will improve performance on both standard and Multisite network installs. See [#351](https://github.com/websharks/quick-cache/pull/351).
353
- - **Enhancement**: Refactored codebase to improve modularity by creating new methods in `includes/share.php` for network-wide clearing/purging/wiping, host/blog-specific clearing/purging/wiping, recursively deleting a directory, assisting in translations, and several new string utilities. Props @jaswsinc. See [#351](https://github.com/websharks/quick-cache/pull/351).
354
- - **Enhancement**: Renamed all `\quick_cache\plugin::auto_purge_*` methods, giving them the proper prefix of `auto_clear_*` instead to reflect proper Wipe/Clear/Purge terminology. Along with this, all of the `auto_purge_` option keys have been renamed as well. See new [Wipe/Clear/Purge wiki article](http://www.websharks-inc.com/r/quick-cache-wipeclearpurge-terminology-wiki/) for a description of these terms. Props @jaswsinc. See [#351](https://github.com/websharks/quick-cache/pull/351).
355
- - **Enhancement**: All URI and Referrer exclusion patterns are now caSe insensitive. WordPress v4.0 will serve URIs without cAse sensitivity. All of the Quick Cache codebase has been updated to support caSe insensitive clearing/purging/wiping; along with caSe insensitive pattern matching against URIs. Props @jaswsinc. See [#351](https://github.com/websharks/quick-cache/pull/351).
356
- - **Bug Fix (Pro)**: Fixed a bug with the Auto-Clear Author Cache routine that was presenting dashboard notices even when `change_notifications_enable` was off. Props @jaswsinc. See [#351](https://github.com/websharks/quick-cache/pull/351).
357
- - **Bug Fix (Pro)**: Fixed a bug with the HTML Compressor where `style`, `link` and/or `script` tags could become out of order in certain scenarios. See: [#45](https://github.com/websharks/html-compressor/issues/45)
358
- - **Bug Fix (Pro)**: Several HTML Compressor bug fixes related to JavaScript compression routines. See [#38](https://github.com/websharks/html-compressor/issues/38)
359
- - **Bug Fix**: Fixed a bug that was occasionally generating "Fatal Error: 'Unable to clear dir'" messages. The root cause of this is believed to be non-atomic purging of cache directories which, on a busy site, could result in new cache files being created before a purging routine was finished clearing the directory. Clearing/purging/wiping is now atomic in all scenarios. Props @jaswsinc. See [#288](https://github.com/websharks/quick-cache/issues/288) and [#351](https://github.com/websharks/quick-cache/pull/351).
360
- - **Bug Fix**: Fixed a bug in the Auto-Clear Custom Post Type Archive Cache that was not checking for the `$post_id` in `$this->static[__FUNCTION__]`. Props @jaswsinc. See [#351](https://github.com/websharks/quick-cache/pull/351).
361
- - **Bug Fix**: Fixed a bug with the uninstaller whereby attempting to uninstall after receiving a notice that PHP 5.3+ is required would result in a blank screen and require manual removal of the plugin. See [#334](https://github.com/websharks/quick-cache/issues/334).
362
- - **Bug Fix**: Fixed an issue with detecting cacheable requests that was, in rare instances, resulting in blank white pages for some site owners. See [#279](https://github.com/websharks/quick-cache/issues/279).
363
-
364
- = v141001 =
365
-
366
- - **Enhancement**: Improved Dashboard messaging for the `auto_clear_cache()` routine. See [#328](https://github.com/websharks/quick-cache/issues/328).
367
- - **Enhancement (Pro)**: Improved consistency of Auto-Cache Engine User-Agent string by removing WordPress-version-specific identifier. See [#315](https://github.com/websharks/quick-cache/issues/315).
368
- - **Enhancement (Pro)**: It is now possible to disable the automatic clear and wipe cache routines. If you have a very large site with many cache files, this feature allows you manual control over when the cache gets cleared or wiped. For complete documentation on this feature, see [Quick Cache Wiki - Clear and Wipe Cache Routines](https://github.com/websharks/quick-cache/wiki/Clear-Cache-and-Wipe-Cache-Routines). See also [#23](https://github.com/websharks/quick-cache/issues/23).
369
- - **Bug Fix**: Fixes an issue with the Pro Preview mode where saving the plugin options may inadvertently save Pro-only options that could later cause issues if the plugin is upgraded to the Pro version. See [#311](https://github.com/websharks/quick-cache/pull/311#issuecomment-54491922).
370
- - **Bug Fix**: Fixes an edge-case where the proper cache files do not get purged when a user with the Editor role publishes a new post with both a category and a tag associated with the post. See [#313](https://github.com/websharks/quick-cache/issues/313).
371
- - **Bug Fix**: When Quick Cache purges/resets the cache for a post with a Custom Post Type, any cache files for the associated Custom Post Type archive view are now auto-purged, along with any associated XML feed cache files. See [#280](https://github.com/websharks/quick-cache/issues/280).
372
- - **Bug Fix**: Fixed missing trailing slash in Directory / Expiration Time configuration panel. This was purely a visual inconsistency and had no effect on Quick Cache's functionality. See [#267](https://github.com/websharks/quick-cache/issues/267).
373
- - **Bug Fix**: When saving custom CSS using JetPack's Custom CSS module, Quick Cache now properly purges the site cache to ensure that outdated cache files are not served to visitors. See [#246](https://github.com/websharks/quick-cache/issues/246).
374
- - **Bug Fix**: When changes are made to WordPress General, Reading, Discussion, or Permalink settings (Dashboard -> Settings), Quick Cache now clears the cache to prevent an outdated cache file from being served to visitors. See [#223](https://github.com/websharks/quick-cache/issues/223).
375
- - **Bug Fix**: When an active plugin is updated, or when an active theme or the parent theme for an active child theme is updated, or when WordPress Core is updated, Quick Cache now properly clears the cache to ensure that an outdated cache file does not get served to a visitor. See [#145](https://github.com/websharks/quick-cache/issues/145) and [#327](https://github.com/websharks/quick-cache/issues/327).
376
- - **Bug Fix**: When a new comment is posted, Quick Cache now properly purges the cache files for any paginated comment pages. See [#336](https://github.com/websharks/quick-cache/issues/336).
377
- - **Bug Fix (Pro)**: Fixed a bug where the HTML Compressor, when enabled with the "remove extra whitespace in the final HTML" option, would incorrectly remove `<!DOCTYPE html>`. See [#299](https://github.com/websharks/quick-cache/issues/299).
378
- - **Bug Fix (Pro)**: Fixed a bug in the HTML Compressor that would, in certain scenarios, leave behind fragments of HTML comments. See [#295](https://github.com/websharks/quick-cache/issues/295).
379
- - **Bug Fix (Pro)**: The Auto-Cache Engine now has an option to configure a delay between each request when pre-caching the site. There were some reports of the Auto-Cache Engine causing load issues with large sites on servers that sometimes had trouble handling many requests. See [#294](https://github.com/websharks/quick-cache/issues/294).
380
- - **Bug Fix (Pro)**: Fixes an Auto-Cache Engine scheduling issue that may, in some scenarios, prevent it from running as expected. See [#291](https://github.com/websharks/quick-cache/issues/291).
381
- - **Bug Fix (Pro)**: Fixed a bug with the HTML Compressor where `style`, `link` and/or `script` tags could end up out of order in certain scenarios. See [#45](https://github.com/websharks/html-compressor/issues/45).
382
- - **Bug Fix (Pro)**: Fixed a bug in the HTML Compressor related to JavaScript compression routines. See [#38](https://github.com/websharks/html-compressor/issues/38).
383
-
384
- = v140829 =
385
-
386
- - **SECURITY FIX - Please upgrade immediately**: Fixes a security related to cached cookies sent in the header of a request. This only affects sites running plugins that might send cookie data via the header. See [#253](https://github.com/websharks/Quick Cache/issues/253)
387
- - **Enhancement**: Auto-Purge RSS Feeds. Quick Cache will now automatically purge the cache for RSS/RDF/Atom Feeds when Feed Caching is enabled. This new option will purge the cache for the master feed, the master comments feed, feeds associated with comments on a Post/Page, term-related feeds (including mixed term-related feeds), and author-related feeds when you update a Post/Page, approve a Comment, or make other changes where Quick Cache can detect that certain types of Feeds should be purged. See [#182](https://github.com/websharks/Quick Cache/issues/182)
388
- - **Enhancement**: Improve handling of symlink creation for 404 cache files by using atomic symlink creation to decrease the possibility of encountering a race condition. See [#242](https://github.com/websharks/Quick Cache/issues/242).
389
- - **Enhancement**: Improved portability of `advanced-cache.php`. This will help reduce configuration overhead for site owners when migrating a WordPress installation from one server to another. See [#258](https://github.com/websharks/Quick Cache/issues/258).
390
- - **Enhancement**: Option Panels now have proper HTML anchor tags so that they work better with browser extensions that rely on anchor tags being available. See [#260.](https://github.com/websharks/Quick Cache/issues/260)
391
- - **Enhancement**: The Plugin Deactivation Safeguards option has been renamed to Plugin Deletion Safeguards. When Plugin Deletion Safeguards are disabled, deactivating and deleting the plugin will now erase your options for the plugin, erase directories/files created by the plugin, remove the advanced-cache.php file, terminate CRON jobs, etc. It completely erases itself, but only when you disable Plugin Deletion Safeguards (enabled by default to prevent accidental loss of data). See [#261](https://github.com/websharks/Quick Cache/issues/261).
392
- - **Enhancement (Pro)**: HTML Compressor now includes FOPEN as transport layer fallback in case cURL is not available. See [#15](https://github.com/websharks/html-compressor/issues/15)
393
- - **Enhancement (Pro)**: HTML Compressor now writes files atomically; this will help avoid race conditions when writing cache files. See [#273](https://github.com/websharks/Quick Cache/issues/273)
394
- - **Enhancement (Pro)**: Improved error handling for the Auto-Cache Engine. There were some scenarios where `XMLReader()` would fail with a PHP Warning notice when it was unable to properly parse the sitemap. See [#250](https://github.com/websharks/Quick Cache/issues/250).
395
- - **Bug Fix**: The cache directory is now properly removed when deleting the plugin from the WordPress Dashboard plugins list. See [#261](https://github.com/websharks/Quick Cache/issues/261).
396
- - **Bug Fix**: WooCommerce compatibility fix for a bug where cart session data appeared to get cached across sessions. See [#253](https://github.com/websharks/Quick Cache/issues/253)
397
- - **Bug Fix (Pro)**: The plugin upgrade notice no longer appears on Child Blogs in a Multisite Network. There was no security risk here; while the upgrade notice was shown, Child Blog admins who did not have permission to upgrade Network-activated plugins were unable to do anything with the message. See [#259](https://github.com/websharks/Quick Cache/issues/259).
398
- - **Bug Fix (Pro)**: Fixed a bug where, in certain scenarios, a WordPress Plugin may break the JavaScript that controls the Clear Cache button on the Dashboard. See [#272](https://github.com/websharks/Quick Cache/issues/259).
399
- - **Bug Fix (Pro)**: CSS files are now excluded from compression by the HTML Compressor when included inside conditional comments. See [#35](https://github.com/websharks/html-compressor/issues/35)
400
- - **Bug Fix (Pro)**: HTML Compressor now preserves whitespace inside CSS `calc()` statements. See [#286](https://github.com/websharks/Quick Cache/issues/286).
401
-
402
- = v140725 =
403
-
404
- - **Enhancement**: Improved overall performance by optimizing the auto-purge routines. See also: [#130](https://github.com/websharks/Quick Cache/issues/130)
405
- - **Enhancement**: The "GET Requests" UI Panel now explains that you can use `?zcAC=0` to disable caching when you ARE caching GET Requests. See also: [#210](https://github.com/websharks/Quick Cache/issues/210).
406
- - **New Pro Feature: Auto-Purge XML Sitemaps**. If you're generating XML Sitemaps with a plugin like Google XML Sitemaps, you can now tell Quick Cache to automatically purge any cached sitemap files whenever it purges a Post/Page cache. You may also specify a list of XML Sitemap patterns to clear, if you have multiple sitemap files. See also: [#169](https://github.com/websharks/Quick Cache/issues/169)
407
- - **Enhancement (Pro)**: The Quick Cache Pro Updater now accepts a License Key in place of the WebSharks password.
408
- - **Enhancement (Pro)**: In a Multisite Network, the Auto-Cache Engine will now also auto-cache each child blog. See also: [#169](https://github.com/websharks/Quick Cache/issues/169)
409
- - **Bug Fix**: Fixed a bug that was causing unapproved, spam, and trash comments to unnecessarily purge the cache. See also: [#159](https://github.com/websharks/Quick Cache/issues/159)
410
- - **Bug Fix**: A custom `WP_CONTENT_DIR` is now obeyed in the scenario where it's set to a path outside of `ABSPATH`. See also: [#95](https://github.com/websharks/Quick Cache/issues/95)
411
- - **Bug Fix**: The UI now correctly displays custom `WP_CONTENT_DIR` in the "Directory/Expiration Time" options panel. See also: [#206](https://github.com/websharks/Quick Cache/issues/206)
412
- - **Bug Fix**: Quick Cache LITE now correctly sets the `Quick Cache_PRO` constant to false. See also: [#229](https://github.com/websharks/Quick Cache/issues/229)
413
- - **Bug Fix**: Workaround for broken page navigation on the front page of some sites. This is a WordPress `redirect_canonical()` bug workaround. See also: [#209](https://github.com/websharks/Quick Cache/issues/209)
414
- - **Bug Fix (Pro)**: 404 Caching now properly returns a 404 HTTP Status code when serving a cached 404 page. See also: [#197](https://github.com/websharks/Quick Cache/issues/197)
415
- - **Bug Fix (Pro)**: The HTML Compressor now properly preserves `[]` character whitespace during CSS compression. See also: [#25](https://github.com/websharks/html-compressor/issues/25)
416
- - **Bug Fix (Pro)**: The Pro Updater upgrade link now points to the correction location when displayed from a Child Blog in a Multisite Network. See also: [#205](https://github.com/websharks/Quick Cache/issues/205)
417
- - **Bug Fix (Pro)**: The Auto-Cache Engine now correctly handles the sitemap when `home_url()` differs from `site_url()`.
418
- - **Bug Fix (Pro)**: The "Dynamic Version Salt" options panel now correctly displays the last saved value. See also: [#231](https://github.com/websharks/Quick Cache/issues/231)
419
-
420
- = v140605 =
421
-
422
- - **New Feature**: Branched Cache Structure. Cache files are now written to the cache directory using a more intuitive format of `PROTOCOL`/`HOSTNAME`/`PERMALINK` (e.g., `http/example-com/sample-page.html`). For more details, please see <http://www.websharks-inc.com/r/Quick Cache-branched-cache-structure-wiki/>
423
- - **New Feature**: 404 Page caching. It's now possible to enable/disable the caching of 404 requests. Enabling this feature generates a single cache file for your 404 Page and then symlinks future 404 requests to that cache file. See *Dashboard -> Quick Cache -> Plugin Options -> 404 Requests*.
424
- - **New Feature (Pro)**: HTML Compressor (experimental). This new experimental feature automatically combines and compresses CSS/JS/HTML code. See *Dashboard -> Quick Cache -> Plugin Options -> HTML Compressor*. For more details about how this feature works, please see <https://github.com/websharks/HTML-Compressor>
425
- - **New Feature (Pro)**: Auto-Cache Engine. When enabled, the Auto-Cache Engine will pre-cache your site at 15-minute intervals, rebuilding cache files when necessary (it will not rebuild cache files until they have expired). This helps eliminate the slowness a user may experience when visiting a page on your site that has not yet been cached. See *Dashboard -> Quick Cache -> Plugin Options -> Auto-Cache Engine*.
426
- - **New Feature**: Auto-Purge "Author Page". When a single Post/Page is changed in some way, Quick Cache can also purge any existing cache files for the associated Author Page. See *Dashboard -> Quick Cache -> Plugin Options -> Clearing the Cache*. (This option is enabled by default; disabling this requires Quick Cache Pro.)
427
- - **New Feature**: Auto-Purge "Category Archives". When a single Post/Page is changed in some way, Quick Cache can also purge any existing cache files for the associated Category archive views. See *Dashboard -> Quick Cache -> Plugin Options -> Clearing the Cache*. (This option is enabled by default; disabling this requires Quick Cache Pro.)
428
- - **New Feature**: Auto-Purge "Tag Archives". When a single Post/Page is changed in some way, Quick Cache can also purge any existing cache files for the associated Tag archive views. See *Dashboard -> Quick Cache -> Plugin Options -> Clearing the Cache*. (This option is enabled by default; disabling this requires Quick Cache Pro.)
429
- - **New Feature**: Auto-Purge "Custom Term Archives". When a single Post/Page is changed in some way, Quick Cache can also purge any custom Terms that may have their own Term archive views. See *Dashboard -> Quick Cache -> Plugin Options -> Clearing the Cache*. (This option is enabled by default; disabling this requires Quick Cache Pro.)
430
- - **Enhancement**: Improved conflict handling of other plugins using `ob_start()`. See <https://github.com/websharks/Quick Cache/issues/97>
431
- - **Enhancement**: Added a postload filter for `status_header` so that Quick Cache can properly detect calls to the WP core function `status_header()`
432
- - **Enhancement**: The Quick Cache cache directory has been changed to `wp-content/cache/Quick Cache/` to provide better organization of cache files and avoid interfering with another plugin that may also be writing to the `wp-content/cache/` directory. See <https://github.com/websharks/Quick Cache/issues/123>
433
- - **Enhancement**: New detailed debugging notes (see *Dashboard -> Quick Cache -> Plugin Options -> Enable/Disable*). There is now an extra option to show detailed debugging information in addition to the Quick Cache notes in the HTML source. For now, this feature only applies when the HTML Compressor is enabled.
434
- - **Enhancement**: Better Debugging Notices. If Quick Cache is not caching a particular page (such as when a logged-in user visits the site and logged-in user caching is not enabled), Quick Cache will now report why that page is not being cached in the HTML notes.
435
- - **Enhancement**: Improved compatibility with the Nav Menu Roles plugin. See <https://github.com/websharks/Quick Cache/issues/164>
436
- - **Bug Fix**: Obey custom content directories. If you have customized your `WP_CONTENT_DIR` and `WP_CONTENT_URL` constants to point somewhere other than the default, Quick Cache will now obey those and use your custom directory for storing cache files. See <https://github.com/websharks/Quick Cache/issues/95>
437
- - **Bug Fix**: Scheduled posts now trigger the clearing of any associated archive views when those posts go live (assuming you have those archive views set to Auto-Purge in *Dashboard -> Quick Cache -> Plugin Options -> Clearing the Cache*). See <https://github.com/websharks/Quick Cache/issues/26>
438
- - **Bug Fix**: Fixed a bug where saving a post as `draft` would trigger the Auto-Purge Post routine and clear the cache for that post. Now only purges post status `publish` and `private` and when transitioning from `publish` or `private` post status to `draft`, `future`, or `private`. See <https://github.com/websharks/Quick Cache/issues/43>
439
- - **Bug Fix**: Split/paginated comments and multi-page Posts/Page cache files are now purged properly when the post cache is purged. See <https://github.com/websharks/Quick Cache/issues/75>
440
-
441
- = v140104 =
442
-
443
- * **New Options for Feed Caching**. It's now possible to control RSS, RDF, and Atom Feed caching. The new default is for feed caching to be disabled, which resolves an issue where new posts don't show up in the feed until the cache is cleared. This version of Quick Cache disables feed caching to prevent this from happening. If you wish to cache feeds, you can enable feed caching in the options. See: <https://github.com/websharks/Quick Cache/issues/44>
444
- * **New Automatic Updater for Quick Cache Pro**. Quick Cache Pro now includes an automatic updater which lets you to keep Quick Cache Pro updated right from within your WordPress Dashboard. To upgrade to a new version of Quick Cache Pro using the Automatic Updater, simply fill in your WebSharks-Inc.com credentials in the new Plugin Updater sub-panel (**Quick Cache Pro -› Plugin Updater**). See: <https://github.com/websharks/Quick Cache/issues/21>
445
-
446
- = v131224 =
447
-
448
- * **New Lite Enhancement**. The Home Page cache and Posts Page cache are now automatically purged when necessary (such as when a new post is published). See: <https://github.com/websharks/Quick Cache/issues/40>
449
- * Improved Quick Cache version check notice.
450
- * Improved Quick Cache options validation.
451
- * **Bug Fix**. Quick Cache was previously not properly excluding systematic WordPress areas reliably, e.g. any file that begins with `wp-` and/or the `xmlrpc` file. These are now properly auto-excluded. On Multisite installations, `/files/` is also auto-excluded from being cached. This bug required fixing incorrect instances of `[?$]` in regex patterns. See: <https://github.com/websharks/Quick Cache/issues/41>
452
- * **Multisite Enhancement**. When running Quick Cache on Multisite Network installation, only allow the plugin to be "Network Activated" (becuase that is how Quick Cache is designed to work). See: <https://github.com/websharks/Quick Cache/issues/50>
453
- * **Multisite Enhancement**. New 'Wipe' button allows a site owner to clear (wipe) the cache for all sites in a Multisite Network at once. See: <https://github.com/websharks/Quick Cache/issues/48>
454
- * **Multisite Bug Fix**. Clearing the cache on a Multisite Network configured to use sub-directories now works properly. See: <https://github.com/websharks/Quick Cache/issues/39>
455
- * **Multisite Bug Fix**. Fixed unmatched closing parenthesis in regex. See: <https://github.com/websharks/Quick Cache/issues/37>
456
- * **Multisite Bug Fix**. Added support for `PATH_CURRENT_SITE` and `$GLOBALS['base']`.
457
- * **Multisite Bug Fix**. Removed depreciated VHOST code that was causing issues with clearing the cache.
458
-
459
- = v131206 =
460
-
461
- * **New Pro Feature**. It's now possible for developers to add custom PHP code to the cache clearing routines (e.g. custom code which might consider things like APC or memcache also). This requires [Quick Cache Pro](http://www.websharks-inc.com/product/Quick Cache/). Please check your Dashboard under: **Quick Cache Pro -› Clearing the Cache**. See also: [this screenshot](https://f.cloud.github.com/assets/1563559/1692324/7ae902c4-5e78-11e3-98ba-acbb08b30585.png).
462
- * **Multisite Bug Fix**. Unable to clear the cache when running sub-directories. See: <https://github.com/websharks/Quick Cache/issues/30>
463
- * **Multisite Bug Fix**. The "Clear Cache" button was not displayed for child blogs in a network. Fixed in this release.
464
-
465
- = v131205 =
466
-
467
- * Added hook to `wp_set_comment_status` to purge the comment cache when a comment status changes.
468
- * Ignore `set_time_limit()` errors in case function is disabled in PHP configuration. This is a temporary fix and will be handled more appropriately in a future maintenance release. See also: <https://github.com/websharks/Quick Cache/issues/20>
469
- * Added Raam Dev to the contributors list. Raam will now be leading the development of Quick Cache and Quick Cache Pro.
470
-
471
- = v131128 =
472
-
473
- * **New Plugin Architecture for Quick Cache.** This release introduces a new way for theme/plugin developers to modify the way Quick Cache operates at the `advanced-cache.php` level (e.g. very early-on). For further details on this, please check your Dashboard under: `Quick Cache -› Theme/Plugin Developers`. See also: <https://github.com/websharks/Quick Cache/issues/17>
474
- * **Compatibility.** This release further improves PHP v5.3 detection. Quick Cache will now generate an administrative notice instead of a PHP exception; allowing the plugin to be activated, but without actually loading the plugin under this scenario. A notice to the site owner is helpful in cases where the plugin is NOT being updated through the Dashboard. This will remove the risk of crashing a site that's attempting to run Quick Cache w/o PHP v5.3+ installed. See also: <https://github.com/websharks/Quick Cache/issues/13>
475
-
476
- = v131127 =
477
-
478
- * **Compatibility.** This release improves PHP v5.3 detection. Quick Cache will now generate an administrative notice instead of a PHP exception; allowing the plugin to be activated, but without actually loading the plugin under this scenario. A notice to the site owner is helpful in cases where the plugin is NOT being updated through the Dashboard. This will remove the risk of crashing a site that's attempting to run Quick Cache w/o PHP v5.3+ installed. See also: <https://github.com/websharks/Quick Cache/issues/13>
479
- * **New Pro Feature.** Clear Home Page (and/or Posts Page) on auto-purge. See: <https://github.com/websharks/Quick Cache/issues/11>
480
- * **Bug Fix (Options -Indexes).** Removing unnecessary `.htaccess` file from the `/wp-content/plugins/Quick Cache/` directory that prevented directory indexing, as this is not compatible in all hosting environents. See: <https://github.com/websharks/Quick Cache/issues/9>
481
- * **Bug Fix (ABSPATH).** Incorrect detection of the `/wp-config.php` file on sites that move this file up one directory. Fixed in this release. See: <https://github.com/websharks/Quick Cache/issues/7>
482
- * **Bug Fix (Parse Error).** Correcting code that deals with an edge case where the `/wp-config.php` file may become corrupted upon deactivation of the Quick Cache plugin through the WP Dashboard. Fixed in this release. See: <https://github.com/websharks/Quick Cache/issues/6>
483
- * **Bug Fix (Error Reporting).** Improving error message via Dashboard whenever permissions are an issue in one specific scenario. See: <https://github.com/websharks/Quick Cache/issues/16>
484
- * **Enhancement (Pro Preview).** Adding a more visible way to disable Pro Preview mode in the Lite version of Quick Cache. See: <https://github.com/websharks/Quick Cache/issues/2>
485
- * **Emergency Scenario** Adding notes in several sections of the `reamde.txt` file regarding "what to do in an emergency scenario".
486
- * **See Also** <https://github.com/websharks/Quick Cache/issues?page=1&state=closed>
487
-
488
- = v131121 =
489
-
490
- * Updated to support all features and functionality of WordPress v3.7+ (this new release of Quick Cache requires WordPress v3.7+). The Quick Cache plugin is now being actively maintained and future updates and improvements will be released periodically by lead developer Jason Caldwell. The popularity of this plugin and recent acknowldegments at WordCamp in Boston have inspired Jason to revamp Quick Cache!
491
- * The latest version of Quick Cache is a complete rewrite (OOP design). Faster! and even more dependable. NOTE: the free version of Quick Cache (this new LITE version); while it remains fully functional and is more-than-adequate for most sites; is now limited in some ways. The following advanced features from the previous release are no longer available in the lite version: a custom MD5 Version Salt; custom Exclusion Patterns; the Clear Cache button in the admin bar. These, and MANY other brand new features are now available only in the pro version of the plugin. For further details, please see: <http://www.websharks-inc.com/product/Quick Cache/>.
492
- * Bug fix. Quick Cache now considers the `HTTPS` evironment variable in order to prevent cache collisions on sites that serve pages over SSL. Nothing to configure, this is now built into the Quick Cache engine.
493
- * UI updates. An improved user interface makes configuring this plugin a dream! Quick Cache got an awesome makeover in this release.
494
- * Improved support for multisite networks. It's never been easier to run Quick Cache on a multisite network. For further details, please see: **Dashboard -› Network Admin -› Quick Cache** when/if you have Multisite Networking enabled in WordPress.
495
- * Update; PUT and DELETE requests are now considered by Quick Cache. By default, Quick Cache does NOT serve cached pages to users who are logged in, or to users who have left comments recently. Quick Cache also excludes administrative pages, login pages, POST/PUT/DELETE/GET(w/ query string) requests and/or CLI processes.
496
- * Dropping support for `ob_gzhandler()`; and the like. Quick Cache will now throw PHP exceptions to warn you about this should it be an issue in your hosting environment. If you want to enable GZIP, please follow the instructions provided by Quick Cache and avoid the use of `ob_gzhandler()` as this is not a recommended way to enable GZIP on any hosting platform.
497
- * Truly atomic cache file write updates. Removing support for SEM vs. FLOCK for file locking. Quick Cache no longer needs a mutex file. Cache file updates are written to a temp file and renamed for the best reliability and improved speed too!
498
- * Localization. Quick Cache is now translatable. This release adds support for gettext translations, a very popular method for translating WordPress plugins. All parts of the Quick Cache plugin can be localized now. The source code was updated with calls to the `__` function and a new text domain was added: `Quick Cache`. PO translation files should be placed in your plugins directory, example: `/wp-content/plugins/Quick Cache-en_US.mo`; or in `WP_LANG_DIR/plugins/Quick Cache-en_US.mo`.
499
- * Capability requirement. This release of Quick Cache requires that an Administrator be logged-in with the Capability of `activate_plugins`. This is a default Capability that comes with the Administrator Role in WordPress. So, unless you've modified your WordPress Roles/Capabilities in some extremely creative way, this should not impact you; just something to be aware of.
500
- * **(Pro Version)** There is now a pro version of this plugin available. Please see: <http://www.websharks-inc.com/product/Quick Cache/>. The initial set of pro features include: the ability to cache logged-in users too! (VERY powerful, particularly for membership sites); a new improved "Clear Cache" button in the admin bar (along with an option to enable/disable this feature); the ability to disable Dashboard notifications related to automatic clearing/purging on change detections; Import/Export functionality for Quick Cache configuration files; URI exclusion patterns (now supporting wildcards too); User-Agent exclusion patterns (now supporting wildcards too); HTTP referrer exclusion patterns (now supporting wildcards too); an MD5 Version Salt; and rockstar support for all Quick Cache features.
501
- * **(Pro Version)** Regarding URI/User-Agent/HTTP Referrer exclusion patterns. If you configured any of these options in the previous release and would like to continue to use them in this release, please upgrade to the pro version or contact lead developer Jason Caldwell for assistance. Note: if you had these options configured in the previous release, once you upgrade to the pro version they will come back just like they were. Either that, or you may choose to continue using the previous version of Quick Cache where this functionality still exists.
502
- * Lite version source code now available on GitHub also: <https://github.com/websharks/Quick Cache>.
503
-
504
- = v111203 =
505
-
506
- * Updated to support WordPress® v3.3. Backward compatibily remains for WordPress® v3.2.x.
507
-
508
- = v110720 =
509
-
510
- * Bug fix. Corrected XSS security issue associated with the handling of ``$_SERVER["REQUEST_URI"]`` inside the comment lines that Quick Cache introduces at the bottom of the source code.
511
- * Bug fix. Corrected cosmetic issue in WordPress v3.2 related to the positioning of the Clear Cache button.
512
-
513
- = v110709 =
514
-
515
- * Routine maintenance. No signifigant changes.
516
-
517
- = v110708 =
518
-
519
- * Routine maintenance. No signifigant changes.
520
- * Compatibility with WordPress v3.2.
521
-
522
- = v110523 =
523
-
524
- * **Versioning.** Starting with this release, versions will follow this format: `yymmdd`. The version for this release is: `110523`.
525
- * Routine maintenance. No signifigant changes.
526
-
527
- = v2.3.6 =
528
-
529
- * Routine maintenance. No signifigant changes.
530
-
531
- = v2.3.5 =
532
-
533
- * Bug fix. Under the right scenario, errors regarding the function `is_user_logged_in()` in the second phase of `advanced-cache.php` have been resolved in this release of Quick Cache.
534
- * Compatibility. Quick Cache is now capable of dealing with themes/plugins that attempt to use `ob_start("ob_gzhandler")` inside a `header.php` file, or in other places that may create a problem in the nesting order of output buffers. For instance, this release of Quick Cache resolves some incompatiblities with Headway themes for WordPress®. Please note that GZIP should be enabled at the Apache level ( i.e. with an .htaccess file ), or in PHP using `zlib.output_compression = on`. Both of these methods are preferred over `ob_start("ob_gzhandler")`. If you must use `ob_start("ob_gzhandler")`, please make this declaration inside your `/wp-config.php` file, and NOT inside `/header.php`, as this creates a problem that Quick Cache must work around, and could ultimately prevent GZIP from working at all if you do it this way. For further details on how to enable GZIP with Quick Cache, please see the included `/readme.txt` file.
535
-
536
- = v2.3.2 =
537
-
538
- * Compatiblity. References to `dirname()` that were processed by the Quick Cache `/advanced-cache.php` handler should have been using `WP_CONTENT_DIR` for improved compatibility with WordPress® installations that may use non-standardized installation directories and/or symlinks.
539
- * New Filter available for developers. Multisite Super Admins can now give their Child Blog owners the ability to manually clear the cache for their own site in the Network. Quick Cache accomplishes this by making the "Clear Cache" button visible in the administrative header for Child Blog owners. If you wish to enable this, you can use this Filter: `add_filter("ws_plugin__qcache_ms_user_can_see_admin_header_controls", "__return_true");`. This button is always visible to Super Admins. Adding this Filter makes it visible to all child Blog Owners as well.
540
-
541
- = v2.3.1 =
542
-
543
- * Framework updated; general cleanup.
544
- * Optimizations. Further internal optimizations applied through configuration checksums that allow Quick Cache to load with even less overhead now.
545
- * Bug fix. Quick Cache was suffering from a bug regression related to stale Last-Modified headers being sent with cached copies. This has been resolved in Quick Cache v2.3.1+.
546
-
547
- = v2.3 =
548
-
549
- * Framework updated; general cleanup.
550
- * Updated with static class methods. Quick Cache now uses PHP's SPL autoload functionality to further optimize all of its routines.
551
-
552
- = v2.2.8 =
553
-
554
- * Framework updated; general cleanup.
555
- * Updated for compatibility with WordPress® 3.1.
556
-
557
- = v2.2.7 =
558
-
559
- * Framework updated. General cleanup.
560
-
561
- = v2.2.6 =
562
-
563
- * Updated to disable caching on database failures that do not trigger a `5xx` error code. Quick Cache is now capable of disabling the cache engine dynamically on all database connection failures within WordPress®.
564
-
565
- = v2.2.5 =
566
-
567
- * Updated to support all `5xx` error codes. Quick Cache now monitors the `status_header` function for `5xx` error codes. If a `5xx` status header is detected, caching is automatically disabled, as it should be.
568
-
569
- = v2.2.3 =
570
-
571
- * Framework updated. General cleanup.
572
-
573
- = v2.2.2 =
574
-
575
- * Minor updates to the Ajax clearing routines that were implemented in v2.2.1.
576
- * This update also adds compatibility with (offline) localhost installations of WordPress® (WAMP/MAMP).
577
-
578
- = v2.2.1 =
579
-
580
- * Support for `glob()` has been added to Quick Cache. In previous versions, it was impossible to pinpoint a specific cache file through Dynamic Pruning routines ( at least, not with 100% accuracy ). This was because an MD5 Version Salt *could* have been generated; based on arbitrary conditionals, set by the site owner. Quick Cache now stores its cache files with three MD5 hash strings, producing longer file names; but with the added benefit of improved Multisite compatibility, and improvements in optimization overall. Quick Cache can now handle dynamic pruning with 100% accuracy. Even supporting complex Multisite installations, with or without `SUBDOMAIN_INSTALL`.
581
- * New feature. Quick Cache now integrates a `Clear Quick Cache` button into the WordPress® Dashboard. This makes it easy to force a "cache reset, via <code>ajax</code>", without having to navigate through the Quick Cache menu for this simple task. Another great benefit to this new button, is that it works in all Dashboard views, even in a Multisite installation across different backends. If you're running a Multisite installation, you can use this new button to clear the cache for a particular site/blog in your network, without interrupting others.
582
- * Bug fix. The Constant `Quick Cache_ALLOWED` was being defined too early in the buffering routine. This has been resolved in v2.2.1.
583
- * Optimization of `advanced-cache.php`. A few things have been streamlined even further.
584
- * Added compatibility for the [WP Maintenance Mode](http://wordpress.org/extend/plugins/wp-maintenance-mode/) plugin, and also the [Maintenance Mode](http://wordpress.org/extend/plugins/maintenance-mode/) plugin. Quick Cache will disable itself when these plugins are enabled for maintenance.
585
- * Added compatibility for other Maintenance Mode plugins that are capable of sending a `Status: 503` header, or a `Retry-After:` header.
586
- * Added compatibility for plugins that create PHP sessions. Quick Cache will automatically disable itself when a PHP session is active.
587
- * Added compatiblity for web hosts that insert a port number into the `$_SERVER["HTTP_HOST"]` variable. Quick Cache is now capable of handling this gracefully.
588
- * Improvement. Removed references to `$blog_id = 1` in favor of `is_main_site()`; providing support for Multisite Mode, where there are multiple sites, instead of just multiple blogs.
589
- * Updated Dynamic Pruning Hooks for Custom Post Types, and Custom Taxonomies in WordPress® 3.0+.
590
- * Extended compatiblity for Quick Cache on SSL enabled blogs.
591
-
592
- = v2.1.9 =
593
-
594
- * Framework updated; general cleanup.
595
- * Updated minimum requirements to WordPress® 3.0.
596
-
597
- = v2.1.8 =
598
-
599
- * Framework updated to WS-P-3.0.
600
-
601
- = v2.1.7 =
602
-
603
- * Bug fix. A bug related to gzinflate variations handled by the WP_Http class has been resolved. This was preventing Quick Cache from validating a custom MD5 Version Salt on some servers.
604
- * Framework updated to WS-P-2.3.
605
-
606
- = v2.1.6 =
607
-
608
- * Auto-Cache Engine. References to `ws_plugin__qcache_curl_get()`, have been replaced by `c_ws_plugin__qcache_utils_urls::remote()`, which makes use of `wp_remote_request()` through the WP_Http class. This removes an absolute dependency on the cURL extension for PHP. This also gives Quick Cache/WordPress® the ability to decide with method of communication to use for HTTP requests; based on what the installation server has available. Note: this only affects the Auto-Cache Engine for Quick Cache, which is completely optional.
609
- * Compatibility. Quick Cache is now smarter about the way it reports errors. For example, when/if there are directory permission issues with your `wp-content` directory; Quick Cache can help with this, in a more intuitive fashion.
610
- * Compatibility. Support has been added for WordPress® 3.0 with Multisite/Networking enabled.
611
- * Updated minimum requirements to WordPress® 2.9.2.
612
- * Framework updated to WS-P-2.2.
613
-
614
- = v2.1.5 =
615
-
616
- * A new option for Dynamic Cache Pruning was added. You can now choose `Single + Front Page`. This makes it possible to Create or Edit a Post/Page, and have the cache automatically updated for that specific Post/Page. And.. in addition, your Front Page ( aka: Home Page ) will also be refreshed at the same time.
617
- * A minor bug was fixed in the Dynamic Cache Pruning routines. This bug was originally introduced in Quick Cache v2.1.1, and has now been corrected in v2.1.5. This bug, under certain circumstances, was preventing Quick Cache from locating an expired md5 cache file, for some Posts/Pages being updated.
618
- * Advanced feature addition. Quick Cache now comes bundled with a robust Auto-Cache Engine. This is an optional feature, for VERY advanced users. You'll find the new Auto-Cache Engine listed right along with all of the other Quick Cache options. This works in conjunction with an XML Sitemap.
619
-
620
- = v2.1.4 =
621
-
622
- * Advanced feature addition. You can now prevent caching dynamically whenever pages on your site receive traffic from specific URLs, specific domains, or even specific word fragments found within the HTTP_REFERER. This feature is very advanced, and will NOT impact your site unless you decide to use it for one reason or another.
623
-
624
- = v2.1.3 =
625
-
626
- * Added `De-Activation Safeguards` to the Quick Cache options panel.
627
- * Updated the Quick Cache options panel. It's been given a make-over.
628
- * Stable tag updated in support of tagged releases within the repository at WordPress.org.
629
-
630
- = v2.1.2 =
631
-
632
- * WebSharks Framework for Plugins has been updated to P-2.1.
633
- * Updated caching routines in support of hosting providers running with CGI/FastCGI. Quick Cache has been tested with VPS.net, HostGator, BlueHost, (mt) Media Temple (gs) and (dv), The Rackspace Cloud, and several dedicated servers ( including some Amazon EC2 instances ) running with Apache; including support for both `mod_php` and also `CGI/FastCGI` implementations. Quick Cache should work fine with any Apache/PHP combination. Please report all bugs through the [Support Forum](http://www.primothemes.com/forums/viewforum.php?f=5).
634
- * An issue was discovered with WordPress® MU `/files/` being accessed through `htaccess/mod_rewrite`. Quick Cache has been updated to exclude all `/files/` served under WordPress® MU, which is the way it should be. Requests that contain `/files/` are a reference to WordPress® Media, and there is no reason, to cache, or send no-cache headers, for Media. Quick Cache now ignores all references to `/files/` under WordPress® MU. This problem was not affecting all installations of WPMU, because there already are/were scans in place for Content-Type headers. However, under some CGI/FastCGI implementations, this was not getting picked on WMPU with `mod_rewrite` rules. This has been resolved in v2.1.2.
635
-
636
- = v2.1.1 =
637
-
638
- * A WPMU bug was corrected in Quick Cache v2.1.1. This bug was related to `HTTP_HOST` detection under WordPress® MU installations that were using sub-domains. Please thank `QuickSander` for reporting this important issue.
639
-
640
- = v2.1 =
641
-
642
- * Quick Cache has added further support for themes and plugins that dynamically set `Content-Type` headers through PHP routines. Quick Cache is now smart enough to automatically disable itself whenever a theme or plugin sends a `Content-Type` header that would be incompatible with Quick Cache. In other words, any `Content-Type` header that is not a variation of `HTML, XHTML or XML`.
643
- * Quick Cache has also been upgraded to support the preservation of scripted headers sent by PHP routines. If a plugin or theme sends scripted headers ( using the `header()` function in PHP ), those headers will be preserved. They'll be stored along with the cache. This allows them to be sent back to the browser whenever a cached version is served on subsequent visits to the original file.
644
- * Compatability checked against WordPress.org 2.9.1, 2.9.2 &amp; WordPress MU 2.9.1, 2.9.2. Everything looks good. No changes required.
645
-
646
- = v2.0 =
647
-
648
- * A few tweaks to the options panel.
649
- * Documentation updated, several small improvements in error reporting.
650
- * Additional error checking to support an even wider range of hosting providers.
651
- * Added automation routines for safe re-activation after an upgrade is performed.
652
-
653
- = v1.9 =
654
-
655
- * Additional support added for WordPress® MU 2.8.6+.
656
- * Security file `Quick Cache-mu.php` added specifically for MU installations. WordPress® MU is a special ( multi-user ) version of WordPress®. If you're running WordPress® MU, check the [readme.txt] file for WordPress® MU notations.
657
-
658
- = v1.8 =
659
-
660
- * Re-organized core framework. Updated to: P-2.0.
661
- * Updated to support WP 2.9+.
662
-
663
- = v1.7 =
664
-
665
- * Updated documentation. Added some additional code samples.
666
- * Tested with WP 2.8.5. Everything ok.
667
-
668
- = v1.6 =
669
-
670
- * We've added the ability to enable Double-Caching ( client-side caching ). Full documentation is provided in the Quick Cache options panel. This feature is for those of you who just want blazing fast speed and are not concerned as much about reliability and control. We don't recommend turning this on unless you realize what you're doing.
671
-
672
- = v1.5 =
673
-
674
- * Support for Dynamic Cache Pruning has been improved. Full documentation is provided in the Quick Cache options panel.
675
- * Additional feature-specific documentation has been added to assist novice webmasters during configuration.
676
-
677
- = v1.4 =
678
-
679
- * Garbage collection has been further optimized for speed and performance on extremely high traffic sites.
680
- * PHP Ternary expressions are now supported in your Version Salt. This takes your Version Salt to a whole new level.
681
- * Additional code samples have been provided for Version Salts; showing you how to deal with mobile devices and other tricky situations.
682
-
683
- = v1.3 =
684
-
685
- * We've implemented both Semaphore ( `sem_get` ) and `flock()` mutex. If you're on a Cloud Computing Model ( such as the Rackspace® Cloud ), then you'll want to go with flock() unless they tell you otherwise. In all other cases we recommend the use of Semaphores over Flock because it is generally more reliable. The folks over at Rackspace® have suggested the use of flock() because of the way their Cloud handles multi-threading. In either case, flock() will be fully functional in any hosting environment, so it makes a great fallback in case you experience any problems.
686
-
687
- = v1.2 =
688
-
689
- * We've implemented a way for plugin developers to disallow caching during certain routines or on specific pages. You can set the following PHP Constant at runtime to disable caching. `define("Quick Cache_ALLOWED", false)`. We have also added backward compatibility for WP Super Cache, so that `define("DONOTCACHEPAGE", true)` will also be supported by plugins that have previously been written for compatibility with Super Cache. In other words, Quick Cache looks for either of these two Constants.
690
-
691
- = v1.1 =
692
-
693
- * Added the ability to create a Version Salt. This is a feature offered ONLY by Quick Cache. Full documentation is provided in the Quick Cache options panel. This can become very useful for sites that provide membership services or have lots and lots of plugins installed that makes their site incompatible with WP Super Cache. With Quick Cache, you'll now have more control over the entire caching process using a custom Version Salt tailored to your specific needs.
694
-
695
- = v1.0 =
696
-
697
- * Initial release.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
comet-cache.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
  /*
3
- Version: 161119
4
  Text Domain: comet-cache
5
  Plugin Name: Comet Cache
6
  Network: true
1
  <?php
2
  /*
3
+ Version: 161221
4
  Text Domain: comet-cache
5
  Plugin Name: Comet Cache
6
  Network: true
readme.txt CHANGED
@@ -1,8 +1,8 @@
1
  === Comet Cache ===
2
 
3
- Stable tag: 161119
4
  Requires at least: 4.2
5
- Tested up to: 4.7
6
  Text Domain: comet-cache
7
 
8
  License: GPLv2 or later
@@ -50,6 +50,7 @@ The Comet Cache plugin uses configuration options that you select from the optio
50
  - Import/Export functionality for Comet Cache configuration files.
51
  - A Dynamic Version Salt (customize the caching engine).
52
  - Multisite Host Exclusion Patterns to exclude specific child blogs from being cached in a Multisite Network.
 
53
  - HTML Compressor to automatically combine and compresses CSS/JS/HTML code.
54
  - Auto-Cache Engine to pre-cache your site at 15-minute intervals.
55
  - Static CDN Filters to serve some and/or ALL static files on your site from a CDN of your choosing, including support for Multiple CDN Host Names, Domain Sharding, and WordPress Multisite Networks.
@@ -276,6 +277,7 @@ Comet Cache is now completely uninstalled and you can start fresh :-)
276
  - Import/Export functionality for Comet Cache configuration files.
277
  - A Dynamic Version Salt (customize the caching engine).
278
  - Multisite Host Exclusion Patterns to exclude specific child blogs from being cached in a Multisite Network.
 
279
  - HTML Compressor to automatically combine and compresses CSS/JS/HTML code.
280
  - Auto-Cache Engine to pre-cache your site at 15-minute intervals.
281
  - Static CDN Filters to serve some and/or ALL static files on your site from a CDN of your choosing, including support for Multiple CDN Host Names, Domain Sharding, and WordPress Multisite Networks.
@@ -338,6 +340,20 @@ Requires WordPress v4.2+.
338
 
339
  == Changelog ==
340
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
341
  = v161119 =
342
 
343
  - **Bug Fix:** Avoid browser autocomplete in configuration fields by adding `autocomplete="off"` to all form tags in Comet Cache menu pages. See [Issue #832](https://github.com/websharks/comet-cache/issues/832).
@@ -403,16 +419,4 @@ Requires WordPress v4.2+.
403
  - Renamed `COMET_CACHE_ALLOW_BROWSER_CACHE` constant to `COMET_CACHE_ALLOW_CLIENT_SIDE_CACHE`. Backwards compatibility has been maintained.
404
  - Renamed `allow_browser_cache` plugin option to `allow_client_side_cache`.
405
 
406
- = v160521 =
407
-
408
- - **Bug Fix**: Fixed a bug that, in some scenarios, resulted in "PHP Fatal error: Undefined class constant 'CACHE_PATH_NO_PATH_INDEX'". This also affected the Cache Statistics feature (Comet Cache Pro), resulting in a blank panel when hovering over the Cache Stats button in the menu bar. See [Issue #752](https://github.com/websharks/comet-cache/issues/752).
409
- - **Bug Fix**: When the PHP OPCache extension is active, the OPCache is now cleared when a WordPress plugin is upgraded, activated, or deactivated. This works around an issue that could produce a fatal error when the PHP OPCache contains cached PHP code that conflicts with new PHP code introduced by an update. See [Issue #740](https://github.com/websharks/comet-cache/issues/740).
410
- - **Enhancement** (Pro): It's now possible to disable the WordPress Admin Toolbar when Logged-In User Caching is enabled with a new option in _Comet Cache → Plugin Options → Logged-In Users → Disable the Admin Toolbar for Logged-In Users & Comment Authors?_ Props @renzms and @KTS915. See [Issue #690](https://github.com/websharks/comet-cache/issues/690).
411
- - **Enhancement**: The the option to automatically clear the cache for Custom Term Archive Views (see _Comet Cache → Plugin Options → Automatic Cache Clearing → Auto-Clear "Custom Term Archives" Too?_) is now enabled by default. This feature was previously disabled by default, which lead to confusion about why those cache files were not being cleared automatically when a Custom Post Type with a Custom Term Archive View was being used. Props @renzms. See [Issue #693](https://github.com/websharks/comet-cache/issues/693).
412
- - **Enhancement** (Pro): A new filter allows overriding the default behavior to clear the user cache upon login and logout when caching for Logged-In Users is enabled. See [this article](https://cometcache.com/r/kb-article-how-can-i-prevent-the-user-cache-from-being-cleared-upon-login-or-logout/) for details. Props @KTS915. See [Issue #756](https://github.com/websharks/comet-cache/issues/756).
413
-
414
- = v160417 =
415
-
416
- - **Bug Fix**: Fixed a "PHP Fatal error: Undefined class constant 'CACHE_PATH_NO_SCHEME'" introduced by the previous release (v160416). This issue only affected sites where Feed Caching was enabled (_Comet Cache → Plugin Options → RSS, RDF, and Atom Feeds_). Props to MassimoD and @emanwebdev for reporting. See [Issue #739](https://github.com/websharks/comet-cache/issues/739).
417
-
418
- For older changelog history going back to 7+ years, please see [CHANGELOG.md](https://github.com/websharks/comet-cache/blob/master/CHANGELOG.md).
1
  === Comet Cache ===
2
 
3
+ Stable tag: 161221
4
  Requires at least: 4.2
5
+ Tested up to: 4.8-alpha
6
  Text Domain: comet-cache
7
 
8
  License: GPLv2 or later
50
  - Import/Export functionality for Comet Cache configuration files.
51
  - A Dynamic Version Salt (customize the caching engine).
52
  - Multisite Host Exclusion Patterns to exclude specific child blogs from being cached in a Multisite Network.
53
+ - Mobile Mode that supports creating multiple versions of the cache for sites with adaptive designs.
54
  - HTML Compressor to automatically combine and compresses CSS/JS/HTML code.
55
  - Auto-Cache Engine to pre-cache your site at 15-minute intervals.
56
  - Static CDN Filters to serve some and/or ALL static files on your site from a CDN of your choosing, including support for Multiple CDN Host Names, Domain Sharding, and WordPress Multisite Networks.
277
  - Import/Export functionality for Comet Cache configuration files.
278
  - A Dynamic Version Salt (customize the caching engine).
279
  - Multisite Host Exclusion Patterns to exclude specific child blogs from being cached in a Multisite Network.
280
+ - Mobile Mode that supports creating multiple versions of the cache for sites with adaptive designs.
281
  - HTML Compressor to automatically combine and compresses CSS/JS/HTML code.
282
  - Auto-Cache Engine to pre-cache your site at 15-minute intervals.
283
  - Static CDN Filters to serve some and/or ALL static files on your site from a CDN of your choosing, including support for Multiple CDN Host Names, Domain Sharding, and WordPress Multisite Networks.
340
 
341
  == Changelog ==
342
 
343
+ = v161221 =
344
+
345
+ - **Bug Fix:** Improving PHP OPcache detection. Now considering the INI option `opcache.restrict_api`. Comet Cache is now smart enough to avoid generating the PHP Warning: _PHP Warning: Zend OPcache API is restricted by "restrict_api" configuration directive_. See [Issue #733](https://github.com/websharks/comet-cache/issues/733).
346
+ - **New Feature (Pro): Mobile Mode.** This release adds a new feature that is designed to improve compatibility with Adaptive themes for mobile devices. To learn more, please see: **Dashboard → Comet Cache Pro → Plugin Options → Mobile Mode**. See also: [Issue #471](https://github.com/websharks/comet-cache/issues/471).
347
+ - **Enhancement: Auto-Clearing Author Page Cache.** This release makes Comet Cache smart enough to detect when a user is deleted (or removed from a child blog in a Network), at which time the Author page for that user will be cleared from the cache so it can be regenerated automatically. See [Issue #304](https://github.com/websharks/comet-cache/issues/304).
348
+ - **Enhancement: Multibyte Compatibility.** This release improves support for WordPress Permalinks that contain UTF-8 symbols (or emojis) in them. More specifically, this release adds the `/u` flag to all `preg_*()` calls in cache clearing routines that generate cache paths from Watered-Down Regex patterns entered by a site owner. See: [Issue #611](https://github.com/websharks/comet-cache/issues/611).
349
+ - **Enhancement: Widget Change Detection.** Comet Cache can now detect when **Appearance → Widgets** are added/edited/removed, and Comet Cache will automatically clear the cache so that your site remains up-to-date. See [Issue #411](https://github.com/websharks/comet-cache/issues/411).
350
+ - **Enhancement (Pro): Static CDN Filters and `srcset`.** This release enhances Static CDN Filters in Comet Cache Pro. Static CDN Filters are now smart enough to filter all image sources included in an `srcset=""` attribute that is generated by WordPress. See [Issue #660](https://github.com/websharks/comet-cache/issues/660). If you'd like to learn more about `srcset=""`, see [this article at WordPress.org](https://make.wordpress.org/core/2015/11/10/responsive-images-in-wordpress-4-4/).
351
+ - **Enhancement (Pro): Automatic Background Updates.** It is now possible to enable automatic background updates that occur quietly in the background whenever new features, bug fixes, or security issues are addressed by our developers. See: **Dashboard → Comet Cache Pro → Config. Options → Update Credentials**. See also: [Issue #827](https://github.com/websharks/comet-cache/issues/827).
352
+ - **Enhancement (Pro): HTML Compressor + Accelerated Mobile Pages (AMP).** Updated to the latest available release of the HTML Compressor (v161208) with improved support for [Accelerated Mobile Pages](https://www.ampproject.org/). See: [Issue #695](https://github.com/websharks/comet-cache/issues/695). See also: [HTML Compressor v161208 changelog](https://github.com/websharks/html-compressor/releases/tag/161208).
353
+ - **Enhancement (Pro): HTML Compressor / AMP Compatibility.** Improved compatibility with [Accelerated Mobile Pages](https://www.ampproject.org/). There is a new HTML Compressor option that is enabled by default and it makes Comet Cache smart enough to auto-detect and selectively disable portions of the HTML Compressor that are incompatible with the AMP spec; i.e., routines that are not necessary when serving APMd pages. In short, if the URI being compressed ends with `/amp/`, or the document contains a top-level `<html ⚡>` tag (`<html amp>` is accepted as well), then features which are incompatible with [Accelerated Mobile Pages](https://www.ampproject.org/) will be disabled accordingly.
354
+ - **Compatibility:** Avoid deprecated `wp_get_sites()` and use `get_sites()` instead. See [Issue #848](https://github.com/websharks/comet-cache/issues/848).
355
+ - **Documentation:** Added Watered-Down Regex documentation notes to the inline documentation (in the software) about the use of `^` and `$` in some places where these special characters are not fully supported. Also adding the same notes to the [Watered-Down Regex KB Article](https://cometcache.com/r/watered-down-regex-syntax/). See also: [Issue #611](https://github.com/websharks/comet-cache/issues/611).
356
+
357
  = v161119 =
358
 
359
  - **Bug Fix:** Avoid browser autocomplete in configuration fields by adding `autocomplete="off"` to all form tags in Comet Cache menu pages. See [Issue #832](https://github.com/websharks/comet-cache/issues/832).
419
  - Renamed `COMET_CACHE_ALLOW_BROWSER_CACHE` constant to `COMET_CACHE_ALLOW_CLIENT_SIDE_CACHE`. Backwards compatibility has been maintained.
420
  - Renamed `allow_browser_cache` plugin option to `allow_client_side_cache`.
421
 
422
+ For older changelog history going back more than 7 years, please see [CHANGELOG.md](https://github.com/websharks/comet-cache/blob/master/CHANGELOG.md).
 
 
 
 
 
 
 
 
 
 
 
 
src/client-s/js/admin-bar.js CHANGED
@@ -14,8 +14,12 @@
14
 
15
  $('#wp-admin-bar-' + plugin.namespace + '-wipe > a').on('click', plugin.wipeCache);
16
  $('#wp-admin-bar-' + plugin.namespace + '-clear > a').on('click', plugin.clearCache);
 
17
 
18
  $document.on('click', '.' + plugin.namespace + '-ajax-response', plugin.hideAJAXResponse);
 
 
 
19
 
20
  };
21
 
@@ -50,21 +54,28 @@
50
 
51
  plugin.clearCache = function (event, options) {
52
  plugin.preventDefault(event);
 
 
 
53
 
54
 
55
  var postVars = {
56
  _wpnonce: plugin.vars._wpnonce
57
  }; // HTTP post vars.
58
 
59
- var isClearOption = false;
 
 
 
 
60
 
61
- {
62
  postVars[plugin.namespace] = {
63
  ajaxClearCache: '1'
64
  };
65
- }
66
- var $clear = $('#wp-admin-bar-' + plugin.namespace + '-clear > a');
67
-
 
68
  plugin.removeAJAXResponse();
69
 
70
  if (isClearOption && $clearOptionsLabel.length) {
@@ -89,6 +100,17 @@
89
  plugin.showAJAXResponse(); // Show response.
90
  });
91
  };
 
 
 
 
 
 
 
 
 
 
 
92
 
93
 
94
  plugin.showAJAXResponse = function () {
@@ -125,7 +147,71 @@
125
  $('.' + plugin.namespace + '-ajax-response')
126
  .off(plugin.animationEndEvents).remove();
127
  };
 
128
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129
  plugin.animationEndEvents = // All vendor prefixes.
130
  'webkitAnimationEnd mozAnimationEnd msAnimationEnd oAnimationEnd animationEnd';
131
 
14
 
15
  $('#wp-admin-bar-' + plugin.namespace + '-wipe > a').on('click', plugin.wipeCache);
16
  $('#wp-admin-bar-' + plugin.namespace + '-clear > a').on('click', plugin.clearCache);
17
+
18
 
19
  $document.on('click', '.' + plugin.namespace + '-ajax-response', plugin.hideAJAXResponse);
20
+
21
+
22
+
23
 
24
  };
25
 
54
 
55
  plugin.clearCache = function (event, options) {
56
  plugin.preventDefault(event);
57
+
58
+
59
+
60
 
61
 
62
  var postVars = {
63
  _wpnonce: plugin.vars._wpnonce
64
  }; // HTTP post vars.
65
 
66
+ var isClearOption = false,
67
+ $clear, // See below.
68
+ $clearOptionsLabel = $(),
69
+ $clearOptions = $();
70
+
71
 
 
72
  postVars[plugin.namespace] = {
73
  ajaxClearCache: '1'
74
  };
75
+
76
+
77
+ $clear = $('#wp-admin-bar-' + plugin.namespace + '-clear > a');
78
+
79
  plugin.removeAJAXResponse();
80
 
81
  if (isClearOption && $clearOptionsLabel.length) {
100
  plugin.showAJAXResponse(); // Show response.
101
  });
102
  };
103
+
104
+
105
+
106
+
107
+
108
+
109
+
110
+
111
+
112
+
113
+
114
 
115
 
116
  plugin.showAJAXResponse = function () {
147
  $('.' + plugin.namespace + '-ajax-response')
148
  .off(plugin.animationEndEvents).remove();
149
  };
150
+
151
 
152
+
153
+ plugin.bytesToSizeLabel = function (bytes, decimals) {
154
+ if (typeof bytes !== 'number' || bytes <= 1) {
155
+ return bytes === 1 ? '1 byte' : '0 bytes';
156
+ } // See: <http://jas.xyz/1gOCXob>
157
+ if (typeof decimals !== 'number' || decimals <= 0) {
158
+ decimals = 0; // Default; integer.
159
+ }
160
+ var base = 1024, // 1 Kilobyte base (binary).
161
+ baseLog = Math.floor(Math.log(bytes) / Math.log(base)),
162
+ sizes = ['bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
163
+ sizeInBaseLog = (bytes / Math.pow(base, baseLog));
164
+
165
+ return sizeInBaseLog.toFixed(decimals) + ' ' + sizes[baseLog];
166
+ };
167
+
168
+ plugin.numberFormat = function (number, decimals) {
169
+ if (typeof number !== 'number') {
170
+ return String(number);
171
+ } // See: <http://jas.xyz/1JlFD9P>
172
+ if (typeof decimals !== 'number' || decimals <= 0) {
173
+ decimals = 0; // Default; integer.
174
+ }
175
+ return number.toFixed(decimals).replace(/./g, function (m, o, s) {
176
+ return o && m !== '.' && ((s.length - o) % 3 === 0) ? ',' + m : m;
177
+ });
178
+ };
179
+
180
+ plugin.escHtml = function (string) {
181
+ var entityMap = {
182
+ '&': '&amp;',
183
+ '<': '&lt;',
184
+ '>': '&gt;',
185
+ '"': '&quot;',
186
+ "'": '&#39;'
187
+ };
188
+ return String(string).replace(/[&<>"']/g, function (specialChar) {
189
+ return entityMap[specialChar];
190
+ });
191
+ };
192
+
193
+ plugin.preventDefault = function (event, stop) {
194
+ if (!event) {
195
+ return; // Not possible.
196
+ }
197
+ event.preventDefault(); // Always.
198
+
199
+ if (stop) {
200
+ event.stopImmediatePropagation();
201
+ }
202
+ };
203
+
204
+ plugin.MutationObserver = (function () {
205
+ var observer = null; // Initialize default value.
206
+ $.each(['', 'WebKit', 'O', 'Moz', 'Ms'], function (index, prefix) {
207
+ if (prefix + 'MutationObserver' in window) {
208
+ observer = window[prefix + 'MutationObserver'];
209
+ return false; // Stop iterating now.
210
+ } // See: <http://jas.xyz/1JlzCdi>
211
+ });
212
+ return observer; // See: <http://caniuse.com/#feat=mutationobserver>
213
+ }());
214
+
215
  plugin.animationEndEvents = // All vendor prefixes.
216
  'webkitAnimationEnd mozAnimationEnd msAnimationEnd oAnimationEnd animationEnd';
217
 
src/client-s/js/admin-bar.min.js CHANGED
@@ -1 +1,26 @@
1
- (function(b){var a={namespace:"comet_cache"},d=b(window),c=b(document);a.onReady=function(){a.statsData=null;a.statsRunning=false;a.hideAJAXResponseTimeout=null;a.vars=b("#"+a.namespace+"-admin-bar-vars").data("json");b("#wp-admin-bar-"+a.namespace+"-wipe > a").on("click",a.wipeCache);b("#wp-admin-bar-"+a.namespace+"-clear > a").on("click",a.clearCache);b("#wp-admin-bar-"+a.namespace+"-clear-options-wrapper .-home-url-only > a").on("click",a.clearCacheHomeUrlOnly);b("#wp-admin-bar-"+a.namespace+"-clear-options-wrapper .-current-url-only > a").on("click",a.clearCacheCurrentUrlOnly);b("#wp-admin-bar-"+a.namespace+"-clear-options-wrapper .-specific-url-only > a").on("click",a.clearCacheSpecificUrlOnly);b("#wp-admin-bar-"+a.namespace+"-clear-options-wrapper .-opcache-only > a").on("click",a.clearCacheOpCacheOnly);b("#wp-admin-bar-"+a.namespace+"-clear-options-wrapper .-cdn-only > a").on("click",a.clearCacheCdnOnly);b("#wp-admin-bar-"+a.namespace+"-clear-options-wrapper .-transients-only > a").on("click",a.clearExpiredTransientsOnly);c.on("click","."+a.namespace+"-ajax-response",a.hideAJAXResponse);var f=b("#wp-admin-bar-"+a.namespace+"-stats"),e=f.find(".-wrapper"),g=e.find(".-container");if(f.length&&a.MutationObserver){(new a.MutationObserver(function(h){b.each(h,function(k,i){if(i.type!=="attributes"){return}if(i.attributeName!=="class"){return}var j=i.oldValue,l=b(i.target).prop(i.attributeName);if(!/\bhover\b/i.test(j)&&/\bhover\b/i.test(l)){a.stats()}return false})})).observe(f[0],{attributes:true,attributeOldValue:true,childList:true,characterData:true})}};a.wipeCache=function(i){a.preventDefault(i);a.statsData=null;var f={_wpnonce:a.vars._wpnonce};f[a.namespace]={ajaxWipeCache:"1"};var e=b("#wp-admin-bar-"+a.namespace+"-wipe > a");var h=b("#wp-admin-bar-"+a.namespace+"-clear-options-wrapper .-label");var g=b("#wp-admin-bar-"+a.namespace+"-clear-options-wrapper .-options");a.removeAJAXResponse();e.parent().addClass("-processing");e.add(g.find("a")).attr("disabled","disabled");b.post(a.vars.ajaxURL,f,function(k){a.removeAJAXResponse();e.parent().removeClass("-processing");e.add(g.find("a")).removeAttr("disabled");var j=b('<div class="'+a.namespace+'-ajax-response -wipe">'+k+"</div>");b("body").append(j);a.showAJAXResponse()})};a.clearCache=function(j,f){a.preventDefault(j);a.statsData=null;f=f||{};var l=b.extend({},{urlOnly:"",opCacheOnly:false,cdnOnly:false,transientsOnly:false},f);var e={_wpnonce:a.vars._wpnonce};var i=false;if(l.urlOnly){i=true;e[a.namespace]={ajaxClearCacheUrl:l.urlOnly}}else{if(l.opCacheOnly){i=true;e[a.namespace]={ajaxClearOpCache:"1"}}else{if(l.cdnOnly){i=true;e[a.namespace]={ajaxClearCdnCache:"1"}}else{if(l.transientsOnly){i=true;e[a.namespace]={ajaxClearExpiredTransients:"1"}}else{e[a.namespace]={ajaxClearCache:"1"}}}}}var k=b("#wp-admin-bar-"+a.namespace+"-clear > a");var h=b("#wp-admin-bar-"+a.namespace+"-clear-options-wrapper .-label");var g=b("#wp-admin-bar-"+a.namespace+"-clear-options-wrapper .-options");a.removeAJAXResponse();if(i&&h.length){h.addClass("-processing")}else{k.parent().addClass("-processing")}k.add(g.find("a")).attr("disabled","disabled");b.post(a.vars.ajaxURL,e,function(n){a.removeAJAXResponse();if(i&&h.length){h.removeClass("-processing")}else{k.parent().removeClass("-processing")}k.add(g.find("a")).removeAttr("disabled");var m=b('<div class="'+a.namespace+'-ajax-response -clear">'+n+"</div>");b("body").append(m);a.showAJAXResponse()})};a.clearCacheHomeUrlOnly=function(e){a.clearCache(e,{urlOnly:"home"})};a.clearCacheCurrentUrlOnly=function(e){a.clearCache(e,{urlOnly:document.URL})};a.clearCacheSpecificUrlOnly=function(f){var e=b.trim(prompt(a.vars.i18n.enterSpecificUrl,"http://"));if(e&&e!=="http://"){a.clearCache(f,{urlOnly:e})}else{a.preventDefault(f)}};a.clearCacheOpCacheOnly=function(e){a.clearCache(e,{opCacheOnly:true})};a.clearCacheCdnOnly=function(e){a.clearCache(e,{cdnOnly:true})};a.clearExpiredTransientsOnly=function(e){a.clearCache(e,{transientsOnly:true})};a.showAJAXResponse=function(){clearTimeout(a.hideAJAXResponseTimeout);b("."+a.namespace+"-ajax-response").off(a.animationEndEvents).on(a.animationEndEvents,function(){a.hideAJAXResponseTimeout=setTimeout(a.hideAJAXResponse,2500)}).addClass(a.namespace+"-admin-bar-animation-zoom-in-down").show().on("mouseover",function(){clearTimeout(a.hideAJAXResponseTimeout);b(this).addClass("-hovered")})};a.hideAJAXResponse=function(e){a.preventDefault(e);clearTimeout(a.hideAJAXResponseTimeout);b("."+a.namespace+"-ajax-response").off(a.animationEndEvents).on(a.animationEndEvents,function(){a.removeAJAXResponse()}).addClass(a.namespace+"-admin-bar-animation-zoom-out-up")};a.removeAJAXResponse=function(){clearTimeout(a.hideAJAXResponseTimeout);b("."+a.namespace+"-ajax-response").off(a.animationEndEvents).remove()};a.stats=function(){if(a.statsRunning){return}a.statsRunning=true;var t=!a.vars.isMultisite||a.vars.currentUserHasNetworkCap;var p=b("body"),o=b("#wp-admin-bar-"+a.namespace+"-stats"),s=o.find(".-wrapper"),q=s.find(".-container"),e=q.find(".-refreshing"),g=q.find(".-chart-a"),f=q.find(".-chart-b"),i=q.find(".-totals"),k=i.find(".-files"),r=i.find(".-size"),j=i.find(".-dir"),h=q.find(".-disk"),l=h.find(".-free"),m=h.find(".-size"),n=q.find(".-more-info");var u=function(){if(!o.hasClass("hover")){a.statsRunning=false;return}e.show();g.hide();f.hide();i.removeClass("-no-charts");i.css("visibility","hidden");if(!t||b.trim(j.text()).length>30){j.hide()}h.css("visibility","hidden");if(t){n.css("visibility","hidden")}else{n.hide()}if(!a.statsData){var w={_wpnonce:a.vars._wpnonce};w[a.namespace]={ajaxDirStats:"1"};b.post(a.vars.ajaxURL,w,function(x){console.log("Admin Bar :: statsData :: %o",x);a.statsData=x;v()})}else{setTimeout(v,500)}},v=function(){if(!a.statsData){a.statsRunning=false;return}if(!o.hasClass("hover")){a.statsRunning=false;return}e.hide();g.css("display","block");f.css("display","block");var Y=null,X=null,T=null,Z=null;var x=t?"forCache":"forHostCache",M=t?"forHtmlCCache":"forHtmlCHostCache",B=t?"largestCacheSize":"largestHostCacheSize",z=t?"largestCacheCount":"largestHostCacheCount";var C=a.statsData[B].size,L=a.statsData[B].days,E=a.statsData[z].count,S=a.statsData[z].days,R=a.statsData[x].stats.total_links_files,aa=a.statsData[M].stats.total_links_files,F=R+aa,J=a.statsData[x].stats.total_size,O=a.statsData[M].stats.total_size,P=J+O,N=a.statsData[x].stats.disk_total_space,K=a.statsData[x].stats.disk_free_space,G=0,W=0,w=0,I=0,D=0,Q=0;if(a.vars.isMultisite&&a.vars.currentUserHasNetworkCap){G=a.statsData.forHostCache.stats.total_links_files;W=a.statsData.forHtmlCHostCache.stats.total_links_files;w=G+W;I=a.statsData.forHostCache.stats.total_size;D=a.statsData.forHtmlCHostCache.stats.total_size;Q=I+D}var y=function(af,ad){if(!(af instanceof Array)){return{}}if(typeof ad!=="number"||ad<=0){ad=10}var ac=[];b.each(af,function(ai,aj){ac.push(Number(aj.value))});var ah=0,ae=Math.min.apply(null,ac),ab=Math.max.apply(null,ac),ag=Math.ceil((ab-ah)/ad);return{scaleSteps:ad,scaleStartValue:ah,scaleStepWidth:ag,scaleIntegersOnly:true,scaleOverride:true}},H={responsive:true,maintainAspectRatio:true,animationSteps:35,scaleFontSize:10,scaleShowLine:true,scaleFontFamily:"sans-serif",scaleShowLabelBackdrop:true,scaleBackdropPaddingY:2,scaleBackdropPaddingX:4,scaleFontColor:"rgba(0,0,0,1)",scaleBackdropColor:"rgba(255,255,255,1)",scaleLineColor:b("body").hasClass("admin-color-light")?"rgba(0,0,0,0.25)":"rgba(255,255,255,0.25)",scaleLabel:function(ab){return a.bytesToSizeLabel(Number(ab.value))},tooltipFontSize:12,tooltipFillColor:"rgba(0,0,0,1)",tooltipFontFamily:"Georgia, serif",tooltipTemplate:function(ab){return ab.label+": "+a.bytesToSizeLabel(Number(ab.value))},segmentShowStroke:true,segmentStrokeWidth:1,segmentStrokeColor:b("body").hasClass("admin-color-light")?"rgba(0,0,0,1)":"rgba(255,255,255,1)"},V=H;var A=[],U=[];A.push({value:C,label:a.vars.i18n.xDayHigh.replace("%s",L),color:"#ff5050",highlight:"#c63f3f"});A.push({value:P,label:a.vars.i18n.currentTotal,color:"#46bf52",highlight:"#33953e"});A.push({value:J,label:a.vars.i18n.pageCache,color:"#0096CC",highlight:"#057ca7"});A.push({value:O,label:a.vars.i18n.htmlCompressor,color:"#FFC870",highlight:"#d6a85d"});if(a.vars.isMultisite&&a.vars.currentUserHasNetworkCap){A.push({value:Q,label:a.vars.i18n.currentSite,color:"#46bfb4",highlight:"#348f87"})}b.extend(H,y(A,5));U=A;b.extend(V,y(U,5));if((Y=o.data("chartA"))){Y.destroy()}if((X=o.data("chartB"))){X.destroy()}if((T=o.data("chartADimensions"))){g.attr("width",parseInt(T.width)).attr("height",parseInt(T.height)).css(T)}if((Z=o.data("chartBDimensions"))){f.attr("width",parseInt(Z.width)).attr("height",parseInt(Z.height)).css(Z)}if(g.length&&A[0].value>0){Y=new Chart(g[0].getContext("2d")).PolarArea(A,H);o.data("chartA",Y).data("chartADimensions",{width:g.width()+"px",height:g.height()+"px"})}else{Y=null;g.hide()}if(f.length&&U[0].value>0){X=new Chart(f[0].getContext("2d")).PolarArea(U,V);o.data("chartB",X).data("chartBDimensions",{width:f.width()+"px",height:f.height()+"px"})}else{X=null;f.hide()}if(!Y&&!X){i.addClass("-no-charts")}i.css("visibility","visible");k.find(".-value").html(a.escHtml(a.numberFormat(F)+" "+(F===1?a.vars.i18n.file:a.vars.i18n.files)));r.find(".-value").html(a.escHtml(a.bytesToSizeLabel(P)));h.css("visibility","visible");m.find(".-value").html(a.escHtml(a.bytesToSizeLabel(N)));l.find(".-value").html(a.escHtml(a.bytesToSizeLabel(K)));if(t){n.css("visibility","visible")}a.statsRunning=false};u()};a.bytesToSizeLabel=function(f,e){if(typeof f!=="number"||f<=1){return f===1?"1 byte":"0 bytes"}if(typeof e!=="number"||e<=0){e=0}var i=1024,j=Math.floor(Math.log(f)/Math.log(i)),h=["bytes","KB","MB","GB","TB","PB","EB","ZB","YB"],g=(f/Math.pow(i,j));return g.toFixed(e)+" "+h[j]};a.numberFormat=function(f,e){if(typeof f!=="number"){return String(f)}if(typeof e!=="number"||e<=0){e=0}return f.toFixed(e).replace(/./g,function(g,i,h){return i&&g!=="."&&((h.length-i)%3===0)?","+g:g})};a.escHtml=function(f){var e={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"};return String(f).replace(/[&<>"']/g,function(g){return e[g]})};a.preventDefault=function(f,e){if(!f){return}f.preventDefault();if(e){f.stopImmediatePropagation()}};a.MutationObserver=(function(){var e=null;b.each(["","WebKit","O","Moz","Ms"],function(f,g){if(g+"MutationObserver" in window){e=window[g+"MutationObserver"];return false}});return e}());a.animationEndEvents="webkitAnimationEnd mozAnimationEnd msAnimationEnd oAnimationEnd animationEnd";c.ready(a.onReady)})(jQuery);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ (function(b){var a={namespace:"comet_cache"},d=b(window),c=b(document);a.onReady=function(){
2
+
3
+ a.hideAJAXResponseTimeout=null;a.vars=b("#"+a.namespace+"-admin-bar-vars").data("json");b("#wp-admin-bar-"+a.namespace+"-wipe > a").on("click",a.wipeCache);b("#wp-admin-bar-"+a.namespace+"-clear > a").on("click",a.clearCache);
4
+
5
+ c.on("click","."+a.namespace+"-ajax-response",a.hideAJAXResponse);
6
+
7
+
8
+ };a.wipeCache=function(i){a.preventDefault(i);a.statsData=null;var f={_wpnonce:a.vars._wpnonce};f[a.namespace]={ajaxWipeCache:"1"};var e=b("#wp-admin-bar-"+a.namespace+"-wipe > a");var h=b("#wp-admin-bar-"+a.namespace+"-clear-options-wrapper .-label");var g=b("#wp-admin-bar-"+a.namespace+"-clear-options-wrapper .-options");a.removeAJAXResponse();e.parent().addClass("-processing");e.add(g.find("a")).attr("disabled","disabled");b.post(a.vars.ajaxURL,f,function(k){a.removeAJAXResponse();e.parent().removeClass("-processing");e.add(g.find("a")).removeAttr("disabled");var j=b('<div class="'+a.namespace+'-ajax-response -wipe">'+k+"</div>");b("body").append(j);a.showAJAXResponse()})};a.clearCache=function(j,f){a.preventDefault(j);
9
+
10
+
11
+ var e={_wpnonce:a.vars._wpnonce};var i=false,k,h=b(),g=b();
12
+
13
+ e[a.namespace]={ajaxClearCache:"1"};
14
+
15
+ k=b("#wp-admin-bar-"+a.namespace+"-clear > a");
16
+
17
+ a.removeAJAXResponse();if(i&&h.length){h.addClass("-processing")}else{k.parent().addClass("-processing")}k.add(g.find("a")).attr("disabled","disabled");b.post(a.vars.ajaxURL,e,function(n){a.removeAJAXResponse();if(i&&h.length){h.removeClass("-processing")}else{k.parent().removeClass("-processing")}k.add(g.find("a")).removeAttr("disabled");var m=b('<div class="'+a.namespace+'-ajax-response -clear">'+n+"</div>");b("body").append(m);a.showAJAXResponse()})};
18
+
19
+
20
+
21
+
22
+
23
+
24
+ a.showAJAXResponse=function(){clearTimeout(a.hideAJAXResponseTimeout);b("."+a.namespace+"-ajax-response").off(a.animationEndEvents).on(a.animationEndEvents,function(){a.hideAJAXResponseTimeout=setTimeout(a.hideAJAXResponse,2500)}).addClass(a.namespace+"-admin-bar-animation-zoom-in-down").show().on("mouseover",function(){clearTimeout(a.hideAJAXResponseTimeout);b(this).addClass("-hovered")})};a.hideAJAXResponse=function(e){a.preventDefault(e);clearTimeout(a.hideAJAXResponseTimeout);b("."+a.namespace+"-ajax-response").off(a.animationEndEvents).on(a.animationEndEvents,function(){a.removeAJAXResponse()}).addClass(a.namespace+"-admin-bar-animation-zoom-out-up")};a.removeAJAXResponse=function(){clearTimeout(a.hideAJAXResponseTimeout);b("."+a.namespace+"-ajax-response").off(a.animationEndEvents).remove()};
25
+
26
+ a.bytesToSizeLabel=function(f,e){if(typeof f!=="number"||f<=1){return f===1?"1 byte":"0 bytes"}if(typeof e!=="number"||e<=0){e=0}var i=1024,j=Math.floor(Math.log(f)/Math.log(i)),h=["bytes","KB","MB","GB","TB","PB","EB","ZB","YB"],g=(f/Math.pow(i,j));return g.toFixed(e)+" "+h[j]};a.numberFormat=function(f,e){if(typeof f!=="number"){return String(f)}if(typeof e!=="number"||e<=0){e=0}return f.toFixed(e).replace(/./g,function(g,i,h){return i&&g!=="."&&((h.length-i)%3===0)?","+g:g})};a.escHtml=function(f){var e={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"};return String(f).replace(/[&<>"']/g,function(g){return e[g]})};a.preventDefault=function(f,e){if(!f){return}f.preventDefault();if(e){f.stopImmediatePropagation()}};a.MutationObserver=(function(){var e=null;b.each(["","WebKit","O","Moz","Ms"],function(f,g){if(g+"MutationObserver" in window){e=window[g+"MutationObserver"];return false}});return e}());a.animationEndEvents="webkitAnimationEnd mozAnimationEnd msAnimationEnd oAnimationEnd animationEnd";c.ready(a.onReady)})(jQuery);
src/client-s/js/menu-pages.js CHANGED
@@ -22,6 +22,12 @@
22
  $('select[name$="_enable\\]"], select[data-toggle~="enable-disable"]', plugin.$menuPage).not('.-no-if-enabled').on('change', plugin.enableDisable).trigger('change');
23
 
24
 
 
 
 
 
 
 
25
  };
26
 
27
  plugin.toggleAllPanelsOpen = function (event) {
@@ -117,6 +123,8 @@
117
  $ss.attr('src', $ss.attr('src').replace(/ops[0-9]\-ss\.png$/, 'ops' + val + '-ss.png'));
118
  };
119
 
 
 
120
  plugin.handleCdnHostsChange = function (event) {
121
  var $cdnHosts = $(this),
122
  $cdnHost = $('input[name$="\[cdn_host\]"]', plugin.$menuPage);
@@ -137,6 +145,10 @@
137
 
138
 
139
 
 
 
 
 
140
  plugin.bytesToSizeLabel = function (bytes, decimals) {
141
  if (typeof bytes !== 'number' || bytes <= 1) {
142
  return bytes === 1 ? '1 byte' : '0 bytes';
22
  $('select[name$="_enable\\]"], select[data-toggle~="enable-disable"]', plugin.$menuPage).not('.-no-if-enabled').on('change', plugin.enableDisable).trigger('change');
23
 
24
 
25
+
26
+
27
+
28
+
29
+
30
+
31
  };
32
 
33
  plugin.toggleAllPanelsOpen = function (event) {
123
  $ss.attr('src', $ss.attr('src').replace(/ops[0-9]\-ss\.png$/, 'ops' + val + '-ss.png'));
124
  };
125
 
126
+
127
+
128
  plugin.handleCdnHostsChange = function (event) {
129
  var $cdnHosts = $(this),
130
  $cdnHost = $('input[name$="\[cdn_host\]"]', plugin.$menuPage);
145
 
146
 
147
 
148
+
149
+
150
+
151
+
152
  plugin.bytesToSizeLabel = function (bytes, decimals) {
153
  if (typeof bytes !== 'number' || bytes <= 1) {
154
  return bytes === 1 ? '1 byte' : '0 bytes';
src/client-s/js/menu-pages.min.js CHANGED
@@ -1,7 +1,14 @@
1
  (function(b){var a={namespace:"comet_cache"},d=b(window),c=b(document);a.onReady=function(){
2
 
3
- ;a.$menuPage=b("#plugin-menu-page");a.vars=window[a.namespace+"_menu_page_vars"];b(".plugin-menu-page-panel-heading",a.$menuPage).on("click",a.togglePanel);b(".plugin-menu-page-panels-open",a.$menuPage).on("click",a.toggleAllPanelsOpen);b(".plugin-menu-page-panels-close",a.$menuPage).on("click",a.toggleAllPanelsClose);b("[data-action]",a.$menuPage).on("click",a.doDataAction);b("[data-toggle-target]",a.$menuPage).on("click",a.doDataToggleTarget);b('select[name$="_enable\\]"], select[data-toggle~="enable-disable"]',a.$menuPage).not(".-no-if-enabled").on("change",a.enableDisable).trigger("change");
4
 
5
- };a.toggleAllPanelsOpen=function(e){a.preventDefault(e);b(".plugin-menu-page-panel-heading",a.$menuPage).addClass("open").next(".plugin-menu-page-panel-body").addClass("open")};a.toggleAllPanelsClose=function(e){a.preventDefault(e);b(".plugin-menu-page-panel-heading",a.$menuPage).removeClass("open").next(".plugin-menu-page-panel-body").removeClass("open")};a.togglePanel=function(e){a.preventDefault(e);b(this).toggleClass("open").next(".plugin-menu-page-panel-body").toggleClass("open")};a.doDataAction=function(e){a.preventDefault(e);var g=b(this),f=g.data();if(typeof f.confirmation!=="string"||confirm(f.confirmation)){location.href=f.action}};a.enableDisable=function(e){var m=b(this),g=m.val(),f=m.attr("name"),o=String(m.data("enabledStrings")||"1,2,3,4,5").split(/,+/),l=b.inArray(g,o)!==-1,i=m.closest(".plugin-menu-page-panel-body"),n=m.data("target"),h=n?b(n,i).filter(".plugin-menu-page-panel-if-enabled"):null,k=m.closest(".plugin-menu-page-panel-if-enabled"),j=k.find("> .plugin-menu-page-panel-if-enabled"),p=i.find("> .plugin-menu-page-panel-if-enabled");if(l){if(n){h.css("opacity",1).find(":input").removeAttr("readonly")}else{if(k.length){j.css("opacity",1).find(":input").removeAttr("readonly")}else{p.css("opacity",1).find(":input").removeAttr("readonly")}}}else{if(n){h.css("opacity",0.4).find(":input").attr("readonly","readonly")}else{if(k.length){j.css("opacity",0.4).find(":input").attr("readonly","readonly")}else{p.css("opacity",0.4).find(":input").attr("readonly","readonly")}}}};a.doDataToggleTarget=function(f){a.preventDefault(f);var g=b(this),e=b(g.data("toggleTarget"));if(e.is(":visible")){e.hide();g.find(".si").removeClass("si-eye-slash").addClass("si-eye")}else{e.show();g.find(".si").removeClass("si-eye").addClass("si-eye-slash")}};a.handleCacheClearAdminBarOpsChange=function(g){var f=b(this),h=f.val(),e=b(".-clear-cache-ops-ss",a.$menuPage);e.attr("src",e.attr("src").replace(/ops[0-9]\-ss\.png$/,"ops"+h+"-ss.png"))};a.handleCdnHostsChange=function(f){var g=b(this),e=b('input[name$="[cdn_host]"]',a.$menuPage);if(b.trim(g.val())){if(e.val()){e.data("hiddenValue",e.val())}e.attr("disabled","disabled").val("")}else{if(!e.val()){e.val(e.data("hiddenValue"))}e.removeAttr("disabled");g.val("")}};
6
 
7
- ;a.bytesToSizeLabel=function(f,e){if(typeof f!=="number"||f<=1){return f===1?"1 byte":"0 bytes"}if(typeof e!=="number"||e<=0){e=0}var i=1024,j=Math.floor(Math.log(f)/Math.log(i)),h=["bytes","KB","MB","GB","TB","PB","EB","ZB","YB"],g=(f/Math.pow(i,j));return g.toFixed(e)+" "+h[j]};a.numberFormat=function(f,e){if(typeof f!=="number"){return String(f)}if(typeof e!=="number"||e<=0){e=0}return f.toFixed(e).replace(/./g,function(g,i,h){return i&&g!=="."&&((h.length-i)%3===0)?","+g:g})};a.escHtml=function(f){var e={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"};return String(f).replace(/[&<>"']/g,function(g){return e[g]})};a.preventDefault=function(f,e){if(!f){return}f.preventDefault();if(e){f.stopImmediatePropagation()}};c.ready(a.onReady)})(jQuery);
 
 
 
 
 
 
 
 
1
  (function(b){var a={namespace:"comet_cache"},d=b(window),c=b(document);a.onReady=function(){
2
 
3
+ a.$menuPage=b("#plugin-menu-page");a.vars=window[a.namespace+"_menu_page_vars"];b(".plugin-menu-page-panel-heading",a.$menuPage).on("click",a.togglePanel);b(".plugin-menu-page-panels-open",a.$menuPage).on("click",a.toggleAllPanelsOpen);b(".plugin-menu-page-panels-close",a.$menuPage).on("click",a.toggleAllPanelsClose);b("[data-action]",a.$menuPage).on("click",a.doDataAction);b("[data-toggle-target]",a.$menuPage).on("click",a.doDataToggleTarget);b('select[name$="_enable\\]"], select[data-toggle~="enable-disable"]',a.$menuPage).not(".-no-if-enabled").on("change",a.enableDisable).trigger("change");
4
 
 
5
 
6
+
7
+
8
+ };a.toggleAllPanelsOpen=function(e){a.preventDefault(e);b(".plugin-menu-page-panel-heading",a.$menuPage).addClass("open").next(".plugin-menu-page-panel-body").addClass("open")};a.toggleAllPanelsClose=function(e){a.preventDefault(e);b(".plugin-menu-page-panel-heading",a.$menuPage).removeClass("open").next(".plugin-menu-page-panel-body").removeClass("open")};a.togglePanel=function(e){a.preventDefault(e);b(this).toggleClass("open").next(".plugin-menu-page-panel-body").toggleClass("open")};a.doDataAction=function(e){a.preventDefault(e);var g=b(this),f=g.data();if(typeof f.confirmation!=="string"||confirm(f.confirmation)){location.href=f.action}};a.enableDisable=function(e){var m=b(this),g=m.val(),f=m.attr("name"),o=String(m.data("enabledStrings")||"1,2,3,4,5").split(/,+/),l=b.inArray(g,o)!==-1,i=m.closest(".plugin-menu-page-panel-body"),n=m.data("target"),h=n?b(n,i).filter(".plugin-menu-page-panel-if-enabled"):null,k=m.closest(".plugin-menu-page-panel-if-enabled"),j=k.find("> .plugin-menu-page-panel-if-enabled"),p=i.find("> .plugin-menu-page-panel-if-enabled");if(l){if(n){h.css("opacity",1).find(":input").removeAttr("readonly")}else{if(k.length){j.css("opacity",1).find(":input").removeAttr("readonly")}else{p.css("opacity",1).find(":input").removeAttr("readonly")}}}else{if(n){h.css("opacity",0.4).find(":input").attr("readonly","readonly")}else{if(k.length){j.css("opacity",0.4).find(":input").attr("readonly","readonly")}else{p.css("opacity",0.4).find(":input").attr("readonly","readonly")}}}};a.doDataToggleTarget=function(f){a.preventDefault(f);var g=b(this),e=b(g.data("toggleTarget"));if(e.is(":visible")){e.hide();g.find(".si").removeClass("si-eye-slash").addClass("si-eye")}else{e.show();g.find(".si").removeClass("si-eye").addClass("si-eye-slash")}};a.handleCacheClearAdminBarOpsChange=function(g){var f=b(this),h=f.val(),e=b(".-clear-cache-ops-ss",a.$menuPage);e.attr("src",e.attr("src").replace(/ops[0-9]\-ss\.png$/,"ops"+h+"-ss.png"))};
9
+
10
+ a.handleCdnHostsChange=function(f){var g=b(this),e=b('input[name$="[cdn_host]"]',a.$menuPage);if(b.trim(g.val())){if(e.val()){e.data("hiddenValue",e.val())}e.attr("disabled","disabled").val("")}else{if(!e.val()){e.val(e.data("hiddenValue"))}e.removeAttr("disabled");g.val("")}};
11
+
12
+
13
+
14
+ a.bytesToSizeLabel=function(f,e){if(typeof f!=="number"||f<=1){return f===1?"1 byte":"0 bytes"}if(typeof e!=="number"||e<=0){e=0}var i=1024,j=Math.floor(Math.log(f)/Math.log(i)),h=["bytes","KB","MB","GB","TB","PB","EB","ZB","YB"],g=(f/Math.pow(i,j));return g.toFixed(e)+" "+h[j]};a.numberFormat=function(f,e){if(typeof f!=="number"){return String(f)}if(typeof e!=="number"||e<=0){e=0}return f.toFixed(e).replace(/./g,function(g,i,h){return i&&g!=="."&&((h.length-i)%3===0)?","+g:g})};a.escHtml=function(f){var e={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"};return String(f).replace(/[&<>"']/g,function(g){return e[g]})};a.preventDefault=function(f,e){if(!f){return}f.preventDefault();if(e){f.stopImmediatePropagation()}};c.ready(a.onReady)})(jQuery);
src/includes/classes/Actions.php CHANGED
@@ -71,8 +71,7 @@ class Actions extends AbsBase
71
  {
72
  if (!is_multisite() || !$this->plugin->currentUserCanWipeCache()) {
73
  return; // Nothing to do.
74
- }
75
- if (empty($_REQUEST['_wpnonce']) || !wp_verify_nonce($_REQUEST['_wpnonce'])) {
76
  return; // Unauthenticated POST data.
77
  }
78
  $counter = $this->plugin->wipeCache(true);
@@ -97,8 +96,7 @@ class Actions extends AbsBase
97
  {
98
  if (!$this->plugin->currentUserCanClearCache()) {
99
  return; // Not allowed to clear.
100
- }
101
- if (empty($_REQUEST['_wpnonce']) || !wp_verify_nonce($_REQUEST['_wpnonce'])) {
102
  return; // Unauthenticated POST data.
103
  }
104
  $counter = $this->plugin->clearCache(true);
@@ -112,7 +110,6 @@ class Actions extends AbsBase
112
  wp_redirect($redirect_to).exit();
113
  }
114
 
115
-
116
  /**
117
  * Action handler.
118
  *
@@ -124,8 +121,7 @@ class Actions extends AbsBase
124
  {
125
  if (!is_multisite() || !$this->plugin->currentUserCanWipeCache()) {
126
  return; // Nothing to do.
127
- }
128
- if (empty($_REQUEST['_wpnonce']) || !wp_verify_nonce($_REQUEST['_wpnonce'])) {
129
  return; // Unauthenticated POST data.
130
  }
131
  $counter = $this->plugin->wipeCache(true);
@@ -138,8 +134,6 @@ class Actions extends AbsBase
138
  exit($response); // JavaScript will take it from here.
139
  }
140
 
141
-
142
-
143
  /**
144
  * Action handler.
145
  *
@@ -151,8 +145,7 @@ class Actions extends AbsBase
151
  {
152
  if (!$this->plugin->currentUserCanClearCache()) {
153
  return; // Not allowed to clear.
154
- }
155
- if (empty($_REQUEST['_wpnonce']) || !wp_verify_nonce($_REQUEST['_wpnonce'])) {
156
  return; // Unauthenticated POST data.
157
  }
158
  $counter = $this->plugin->clearCache(true);
@@ -168,7 +161,6 @@ class Actions extends AbsBase
168
  exit($response); // JavaScript will take it from here.
169
  }
170
 
171
-
172
 
173
 
174
 
@@ -196,10 +188,11 @@ class Actions extends AbsBase
196
  */
197
  protected function saveOptions($args)
198
  {
 
 
199
  if (!current_user_can($this->plugin->cap)) {
200
  return; // Nothing to do.
201
- }
202
- if (empty($_REQUEST['_wpnonce']) || !wp_verify_nonce($_REQUEST['_wpnonce'])) {
203
  return; // Unauthenticated POST data.
204
  }
205
  if (!empty($_FILES[GLOBAL_NS]['tmp_name']['import_options'])) {
@@ -213,10 +206,11 @@ class Actions extends AbsBase
213
  unset($args['last_pro_stats_log']); // CANNOT be imported!
214
  }
215
 
 
216
  $args = $this->plugin->trimDeep(stripslashes_deep((array) $args));
217
  $this->plugin->updateOptions($args); // Save/update options.
218
 
219
- // Ensures `autoCacheMaybeClearPrimaryXmlSitemapError()` always validates the XML Sitemap when saving options (when applicable)
220
  delete_transient(GLOBAL_NS.'-'.md5($this->plugin->options['auto_cache_sitemap_url']));
221
 
222
  $redirect_to = self_admin_url('/admin.php'); // Redirect preparations.
@@ -224,8 +218,6 @@ class Actions extends AbsBase
224
 
225
  $this->plugin->autoWipeCache(); // May produce a notice.
226
 
227
- global $is_apache, $is_nginx;
228
-
229
  if ($this->plugin->options['enable']) {
230
  if (!($add_wp_cache_to_wp_config = $this->plugin->addWpCacheToWpConfig())) {
231
  $query_args[GLOBAL_NS.'_wp_config_wp_cache_add_failure'] = '1';
@@ -233,17 +225,21 @@ class Actions extends AbsBase
233
  if ($is_apache && !($add_wp_htaccess = $this->plugin->addWpHtaccess())) {
234
  $query_args[GLOBAL_NS.'_wp_htaccess_add_failure'] = '1';
235
  }
236
- if ($is_nginx && $this->plugin->applyWpFilters(GLOBAL_NS.'_wp_htaccess_nginx_notice', true) && (!isset($_SERVER['WP_NGINX_CONFIG']) || $_SERVER['WP_NGINX_CONFIG'] !== 'done')) {
 
237
  $query_args[GLOBAL_NS.'_wp_htaccess_nginx_notice'] = '1';
238
  }
239
  if (!($add_advanced_cache = $this->plugin->addAdvancedCache())) {
240
  $query_args[GLOBAL_NS.'_advanced_cache_add_failure'] = $add_advanced_cache === null ? 'advanced-cache' : '1';
241
  }
 
242
  if (!$this->plugin->options['auto_cache_enable']) {
243
- $this->plugin->dismissMainNotice('auto_cache_engine_minimum_requirements'); // Dismiss and check again on `admin_init` via `autoCacheMaybeClearPhpReqsError()`
 
244
  }
245
  if (!$this->plugin->options['auto_cache_enable'] || !$this->plugin->options['auto_cache_sitemap_url']) {
246
- $this->plugin->dismissMainNotice('xml_sitemap_missing'); // Dismiss and check again on `admin_init` via `autoCacheMaybeClearPrimaryXmlSitemapError()`
 
247
  }
248
  $this->plugin->updateBlogPaths(); // Multisite networks only.
249
  } else {
@@ -256,8 +252,11 @@ class Actions extends AbsBase
256
  if (!($remove_advanced_cache = $this->plugin->removeAdvancedCache())) {
257
  $query_args[GLOBAL_NS.'_advanced_cache_remove_failure'] = '1';
258
  }
259
- $this->plugin->dismissMainNotice('xml_sitemap_missing'); // Dismiss notice when disabling plugin
260
- $this->plugin->dismissMainNotice('auto_cache_engine_minimum_requirements'); // Dismiss notice when disabling plugin
 
 
 
261
  }
262
  $redirect_to = add_query_arg(urlencode_deep($query_args), $redirect_to);
263
 
@@ -273,24 +272,22 @@ class Actions extends AbsBase
273
  */
274
  protected function restoreDefaultOptions($args)
275
  {
 
 
276
  if (!current_user_can($this->plugin->cap)) {
277
  return; // Nothing to do.
278
- }
279
- if (is_multisite() && !current_user_can($this->plugin->network_cap)) {
280
  return; // Nothing to do.
281
- }
282
- if (empty($_REQUEST['_wpnonce']) || !wp_verify_nonce($_REQUEST['_wpnonce'])) {
283
  return; // Unauthenticated POST data.
284
  }
285
  $this->plugin->restoreDefaultOptions(); // Restore defaults.
286
 
287
- $redirect_to = self_admin_url('/admin.php'); // Redirect preparations.
288
  $query_args = ['page' => GLOBAL_NS, GLOBAL_NS.'_restored' => '1'];
289
 
290
  $this->plugin->autoWipeCache(); // May produce a notice.
291
 
292
- global $is_apache, $is_nginx;
293
-
294
  if ($this->plugin->options['enable']) {
295
  if (!($add_wp_cache_to_wp_config = $this->plugin->addWpCacheToWpConfig())) {
296
  $query_args[GLOBAL_NS.'_wp_config_wp_cache_add_failure'] = '1';
@@ -298,12 +295,22 @@ class Actions extends AbsBase
298
  if ($is_apache && !($add_wp_htaccess = $this->plugin->addWpHtaccess())) {
299
  $query_args[GLOBAL_NS.'_wp_htaccess_add_failure'] = '1';
300
  }
301
- if ($is_nginx && $this->plugin->applyWpFilters(GLOBAL_NS.'_wp_htaccess_nginx_notice', true) && (!isset($_SERVER['WP_NGINX_CONFIG']) || $_SERVER['WP_NGINX_CONFIG'] !== 'done')) {
 
302
  $query_args[GLOBAL_NS.'_wp_htaccess_nginx_notice'] = '1';
303
  }
304
  if (!($add_advanced_cache = $this->plugin->addAdvancedCache())) {
305
  $query_args[GLOBAL_NS.'_advanced_cache_add_failure'] = $add_advanced_cache === null ? 'advanced-cache' : '1';
306
  }
 
 
 
 
 
 
 
 
 
307
  $this->plugin->updateBlogPaths(); // Multisite networks only.
308
  } else {
309
  if (!($remove_wp_cache_from_wp_config = $this->plugin->removeWpCacheFromWpConfig())) {
@@ -315,6 +322,11 @@ class Actions extends AbsBase
315
  if (!($remove_advanced_cache = $this->plugin->removeAdvancedCache())) {
316
  $query_args[GLOBAL_NS.'_advanced_cache_remove_failure'] = '1';
317
  }
 
 
 
 
 
318
  }
319
  $redirect_to = add_query_arg(urlencode_deep($query_args), $redirect_to);
320
 
@@ -334,8 +346,7 @@ class Actions extends AbsBase
334
  {
335
  if (!current_user_can($this->plugin->cap)) {
336
  return; // Nothing to do.
337
- }
338
- if (empty($_REQUEST['_wpnonce']) || !wp_verify_nonce($_REQUEST['_wpnonce'])) {
339
  return; // Unauthenticated POST data.
340
  }
341
  $args = $this->plugin->trimDeep(stripslashes_deep((array) $args));
71
  {
72
  if (!is_multisite() || !$this->plugin->currentUserCanWipeCache()) {
73
  return; // Nothing to do.
74
+ } elseif (empty($_REQUEST['_wpnonce']) || !wp_verify_nonce($_REQUEST['_wpnonce'])) {
 
75
  return; // Unauthenticated POST data.
76
  }
77
  $counter = $this->plugin->wipeCache(true);
96
  {
97
  if (!$this->plugin->currentUserCanClearCache()) {
98
  return; // Not allowed to clear.
99
+ } elseif (empty($_REQUEST['_wpnonce']) || !wp_verify_nonce($_REQUEST['_wpnonce'])) {
 
100
  return; // Unauthenticated POST data.
101
  }
102
  $counter = $this->plugin->clearCache(true);
110
  wp_redirect($redirect_to).exit();
111
  }
112
 
 
113
  /**
114
  * Action handler.
115
  *
121
  {
122
  if (!is_multisite() || !$this->plugin->currentUserCanWipeCache()) {
123
  return; // Nothing to do.
124
+ } elseif (empty($_REQUEST['_wpnonce']) || !wp_verify_nonce($_REQUEST['_wpnonce'])) {
 
125
  return; // Unauthenticated POST data.
126
  }
127
  $counter = $this->plugin->wipeCache(true);
134
  exit($response); // JavaScript will take it from here.
135
  }
136
 
 
 
137
  /**
138
  * Action handler.
139
  *
145
  {
146
  if (!$this->plugin->currentUserCanClearCache()) {
147
  return; // Not allowed to clear.
148
+ } elseif (empty($_REQUEST['_wpnonce']) || !wp_verify_nonce($_REQUEST['_wpnonce'])) {
 
149
  return; // Unauthenticated POST data.
150
  }
151
  $counter = $this->plugin->clearCache(true);
161
  exit($response); // JavaScript will take it from here.
162
  }
163
 
 
164
 
165
 
166
 
188
  */
189
  protected function saveOptions($args)
190
  {
191
+ global $is_apache, $is_nginx;
192
+
193
  if (!current_user_can($this->plugin->cap)) {
194
  return; // Nothing to do.
195
+ } elseif (empty($_REQUEST['_wpnonce']) || !wp_verify_nonce($_REQUEST['_wpnonce'])) {
 
196
  return; // Unauthenticated POST data.
197
  }
198
  if (!empty($_FILES[GLOBAL_NS]['tmp_name']['import_options'])) {
206
  unset($args['last_pro_stats_log']); // CANNOT be imported!
207
  }
208
 
209
+
210
  $args = $this->plugin->trimDeep(stripslashes_deep((array) $args));
211
  $this->plugin->updateOptions($args); // Save/update options.
212
 
213
+ // Ensures `autoCacheMaybeClearPrimaryXmlSitemapError()` always validates the XML Sitemap when saving options (when applicable).
214
  delete_transient(GLOBAL_NS.'-'.md5($this->plugin->options['auto_cache_sitemap_url']));
215
 
216
  $redirect_to = self_admin_url('/admin.php'); // Redirect preparations.
218
 
219
  $this->plugin->autoWipeCache(); // May produce a notice.
220
 
 
 
221
  if ($this->plugin->options['enable']) {
222
  if (!($add_wp_cache_to_wp_config = $this->plugin->addWpCacheToWpConfig())) {
223
  $query_args[GLOBAL_NS.'_wp_config_wp_cache_add_failure'] = '1';
225
  if ($is_apache && !($add_wp_htaccess = $this->plugin->addWpHtaccess())) {
226
  $query_args[GLOBAL_NS.'_wp_htaccess_add_failure'] = '1';
227
  }
228
+ if ($is_nginx && $this->plugin->applyWpFilters(GLOBAL_NS.'_wp_htaccess_nginx_notice', true)
229
+ && (!isset($_SERVER['WP_NGINX_CONFIG']) || $_SERVER['WP_NGINX_CONFIG'] !== 'done')) {
230
  $query_args[GLOBAL_NS.'_wp_htaccess_nginx_notice'] = '1';
231
  }
232
  if (!($add_advanced_cache = $this->plugin->addAdvancedCache())) {
233
  $query_args[GLOBAL_NS.'_advanced_cache_add_failure'] = $add_advanced_cache === null ? 'advanced-cache' : '1';
234
  }
235
+
236
  if (!$this->plugin->options['auto_cache_enable']) {
237
+ // Dismiss and check again on `admin_init` via `autoCacheMaybeClearPhpReqsError()`.
238
+ $this->plugin->dismissMainNotice('auto_cache_engine_minimum_requirements');
239
  }
240
  if (!$this->plugin->options['auto_cache_enable'] || !$this->plugin->options['auto_cache_sitemap_url']) {
241
+ // Dismiss and check again on `admin_init` via `autoCacheMaybeClearPrimaryXmlSitemapError()`.
242
+ $this->plugin->dismissMainNotice('xml_sitemap_missing');
243
  }
244
  $this->plugin->updateBlogPaths(); // Multisite networks only.
245
  } else {
252
  if (!($remove_advanced_cache = $this->plugin->removeAdvancedCache())) {
253
  $query_args[GLOBAL_NS.'_advanced_cache_remove_failure'] = '1';
254
  }
255
+ // Dismiss notice when disabling plugin.
256
+ $this->plugin->dismissMainNotice('xml_sitemap_missing');
257
+
258
+ // Dismiss notice when disabling plugin.
259
+ $this->plugin->dismissMainNotice('auto_cache_engine_minimum_requirements');
260
  }
261
  $redirect_to = add_query_arg(urlencode_deep($query_args), $redirect_to);
262
 
272
  */
273
  protected function restoreDefaultOptions($args)
274
  {
275
+ global $is_apache, $is_nginx;
276
+
277
  if (!current_user_can($this->plugin->cap)) {
278
  return; // Nothing to do.
279
+ } elseif (is_multisite() && !current_user_can($this->plugin->network_cap)) {
 
280
  return; // Nothing to do.
281
+ } elseif (empty($_REQUEST['_wpnonce']) || !wp_verify_nonce($_REQUEST['_wpnonce'])) {
 
282
  return; // Unauthenticated POST data.
283
  }
284
  $this->plugin->restoreDefaultOptions(); // Restore defaults.
285
 
286
+ $redirect_to = self_admin_url('/admin.php'); // Redirect prep.
287
  $query_args = ['page' => GLOBAL_NS, GLOBAL_NS.'_restored' => '1'];
288
 
289
  $this->plugin->autoWipeCache(); // May produce a notice.
290
 
 
 
291
  if ($this->plugin->options['enable']) {
292
  if (!($add_wp_cache_to_wp_config = $this->plugin->addWpCacheToWpConfig())) {
293
  $query_args[GLOBAL_NS.'_wp_config_wp_cache_add_failure'] = '1';
295
  if ($is_apache && !($add_wp_htaccess = $this->plugin->addWpHtaccess())) {
296
  $query_args[GLOBAL_NS.'_wp_htaccess_add_failure'] = '1';
297
  }
298
+ if ($is_nginx && $this->plugin->applyWpFilters(GLOBAL_NS.'_wp_htaccess_nginx_notice', true)
299
+ && (!isset($_SERVER['WP_NGINX_CONFIG']) || $_SERVER['WP_NGINX_CONFIG'] !== 'done')) {
300
  $query_args[GLOBAL_NS.'_wp_htaccess_nginx_notice'] = '1';
301
  }
302
  if (!($add_advanced_cache = $this->plugin->addAdvancedCache())) {
303
  $query_args[GLOBAL_NS.'_advanced_cache_add_failure'] = $add_advanced_cache === null ? 'advanced-cache' : '1';
304
  }
305
+
306
+ if (!$this->plugin->options['auto_cache_enable']) {
307
+ // Dismiss and check again on `admin_init` via `autoCacheMaybeClearPhpReqsError()`.
308
+ $this->plugin->dismissMainNotice('auto_cache_engine_minimum_requirements');
309
+ }
310
+ if (!$this->plugin->options['auto_cache_enable'] || !$this->plugin->options['auto_cache_sitemap_url']) {
311
+ // Dismiss and check again on `admin_init` via `autoCacheMaybeClearPrimaryXmlSitemapError()`.
312
+ $this->plugin->dismissMainNotice('xml_sitemap_missing');
313
+ }
314
  $this->plugin->updateBlogPaths(); // Multisite networks only.
315
  } else {
316
  if (!($remove_wp_cache_from_wp_config = $this->plugin->removeWpCacheFromWpConfig())) {
322
  if (!($remove_advanced_cache = $this->plugin->removeAdvancedCache())) {
323
  $query_args[GLOBAL_NS.'_advanced_cache_remove_failure'] = '1';
324
  }
325
+ // Dismiss notice when disabling plugin.
326
+ $this->plugin->dismissMainNotice('xml_sitemap_missing');
327
+
328
+ // Dismiss notice when disabling plugin.
329
+ $this->plugin->dismissMainNotice('auto_cache_engine_minimum_requirements');
330
  }
331
  $redirect_to = add_query_arg(urlencode_deep($query_args), $redirect_to);
332
 
346
  {
347
  if (!current_user_can($this->plugin->cap)) {
348
  return; // Nothing to do.
349
+ } elseif (empty($_REQUEST['_wpnonce']) || !wp_verify_nonce($_REQUEST['_wpnonce'])) {
 
350
  return; // Unauthenticated POST data.
351
  }
352
  $args = $this->plugin->trimDeep(stripslashes_deep((array) $args));
src/includes/classes/ApiBase.php CHANGED
@@ -44,6 +44,8 @@ class ApiBase
44
  return $GLOBALS[GLOBAL_NS]->options;
45
  }
46
 
 
 
47
  /**
48
  * Purges expired cache files, leaving all others intact.
49
  *
44
  return $GLOBALS[GLOBAL_NS]->options;
45
  }
46
 
47
+
48
+
49
  /**
50
  * Purges expired cache files, leaving all others intact.
51
  *
src/includes/classes/MenuPageOptions.php CHANGED
@@ -163,6 +163,11 @@ class MenuPageOptions extends MenuPage
163
  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>.', 'comet-cache')."\n";
164
  echo '</div>'."\n";
165
  }
 
 
 
 
 
166
  if (!IS_PRO && $this->plugin->isProPreview()) {
167
  echo '<div class="plugin-menu-page-notice info">'."\n";
168
  echo '<a href="'.add_query_arg(urlencode_deep(['page' => 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', 'comet-cache').' <i class="si si-eye-slash"></i></a>'."\n";
@@ -234,10 +239,19 @@ class MenuPageOptions extends MenuPage
234
  echo ' <h3>'.sprintf(__('License Key', 'comet-cache'), esc_html(NAME)).'</h3>'."\n";
235
  echo ' <p><input type="password" name="'.esc_attr(GLOBAL_NS).'[saveOptions][pro_update_password]" value="'.esc_attr($this->plugin->options['pro_update_password']).'" autocomplete="new-password" /></p>'."\n";
236
 
 
 
 
 
 
 
 
 
 
 
237
  echo ' <hr />'."\n";
238
  echo ' <h3>'.__('Beta Program', 'comet-cache').'</h3>'."\n";
239
  echo ' <p>'.sprintf(__('If you would like to participate in our beta program and receive new features and bug fixes before they are released to the public, %1$s can include Release Candidates when checking for automatic updates. Release Candidates are almost-ready-for-production and have already been through many internal test runs. Our team runs the latest Release Candidate on all of our production sites, but that doesn\'t mean you\'ll want to do the same. :-) Please report any issues with Release Candidates on <a href="https://github.com/websharks/comet-cache/issues/" target="_blank">GitHub</a>.', 'comet-cache'), esc_html(NAME)).'</p>'."\n";
240
-
241
  echo ' <p><select name="'.esc_attr(GLOBAL_NS).'[saveOptions][pro_update_check_stable]" autocomplete="off">'."\n";
242
  echo ' <option value="1"'.selected($this->plugin->options['pro_update_check_stable'], '1', false).'>'.sprintf(__('No, do not check for Release Candidates; I only want public releases.', 'comet-cache'), esc_html(NAME)).'</option>'."\n";
243
  echo ' <option value="0"'.selected($this->plugin->options['pro_update_check_stable'], '0', false).'>'.sprintf(__('Yes, check for Release Candidates; I want to help with testing.', 'comet-cache'), esc_html(NAME)).'</option>'."\n";
@@ -306,7 +320,6 @@ class MenuPageOptions extends MenuPage
306
  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="http://cometcache.com/r/wp-roles-caps/" 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.', 'comet-cache'), esc_html(NAME)).'</p>'."\n";
307
  echo ' <p style="margin-bottom:0;"><input type="text" name="'.esc_attr(GLOBAL_NS).'[saveOptions][cache_clear_admin_bar_roles_caps]" value="'.esc_attr($this->plugin->options['cache_clear_admin_bar_roles_caps']).'" /></p>'."\n";
308
  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>.', 'comet-cache'), esc_html(IS_PRO ? $this->plugin->clear_min_cap : 'edit_posts')).'</p>'."\n";
309
- echo ' </select></p>'."\n";
310
  echo ' </div>'."\n";
311
  } else {
312
  echo ' <div class="plugin-menu-page-panel-if-enabled -cache-clear-admin-bar-roles-caps">'."\n";
@@ -314,7 +327,6 @@ class MenuPageOptions extends MenuPage
314
  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="http://cometcache.com/r/wp-roles-caps/" 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.', 'comet-cache'), esc_html(NAME)).'</p>'."\n";
315
  echo ' <p style="margin-bottom:0;"><input type="text" name="'.esc_attr(GLOBAL_NS).'[saveOptions][cache_clear_admin_bar_roles_caps]" value="'.esc_attr($this->plugin->options['cache_clear_admin_bar_roles_caps']).'" /></p>'."\n";
316
  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>.', 'comet-cache'), esc_html(IS_PRO ? $this->plugin->clear_min_cap : 'edit_posts')).'</p>'."\n";
317
- echo ' </select></p>'."\n";
318
  echo ' </div>'."\n";
319
  }
320
  if ($this->plugin->functionIsPossible('opcache_reset')) {
@@ -447,7 +459,7 @@ class MenuPageOptions extends MenuPage
447
  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.', 'comet-cache').'</option>'."\n";
448
  echo ' </select></p>'."\n";
449
  echo ' <div class="plugin-menu-page-panel-if-enabled -cache-clear-xml-sitemap-patterns">'."\n";
450
- echo ' <p>'.__('<strong style="font-size:110%;">XML Sitemap Patterns...</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. <strong>Please list one pattern per line.</strong> These 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> character can also be used when necessary; e.g., <code>/sitemap**.xml</code> (where <code>**</code> = 0 or more characters of any kind, including <code>/</code> slashes). Other special characters include: <code>*</code> = 0 or more characters that are NOT a slash <code>/</code>; <code>^</code> = beginning of the string; <code>$</code> = end of the string. To learn more about this syntax, please see <a href="http://cometcache.com/r/watered-down-regex-syntax/" target="_blank">this KB article</a>.', 'comet-cache').'</p>'."\n";
451
  echo ' <p><textarea name="'.esc_attr(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";
452
  if (is_multisite()) {
453
  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.', 'comet-cache').'</p>'."\n";
@@ -457,10 +469,10 @@ class MenuPageOptions extends MenuPage
457
  if (IS_PRO || $this->plugin->isProPreview()) {
458
  echo ' <hr />'."\n";
459
  echo ' <h3 data-pro-version-only="'.(!IS_PRO ? __('pro version only', 'comet-cache') : '').'">'.__('Misc. Auto-Clear Options', 'comet-cache').'</h3>'."\n";
460
- echo ' <h4 style="margin-bottom:0;">'.__('Auto-Clear a List of Custom URLs Too?', 'comet-cache').'</h4>'."\n";
461
- echo ' <p style="margin-top:2px;">'.sprintf(__('When you update a Post/Page, approve a Comment, or make other changes where %1$s can detect that a Post/Page cache should be cleared to keep your site up-to-date; then %1$s will also clear a list of custom URLs that you list here. <strong>Please list one URL per line.</strong> A wildcard <code>*</code> character can also be used when necessary; e.g., <code>https://example.com/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 ="http://cometcache.com/r/watered-down-regex-syntax/" target="_blank">this KB article</a>.', 'comet-cache'), esc_html(NAME)).'</p>'."\n";
462
  echo ' <p><textarea name="'.esc_attr(GLOBAL_NS).'[saveOptions][cache_clear_urls]" spellcheck="false" wrap="off" rows="5">'.format_to_edit($this->plugin->options['cache_clear_urls']).'</textarea></p>'."\n";
463
- 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.', 'comet-cache').'</p>'."\n";
464
  }
465
  echo ' </div>'."\n";
466
 
@@ -501,7 +513,6 @@ class MenuPageOptions extends MenuPage
501
  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="http://cometcache.com/r/wp-roles-caps/" 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.', 'comet-cache'), esc_html(NAME)).'</p>'."\n";
502
  echo ' <p style="margin-bottom:0;"><input type="text" name="'.esc_attr(GLOBAL_NS).'[saveOptions][stats_admin_bar_roles_caps]" value="'.esc_attr($this->plugin->options['stats_admin_bar_roles_caps']).'" /></p>'."\n";
503
  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>.', 'comet-cache'), esc_html(IS_PRO ? $this->plugin->stats_min_cap : 'edit_posts')).'</p>'."\n";
504
- echo ' </select></p>'."\n";
505
  echo ' </div>'."\n";
506
  } else {
507
  echo ' <div class="plugin-menu-page-panel-if-enabled -stats-admin-bar-roles-caps">'."\n";
@@ -509,7 +520,6 @@ class MenuPageOptions extends MenuPage
509
  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="http://cometcache.com/r/wp-roles-caps/" 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.', 'comet-cache'), esc_html(NAME)).'</p>'."\n";
510
  echo ' <p style="margin-bottom:0;"><input type="text" name="'.esc_attr(GLOBAL_NS).'[saveOptions][stats_admin_bar_roles_caps]" value="'.esc_attr($this->plugin->options['stats_admin_bar_roles_caps']).'" /></p>'."\n";
511
  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>.', 'comet-cache'), esc_html(IS_PRO ? $this->plugin->stats_min_cap : 'edit_posts')).'</p>'."\n";
512
- echo ' </select></p>'."\n";
513
  echo ' </div>'."\n";
514
  }
515
  echo ' </div>'."\n";
@@ -941,6 +951,10 @@ class MenuPageOptions extends MenuPage
941
  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.', 'comet-cache').'</option>'."\n";
942
  echo ' <option value="0"'.selected($this->plugin->options['htmlc_compress_html_code'], '0', false).'>'.__('No, do not compress the final HTML code.', 'comet-cache').'</option>'."\n";
943
  echo ' </select></p>'."\n";
 
 
 
 
944
  echo ' <hr />'."\n";
945
  echo ' <h3>'.__('CSS Exclusion Patterns?', 'comet-cache').'</h3>'."\n";
946
  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 ="http://cometcache.com/r/watered-down-regex-syntax/" target="_blank">this KB article</a>.', 'comet-cache').'</p>'."\n";
@@ -1102,7 +1116,6 @@ class MenuPageOptions extends MenuPage
1102
  echo ' <hr />'."\n";
1103
  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!', 'comet-cache'), esc_attr(add_query_arg(urlencode_deep(['page' => GLOBAL_NS, GLOBAL_NS.'_pro_preview' => '1']), self_admin_url('/admin.php')))).'</p>'."\n";
1104
  }
1105
-
1106
  if (IS_PRO || $this->plugin->isProPreview()) {
1107
  echo ' <hr />'."\n";
1108
  echo ' <h3 data-pro-version-only="'.(!IS_PRO ? __('pro version only', 'comet-cache') : '').'">'.__('Leverage Browser Caching?', 'comet-cache').'</h3>'."\n";
@@ -1118,7 +1131,6 @@ class MenuPageOptions extends MenuPage
1118
  echo ' <pre class="code"><code>'.esc_html($this->plugin->fillReplacementCodes(file_get_contents(dirname(__DIR__).'/templates/htaccess/browser-caching-enable.txt'))).'</code></pre>'."\n";
1119
  echo ' </div>'."\n";
1120
  }
1121
-
1122
  if ((IS_PRO && !empty($GLOBALS['wp_rewrite']->permalink_structure)) || $this->plugin->isProPreview()) {
1123
  echo ' <hr />'."\n";
1124
  echo ' <h3 data-pro-version-only="'.(!IS_PRO ? __('pro version only', 'comet-cache') : '').'">'.__('Enforce Canonical URLs?', 'comet-cache').'</h3>'."\n";
@@ -1137,7 +1149,6 @@ class MenuPageOptions extends MenuPage
1137
  }
1138
  echo ' </div>'."\n";
1139
  }
1140
-
1141
  if ((IS_PRO && $this->plugin->options['cdn_enable']) || $this->plugin->isProPreview()) {
1142
  echo ' <hr />'."\n";
1143
  echo ' <h3 data-pro-version-only="'.(!IS_PRO ? __('pro version only', 'comet-cache') : '').'">'.__('Send Access-Control-Allow-Origin Header?', 'comet-cache').'</h3>'."\n";
@@ -1158,8 +1169,52 @@ class MenuPageOptions extends MenuPage
1158
  echo ' </div>'."\n";
1159
  echo '</div>'."\n";
1160
  }
 
 
 
 
1161
 
1162
- /* ----------------------------------------------------------------------------------------- */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1163
 
1164
  if (IS_PRO || $this->plugin->isProPreview()) {
1165
  echo '<div class="plugin-menu-page-panel'.(!IS_PRO ? ' pro-preview' : '').'">'."\n";
163
  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>.', 'comet-cache')."\n";
164
  echo '</div>'."\n";
165
  }
166
+ if (!empty($_REQUEST[GLOBAL_NS.'_ua_info_dir_population_failure'])) {
167
+ echo '<div class="plugin-menu-page-notice error">'."\n";
168
+ 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.', 'comet-cache'), esc_html(NAME))."\n";
169
+ echo '</div>'."\n";
170
+ }
171
  if (!IS_PRO && $this->plugin->isProPreview()) {
172
  echo '<div class="plugin-menu-page-notice info">'."\n";
173
  echo '<a href="'.add_query_arg(urlencode_deep(['page' => 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', 'comet-cache').' <i class="si si-eye-slash"></i></a>'."\n";
239
  echo ' <h3>'.sprintf(__('License Key', 'comet-cache'), esc_html(NAME)).'</h3>'."\n";
240
  echo ' <p><input type="password" name="'.esc_attr(GLOBAL_NS).'[saveOptions][pro_update_password]" value="'.esc_attr($this->plugin->options['pro_update_password']).'" autocomplete="new-password" /></p>'."\n";
241
 
242
+ if ((!defined('DISALLOW_FILE_MODS') || !DISALLOW_FILE_MODS) && !apply_filters('automatic_updater_disabled', defined('AUTOMATIC_UPDATER_DISABLED') && AUTOMATIC_UPDATER_DISABLED)) {
243
+ // See: <http://jas.xyz/2gFcnPd> and note that `automatic_updater_disabled` is a core filter.
244
+ echo ' <hr />'."\n";
245
+ echo ' <h3>'.__('Automatic Background Updates', 'comet-cache').'</h3>'."\n";
246
+ echo ' <p>'.sprintf(__('Enable this if you\'d like %1$s to download and install bug fixes and security updates automatically in the background. Requires a valid license key in the field above.', 'comet-cache'), esc_html(NAME)).'</p>'."\n";
247
+ echo ' <p><select name="'.esc_attr(GLOBAL_NS).'[saveOptions][pro_auto_update_enable]" autocomplete="off">'."\n";
248
+ echo ' <option value="0"'.selected($this->plugin->options['pro_auto_update_enable'], '0', false).'>'.sprintf(__('No, I\'ll wait for an update notification in my dashboard.', 'comet-cache'), esc_html(NAME)).'</option>'."\n";
249
+ echo ' <option value="1"'.selected($this->plugin->options['pro_auto_update_enable'], '1', false).'>'.sprintf(__('Yes, enable automatic background updates.', 'comet-cache'), esc_html(NAME)).'</option>'."\n";
250
+ echo ' </select></p>'."\n";
251
+ }
252
  echo ' <hr />'."\n";
253
  echo ' <h3>'.__('Beta Program', 'comet-cache').'</h3>'."\n";
254
  echo ' <p>'.sprintf(__('If you would like to participate in our beta program and receive new features and bug fixes before they are released to the public, %1$s can include Release Candidates when checking for automatic updates. Release Candidates are almost-ready-for-production and have already been through many internal test runs. Our team runs the latest Release Candidate on all of our production sites, but that doesn\'t mean you\'ll want to do the same. :-) Please report any issues with Release Candidates on <a href="https://github.com/websharks/comet-cache/issues/" target="_blank">GitHub</a>.', 'comet-cache'), esc_html(NAME)).'</p>'."\n";
 
255
  echo ' <p><select name="'.esc_attr(GLOBAL_NS).'[saveOptions][pro_update_check_stable]" autocomplete="off">'."\n";
256
  echo ' <option value="1"'.selected($this->plugin->options['pro_update_check_stable'], '1', false).'>'.sprintf(__('No, do not check for Release Candidates; I only want public releases.', 'comet-cache'), esc_html(NAME)).'</option>'."\n";
257
  echo ' <option value="0"'.selected($this->plugin->options['pro_update_check_stable'], '0', false).'>'.sprintf(__('Yes, check for Release Candidates; I want to help with testing.', 'comet-cache'), esc_html(NAME)).'</option>'."\n";
320
  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="http://cometcache.com/r/wp-roles-caps/" 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.', 'comet-cache'), esc_html(NAME)).'</p>'."\n";
321
  echo ' <p style="margin-bottom:0;"><input type="text" name="'.esc_attr(GLOBAL_NS).'[saveOptions][cache_clear_admin_bar_roles_caps]" value="'.esc_attr($this->plugin->options['cache_clear_admin_bar_roles_caps']).'" /></p>'."\n";
322
  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>.', 'comet-cache'), esc_html(IS_PRO ? $this->plugin->clear_min_cap : 'edit_posts')).'</p>'."\n";
 
323
  echo ' </div>'."\n";
324
  } else {
325
  echo ' <div class="plugin-menu-page-panel-if-enabled -cache-clear-admin-bar-roles-caps">'."\n";
327
  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="http://cometcache.com/r/wp-roles-caps/" 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.', 'comet-cache'), esc_html(NAME)).'</p>'."\n";
328
  echo ' <p style="margin-bottom:0;"><input type="text" name="'.esc_attr(GLOBAL_NS).'[saveOptions][cache_clear_admin_bar_roles_caps]" value="'.esc_attr($this->plugin->options['cache_clear_admin_bar_roles_caps']).'" /></p>'."\n";
329
  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>.', 'comet-cache'), esc_html(IS_PRO ? $this->plugin->clear_min_cap : 'edit_posts')).'</p>'."\n";
 
330
  echo ' </div>'."\n";
331
  }
332
  if ($this->plugin->functionIsPossible('opcache_reset')) {
459
  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.', 'comet-cache').'</option>'."\n";
460
  echo ' </select></p>'."\n";
461
  echo ' <div class="plugin-menu-page-panel-if-enabled -cache-clear-xml-sitemap-patterns">'."\n";
462
+ 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="http://cometcache.com/r/watered-down-regex-syntax/" target="_blank">this KB article</a>.', 'comet-cache').'</p>'."\n";
463
  echo ' <p><textarea name="'.esc_attr(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";
464
  if (is_multisite()) {
465
  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.', 'comet-cache').'</p>'."\n";
469
  if (IS_PRO || $this->plugin->isProPreview()) {
470
  echo ' <hr />'."\n";
471
  echo ' <h3 data-pro-version-only="'.(!IS_PRO ? __('pro version only', 'comet-cache') : '').'">'.__('Misc. Auto-Clear Options', 'comet-cache').'</h3>'."\n";
472
+ echo ' <h4 style="margin-bottom:0;">'.__('Auto-Clear Custom URL Patterns Too?', 'comet-cache').'</h4>'."\n";
473
+ 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="http://cometcache.com/r/watered-down-regex-syntax/" target="_blank">this KB article</a>.', 'comet-cache'), esc_html(NAME)).'</p>'."\n";
474
  echo ' <p><textarea name="'.esc_attr(GLOBAL_NS).'[saveOptions][cache_clear_urls]" spellcheck="false" wrap="off" rows="5">'.format_to_edit($this->plugin->options['cache_clear_urls']).'</textarea></p>'."\n";
475
+ 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).', 'comet-cache').'</p>'."\n";
476
  }
477
  echo ' </div>'."\n";
478
 
513
  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="http://cometcache.com/r/wp-roles-caps/" 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.', 'comet-cache'), esc_html(NAME)).'</p>'."\n";
514
  echo ' <p style="margin-bottom:0;"><input type="text" name="'.esc_attr(GLOBAL_NS).'[saveOptions][stats_admin_bar_roles_caps]" value="'.esc_attr($this->plugin->options['stats_admin_bar_roles_caps']).'" /></p>'."\n";
515
  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>.', 'comet-cache'), esc_html(IS_PRO ? $this->plugin->stats_min_cap : 'edit_posts')).'</p>'."\n";
 
516
  echo ' </div>'."\n";
517
  } else {
518
  echo ' <div class="plugin-menu-page-panel-if-enabled -stats-admin-bar-roles-caps">'."\n";
520
  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="http://cometcache.com/r/wp-roles-caps/" 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.', 'comet-cache'), esc_html(NAME)).'</p>'."\n";
521
  echo ' <p style="margin-bottom:0;"><input type="text" name="'.esc_attr(GLOBAL_NS).'[saveOptions][stats_admin_bar_roles_caps]" value="'.esc_attr($this->plugin->options['stats_admin_bar_roles_caps']).'" /></p>'."\n";
522
  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>.', 'comet-cache'), esc_html(IS_PRO ? $this->plugin->stats_min_cap : 'edit_posts')).'</p>'."\n";
 
523
  echo ' </div>'."\n";
524
  }
525
  echo ' </div>'."\n";
951
  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.', 'comet-cache').'</option>'."\n";
952
  echo ' <option value="0"'.selected($this->plugin->options['htmlc_compress_html_code'], '0', false).'>'.__('No, do not compress the final HTML code.', 'comet-cache').'</option>'."\n";
953
  echo ' </select></p>'."\n";
954
+ echo ' <p><select name="'.esc_attr(GLOBAL_NS).'[saveOptions][htmlc_amp_exclusions_enable]" autocomplete="off">'."\n";
955
+ 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.', 'comet-cache').'</option>'."\n";
956
+ 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', 'comet-cache').'</option>'."\n";
957
+ echo ' </select></p>'."\n";
958
  echo ' <hr />'."\n";
959
  echo ' <h3>'.__('CSS Exclusion Patterns?', 'comet-cache').'</h3>'."\n";
960
  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 ="http://cometcache.com/r/watered-down-regex-syntax/" target="_blank">this KB article</a>.', 'comet-cache').'</p>'."\n";
1116
  echo ' <hr />'."\n";
1117
  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!', 'comet-cache'), esc_attr(add_query_arg(urlencode_deep(['page' => GLOBAL_NS, GLOBAL_NS.'_pro_preview' => '1']), self_admin_url('/admin.php')))).'</p>'."\n";
1118
  }
 
1119
  if (IS_PRO || $this->plugin->isProPreview()) {
1120
  echo ' <hr />'."\n";
1121
  echo ' <h3 data-pro-version-only="'.(!IS_PRO ? __('pro version only', 'comet-cache') : '').'">'.__('Leverage Browser Caching?', 'comet-cache').'</h3>'."\n";
1131
  echo ' <pre class="code"><code>'.esc_html($this->plugin->fillReplacementCodes(file_get_contents(dirname(__DIR__).'/templates/htaccess/browser-caching-enable.txt'))).'</code></pre>'."\n";
1132
  echo ' </div>'."\n";
1133
  }
 
1134
  if ((IS_PRO && !empty($GLOBALS['wp_rewrite']->permalink_structure)) || $this->plugin->isProPreview()) {
1135
  echo ' <hr />'."\n";
1136
  echo ' <h3 data-pro-version-only="'.(!IS_PRO ? __('pro version only', 'comet-cache') : '').'">'.__('Enforce Canonical URLs?', 'comet-cache').'</h3>'."\n";
1149
  }
1150
  echo ' </div>'."\n";
1151
  }
 
1152
  if ((IS_PRO && $this->plugin->options['cdn_enable']) || $this->plugin->isProPreview()) {
1153
  echo ' <hr />'."\n";
1154
  echo ' <h3 data-pro-version-only="'.(!IS_PRO ? __('pro version only', 'comet-cache') : '').'">'.__('Send Access-Control-Allow-Origin Header?', 'comet-cache').'</h3>'."\n";
1169
  echo ' </div>'."\n";
1170
  echo '</div>'."\n";
1171
  }
1172
+ /* ----------------------------------------------------------------------------------------- */
1173
+
1174
+ if (IS_PRO || $this->plugin->isProPreview()) {
1175
+ echo '<div class="plugin-menu-page-panel'.(!IS_PRO ? ' pro-preview' : '').'">'."\n";
1176
 
1177
+ echo ' <a href="#" class="plugin-menu-page-panel-heading" data-pro-version-only="'.(!IS_PRO ? __('pro version only', 'comet-cache') : '').'">'."\n";
1178
+ echo ' <i class="si si-tablet"></i> '.__('Mobile Mode', 'comet-cache')."\n";
1179
+ echo ' </a>'."\n";
1180
+
1181
+ echo ' <div class="plugin-menu-page-panel-body clearfix">'."\n";
1182
+ echo ' <h3>'.__('<i class="si si-tablet"></i> <i class="si si-mobile"></i> Enable Mobile-Adaptive Mode?', 'comet-cache').'</h3>'."\n";
1183
+ echo ' <p>'.__('<em><strong>Tip:</strong> Generally speaking, you should only enable this if your WordPress theme uses an \'Adaptive\' design, as opposed to a design that\'s \'Responsive\'—the way most WordPress themes are built.', 'comet-cache').'</em></p>'."\n";
1184
+ echo ' <p><select name="'.esc_attr(GLOBAL_NS).'[saveOptions][mobile_adaptive_salt_enable]" data-target=".-mobile-adaptive-options">'."\n";
1185
+ echo ' <option value="0"'.(!IS_PRO ? '' : selected($this->plugin->options['mobile_adaptive_salt_enable'], '0', false)).'>'.__('No, my theme is Responsive; i.e., not Adaptive.', 'comet-cache').'</option>'."\n";
1186
+ echo ' <option value="1"'.(!IS_PRO ? ' selected' : selected($this->plugin->options['mobile_adaptive_salt_enable'], '1', false)).'>'.__('Yes, create multiple cache variations based on mobile device type.', 'comet-cache').'</option>'."\n";
1187
+ echo ' </select></p>'."\n";
1188
+
1189
+ if (!version_compare(PHP_VERSION, '5.6', '>=')) {
1190
+ echo '<p class="error">'.sprintf(__('<strong>PHP Version:</strong> This feature requires PHP v5.6 (or higher). You\'re currently running PHP v%1$s. Please contact your web hosting company for assistance.', 'comet-cache'), esc_html(PHP_VERSION)).'</p>'."\n";
1191
+ }
1192
+
1193
+ echo ' <h4 style="margin-bottom:0;">'.__('What\'s the Difference Between Responsive and Adaptive?', 'comet-cache').'</h4>'."\n";
1194
+ echo ' <p>'.__('Responsive and Adaptive designs both attempt to optimize the user experience across different devices, adjusting for different viewport sizes, resolutions, usage contexts, control mechanisms, and so on. Responsive design (common for WordPress sites) works on the principle of flexibility — a single fluid website that can look good on any device. Responsive websites use media queries, flexible grids, and responsive images to create a user experience that flexes and changes based on a multitude of factors. If you have a Responsive theme, you probably do NOT need to enable Mobile-Adaptive Mode.', 'comet-cache').'</p>'."\n";
1195
+ echo ' <p>'.sprintf(__('<strong>Adaptive design</strong> detects the device and other features, and then it provides the appropriate feature and layout based on a predefined set of viewport sizes and other characteristics. Adaptive themes generally decide what to display based on a visitor\'s User-Agent (i.e., OS, device, browser, version). Since this design choice results in multiple versions of a page being served to visitors, based on the device they access the site with, it then becomes important to cache each of those variations separately. That way a visitor on an iPhone isn\'t accidentally shown the cached copy of a page that was originally viewed by another visitor who was on a desktop computer. If your theme uses an Adaptive design, you probably DO want to enable Mobile-Adaptive Mode in %1$s.', 'comet-cache'), esc_html(NAME)).'</p>'."\n";
1196
+
1197
+ echo ' <div class="plugin-menu-page-panel-if-enabled -mobile-adaptive-options"><hr />'."\n";
1198
+ echo ' <h3>'.__('Mobile-Adaptive Tokens', 'comet-cache').'</h3>'."\n";
1199
+ echo ' <p>'.sprintf(__('When %1$s runs in Mobile-Adaptive Mode and it detects that a device is Mobile (e.g., a phone, tablet), it needs to know which factors you\'d like to consider. Mobile-Adaptive Tokens make this easy. In the field below, please configure a list of Mobile-Adaptive Tokens that establish the important factors on your site. Each token must be separated by a <code>+</code> sign. You can use just one, or use them all. <strong>However, it\'s IMPORTANT to note:</strong> With each new token, you add additional permutations that can fragment the cache and eat up a lot of disk space. Enable and monitor Cache Statistics so you can keep an eye on this. See: <strong>%1$s → Plugin Options → Cache-Related Statistics</strong>', 'comet-cache'), esc_html(NAME)).'</p>'."\n";
1200
+ echo ' <p>'.__('The available Tokens are as follows:', 'comet-cache').'</p>'."\n";
1201
+ echo ' <ul style="list-style-type:disc; margin-left: 1.5em;">'."\n";
1202
+ echo ' <li>'.__('<code>os.name</code> <small><em>This token is replaced automatically with: <tt>iOS</tt>, <tt>Android</tt>, etc.</em></small>', 'comet-cache').'</li>'."\n";
1203
+ echo ' <li>'.__('<code>device.type</code> <small><em>This token is replaced with: <tt>Tablet</tt>, <tt>Mobile Device</tt>, <tt>Mobile Phone</tt>, etc.</em></small>', 'comet-cache').'</li>'."\n";
1204
+ echo ' <li>'.__('<code>browser.name</code> <small><em>This token is replaced with: <tt>Safari</tt>, <tt>Mobile Safari UIWebView</tt>, <tt>Chrome</tt>, etc.</small></em>', 'comet-cache').'</li>'."\n";
1205
+ echo ' <li>'.__('<code>browser.version</code> <small><em>Major &amp; minor version. Not recommended, many permutations. Replaced with: <tt>55.0</tt>, <tt>1.3</tt>, <tt>9383242.2392</tt>, etc.</em></small>', 'comet-cache').'</li>'."\n";
1206
+ echo ' <li>'.__('<code>browser.version.major</code> <small><em>Major version only. More feasible, fewer permutations. Replaced with: <tt>55</tt>, <tt>1</tt>, <tt>9383242</tt>, etc.</em></small>', 'comet-cache').'</li>'."\n";
1207
+ echo ' </ul>'."\n";
1208
+ echo ' <p><input type="text" id="'.esc_attr(GLOBAL_NS.'-mobile-adaptive-salt').'" name="'.esc_attr(GLOBAL_NS).'[saveOptions][mobile_adaptive_salt]" value="'.esc_attr($this->plugin->options['mobile_adaptive_salt']).'" /></p>'."\n";
1209
+ echo ' <p>'.sprintf(__('The suggested default value is: <code>%2$s</code><br />However, just: <code>os.name + device.type</code> is better, if that will do.', 'comet-cache'), esc_html(NAME), esc_html($this->plugin->default_options['mobile_adaptive_salt'])).'</p>'."\n";
1210
+ echo ' <p class="info">'.__('The special token: <code>device.is_mobile</code> (i.e., any mobile device, including tablets, excluding laptops) can be used by itself. For example, if you simply want to break the cache down into mobile vs. NOT mobile.', 'comet-cache').'</p>'."\n";
1211
+ echo ' <p><small><em>'.sprintf(__('<strong>Note:</strong> The underlying logic behind mobile detection is accomplished using a faster, precompiled version of <a href="https://cometcache.com/r/browscap/" target="_blank">Browscap Lite</a>, and Browcap data is automatically updated (and recompiled) whenever you save %1$s options and/or when upgrading %1$s to a new version.', 'comet-cache'), esc_html(NAME)).'</em></small></p>'."\n";
1212
+ echo ' </div>'."\n";
1213
+
1214
+ echo ' </div>'."\n";
1215
+ echo '</div>'."\n";
1216
+ }
1217
+ /* ----------------------------------------------------------------------------------------- */
1218
 
1219
  if (IS_PRO || $this->plugin->isProPreview()) {
1220
  echo '<div class="plugin-menu-page-panel'.(!IS_PRO ? ' pro-preview' : '').'">'."\n";
src/includes/classes/Plugin.php CHANGED
@@ -51,7 +51,7 @@ class Plugin extends AbsBaseAp
51
  *
52
  * @since 150422 Rewrite.
53
  *
54
- * @var bool If `FALSE`, run without hooks.
55
  */
56
  public $enable_hooks = true;
57
 
@@ -60,7 +60,7 @@ class Plugin extends AbsBaseAp
60
  *
61
  * @since 150422 Rewrite.
62
  *
63
- * @var array Pro-only option keys.
64
  */
65
  public $pro_only_option_keys = [];
66
 
@@ -69,7 +69,7 @@ class Plugin extends AbsBaseAp
69
  *
70
  * @since 150422 Rewrite.
71
  *
72
- * @var array Default options.
73
  */
74
  public $default_options = [];
75
 
@@ -78,7 +78,7 @@ class Plugin extends AbsBaseAp
78
  *
79
  * @since 150422 Rewrite.
80
  *
81
- * @var array Configured options.
82
  */
83
  public $options = [];
84
 
@@ -87,7 +87,7 @@ class Plugin extends AbsBaseAp
87
  *
88
  * @since 150422 Rewrite.
89
  *
90
- * @var string WordPress capability.
91
  */
92
  public $cap = 'activate_plugins';
93
 
@@ -96,7 +96,7 @@ class Plugin extends AbsBaseAp
96
  *
97
  * @since 150422 Rewrite.
98
  *
99
- * @var string WordPress capability.
100
  */
101
  public $update_cap = 'update_plugins';
102
 
@@ -105,7 +105,7 @@ class Plugin extends AbsBaseAp
105
  *
106
  * @since 150422 Rewrite.
107
  *
108
- * @var string WordPress capability.
109
  */
110
  public $network_cap = 'manage_network_plugins';
111
 
@@ -114,7 +114,7 @@ class Plugin extends AbsBaseAp
114
  *
115
  * @since 150422 Rewrite.
116
  *
117
- * @var string WordPress capability.
118
  */
119
  public $uninstall_cap = 'delete_plugins';
120
 
@@ -127,7 +127,7 @@ class Plugin extends AbsBaseAp
127
  *
128
  * @since 150422 Rewrite.
129
  *
130
- * @var string Cache directory; relative to the configured base directory.
131
  */
132
  public $cache_sub_dir = 'cache';
133
 
@@ -135,6 +135,8 @@ class Plugin extends AbsBaseAp
135
 
136
 
137
 
 
 
138
  /**
139
  * Plugin constructor.
140
  *
@@ -196,6 +198,9 @@ class Plugin extends AbsBaseAp
196
  'when_logged_in',
197
 
198
  'version_salt',
 
 
 
199
 
200
  'htmlc_enable',
201
  'htmlc_css_exclusions',
@@ -210,6 +215,7 @@ class Plugin extends AbsBaseAp
210
  'htmlc_compress_css_code',
211
  'htmlc_compress_js_code',
212
  'htmlc_compress_html_code',
 
213
  'htmlc_when_logged_in',
214
 
215
  'auto_cache_enable',
@@ -254,6 +260,8 @@ class Plugin extends AbsBaseAp
254
  'pro_update_username',
255
  'pro_update_password',
256
 
 
 
257
  'last_pro_stats_log',
258
  ];
259
  $this->default_options = [
@@ -335,7 +343,14 @@ class Plugin extends AbsBaseAp
335
 
336
  /* Related to version salt. */
337
 
338
- 'version_salt' => '', // Any string value.
 
 
 
 
 
 
 
339
 
340
  /* Related to HTML compressor. */
341
 
@@ -356,6 +371,7 @@ class Plugin extends AbsBaseAp
356
  'htmlc_compress_css_code' => '1', // `0|1`.
357
  'htmlc_compress_js_code' => '1', // `0|1`.
358
  'htmlc_compress_html_code' => '1', // `0|1`.
 
359
  'htmlc_when_logged_in' => '0', // `0|1`; enable when logged in?
360
 
361
  /* Related to auto-cache engine. */
@@ -427,6 +443,8 @@ class Plugin extends AbsBaseAp
427
  'pro_update_username' => '', // Username.
428
  'pro_update_password' => '', // Password or license key.
429
 
 
 
430
  /* Related to stats logging. */
431
 
432
  'last_pro_stats_log' => '0', // Timestamp.
@@ -494,6 +512,7 @@ class Plugin extends AbsBaseAp
494
  add_action('wp_create_nav_menu', [$this, 'autoClearCache']);
495
  add_action('wp_update_nav_menu', [$this, 'autoClearCache']);
496
  add_action('wp_delete_nav_menu', [$this, 'autoClearCache']);
 
497
 
498
  add_action('save_post', [$this, 'autoClearPostCache']);
499
  add_action('delete_post', [$this, 'autoClearPostCache']);
@@ -523,6 +542,9 @@ class Plugin extends AbsBaseAp
523
 
524
 
525
 
 
 
 
526
  if ($this->options['enable'] && $this->applyWpFilters(GLOBAL_NS.'_disable_akismet_comment_nonce', true)) {
527
  add_filter('akismet_comment_nonce', function () {
528
  return 'disabled-by-'.SLUG_TD; // MUST return a string literal that is not 'true' or '' (an empty string). See <http://bit.ly/1YItpdE>
@@ -530,6 +552,7 @@ class Plugin extends AbsBaseAp
530
  }
531
 
532
 
 
533
  /* -------------------------------------------------------------- */
534
 
535
  if (!is_multisite() || is_main_site()) { // Main site only.
51
  *
52
  * @since 150422 Rewrite.
53
  *
54
+ * @type bool If `FALSE`, run without hooks.
55
  */
56
  public $enable_hooks = true;
57
 
60
  *
61
  * @since 150422 Rewrite.
62
  *
63
+ * @type array Pro-only option keys.
64
  */
65
  public $pro_only_option_keys = [];
66
 
69
  *
70
  * @since 150422 Rewrite.
71
  *
72
+ * @type array Default options.
73
  */
74
  public $default_options = [];
75
 
78
  *
79
  * @since 150422 Rewrite.
80
  *
81
+ * @type array Configured options.
82
  */
83
  public $options = [];
84
 
87
  *
88
  * @since 150422 Rewrite.
89
  *
90
+ * @type string WordPress capability.
91
  */
92
  public $cap = 'activate_plugins';
93
 
96
  *
97
  * @since 150422 Rewrite.
98
  *
99
+ * @type string WordPress capability.
100
  */
101
  public $update_cap = 'update_plugins';
102
 
105
  *
106
  * @since 150422 Rewrite.
107
  *
108
+ * @type string WordPress capability.
109
  */
110
  public $network_cap = 'manage_network_plugins';
111
 
114
  *
115
  * @since 150422 Rewrite.
116
  *
117
+ * @type string WordPress capability.
118
  */
119
  public $uninstall_cap = 'delete_plugins';
120
 
127
  *
128
  * @since 150422 Rewrite.
129
  *
130
+ * @type string Cache directory; relative to the configured base directory.
131
  */
132
  public $cache_sub_dir = 'cache';
133
 
135
 
136
 
137
 
138
+
139
+
140
  /**
141
  * Plugin constructor.
142
  *
198
  'when_logged_in',
199
 
200
  'version_salt',
201
+ 'mobile_adaptive_salt',
202
+ 'mobile_adaptive_salt_enable',
203
+ 'ua_info_last_data_update',
204
 
205
  'htmlc_enable',
206
  'htmlc_css_exclusions',
215
  'htmlc_compress_css_code',
216
  'htmlc_compress_js_code',
217
  'htmlc_compress_html_code',
218
+ 'htmlc_amp_exclusions_enable',
219
  'htmlc_when_logged_in',
220
 
221
  'auto_cache_enable',
260
  'pro_update_username',
261
  'pro_update_password',
262
 
263
+ 'pro_auto_update_enable',
264
+
265
  'last_pro_stats_log',
266
  ];
267
  $this->default_options = [
343
 
344
  /* Related to version salt. */
345
 
346
+ 'version_salt' => '', // Any string value as a cache path component.
347
+
348
+ // This should be set to a `+` delimited string containing any of these tokens: `os.name + device.type + browser.name + browser.version.major`.
349
+ // There is an additional token (`browser.version`) that contains both the major and minor versions, but this token is not recommended due to many permutations.
350
+ // There is an additional token (`device.is_mobile`) that can be used stand-alone; i.e., to indicate that being mobile is the only factor worth considering.
351
+ 'mobile_adaptive_salt' => 'os.name + device.type + browser.name',
352
+ 'mobile_adaptive_salt_enable' => '0', // `0|1` Enable the mobile adaptive salt?
353
+ 'ua_info_last_data_update' => '0', // Timestamp.
354
 
355
  /* Related to HTML compressor. */
356
 
371
  'htmlc_compress_css_code' => '1', // `0|1`.
372
  'htmlc_compress_js_code' => '1', // `0|1`.
373
  'htmlc_compress_html_code' => '1', // `0|1`.
374
+ 'htmlc_amp_exclusions_enable' => '1', // `0|1`.
375
  'htmlc_when_logged_in' => '0', // `0|1`; enable when logged in?
376
 
377
  /* Related to auto-cache engine. */
443
  'pro_update_username' => '', // Username.
444
  'pro_update_password' => '', // Password or license key.
445
 
446
+ 'pro_auto_update_enable' => '0', // `0|1`; enable?
447
+
448
  /* Related to stats logging. */
449
 
450
  'last_pro_stats_log' => '0', // Timestamp.
512
  add_action('wp_create_nav_menu', [$this, 'autoClearCache']);
513
  add_action('wp_update_nav_menu', [$this, 'autoClearCache']);
514
  add_action('wp_delete_nav_menu', [$this, 'autoClearCache']);
515
+ add_action('update_option_sidebars_widgets', [$this, 'autoClearCache']);
516
 
517
  add_action('save_post', [$this, 'autoClearPostCache']);
518
  add_action('delete_post', [$this, 'autoClearPostCache']);
542
 
543
 
544
 
545
+ add_action('delete_user', [$this, 'autoClearAuthorPageCacheOnUserDeletion'], 10, 2);
546
+ add_action('remove_user_from_blog', [$this, 'autoClearAuthorPageCacheOnUserDeletion'], 10, 1);
547
+
548
  if ($this->options['enable'] && $this->applyWpFilters(GLOBAL_NS.'_disable_akismet_comment_nonce', true)) {
549
  add_filter('akismet_comment_nonce', function () {
550
  return 'disabled-by-'.SLUG_TD; // MUST return a string literal that is not 'true' or '' (an empty string). See <http://bit.ly/1YItpdE>
552
  }
553
 
554
 
555
+
556
  /* -------------------------------------------------------------- */
557
 
558
  if (!is_multisite() || is_main_site()) { // Main site only.
src/includes/classes/VsUpgrades.php CHANGED
@@ -57,7 +57,7 @@ class VsUpgrades extends AbsBase
57
  if (version_compare($this->prev_version, '150807', '<=')) {
58
  delete_site_option(GLOBAL_NS.'_errors'); // No longer necessary.
59
 
60
- if (is_multisite() && is_array($child_blogs = wp_get_sites())) {
61
  $current_site = get_current_site(); // Current site.
62
  foreach ($child_blogs as $_child_blog) {
63
  switch_to_blog($_child_blog['blog_id']);
57
  if (version_compare($this->prev_version, '150807', '<=')) {
58
  delete_site_option(GLOBAL_NS.'_errors'); // No longer necessary.
59
 
60
+ if (is_multisite() && is_array($child_blogs = $this->plugin->getBlogs())) {
61
  $current_site = get_current_site(); // Current site.
62
  foreach ($child_blogs as $_child_blog) {
63
  switch_to_blog($_child_blog['blog_id']);
src/includes/stub.php CHANGED
@@ -13,7 +13,7 @@ if (!defined('WPINC')) {
13
  require_once dirname(__DIR__).'/vendor/autoload.php';
14
  require_once __DIR__.'/functions/i18n-utils.php';
15
 
16
- ${__FILE__}['version'] = '161119'; //version//
17
  ${__FILE__}['plugin'] = dirname(dirname(__DIR__));
18
  ${__FILE__}['plugin'] .= '/'.basename(${__FILE__}['plugin']).'.php';
19
  ${__FILE__}['ns_path'] = str_replace('\\', '/', __NAMESPACE__); // To dir/path.
13
  require_once dirname(__DIR__).'/vendor/autoload.php';
14
  require_once __DIR__.'/functions/i18n-utils.php';
15
 
16
+ ${__FILE__}['version'] = '161221'; //version//
17
  ${__FILE__}['plugin'] = dirname(dirname(__DIR__));
18
  ${__FILE__}['plugin'] .= '/'.basename(${__FILE__}['plugin']).'.php';
19
  ${__FILE__}['ns_path'] = str_replace('\\', '/', __NAMESPACE__); // To dir/path.
src/includes/templates/advanced-cache.x-php CHANGED
@@ -153,6 +153,7 @@ if (!defined('COMET_CACHE_DIR')) {
153
  */
154
  define('COMET_CACHE_DIR', WP_CONTENT_DIR.'/'.'%%COMET_CACHE_DIR%%');
155
  }
 
156
  if (!defined('COMET_CACHE_MAX_AGE')) {
157
  /*
158
  * Cache expiration time.
@@ -241,6 +242,9 @@ if (!defined('COMET_CACHE_404_CACHE_FILENAME')) {
241
 
242
 
243
 
 
 
 
244
  $GLOBALS[GLOBAL_NS.'_advanced_cache'] = new Classes\AdvancedCache();
245
  $GLOBALS[GLOBAL_NS.'__advanced_cache'] = &$GLOBALS[GLOBAL_NS.'_advanced_cache'];
246
  if (!isset($GLOBALS['zencache__advanced_cache'])) {
153
  */
154
  define('COMET_CACHE_DIR', WP_CONTENT_DIR.'/'.'%%COMET_CACHE_DIR%%');
155
  }
156
+
157
  if (!defined('COMET_CACHE_MAX_AGE')) {
158
  /*
159
  * Cache expiration time.
242
 
243
 
244
 
245
+
246
+
247
+
248
  $GLOBALS[GLOBAL_NS.'_advanced_cache'] = new Classes\AdvancedCache();
249
  $GLOBALS[GLOBAL_NS.'__advanced_cache'] = &$GLOBALS[GLOBAL_NS.'_advanced_cache'];
250
  if (!isset($GLOBALS['zencache__advanced_cache'])) {
src/includes/traits/Ac/ObUtils.php CHANGED
@@ -6,92 +6,94 @@ use WebSharks\CometCache\Classes;
6
  trait ObUtils
7
  {
8
  /**
9
- * Calculated protocol; one of `http://` or `https://`.
10
  *
11
  * @since 150422 Rewrite.
12
  *
13
- * @var float One of `http://` or `https://`.
14
  */
15
  public $protocol = '';
16
 
17
  /**
18
- * Host token for this request.
19
  *
20
  * @since 150821 Improving multisite compat.
21
  *
22
- * @var string Host token for this request.
23
  */
24
  public $host_token = '';
25
 
26
  /**
27
- * Host base/dir tokens for this request.
28
  *
29
  * @since 150821 Improving multisite compat.
30
  *
31
- * @var string Host base/dir tokens for this request.
32
  */
33
  public $host_base_dir_tokens = '';
34
 
 
 
35
  /**
36
- * Calculated version salt; set by site configuration data.
37
  *
38
  * @since 150422 Rewrite.
39
  *
40
- * @var string|mixed Any scalar value does fine.
41
  */
42
  public $version_salt = '';
43
 
44
  /**
45
- * Relative cache path for the current request.
46
  *
47
  * @since 150422 Rewrite.
48
  *
49
- * @var string Cache path for the current request.
50
  */
51
  public $cache_path = '';
52
 
53
  /**
54
- * Absolute cache file path for the current request.
55
  *
56
  * @since 150422 Rewrite.
57
  *
58
- * @var string Absolute cache file path for the current request.
59
  */
60
  public $cache_file = '';
61
 
62
  /**
63
- * Relative 404 cache path for the current request.
64
  *
65
  * @since 150422 Rewrite.
66
  *
67
- * @var string 404 cache path for the current request.
68
  */
69
  public $cache_path_404 = '';
70
 
71
  /**
72
- * Absolute 404 cache file path for the current request.
73
  *
74
  * @since 150422 Rewrite.
75
  *
76
- * @var string Absolute 404 cache file path for the current request.
77
  */
78
  public $cache_file_404 = '';
79
 
80
  /**
81
- * Version salt followed by the current request location.
82
  *
83
  * @since 150422 Rewrite.
84
  *
85
- * @var string Version salt followed by the current request location.
86
  */
87
  public $salt_location = '';
88
 
89
  /**
90
- * Calculated max age; i.e., before expiration.
91
  *
92
- * @since 151002 Load average checks in pro version.
93
  *
94
- * @var int Calculated max age; i.e., before expiration.
95
  */
96
  public $cache_max_age = 0;
97
 
@@ -100,17 +102,16 @@ trait ObUtils
100
  *
101
  * @since 161119 Calculated 12 hour expiration time.
102
  *
103
- * @var int Calculated 12 hour expiration time.
104
  */
105
  public $nonce_cache_max_age = 0;
106
 
107
  /**
108
- * Start output buffering (if applicable); or serve a cache file (if possible).
109
- *
110
- * @since 150422 Rewrite.
111
  *
112
- * @note This is a vital part of Comet Cache. This method serves existing (fresh) cache files.
113
- * It is also responsible for beginning the process of collecting the output buffer.
 
114
  */
115
  public function maybeStartOutputBuffering()
116
  {
@@ -193,7 +194,9 @@ trait ObUtils
193
  $this->protocol = $this->isSsl() ? 'https://' : 'http://';
194
 
195
  $this->version_salt = ''; // Initialize the version salt.
 
196
 
 
197
  $this->version_salt = $this->applyFilters(get_class($this).'__version_salt', $this->version_salt);
198
  $this->version_salt = $this->applyFilters(GLOBAL_NS.'_version_salt', $this->version_salt);
199
 
@@ -362,11 +365,15 @@ trait ObUtils
362
  $DebugNotes->addAsciiArt(sprintf(__('%1$s Notes', 'comet-cache'), NAME));
363
  $DebugNotes->addLineBreak();
364
 
365
- $DebugNotes->add(__('Cache File Version Salt', 'comet-cache'), $this->version_salt ? $this->version_salt : __('n/a', 'comet-cache'));
366
-
367
  if (IS_PRO && COMET_CACHE_WHEN_LOGGED_IN && $this->user_token) {
368
  $DebugNotes->add(__('Cache File User Token', 'comet-cache'), $this->user_token);
369
  }
 
 
 
 
 
 
370
  $DebugNotes->addLineBreak();
371
 
372
  $DebugNotes->add(__('Cache File URL', 'comet-cache'), $this->is_404 ? __('404 [error document]', 'comet-cache') : $this->protocol.$this->host_token.$_SERVER['REQUEST_URI']);
6
  trait ObUtils
7
  {
8
  /**
9
+ * Protocol.
10
  *
11
  * @since 150422 Rewrite.
12
  *
13
+ * @type string Protocol
14
  */
15
  public $protocol = '';
16
 
17
  /**
18
+ * Host token.
19
  *
20
  * @since 150821 Improving multisite compat.
21
  *
22
+ * @type string Host token.
23
  */
24
  public $host_token = '';
25
 
26
  /**
27
+ * Host base/dir tokens.
28
  *
29
  * @since 150821 Improving multisite compat.
30
  *
31
+ * @type string Host base/dir tokens.
32
  */
33
  public $host_base_dir_tokens = '';
34
 
35
+
36
+
37
  /**
38
+ * Version salt.
39
  *
40
  * @since 150422 Rewrite.
41
  *
42
+ * @type string Forced to a string.
43
  */
44
  public $version_salt = '';
45
 
46
  /**
47
+ * Relative cache path.
48
  *
49
  * @since 150422 Rewrite.
50
  *
51
+ * @type string Cache path.
52
  */
53
  public $cache_path = '';
54
 
55
  /**
56
+ * Absolute cache file path.
57
  *
58
  * @since 150422 Rewrite.
59
  *
60
+ * @type string Absolute cache file path.
61
  */
62
  public $cache_file = '';
63
 
64
  /**
65
+ * Relative 404 cache path.
66
  *
67
  * @since 150422 Rewrite.
68
  *
69
+ * @type string 404 cache path.
70
  */
71
  public $cache_path_404 = '';
72
 
73
  /**
74
+ * Absolute 404 cache file path.
75
  *
76
  * @since 150422 Rewrite.
77
  *
78
+ * @type string Absolute 404 cache file path.
79
  */
80
  public $cache_file_404 = '';
81
 
82
  /**
83
+ * Version salt + location.
84
  *
85
  * @since 150422 Rewrite.
86
  *
87
+ * @type string Version salt + location.
88
  */
89
  public $salt_location = '';
90
 
91
  /**
92
+ * Calculated max age.
93
  *
94
+ * @since 151002 Load average checks.
95
  *
96
+ * @type int Calculated max age.
97
  */
98
  public $cache_max_age = 0;
99
 
102
  *
103
  * @since 161119 Calculated 12 hour expiration time.
104
  *
105
+ * @type int Calculated 12 hour expiration time.
106
  */
107
  public $nonce_cache_max_age = 0;
108
 
109
  /**
110
+ * Start output buffering or serve cache.
 
 
111
  *
112
+ * @since 150422 Rewrite. This is a vital part of Comet Cache.
113
+ * This method serves existing (fresh) cache files. It is also responsible
114
+ * for beginning the process of collecting the output buffer.
115
  */
116
  public function maybeStartOutputBuffering()
117
  {
194
  $this->protocol = $this->isSsl() ? 'https://' : 'http://';
195
 
196
  $this->version_salt = ''; // Initialize the version salt.
197
+
198
 
199
+
200
  $this->version_salt = $this->applyFilters(get_class($this).'__version_salt', $this->version_salt);
201
  $this->version_salt = $this->applyFilters(GLOBAL_NS.'_version_salt', $this->version_salt);
202
 
365
  $DebugNotes->addAsciiArt(sprintf(__('%1$s Notes', 'comet-cache'), NAME));
366
  $DebugNotes->addLineBreak();
367
 
 
 
368
  if (IS_PRO && COMET_CACHE_WHEN_LOGGED_IN && $this->user_token) {
369
  $DebugNotes->add(__('Cache File User Token', 'comet-cache'), $this->user_token);
370
  }
371
+ if (IS_PRO && COMET_CACHE_MOBILE_ADAPTIVE_SALT_ENABLE && COMET_CACHE_MOBILE_ADAPTIVE_SALT && $this->mobile_adaptive_salt) {
372
+ // Note: Not using `$this->mobile_adaptive_salt` here. Instead, generating a human readable variation.
373
+ $DebugNotes->add(__('Cache File for Mobile Device', 'comet-cache'), $this->fillUaTokens(COMET_CACHE_MOBILE_ADAPTIVE_SALT, false));
374
+ }
375
+ $DebugNotes->add(__('Cache File Version Salt', 'comet-cache'), $this->version_salt ? $this->version_salt : __('n/a', 'comet-cache'));
376
+
377
  $DebugNotes->addLineBreak();
378
 
379
  $DebugNotes->add(__('Cache File URL', 'comet-cache'), $this->is_404 ? __('404 [error document]', 'comet-cache') : $this->protocol.$this->host_token.$_SERVER['REQUEST_URI']);
src/includes/traits/Plugin/InstallUtils.php CHANGED
@@ -35,6 +35,7 @@ trait InstallUtils
35
  $this->addWpHtaccess();
36
  $this->addAdvancedCache();
37
  $this->updateBlogPaths();
 
38
  $this->autoClearCache();
39
  }
40
 
@@ -48,22 +49,28 @@ trait InstallUtils
48
  public function checkVersion()
49
  {
50
  $prev_version = $this->options['version'];
 
51
  if (version_compare($prev_version, VERSION, '>=')) {
52
  return; // Nothing to do; up-to-date.
53
  }
54
- $this->options = $this->getOptions(false, true); // Don't discard options not present in $this->default_options, and DO force-pull options directly from get_site_option()
 
 
55
 
56
- $this->updateOptions(['version' => VERSION], false); // Retain all options in database for VS Upgrade routine
 
57
 
58
  new Classes\VsUpgrades($prev_version);
59
 
60
- $this->updateOptions(['version' => VERSION], true); // Discard options not present in $this->default_options
 
61
 
62
  if ($this->options['enable']) {
63
  $this->addWpCacheToWpConfig();
64
  $this->addWpHtaccess();
65
  $this->addAdvancedCache();
66
  $this->updateBlogPaths();
 
67
  }
68
  $this->wipeCache(); // Fresh start now.
69
 
@@ -103,11 +110,9 @@ trait InstallUtils
103
 
104
  if (!defined('WP_UNINSTALL_PLUGIN')) {
105
  return; // Disallow.
106
- }
107
- if (empty($GLOBALS[GLOBAL_NS.'_uninstalling'])) {
108
  return; // Not uninstalling.
109
- }
110
- if (!current_user_can($this->uninstall_cap)) {
111
  return; // Extra layer of security.
112
  }
113
  $this->removeWpCacheFromWpConfig();
@@ -149,38 +154,27 @@ trait InstallUtils
149
  {
150
  if (!$this->options['enable']) {
151
  return ''; // Nothing to do.
152
- }
153
- if (!($wp_config_file = $this->findWpConfigFile())) {
154
  return ''; // Unable to find `/wp-config.php`.
155
- }
156
- if (!is_readable($wp_config_file)) {
157
  return ''; // Not possible.
158
- }
159
- if (!($wp_config_file_contents = file_get_contents($wp_config_file))) {
160
  return ''; // Failure; could not read file.
161
- }
162
- if (!($wp_config_file_contents_no_whitespace = php_strip_whitespace($wp_config_file))) {
163
  return ''; // Failure; file empty
164
- }
165
- if (preg_match('/\bdefine\s*\(\s*([\'"])WP_CACHE\\1\s*,\s*(?:\-?[1-9][0-9\.]*|true|([\'"])(?:[^0\'"]|[^\'"]{2,})\\2)\s*\)\s*;/ui', $wp_config_file_contents_no_whitespace)) {
166
  return $wp_config_file_contents; // It's already in there; no need to modify this file.
167
- }
168
- if (!($wp_config_file_contents = $this->removeWpCacheFromWpConfig())) {
169
  return ''; // Unable to remove previous value.
170
- }
171
- if (!($wp_config_file_contents = preg_replace('/^\s*(\<\?php|\<\?)\s+/ui', '${1}'."\n"."define( 'WP_CACHE', true );"."\n", $wp_config_file_contents, 1))) {
172
  return ''; // Failure; something went terribly wrong here.
173
- }
174
- if (mb_strpos($wp_config_file_contents, "define( 'WP_CACHE', true );") === false) {
175
  return ''; // Failure; unable to add; unexpected PHP code.
176
- }
177
- if (defined('DISALLOW_FILE_MODS') && DISALLOW_FILE_MODS) {
178
  return ''; // We may NOT edit any files.
179
- }
180
- if (!is_writable($wp_config_file)) {
181
  return ''; // Not possible.
182
- }
183
- if (!file_put_contents($wp_config_file, $wp_config_file_contents)) {
184
  return ''; // Failure; could not write changes.
185
  }
186
  return $wp_config_file_contents;
@@ -198,35 +192,25 @@ trait InstallUtils
198
  {
199
  if (!($wp_config_file = $this->findWpConfigFile())) {
200
  return ''; // Unable to find `/wp-config.php`.
201
- }
202
- if (!is_readable($wp_config_file)) {
203
  return ''; // Not possible.
204
- }
205
- if (!($wp_config_file_contents = file_get_contents($wp_config_file))) {
206
  return ''; // Failure; could not read file.
207
- }
208
- if (!($wp_config_file_contents_no_whitespace = php_strip_whitespace($wp_config_file))) {
209
  return ''; // Failure; file empty
210
- }
211
- if (!preg_match('/([\'"])WP_CACHE\\1/ui', $wp_config_file_contents_no_whitespace)) {
212
  return $wp_config_file_contents; // Already gone.
213
- }
214
- if (preg_match('/\bdefine\s*\(\s*([\'"])WP_CACHE\\1\s*,\s*(?:0|FALSE|NULL|([\'"])0?\\2)\s*\)\s*;/ui', $wp_config_file_contents_no_whitespace) && !is_writable($wp_config_file)) {
215
  return $wp_config_file_contents; // It's already disabled, and since we can't write to this file let's let this slide.
216
- }
217
- if (!($wp_config_file_contents = preg_replace('/\bdefine\s*\(\s*([\'"])WP_CACHE\\1\s*,\s*(?:\-?[0-9\.]+|TRUE|FALSE|NULL|([\'"])[^\'"]*\\2)\s*\)\s*;/ui', '', $wp_config_file_contents))) {
218
  return ''; // Failure; something went terribly wrong here.
219
- }
220
- if (preg_match('/([\'"])WP_CACHE\\1/ui', $wp_config_file_contents)) {
221
  return ''; // Failure; perhaps the `/wp-config.php` file contains syntax we cannot remove safely.
222
- }
223
- if (defined('DISALLOW_FILE_MODS') && DISALLOW_FILE_MODS) {
224
  return ''; // We may NOT edit any files.
225
- }
226
- if (!is_writable($wp_config_file)) {
227
  return ''; // Not possible.
228
- }
229
- if (!file_put_contents($wp_config_file, $wp_config_file_contents)) {
230
  return ''; // Failure; could not write changes.
231
  }
232
  return $wp_config_file_contents;
@@ -253,8 +237,7 @@ trait InstallUtils
253
  {
254
  if (!$this->options['enable']) {
255
  return; // Nothing to do.
256
- }
257
- if (!empty($_REQUEST[GLOBAL_NS])) {
258
  return; // Skip on plugin actions.
259
  }
260
  $cache_dir = $this->cacheDir();
@@ -294,20 +277,20 @@ trait InstallUtils
294
 
295
  if (is_file($advanced_cache_file) && !is_writable($advanced_cache_file)) {
296
  return false; // Not possible to create.
297
- }
298
- if (!is_file($advanced_cache_file) && !is_writable(dirname($advanced_cache_file))) {
299
  return false; // Not possible to create.
300
- }
301
- if (!is_file($advanced_cache_template) || !is_readable($advanced_cache_template)) {
302
  return false; // Template file is missing; or not readable.
303
- }
304
- if (!($advanced_cache_contents = file_get_contents($advanced_cache_template))) {
305
  return false; // Template file is missing; or is not readable.
306
  }
307
  $possible_advanced_cache_constant_key_values = array_merge(
308
  $this->options, // The following additional keys are dynamic.
309
  [
310
  'cache_dir' => $this->basePathTo($this->cache_sub_dir),
 
 
 
311
 
312
  ]
313
  );
@@ -345,8 +328,7 @@ trait InstallUtils
345
  $_value,
346
  $advanced_cache_contents
347
  );
348
- }
349
- unset($_option, $_value, $_values, $_response); // Housekeeping.
350
 
351
  if (mb_strpos(PLUGIN_FILE, WP_CONTENT_DIR) === 0) {
352
  $plugin_file = "WP_CONTENT_DIR.'".$this->escSq(str_replace(WP_CONTENT_DIR, '', PLUGIN_FILE))."'";
@@ -406,11 +388,9 @@ trait InstallUtils
406
 
407
  if (!is_file($advanced_cache_file)) {
408
  return true; // Already gone.
409
- }
410
- if (is_readable($advanced_cache_file) && filesize($advanced_cache_file) === 0) {
411
  return true; // Already gone; i.e. it's empty already.
412
- }
413
- if (!is_writable($advanced_cache_file)) {
414
  return false; // Not possible.
415
  }
416
  /* Empty the file only. This way permissions are NOT lost in cases where
@@ -474,11 +454,9 @@ trait InstallUtils
474
  {
475
  if (!$this->options['enable']) {
476
  return; // Nothing to do.
477
- }
478
- if (!is_multisite()) {
479
  return; // N/A.
480
- }
481
- if (!empty($_REQUEST[GLOBAL_NS])) {
482
  return; // Skip on plugin actions.
483
  }
484
  $cache_dir = $this->cacheDir();
@@ -508,8 +486,7 @@ trait InstallUtils
508
 
509
  if (!$this->options['enable']) {
510
  return $value; // Nothing to do.
511
- }
512
- if (!is_multisite()) {
513
  return $value; // N/A.
514
  }
515
  $cache_dir = $this->cacheDir();
@@ -517,7 +494,8 @@ trait InstallUtils
517
 
518
  $cache_lock = $this->cacheLock();
519
 
520
- clearstatcache();
 
521
  if (!file_exists($cache_dir)) {
522
  mkdir($cache_dir, 0775, true);
523
  }
@@ -538,7 +516,7 @@ trait InstallUtils
538
  if (!$_path || $_path === '/') {
539
  unset($paths[$_key]); // Exclude main site.
540
  }
541
- }
542
  unset($_key, $_path); // Housekeeping.
543
 
544
  file_put_contents($blog_paths_file, serialize($paths));
@@ -548,6 +526,8 @@ trait InstallUtils
548
  return $value; // Pass through untouched (always).
549
  }
550
 
 
 
551
  /**
552
  * Deletes base directory.
553
  *
35
  $this->addWpHtaccess();
36
  $this->addAdvancedCache();
37
  $this->updateBlogPaths();
38
+
39
  $this->autoClearCache();
40
  }
41
 
49
  public function checkVersion()
50
  {
51
  $prev_version = $this->options['version'];
52
+
53
  if (version_compare($prev_version, VERSION, '>=')) {
54
  return; // Nothing to do; up-to-date.
55
  }
56
+ $this->options = $this->getOptions(false, true);
57
+ // Don't discard options not present in $this->default_options,
58
+ // and DO force-pull options directly from get_site_option().
59
 
60
+ $this->updateOptions(['version' => VERSION], false);
61
+ // Retain all options in database for VS Upgrade routine.
62
 
63
  new Classes\VsUpgrades($prev_version);
64
 
65
+ $this->updateOptions(['version' => VERSION], true);
66
+ // Discard options not present in $this->default_options.
67
 
68
  if ($this->options['enable']) {
69
  $this->addWpCacheToWpConfig();
70
  $this->addWpHtaccess();
71
  $this->addAdvancedCache();
72
  $this->updateBlogPaths();
73
+
74
  }
75
  $this->wipeCache(); // Fresh start now.
76
 
110
 
111
  if (!defined('WP_UNINSTALL_PLUGIN')) {
112
  return; // Disallow.
113
+ } elseif (empty($GLOBALS[GLOBAL_NS.'_uninstalling'])) {
 
114
  return; // Not uninstalling.
115
+ } elseif (!current_user_can($this->uninstall_cap)) {
 
116
  return; // Extra layer of security.
117
  }
118
  $this->removeWpCacheFromWpConfig();
154
  {
155
  if (!$this->options['enable']) {
156
  return ''; // Nothing to do.
157
+ } elseif (!($wp_config_file = $this->findWpConfigFile())) {
 
158
  return ''; // Unable to find `/wp-config.php`.
159
+ } elseif (!is_readable($wp_config_file)) {
 
160
  return ''; // Not possible.
161
+ } elseif (!($wp_config_file_contents = file_get_contents($wp_config_file))) {
 
162
  return ''; // Failure; could not read file.
163
+ } elseif (!($wp_config_file_contents_no_whitespace = php_strip_whitespace($wp_config_file))) {
 
164
  return ''; // Failure; file empty
165
+ } elseif (preg_match('/\bdefine\s*\(\s*([\'"])WP_CACHE\\1\s*,\s*(?:\-?[1-9][0-9\.]*|true|([\'"])(?:[^0\'"]|[^\'"]{2,})\\2)\s*\)\s*;/ui', $wp_config_file_contents_no_whitespace)) {
 
166
  return $wp_config_file_contents; // It's already in there; no need to modify this file.
167
+ } elseif (!($wp_config_file_contents = $this->removeWpCacheFromWpConfig())) {
 
168
  return ''; // Unable to remove previous value.
169
+ } elseif (!($wp_config_file_contents = preg_replace('/^\s*(\<\?php|\<\?)\s+/ui', '${1}'."\n"."define( 'WP_CACHE', true );"."\n", $wp_config_file_contents, 1))) {
 
170
  return ''; // Failure; something went terribly wrong here.
171
+ } elseif (mb_strpos($wp_config_file_contents, "define( 'WP_CACHE', true );") === false) {
 
172
  return ''; // Failure; unable to add; unexpected PHP code.
173
+ } elseif (defined('DISALLOW_FILE_MODS') && DISALLOW_FILE_MODS) {
 
174
  return ''; // We may NOT edit any files.
175
+ } elseif (!is_writable($wp_config_file)) {
 
176
  return ''; // Not possible.
177
+ } elseif (!file_put_contents($wp_config_file, $wp_config_file_contents)) {
 
178
  return ''; // Failure; could not write changes.
179
  }
180
  return $wp_config_file_contents;
192
  {
193
  if (!($wp_config_file = $this->findWpConfigFile())) {
194
  return ''; // Unable to find `/wp-config.php`.
195
+ } elseif (!is_readable($wp_config_file)) {
 
196
  return ''; // Not possible.
197
+ } elseif (!($wp_config_file_contents = file_get_contents($wp_config_file))) {
 
198
  return ''; // Failure; could not read file.
199
+ } elseif (!($wp_config_file_contents_no_whitespace = php_strip_whitespace($wp_config_file))) {
 
200
  return ''; // Failure; file empty
201
+ } elseif (!preg_match('/([\'"])WP_CACHE\\1/ui', $wp_config_file_contents_no_whitespace)) {
 
202
  return $wp_config_file_contents; // Already gone.
203
+ } elseif (preg_match('/\bdefine\s*\(\s*([\'"])WP_CACHE\\1\s*,\s*(?:0|FALSE|NULL|([\'"])0?\\2)\s*\)\s*;/ui', $wp_config_file_contents_no_whitespace) && !is_writable($wp_config_file)) {
 
204
  return $wp_config_file_contents; // It's already disabled, and since we can't write to this file let's let this slide.
205
+ } elseif (!($wp_config_file_contents = preg_replace('/\bdefine\s*\(\s*([\'"])WP_CACHE\\1\s*,\s*(?:\-?[0-9\.]+|TRUE|FALSE|NULL|([\'"])[^\'"]*\\2)\s*\)\s*;/ui', '', $wp_config_file_contents))) {
 
206
  return ''; // Failure; something went terribly wrong here.
207
+ } elseif (preg_match('/([\'"])WP_CACHE\\1/ui', $wp_config_file_contents)) {
 
208
  return ''; // Failure; perhaps the `/wp-config.php` file contains syntax we cannot remove safely.
209
+ } elseif (defined('DISALLOW_FILE_MODS') && DISALLOW_FILE_MODS) {
 
210
  return ''; // We may NOT edit any files.
211
+ } elseif (!is_writable($wp_config_file)) {
 
212
  return ''; // Not possible.
213
+ } elseif (!file_put_contents($wp_config_file, $wp_config_file_contents)) {
 
214
  return ''; // Failure; could not write changes.
215
  }
216
  return $wp_config_file_contents;
237
  {
238
  if (!$this->options['enable']) {
239
  return; // Nothing to do.
240
+ } elseif (!empty($_REQUEST[GLOBAL_NS])) {
 
241
  return; // Skip on plugin actions.
242
  }
243
  $cache_dir = $this->cacheDir();
277
 
278
  if (is_file($advanced_cache_file) && !is_writable($advanced_cache_file)) {
279
  return false; // Not possible to create.
280
+ } elseif (!is_file($advanced_cache_file) && !is_writable(dirname($advanced_cache_file))) {
 
281
  return false; // Not possible to create.
282
+ } elseif (!is_file($advanced_cache_template) || !is_readable($advanced_cache_template)) {
 
283
  return false; // Template file is missing; or not readable.
284
+ } elseif (!($advanced_cache_contents = file_get_contents($advanced_cache_template))) {
 
285
  return false; // Template file is missing; or is not readable.
286
  }
287
  $possible_advanced_cache_constant_key_values = array_merge(
288
  $this->options, // The following additional keys are dynamic.
289
  [
290
  'cache_dir' => $this->basePathTo($this->cache_sub_dir),
291
+
292
+
293
+
294
 
295
  ]
296
  );
328
  $_value,
329
  $advanced_cache_contents
330
  );
331
+ } // unset($_option, $_value, $_values, $_response); // Housekeeping.
 
332
 
333
  if (mb_strpos(PLUGIN_FILE, WP_CONTENT_DIR) === 0) {
334
  $plugin_file = "WP_CONTENT_DIR.'".$this->escSq(str_replace(WP_CONTENT_DIR, '', PLUGIN_FILE))."'";
388
 
389
  if (!is_file($advanced_cache_file)) {
390
  return true; // Already gone.
391
+ } elseif (is_readable($advanced_cache_file) && filesize($advanced_cache_file) === 0) {
 
392
  return true; // Already gone; i.e. it's empty already.
393
+ } elseif (!is_writable($advanced_cache_file)) {
 
394
  return false; // Not possible.
395
  }
396
  /* Empty the file only. This way permissions are NOT lost in cases where
454
  {
455
  if (!$this->options['enable']) {
456
  return; // Nothing to do.
457
+ } elseif (!is_multisite()) {
 
458
  return; // N/A.
459
+ } elseif (!empty($_REQUEST[GLOBAL_NS])) {
 
460
  return; // Skip on plugin actions.
461
  }
462
  $cache_dir = $this->cacheDir();
486
 
487
  if (!$this->options['enable']) {
488
  return $value; // Nothing to do.
489
+ } elseif (!is_multisite()) {
 
490
  return $value; // N/A.
491
  }
492
  $cache_dir = $this->cacheDir();
494
 
495
  $cache_lock = $this->cacheLock();
496
 
497
+ clearstatcache(); // Clear `stat()` cache.
498
+
499
  if (!file_exists($cache_dir)) {
500
  mkdir($cache_dir, 0775, true);
501
  }
516
  if (!$_path || $_path === '/') {
517
  unset($paths[$_key]); // Exclude main site.
518
  }
519
+ } // Must unset iteration by reference here.
520
  unset($_key, $_path); // Housekeeping.
521
 
522
  file_put_contents($blog_paths_file, serialize($paths));
526
  return $value; // Pass through untouched (always).
527
  }
528
 
529
+
530
+
531
  /**
532
  * Deletes base directory.
533
  *
src/includes/traits/Plugin/MenuPageUtils.php CHANGED
@@ -54,15 +54,16 @@ trait MenuPageUtils
54
  'emptyStatsCountsImageUrl' => $this->url('/src/client-s/images/stats-fc-empty.png'),
55
  'emptyStatsFilesImageUrl' => $this->url('/src/client-s/images/stats-fs-empty.png'),
56
  'i18n' => [
57
- 'name' => NAME,
58
- 'perSymbol' => __('%', 'comet-cache'),
59
- 'file' => __('file', 'comet-cache'),
60
- 'files' => __('files', 'comet-cache'),
61
- 'pageCache' => __('Page Cache', 'comet-cache'),
62
- 'htmlCompressor' => __('HTML Compressor', 'comet-cache'),
63
- 'currentTotal' => __('Current Total', 'comet-cache'),
64
- 'currentSite' => __('Current Site', 'comet-cache'),
65
- 'xDayHigh' => __('%s Day High', 'comet-cache'),
 
66
  ],
67
  ]
68
  );
@@ -181,7 +182,7 @@ trait MenuPageUtils
181
  *
182
  * @since 150422 Rewrite.
183
  *
184
- * @var array WP admin icon colors.
185
  *
186
  * @note These must be hard-coded, because they don't become available
187
  * in core until `admin_init`; i.e., too late for `admin_menu`.
54
  'emptyStatsCountsImageUrl' => $this->url('/src/client-s/images/stats-fc-empty.png'),
55
  'emptyStatsFilesImageUrl' => $this->url('/src/client-s/images/stats-fs-empty.png'),
56
  'i18n' => [
57
+ 'name' => NAME,
58
+ 'perSymbol' => __('%', 'comet-cache'),
59
+ 'file' => __('file', 'comet-cache'),
60
+ 'files' => __('files', 'comet-cache'),
61
+ 'pageCache' => __('Page Cache', 'comet-cache'),
62
+ 'htmlCompressor' => __('HTML Compressor', 'comet-cache'),
63
+ 'currentTotal' => __('Current Total', 'comet-cache'),
64
+ 'currentSite' => __('Current Site', 'comet-cache'),
65
+ 'xDayHigh' => __('%s Day High', 'comet-cache'),
66
+ 'mobileAdaptiveSaltError' => __('Invalid Mobile-Adaptive Tokens. This field must contain one or more of the listed Tokens (separated by a + sign). Please use Tokens only, NOT string literals.', 'comet-cache'),
67
  ],
68
  ]
69
  );
182
  *
183
  * @since 150422 Rewrite.
184
  *
185
+ * @type array WP admin icon colors.
186
  *
187
  * @note These must be hard-coded, because they don't become available
188
  * in core until `admin_init`; i.e., too late for `admin_menu`.
src/includes/traits/Plugin/WcpAuthorUtils.php CHANGED
@@ -6,7 +6,7 @@ use WebSharks\CometCache\Classes;
6
  trait WcpAuthorUtils
7
  {
8
  /**
9
- * Automatically clears cache files for the author page(s).
10
  *
11
  * @attaches-to `post_updated` hook.
12
  *
@@ -25,26 +25,21 @@ trait WcpAuthorUtils
25
  */
26
  public function autoClearAuthorPageCache($post_id, \WP_Post $post_after, \WP_Post $post_before)
27
  {
28
- $counter = 0; // Initialize.
29
- $enqueued_notices = 0; // Initialize.
30
- $authors = []; // Initialize.
31
- $authors_to_clear = []; // Initialize.
32
 
33
- if (!($post_id = (integer) $post_id)) {
34
  return $counter; // Nothing to do.
35
- }
36
- if (!is_null($done = &$this->cacheKey('autoClearAuthorPageCache', [$post_id, $post_after->ID, $post_before->ID]))) {
37
  return $counter; // Already did this.
38
  }
39
  $done = true; // Flag as having been done.
40
 
41
  if (!$this->options['enable']) {
42
  return $counter; // Nothing to do.
43
- }
44
- if (!$this->options['cache_clear_author_page_enable']) {
45
  return $counter; // Nothing to do.
46
- }
47
- if (!is_dir($cache_dir = $this->cacheDir())) {
48
  return $counter; // Nothing to do.
49
  }
50
  /*
@@ -58,25 +53,22 @@ trait WcpAuthorUtils
58
  *
59
  * Else return the counter; post status does not warrant clearing author page cache.
60
  */
61
- if ($post_after->post_author !== $post_before->post_author &&
62
- ($post_before->post_status === 'publish' || $post_before->post_status === 'private')
63
- ) {
64
- $authors[] = (integer) $post_before->post_author;
65
- $authors[] = (integer) $post_after->post_author;
66
- } elseif (($post_before->post_status === 'publish' || $post_before->post_status === 'private') ||
67
- ($post_after->post_status === 'publish' || $post_after->post_status === 'private')
68
- ) {
69
- $authors[] = (integer) $post_after->post_author;
70
- }
71
- if (!$authors) {
72
- return $counter; // Nothing to do.
73
  }
74
  foreach ($authors as $_author_id) {
75
  $authors_to_clear[$_author_id]['posts_url'] = get_author_posts_url($_author_id);
76
  $authors_to_clear[$_author_id]['display_name'] = get_the_author_meta('display_name', $_author_id);
77
- }
78
- unset($_author_id); // Housekeeping.
79
 
 
 
 
80
  foreach ($authors_to_clear as $_author) {
81
  $_author_regex = $this->buildHostCachePathRegex($_author['posts_url']);
82
  $_author_counter = $this->clearFilesFromHostCacheDir($_author_regex);
@@ -86,12 +78,72 @@ trait WcpAuthorUtils
86
  $this->enqueueNotice(sprintf(__('Found %1$s in the cache for Author Page: <code>%2$s</code>; auto-clearing.', 'comet-cache'), esc_html($this->i18nFiles($_author_counter)), esc_html($_author['display_name'])), ['combinable' => true]);
87
  ++$enqueued_notices; // Increment enqueued notices counter.
88
  }
89
- }
90
- unset($_author, $_author_regex, $_author_counter); // Housekeeping.
91
 
92
  $counter += $this->autoClearXmlFeedsCache('blog');
93
  $counter += $this->autoClearXmlFeedsCache('post-authors', $post_id);
94
 
95
  return $counter;
96
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97
  }
6
  trait WcpAuthorUtils
7
  {
8
  /**
9
+ * Clears cache files for the author page(s).
10
  *
11
  * @attaches-to `post_updated` hook.
12
  *
25
  */
26
  public function autoClearAuthorPageCache($post_id, \WP_Post $post_after, \WP_Post $post_before)
27
  {
28
+ $authors = $authors_to_clear = []; // Initialize.
29
+ $counter = $enqueued_notices = 0; // Initialize.
 
 
30
 
31
+ if (!($post_id = (int) $post_id)) {
32
  return $counter; // Nothing to do.
33
+ } elseif (($done = &$this->cacheKey('autoClearAuthorPageCache', [$post_id, $post_after->ID, $post_before->ID]))) {
 
34
  return $counter; // Already did this.
35
  }
36
  $done = true; // Flag as having been done.
37
 
38
  if (!$this->options['enable']) {
39
  return $counter; // Nothing to do.
40
+ } elseif (!$this->options['cache_clear_author_page_enable']) {
 
41
  return $counter; // Nothing to do.
42
+ } elseif (!is_dir($cache_dir = $this->cacheDir())) {
 
43
  return $counter; // Nothing to do.
44
  }
45
  /*
53
  *
54
  * Else return the counter; post status does not warrant clearing author page cache.
55
  */
56
+ if ($post_after->post_author !== $post_before->post_author
57
+ && ($post_before->post_status === 'publish' || $post_before->post_status === 'private')) {
58
+ $authors[] = (int) $post_before->post_author;
59
+ $authors[] = (int) $post_after->post_author;
60
+ } elseif (($post_before->post_status === 'publish' || $post_before->post_status === 'private')
61
+ || ($post_after->post_status === 'publish' || $post_after->post_status === 'private')) {
62
+ $authors[] = (int) $post_after->post_author;
 
 
 
 
 
63
  }
64
  foreach ($authors as $_author_id) {
65
  $authors_to_clear[$_author_id]['posts_url'] = get_author_posts_url($_author_id);
66
  $authors_to_clear[$_author_id]['display_name'] = get_the_author_meta('display_name', $_author_id);
67
+ } // unset($_author_id); // Housekeeping.
 
68
 
69
+ if (!$authors_to_clear) {
70
+ return $counter; // Nothing to do.
71
+ }
72
  foreach ($authors_to_clear as $_author) {
73
  $_author_regex = $this->buildHostCachePathRegex($_author['posts_url']);
74
  $_author_counter = $this->clearFilesFromHostCacheDir($_author_regex);
78
  $this->enqueueNotice(sprintf(__('Found %1$s in the cache for Author Page: <code>%2$s</code>; auto-clearing.', 'comet-cache'), esc_html($this->i18nFiles($_author_counter)), esc_html($_author['display_name'])), ['combinable' => true]);
79
  ++$enqueued_notices; // Increment enqueued notices counter.
80
  }
81
+ } // unset($_author, $_author_regex, $_author_counter); // Housekeeping.
 
82
 
83
  $counter += $this->autoClearXmlFeedsCache('blog');
84
  $counter += $this->autoClearXmlFeedsCache('post-authors', $post_id);
85
 
86
  return $counter;
87
  }
88
+
89
+ /**
90
+ * Clears cache files for the author page(s).
91
+ *
92
+ * @attaches-to `remove_user_from_blog` hook.
93
+ * @attaches-to `delete_user` hook.
94
+ *
95
+ * @since 161221 Adding support for user deletions.
96
+ *
97
+ * @param int $user_id A WordPress user ID.
98
+ * @param int $rat_user_id User ID (reassign via `delete_user` hook).
99
+ *
100
+ * @throws \Exception If a clear failure occurs.
101
+ *
102
+ * @return int Total files cleared by this routine (if any).
103
+ */
104
+ public function autoClearAuthorPageCacheOnUserDeletion($user_id, $rat_user_id = 0)
105
+ {
106
+ $authors_to_clear = []; // Initialize.
107
+ $rat_user_id = (int) $rat_user_id;
108
+ $counter = $enqueued_notices = 0;
109
+
110
+ if (!($user_id = (int) $user_id)) {
111
+ return $counter; // Nothing to do.
112
+ } elseif (($done = &$this->cacheKey('autoClearAuthorPageCacheOnUserDeletion', [$user_id, $rat_user_id]))) {
113
+ return $counter; // Already did this.
114
+ }
115
+ $done = true; // Flag as having been done.
116
+
117
+ if (!$this->options['enable']) {
118
+ return $counter; // Nothing to do.
119
+ } elseif (!$this->options['cache_clear_author_page_enable']) {
120
+ return $counter; // Nothing to do.
121
+ } elseif (!is_dir($cache_dir = $this->cacheDir())) {
122
+ return $counter; // Nothing to do.
123
+ }
124
+ if (($WP_User = new \WP_User($user_id)) && $WP_User->exists() && $WP_User->has_cap('edit_posts')) {
125
+ $authors_to_clear[$WP_User->ID]['posts_url'] = get_author_posts_url($WP_User->ID);
126
+ $authors_to_clear[$WP_User->ID]['display_name'] = get_the_author_meta('display_name', $WP_User->ID);
127
+ }
128
+ if ($rat_user_id && ($rat_WP_User = new \WP_User($rat_user_id)) && $rat_WP_User->exists() && $rat_WP_User->has_cap('edit_posts')) {
129
+ $authors_to_clear[$rat_WP_User->ID]['posts_url'] = get_author_posts_url($rat_WP_User->ID);
130
+ $authors_to_clear[$rat_WP_User->ID]['display_name'] = get_the_author_meta('display_name', $rat_WP_User->ID);
131
+ }
132
+ if (!$authors_to_clear) {
133
+ return $counter; // Nothing to do.
134
+ }
135
+ foreach ($authors_to_clear as $_author) {
136
+ $_author_regex = $this->buildHostCachePathRegex($_author['posts_url']);
137
+ $_author_counter = $this->clearFilesFromHostCacheDir($_author_regex);
138
+ $counter += $_author_counter; // Add to overall counter.
139
+
140
+ if ($_author_counter && $enqueued_notices < 100 && is_admin() && (!IS_PRO || $this->options['change_notifications_enable'])) {
141
+ $this->enqueueNotice(sprintf(__('Found %1$s in the cache for Author Page: <code>%2$s</code>; auto-clearing.', 'comet-cache'), esc_html($this->i18nFiles($_author_counter)), esc_html($_author['display_name'])), ['combinable' => true]);
142
+ ++$enqueued_notices; // Increment enqueued notices counter.
143
+ }
144
+ // @TODO Consider clearing other cached locations here too.
145
+ } // unset($_author, $_author_regex, $_author_counter); // Housekeeping.
146
+
147
+ return $counter;
148
+ }
149
  }
src/includes/traits/Plugin/WcpFeedUtils.php CHANGED
@@ -27,23 +27,20 @@ trait WcpFeedUtils
27
  if (!($type = (string) $type)) {
28
  return $counter; // Nothing we can do.
29
  }
30
- $post_id = (integer) $post_id; // Force integer.
31
 
32
- if (!is_null($done = &$this->cacheKey('autoClearXmlFeedsCache', [$type, $post_id]))) {
33
  return $counter; // Already did this.
34
  }
35
  $done = true; // Flag as having been done.
36
 
37
  if (!$this->options['enable']) {
38
  return $counter; // Nothing to do.
39
- }
40
- if (!$this->options['feeds_enable']) {
41
  return $counter; // Nothing to do.
42
- }
43
- if (!$this->options['cache_clear_xml_feeds_enable']) {
44
  return $counter; // Nothing to do.
45
- }
46
- if (!is_dir($cache_dir = $this->cacheDir())) {
47
  return $counter; // Nothing to do.
48
  }
49
  $utils = new Classes\FeedUtils(); // Feed utilities.
@@ -106,12 +103,12 @@ trait WcpFeedUtils
106
  return $counter; // Nothing to do here.
107
  }
108
  $in_sets_of = $this->applyWpFilters(GLOBAL_NS.'_autoClearXmlFeedsCache_in_sets_of', 10, get_defined_vars());
 
109
  for ($_i = 0; $_i < count($variation_regex_frags); $_i = $_i + $in_sets_of) {
110
  $_variation_regex_frags = array_slice($variation_regex_frags, $_i, $in_sets_of);
111
  $_regex = '/^\/(?:'.implode('|', $_variation_regex_frags).')\./i';
112
  $counter += $this->clearFilesFromHostCacheDir($_regex);
113
- }
114
- unset($_i, $_variation_regex_frags, $_regex); // Housekeeping.
115
 
116
  if ($counter && is_admin() && (!IS_PRO || $this->options['change_notifications_enable'])) {
117
  $this->enqueueNotice(sprintf(__('Found %1$s in the cache, for XML feeds of type: <code>%2$s</code>; auto-clearing.', 'comet-cache'), esc_html($this->i18nFiles($counter)), esc_html($type)), ['combinable' => true]);
27
  if (!($type = (string) $type)) {
28
  return $counter; // Nothing we can do.
29
  }
30
+ $post_id = (int) $post_id; // Force integer.
31
 
32
+ if (($done = &$this->cacheKey('autoClearXmlFeedsCache', [$type, $post_id]))) {
33
  return $counter; // Already did this.
34
  }
35
  $done = true; // Flag as having been done.
36
 
37
  if (!$this->options['enable']) {
38
  return $counter; // Nothing to do.
39
+ } elseif (!$this->options['feeds_enable']) {
 
40
  return $counter; // Nothing to do.
41
+ } elseif (!$this->options['cache_clear_xml_feeds_enable']) {
 
42
  return $counter; // Nothing to do.
43
+ } elseif (!is_dir($cache_dir = $this->cacheDir())) {
 
44
  return $counter; // Nothing to do.
45
  }
46
  $utils = new Classes\FeedUtils(); // Feed utilities.
103
  return $counter; // Nothing to do here.
104
  }
105
  $in_sets_of = $this->applyWpFilters(GLOBAL_NS.'_autoClearXmlFeedsCache_in_sets_of', 10, get_defined_vars());
106
+
107
  for ($_i = 0; $_i < count($variation_regex_frags); $_i = $_i + $in_sets_of) {
108
  $_variation_regex_frags = array_slice($variation_regex_frags, $_i, $in_sets_of);
109
  $_regex = '/^\/(?:'.implode('|', $_variation_regex_frags).')\./i';
110
  $counter += $this->clearFilesFromHostCacheDir($_regex);
111
+ } // unset($_i, $_variation_regex_frags, $_regex); // Housekeeping.
 
112
 
113
  if ($counter && is_admin() && (!IS_PRO || $this->options['change_notifications_enable'])) {
114
  $this->enqueueNotice(sprintf(__('Found %1$s in the cache, for XML feeds of type: <code>%2$s</code>; auto-clearing.', 'comet-cache'), esc_html($this->i18nFiles($counter)), esc_html($type)), ['combinable' => true]);
src/includes/traits/Shared/BlogUtils.php CHANGED
@@ -5,6 +5,34 @@ use WebSharks\CometCache\Classes;
5
 
6
  trait BlogUtils
7
  {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
  /**
9
  * Get blog details.
10
  *
@@ -21,11 +49,11 @@ trait BlogUtils
21
  if (!is_multisite() || $this->isAdvancedCache()) {
22
  return null; // Not possible.
23
  }
24
- if (($blog_id = (integer) $blog_id) < 0) {
25
- $blog_id = (integer) get_current_site()->blog_id;
26
  }
27
  if (!$blog_id) {
28
- $blog_id = (integer) get_current_blog_id();
29
  }
30
  if (!$blog_id || $blog_id < 0) {
31
  return null; // Not possible.
5
 
6
  trait BlogUtils
7
  {
8
+ /**
9
+ * Get child blogs.
10
+ *
11
+ * @since 161221 Replacing `wp_get_sites()`.
12
+ *
13
+ * @return array An array of child blogs (max 100).
14
+ *
15
+ * @note The return value of this function is NOT cached in support of `$GLOBALS['wpdb']->siteid`.
16
+ */
17
+ public function getBlogs()
18
+ {
19
+ if (!is_multisite()) {
20
+ return []; // Not possible.
21
+ }
22
+ $sites = []; // Initialize.
23
+
24
+ foreach (get_sites([
25
+ 'number' => 100, 'count' => false,
26
+ 'network_id' => $GLOBALS['wpdb']->siteid,
27
+ ]) as $_site) {
28
+ if (($_site = get_site($_site))) {
29
+ $sites[] = $_site->to_array();
30
+ } // For compatibiliey with old `wp_get_sites()`.
31
+ } // unset($_site);
32
+
33
+ return $sites;
34
+ }
35
+
36
  /**
37
  * Get blog details.
38
  *
49
  if (!is_multisite() || $this->isAdvancedCache()) {
50
  return null; // Not possible.
51
  }
52
+ if (($blog_id = (int) $blog_id) < 0) {
53
+ $blog_id = (int) get_current_site()->blog_id;
54
  }
55
  if (!$blog_id) {
56
+ $blog_id = (int) get_current_blog_id();
57
  }
58
  if (!$blog_id || $blog_id < 0) {
59
  return null; // Not possible.
src/includes/traits/Shared/CacheDirUtils.php CHANGED
@@ -106,6 +106,7 @@ trait CacheDirUtils
106
  * @param bool $check_max_age Check max age? i.e., use purge behavior?
107
  *
108
  * @throws \Exception If unable to delete a file for any reason.
 
109
  * @return int Total files deleted by this routine (if any).
110
  *
111
  *
@@ -166,7 +167,6 @@ trait CacheDirUtils
166
  // Actual `http|https/...` cache links/files are nested. Links/files in the immediate directory are for other purposes.
167
  }
168
  switch ($_resource_type) {// Based on type; i.e., `link`, `file`, `dir`.
169
-
170
  case 'link': // Symbolic links; i.e., 404 errors.
171
 
172
  if ($check_max_age && !empty($max_age) && is_file($_resource->getLinkTarget())) {
@@ -201,7 +201,7 @@ trait CacheDirUtils
201
 
202
  case 'dir': // A regular directory; i.e., not a symlink.
203
 
204
- if ($regex !== '/^.+/i') {
205
  break; // Not deleting everything.
206
  }
207
  if ($check_max_age && !empty($max_age)) {
@@ -251,8 +251,8 @@ trait CacheDirUtils
251
  * @param bool $___consider_domain_mapping_host_base_dir_tokens For internal use only.
252
  *
253
  * @throws \Exception If unable to delete a file for any reason.
254
- * @return int Total files deleted by this routine (if any).
255
  *
 
256
  */
257
  public function deleteFilesFromHostCacheDir(
258
  $regex,
@@ -344,7 +344,6 @@ trait CacheDirUtils
344
  // Actual `http|https/...` cache links/files are nested. Links/files in the immediate directory are for other purposes.
345
  }
346
  switch ($_resource_type) {// Based on type; i.e., `link`, `file`, `dir`.
347
-
348
  case 'link': // Symbolic links; i.e., 404 errors.
349
 
350
  if ($check_max_age && !empty($max_age) && is_file($_resource->getLinkTarget())) {
@@ -379,7 +378,7 @@ trait CacheDirUtils
379
 
380
  case 'dir': // A regular directory; i.e., not a symlink.
381
 
382
- if ($regex !== '/^.+/i') {
383
  break; // Not deleting everything.
384
  }
385
  if ($check_max_age && !empty($max_age)) {
@@ -455,8 +454,8 @@ trait CacheDirUtils
455
  * @param bool $delete_dir_too Delete parent? i.e., delete the `$dir` itself also?
456
  *
457
  * @throws \Exception If unable to delete a file/directory for any reason.
458
- * @return int Total files/directories deleted by this routine (if any).
459
  *
 
460
  */
461
  public function deleteAllFilesDirsIn($dir, $delete_dir_too = false)
462
  {
@@ -485,13 +484,12 @@ trait CacheDirUtils
485
  if (!rename($dir, $dir_temp)) {
486
  throw new \Exception(sprintf(__('Unable to delete all files/dirs. Rename failure on tmp directory: `%1$s`.', 'comet-cache'), $dir));
487
  }
488
- foreach (($_dir_regex_iteration = $this->dirRegexIteration($dir_temp, '/.+/')) as $_resource) {
489
  $_resource_type = $_resource->getType();
490
  $_sub_path_name = $_resource->getSubpathname();
491
  $_path_name = $_resource->getPathname();
492
 
493
  switch ($_resource_type) {// Based on type; i.e., `link`, `file`, `dir`.
494
-
495
  case 'link': // Symbolic links; i.e., 404 errors.
496
 
497
  if (!unlink($_path_name)) {
@@ -562,8 +560,8 @@ trait CacheDirUtils
562
  * @param bool $erase_dir_too Erase parent? i.e., erase the `$dir` itself also?
563
  *
564
  * @throws \Exception If unable to erase a file/directory for any reason.
565
- * @return int Total files/directories erased by this routine (if any).
566
  *
 
567
  */
568
  public function eraseAllFilesDirsIn($dir, $erase_dir_too = false)
569
  {
@@ -584,13 +582,12 @@ trait CacheDirUtils
584
  }
585
  clearstatcache(); // Clear stat cache to be sure we have a fresh start below.
586
 
587
- foreach (($_dir_regex_iteration = $this->dirRegexIteration($dir, '/.+/')) as $_resource) {
588
  $_resource_type = $_resource->getType();
589
  $_sub_path_name = $_resource->getSubpathname();
590
  $_path_name = $_resource->getPathname();
591
 
592
  switch ($_resource_type) {// Based on type; i.e., `link`, `file`, `dir`.
593
-
594
  case 'link': // Symbolic links; i.e., 404 errors.
595
 
596
  if (!unlink($_path_name)) {
106
  * @param bool $check_max_age Check max age? i.e., use purge behavior?
107
  *
108
  * @throws \Exception If unable to delete a file for any reason.
109
+ *
110
  * @return int Total files deleted by this routine (if any).
111
  *
112
  *
167
  // Actual `http|https/...` cache links/files are nested. Links/files in the immediate directory are for other purposes.
168
  }
169
  switch ($_resource_type) {// Based on type; i.e., `link`, `file`, `dir`.
 
170
  case 'link': // Symbolic links; i.e., 404 errors.
171
 
172
  if ($check_max_age && !empty($max_age) && is_file($_resource->getLinkTarget())) {
201
 
202
  case 'dir': // A regular directory; i.e., not a symlink.
203
 
204
+ if (!in_array(rtrim(str_replace(['^', '$'], '', $regex), 'ui'), ['/.*/', '/.+/'], true)) {
205
  break; // Not deleting everything.
206
  }
207
  if ($check_max_age && !empty($max_age)) {
251
  * @param bool $___consider_domain_mapping_host_base_dir_tokens For internal use only.
252
  *
253
  * @throws \Exception If unable to delete a file for any reason.
 
254
  *
255
+ * @return int Total files deleted by this routine (if any).
256
  */
257
  public function deleteFilesFromHostCacheDir(
258
  $regex,
344
  // Actual `http|https/...` cache links/files are nested. Links/files in the immediate directory are for other purposes.
345
  }
346
  switch ($_resource_type) {// Based on type; i.e., `link`, `file`, `dir`.
 
347
  case 'link': // Symbolic links; i.e., 404 errors.
348
 
349
  if ($check_max_age && !empty($max_age) && is_file($_resource->getLinkTarget())) {
378
 
379
  case 'dir': // A regular directory; i.e., not a symlink.
380
 
381
+ if (!in_array(rtrim(str_replace(['^', '$'], '', $regex), 'ui'), ['/.*/', '/.+/'], true)) {
382
  break; // Not deleting everything.
383
  }
384
  if ($check_max_age && !empty($max_age)) {
454
  * @param bool $delete_dir_too Delete parent? i.e., delete the `$dir` itself also?
455
  *
456
  * @throws \Exception If unable to delete a file/directory for any reason.
 
457
  *
458
+ * @return int Total files/directories deleted by this routine (if any).
459
  */
460
  public function deleteAllFilesDirsIn($dir, $delete_dir_too = false)
461
  {
484
  if (!rename($dir, $dir_temp)) {
485
  throw new \Exception(sprintf(__('Unable to delete all files/dirs. Rename failure on tmp directory: `%1$s`.', 'comet-cache'), $dir));
486
  }
487
+ foreach (($_dir_regex_iteration = $this->dirRegexIteration($dir_temp, '/.+/u')) as $_resource) {
488
  $_resource_type = $_resource->getType();
489
  $_sub_path_name = $_resource->getSubpathname();
490
  $_path_name = $_resource->getPathname();
491
 
492
  switch ($_resource_type) {// Based on type; i.e., `link`, `file`, `dir`.
 
493
  case 'link': // Symbolic links; i.e., 404 errors.
494
 
495
  if (!unlink($_path_name)) {
560
  * @param bool $erase_dir_too Erase parent? i.e., erase the `$dir` itself also?
561
  *
562
  * @throws \Exception If unable to erase a file/directory for any reason.
 
563
  *
564
+ * @return int Total files/directories erased by this routine (if any).
565
  */
566
  public function eraseAllFilesDirsIn($dir, $erase_dir_too = false)
567
  {
582
  }
583
  clearstatcache(); // Clear stat cache to be sure we have a fresh start below.
584
 
585
+ foreach (($_dir_regex_iteration = $this->dirRegexIteration($dir, '/.+/u')) as $_resource) {
586
  $_resource_type = $_resource->getType();
587
  $_sub_path_name = $_resource->getSubpathname();
588
  $_path_name = $_resource->getPathname();
589
 
590
  switch ($_resource_type) {// Based on type; i.e., `link`, `file`, `dir`.
 
591
  case 'link': // Symbolic links; i.e., 404 errors.
592
 
593
  if (!unlink($_path_name)) {
src/includes/traits/Shared/CachePathUtils.php CHANGED
@@ -63,8 +63,6 @@ trait CachePathUtils
63
  * @since 151220 Enhancing translation support.
64
  *
65
  * @return string Default cache-path suffix frag (regex).
66
- *
67
- * @TODO Use conditional to detect the AMP plugin (e.g., `isAmpInstalled()`) to avoid edge cases with the `|\/amp` regex here
68
  */
69
  public function cachePathRegexDefaultSuffixFrag()
70
  {
@@ -181,7 +179,6 @@ trait CachePathUtils
181
  if (!($flags & $this::CACHE_PATH_NO_QUV)) {
182
  if (!($flags & $this::CACHE_PATH_NO_QUERY)) {
183
  if (isset($url_parts['query']) && $url_parts['query'] !== '') {
184
-
185
  // Support for ignored GET vars.
186
  parse_str($url_parts['query'], $_query_vars);
187
  $_query_vars = $this->filterQueryVars($_query_vars);
@@ -206,11 +203,11 @@ trait CachePathUtils
206
  $cache_path = trim(preg_replace(['/\/+/u', '/\.+/u'], ['/', '.'], $cache_path), '/');
207
 
208
  if ($flags & $this::CACHE_PATH_ALLOW_WD_REGEX) {
209
- $cache_path = preg_replace('/[^a-z0-9\/.*\^$]/ui', '-', $cache_path);
210
  } elseif ($flags & $this::CACHE_PATH_ALLOW_WILDCARDS) {
211
- $cache_path = preg_replace('/[^a-z0-9\/.*]/ui', '-', $cache_path);
212
  } else {
213
- $cache_path = preg_replace('/[^a-z0-9\/.]/ui', '-', $cache_path);
214
  }
215
  if (!($flags & $this::CACHE_PATH_NO_EXT)) {
216
  $cache_path .= '.html';
@@ -224,7 +221,7 @@ trait CachePathUtils
224
  * @since 151114 Updated to support an arbitrary URL instead of a regex frag.
225
  *
226
  * @param string $url The input URL to convert. This CAN be left empty when necessary.
227
- * If empty, the final regex pattern will be `/^'.$regex_suffix_frag.'/i`.
228
  * If empty, it's a good idea to start `$regex_suffix_frag` with `.*?`.
229
  * @param string $regex_suffix_frag Regex fragment to come after the `$regex_frag`.
230
  * Defaults to: `(?:\/index)?(?:\.|\/(?:page\/[0-9]+|comment\-page\-[0-9]+)[.\/])`.
@@ -245,7 +242,7 @@ trait CachePathUtils
245
  $cache_path = $this->buildCachePath($url, '', '', $flags); // Without the scheme.
246
  $cache_path_regex = isset($cache_path[0]) ? '\/https?\/'.preg_quote($cache_path, '/') : '';
247
  }
248
- return '/^'.$cache_path_regex.$regex_suffix_frag.'/i';
249
  }
250
 
251
  /**
@@ -254,7 +251,7 @@ trait CachePathUtils
254
  * @since 150422 Rewrite. Updated 151002 w/ multisite compat. improvements.
255
  *
256
  * @param string $url The input URL to convert. This CAN be left empty when necessary.
257
- * If empty, the final regex pattern will be `/^'.$regex_suffix_frag.'/i`.
258
  * If empty, it's a good idea to start `$regex_suffix_frag` with `.*?`.
259
  * @param string $regex_suffix_frag Regex fragment to come after the relative cache/path regex frag.
260
  * Defaults to: `(?:\/index)?(?:\.|\/(?:page\/[0-9]+|comment\-page\-[0-9]+)[.\/])`.
@@ -291,7 +288,7 @@ trait CachePathUtils
291
  $abs_relative_cache_path_regex = isset($abs_relative_cache_path[0]) ? preg_quote($abs_relative_cache_path, '/') : '';
292
  }
293
  }
294
- return '/^'.$abs_relative_cache_path_regex.$regex_suffix_frag.'/i';
295
  }
296
 
297
  /**
@@ -303,7 +300,7 @@ trait CachePathUtils
303
  * This may also contain watered-down regex; i.e., `*^$` characters are OK here.
304
  * However, `^$` are discarded, as they are unnecessary in this context.
305
  *
306
- * If empty, the final regex pattern will be `/^'.$regex_suffix_frag.'/i`.
307
  * If empty, it's a good idea to start `$regex_suffix_frag` with `.*?`.
308
  * @param string $regex_suffix_frag Regex fragment to come after the `$regex_frag`.
309
  * Defaults to: `(?:\/index)?(?:\.|\/(?:page\/[0-9]+|comment\-page\-[0-9]+)[.\/])`.
@@ -324,7 +321,7 @@ trait CachePathUtils
324
  $cache_path = $this->buildCachePath($url, '', '', $flags); // Without the scheme.
325
  $cache_path_regex = isset($cache_path[0]) ? '\/https?\/'.$this->wdRegexToActualRegexFrag($cache_path) : '';
326
  }
327
- return '/^'.$cache_path_regex.$regex_suffix_frag.'/i';
328
  }
329
 
330
  /**
@@ -375,7 +372,7 @@ trait CachePathUtils
375
  * @since 151114 Moving this low-level routine into a method of a different name.
376
  *
377
  * @param string $regex_frag A regex fragment. This CAN be left empty when necessary.
378
- * If empty, the final regex pattern will be `/^'.$regex_suffix_frag.'/i`.
379
  * If empty, it's a good idea to start `$regex_suffix_frag` with `.*?`.
380
  * @param string $regex_suffix_frag Regex fragment to come after the `$regex_frag`.
381
  * Defaults to: `(?:\/index)?(?:\.|\/(?:page\/[0-9]+|comment\-page\-[0-9]+)[.\/])`.
@@ -389,6 +386,6 @@ trait CachePathUtils
389
  $regex_frag = (string) $regex_frag;
390
  $regex_suffix_frag = $this->cachePathRegexSuffixFrag($regex_suffix_frag);
391
 
392
- return '/^'.$regex_frag.$regex_suffix_frag.'/i';
393
  }
394
  }
63
  * @since 151220 Enhancing translation support.
64
  *
65
  * @return string Default cache-path suffix frag (regex).
 
 
66
  */
67
  public function cachePathRegexDefaultSuffixFrag()
68
  {
179
  if (!($flags & $this::CACHE_PATH_NO_QUV)) {
180
  if (!($flags & $this::CACHE_PATH_NO_QUERY)) {
181
  if (isset($url_parts['query']) && $url_parts['query'] !== '') {
 
182
  // Support for ignored GET vars.
183
  parse_str($url_parts['query'], $_query_vars);
184
  $_query_vars = $this->filterQueryVars($_query_vars);
203
  $cache_path = trim(preg_replace(['/\/+/u', '/\.+/u'], ['/', '.'], $cache_path), '/');
204
 
205
  if ($flags & $this::CACHE_PATH_ALLOW_WD_REGEX) {
206
+ $cache_path = preg_replace('/[^a-z0-9\/.+*\^$]/ui', '-', $cache_path);
207
  } elseif ($flags & $this::CACHE_PATH_ALLOW_WILDCARDS) {
208
+ $cache_path = preg_replace('/[^a-z0-9\/.+*]/ui', '-', $cache_path);
209
  } else {
210
+ $cache_path = preg_replace('/[^a-z0-9\/.+]/ui', '-', $cache_path);
211
  }
212
  if (!($flags & $this::CACHE_PATH_NO_EXT)) {
213
  $cache_path .= '.html';
221
  * @since 151114 Updated to support an arbitrary URL instead of a regex frag.
222
  *
223
  * @param string $url The input URL to convert. This CAN be left empty when necessary.
224
+ * If empty, the final regex pattern will be `/^'.$regex_suffix_frag.'/ui`.
225
  * If empty, it's a good idea to start `$regex_suffix_frag` with `.*?`.
226
  * @param string $regex_suffix_frag Regex fragment to come after the `$regex_frag`.
227
  * Defaults to: `(?:\/index)?(?:\.|\/(?:page\/[0-9]+|comment\-page\-[0-9]+)[.\/])`.
242
  $cache_path = $this->buildCachePath($url, '', '', $flags); // Without the scheme.
243
  $cache_path_regex = isset($cache_path[0]) ? '\/https?\/'.preg_quote($cache_path, '/') : '';
244
  }
245
+ return '/^'.$cache_path_regex.$regex_suffix_frag.'/ui';
246
  }
247
 
248
  /**
251
  * @since 150422 Rewrite. Updated 151002 w/ multisite compat. improvements.
252
  *
253
  * @param string $url The input URL to convert. This CAN be left empty when necessary.
254
+ * If empty, the final regex pattern will be `/^'.$regex_suffix_frag.'/ui`.
255
  * If empty, it's a good idea to start `$regex_suffix_frag` with `.*?`.
256
  * @param string $regex_suffix_frag Regex fragment to come after the relative cache/path regex frag.
257
  * Defaults to: `(?:\/index)?(?:\.|\/(?:page\/[0-9]+|comment\-page\-[0-9]+)[.\/])`.
288
  $abs_relative_cache_path_regex = isset($abs_relative_cache_path[0]) ? preg_quote($abs_relative_cache_path, '/') : '';
289
  }
290
  }
291
+ return '/^'.$abs_relative_cache_path_regex.$regex_suffix_frag.'/ui';
292
  }
293
 
294
  /**
300
  * This may also contain watered-down regex; i.e., `*^$` characters are OK here.
301
  * However, `^$` are discarded, as they are unnecessary in this context.
302
  *
303
+ * If empty, the final regex pattern will be `/^'.$regex_suffix_frag.'/ui`.
304
  * If empty, it's a good idea to start `$regex_suffix_frag` with `.*?`.
305
  * @param string $regex_suffix_frag Regex fragment to come after the `$regex_frag`.
306
  * Defaults to: `(?:\/index)?(?:\.|\/(?:page\/[0-9]+|comment\-page\-[0-9]+)[.\/])`.
321
  $cache_path = $this->buildCachePath($url, '', '', $flags); // Without the scheme.
322
  $cache_path_regex = isset($cache_path[0]) ? '\/https?\/'.$this->wdRegexToActualRegexFrag($cache_path) : '';
323
  }
324
+ return '/^'.$cache_path_regex.$regex_suffix_frag.'/ui';
325
  }
326
 
327
  /**
372
  * @since 151114 Moving this low-level routine into a method of a different name.
373
  *
374
  * @param string $regex_frag A regex fragment. This CAN be left empty when necessary.
375
+ * If empty, the final regex pattern will be `/^'.$regex_suffix_frag.'/ui`.
376
  * If empty, it's a good idea to start `$regex_suffix_frag` with `.*?`.
377
  * @param string $regex_suffix_frag Regex fragment to come after the `$regex_frag`.
378
  * Defaults to: `(?:\/index)?(?:\.|\/(?:page\/[0-9]+|comment\-page\-[0-9]+)[.\/])`.
386
  $regex_frag = (string) $regex_frag;
387
  $regex_suffix_frag = $this->cachePathRegexSuffixFrag($regex_suffix_frag);
388
 
389
+ return '/^'.$regex_frag.$regex_suffix_frag.'/ui';
390
  }
391
  }
src/includes/traits/Shared/ConditionalUtils.php CHANGED
@@ -8,7 +8,7 @@ trait ConditionalUtils
8
  /**
9
  * PHP's language constructs.
10
  *
11
- * @var array PHP's language constructs.
12
  * @note Keys unimportant; subject to change.
13
  *
14
  * @since 160222 First documented version.
@@ -152,6 +152,10 @@ trait ConditionalUtils
152
  $regex_logged_in_cookies .= '/'; // Close regex.
153
 
154
  foreach ($_COOKIE as $_key => $_value) {
 
 
 
 
155
  $_key = (string) $_key;
156
  $_value = (string) $_value;
157
 
@@ -321,7 +325,7 @@ trait ConditionalUtils
321
  */
322
  public function functionIsPossible($function)
323
  {
324
- $function = (string) $function;
325
 
326
  if (($is = &$this->staticKey(__FUNCTION__, $function)) !== null) {
327
  return $is; // Already cached this.
@@ -335,17 +339,16 @@ trait ConditionalUtils
335
  if (($blacklist_functions = trim(ini_get('suhosin.executor.func.blacklist')))) {
336
  $disabled_functions = array_merge($disabled_functions, preg_split('/[\s;,]+/', mb_strtolower($blacklist_functions), -1, PREG_SPLIT_NO_EMPTY));
337
  }
 
 
 
338
  if (filter_var(ini_get('suhosin.executor.disable_eval'), FILTER_VALIDATE_BOOLEAN)) {
339
  $disabled_functions = array_merge($disabled_functions, ['eval']);
340
  }
341
  }
342
- if (!function_exists($function) || !is_callable($function)) {
343
- if (!in_array($function, $this->php_constructs, true)) {
344
- return $is = false; // Not possible.
345
- }
346
- } // In PHP, language constructs cannot be disabled/blacklisted whatsoever.
347
-
348
- if ($disabled_functions && in_array(mb_strtolower($function), $disabled_functions, true)) {
349
  return $is = false; // Not possible.
350
  }
351
  return $is = true;
8
  /**
9
  * PHP's language constructs.
10
  *
11
+ * @type array PHP's language constructs.
12
  * @note Keys unimportant; subject to change.
13
  *
14
  * @since 160222 First documented version.
152
  $regex_logged_in_cookies .= '/'; // Close regex.
153
 
154
  foreach ($_COOKIE as $_key => $_value) {
155
+ if (!is_scalar($_value)) {
156
+ continue; // See https://git.io/v1dTw
157
+ }
158
+
159
  $_key = (string) $_key;
160
  $_value = (string) $_value;
161
 
325
  */
326
  public function functionIsPossible($function)
327
  {
328
+ $function = mb_strtolower((string) $function);
329
 
330
  if (($is = &$this->staticKey(__FUNCTION__, $function)) !== null) {
331
  return $is; // Already cached this.
339
  if (($blacklist_functions = trim(ini_get('suhosin.executor.func.blacklist')))) {
340
  $disabled_functions = array_merge($disabled_functions, preg_split('/[\s;,]+/', mb_strtolower($blacklist_functions), -1, PREG_SPLIT_NO_EMPTY));
341
  }
342
+ if (($opcache_restrict_api = trim(ini_get('opcache.restrict_api'))) && mb_stripos(__FILE__, $opcache_restrict_api) !== 0) {
343
+ $disabled_functions = array_merge($disabled_functions, ['opcache_compile_file', 'opcache_get_configuration', 'opcache_get_status', 'opcache_invalidate', 'opcache_is_script_cached', 'opcache_reset']);
344
+ }
345
  if (filter_var(ini_get('suhosin.executor.disable_eval'), FILTER_VALIDATE_BOOLEAN)) {
346
  $disabled_functions = array_merge($disabled_functions, ['eval']);
347
  }
348
  }
349
+ if ($disabled_functions && in_array($function, $disabled_functions, true)) {
350
+ return $is = false; // Not possible.
351
+ } elseif ((!function_exists($function) || !is_callable($function)) && !in_array($function, $this->php_constructs, true)) {
 
 
 
 
352
  return $is = false; // Not possible.
353
  }
354
  return $is = true;
src/includes/traits/Shared/FsUtils.php CHANGED
@@ -151,8 +151,7 @@ trait FsUtils
151
  $dir_iterator = new \RecursiveDirectoryIterator($dir, \FilesystemIterator::KEY_AS_PATHNAME | \FilesystemIterator::CURRENT_AS_SELF | \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::UNIX_PATHS);
152
  $iterator_iterator = new \RecursiveIteratorIterator($dir_iterator, \RecursiveIteratorIterator::CHILD_FIRST);
153
 
154
- if ($regex && $regex !== '/.*/' && $regex !== '/.+/') { // Apply regex filter?
155
- // @TODO Optimize calls to this method in order to avoid the regex iterator when not necessary.
156
  return new \RegexIterator($iterator_iterator, $regex, \RegexIterator::MATCH, \RegexIterator::USE_KEY);
157
  }
158
  return $iterator_iterator; // Iterate everything.
@@ -171,7 +170,7 @@ trait FsUtils
171
  public function bytesAbbr($bytes, $precision = 2)
172
  {
173
  $bytes = max(0.0, (float) $bytes);
174
- $precision = max(0, (integer) $precision);
175
  $units = ['bytes', 'kbs', 'MB', 'GB', 'TB'];
176
 
177
  $power = floor(($bytes ? log($bytes) : 0) / log(1024));
151
  $dir_iterator = new \RecursiveDirectoryIterator($dir, \FilesystemIterator::KEY_AS_PATHNAME | \FilesystemIterator::CURRENT_AS_SELF | \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::UNIX_PATHS);
152
  $iterator_iterator = new \RecursiveIteratorIterator($dir_iterator, \RecursiveIteratorIterator::CHILD_FIRST);
153
 
154
+ if ($regex && !in_array(rtrim(str_replace(['^', '$'], '', $regex), 'ui'), ['/.*/', '/.+/'], true)) { // Apply regex filter?
 
155
  return new \RegexIterator($iterator_iterator, $regex, \RegexIterator::MATCH, \RegexIterator::USE_KEY);
156
  }
157
  return $iterator_iterator; // Iterate everything.
170
  public function bytesAbbr($bytes, $precision = 2)
171
  {
172
  $bytes = max(0.0, (float) $bytes);
173
+ $precision = max(0, (int) $precision);
174
  $units = ['bytes', 'kbs', 'MB', 'GB', 'TB'];
175
 
176
  $power = floor(($bytes ? log($bytes) : 0) / log(1024));
src/vendor/autoload.php CHANGED
@@ -4,4 +4,4 @@
4
 
5
  require_once __DIR__ . '/composer' . '/autoload_real.php';
6
 
7
- return ComposerAutoloaderInite04c11378fd6d65cfa7ace2de8ffa898::getLoader();
4
 
5
  require_once __DIR__ . '/composer' . '/autoload_real.php';
6
 
7
+ return ComposerAutoloaderInit958f5164d6bdff050048118f7698d0e4::getLoader();
src/vendor/composer/autoload_classmap.php CHANGED
@@ -81,9 +81,4 @@ return array(
81
  'WebSharks\\CometCache\\Traits\\Shared\\TokenUtils' => $baseDir . '/src/includes/traits/Shared/TokenUtils.php',
82
  'WebSharks\\CometCache\\Traits\\Shared\\TrimUtils' => $baseDir . '/src/includes/traits/Shared/TrimUtils.php',
83
  'WebSharks\\CometCache\\Traits\\Shared\\UrlUtils' => $baseDir . '/src/includes/traits/Shared/UrlUtils.php',
84
- 'WebSharks\\CssMinifier\\Core' => $vendorDir . '/websharks/css-minifier/src/includes/classes/Core.php',
85
- 'WebSharks\\HtmlCompressor\\Benchmark' => $vendorDir . '/websharks/html-compressor/src/includes/classes/Benchmark.php',
86
- 'WebSharks\\HtmlCompressor\\Core' => $vendorDir . '/websharks/html-compressor/src/includes/classes/Core.php',
87
- 'WebSharks\\HtmlCompressor\\HookApi' => $vendorDir . '/websharks/html-compressor/src/includes/classes/HookApi.php',
88
- 'WebSharks\\JsMinifier\\Core' => $vendorDir . '/websharks/js-minifier/src/includes/classes/Core.php',
89
  );
81
  'WebSharks\\CometCache\\Traits\\Shared\\TokenUtils' => $baseDir . '/src/includes/traits/Shared/TokenUtils.php',
82
  'WebSharks\\CometCache\\Traits\\Shared\\TrimUtils' => $baseDir . '/src/includes/traits/Shared/TrimUtils.php',
83
  'WebSharks\\CometCache\\Traits\\Shared\\UrlUtils' => $baseDir . '/src/includes/traits/Shared/UrlUtils.php',
 
 
 
 
 
84
  );
src/vendor/composer/autoload_psr4.php CHANGED
@@ -6,9 +6,6 @@ $vendorDir = dirname(dirname(__FILE__));
6
  $baseDir = dirname(dirname($vendorDir));
7
 
8
  return array(
9
- 'WebSharks\\JsMinifier\\' => array($vendorDir . '/websharks/js-minifier/src/includes/classes'),
10
- 'WebSharks\\HtmlCompressor\\' => array($vendorDir . '/websharks/html-compressor/src/includes/classes'),
11
- 'WebSharks\\CssMinifier\\' => array($vendorDir . '/websharks/css-minifier/src/includes/classes'),
12
  'WebSharks\\CometCache\\Traits\\' => array($baseDir . '/src/includes/traits'),
13
  'WebSharks\\CometCache\\Interfaces\\' => array($baseDir . '/src/includes/interfaces'),
14
  'WebSharks\\CometCache\\Classes\\' => array($baseDir . '/src/includes/classes'),
6
  $baseDir = dirname(dirname($vendorDir));
7
 
8
  return array(
 
 
 
9
  'WebSharks\\CometCache\\Traits\\' => array($baseDir . '/src/includes/traits'),
10
  'WebSharks\\CometCache\\Interfaces\\' => array($baseDir . '/src/includes/interfaces'),
11
  'WebSharks\\CometCache\\Classes\\' => array($baseDir . '/src/includes/classes'),
src/vendor/composer/autoload_real.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
- class ComposerAutoloaderInite04c11378fd6d65cfa7ace2de8ffa898
6
  {
7
  private static $loader;
8
 
@@ -19,9 +19,9 @@ class ComposerAutoloaderInite04c11378fd6d65cfa7ace2de8ffa898
19
  return self::$loader;
20
  }
21
 
22
- spl_autoload_register(array('ComposerAutoloaderInite04c11378fd6d65cfa7ace2de8ffa898', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
- spl_autoload_unregister(array('ComposerAutoloaderInite04c11378fd6d65cfa7ace2de8ffa898', 'loadClassLoader'));
25
 
26
  $map = require __DIR__ . '/autoload_namespaces.php';
27
  foreach ($map as $namespace => $path) {
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
+ class ComposerAutoloaderInit958f5164d6bdff050048118f7698d0e4
6
  {
7
  private static $loader;
8
 
19
  return self::$loader;
20
  }
21
 
22
+ spl_autoload_register(array('ComposerAutoloaderInit958f5164d6bdff050048118f7698d0e4', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
+ spl_autoload_unregister(array('ComposerAutoloaderInit958f5164d6bdff050048118f7698d0e4', 'loadClassLoader'));
25
 
26
  $map = require __DIR__ . '/autoload_namespaces.php';
27
  foreach ($map as $namespace => $path) {
src/vendor/composer/installed.json CHANGED
@@ -1,177 +1,4 @@
1
  [
2
- {
3
- "name": "websharks/js-minifier",
4
- "version": "dev-master",
5
- "version_normalized": "9999999-dev",
6
- "source": {
7
- "type": "git",
8
- "url": "https://github.com/websharks/js-minifier.git",
9
- "reference": "3c1e99af6df9df8f691642fbb769a10e49bfba23"
10
- },
11
- "dist": {
12
- "type": "zip",
13
- "url": "https://api.github.com/repos/websharks/js-minifier/zipball/3c1e99af6df9df8f691642fbb769a10e49bfba23",
14
- "reference": "3c1e99af6df9df8f691642fbb769a10e49bfba23",
15
- "shasum": ""
16
- },
17
- "require": {
18
- "ext-mbstring": "*",
19
- "php": ">=5.3"
20
- },
21
- "time": "2015-05-11 20:53:04",
22
- "type": "library",
23
- "installation-source": "dist",
24
- "autoload": {
25
- "psr-4": {
26
- "WebSharks\\JsMinifier\\": "src/includes/classes"
27
- }
28
- },
29
- "notification-url": "https://packagist.org/downloads/",
30
- "license": [
31
- "GPL-3.0+"
32
- ],
33
- "authors": [
34
- {
35
- "name": "websharks",
36
- "homepage": "http://websharks-inc.com/",
37
- "role": "company"
38
- },
39
- {
40
- "name": "jaswsinc",
41
- "homepage": "http://jaswsinc.com/",
42
- "role": "developer"
43
- },
44
- {
45
- "name": "raamdev",
46
- "homepage": "http://raam.org/",
47
- "role": "developer"
48
- }
49
- ],
50
- "description": "Compresses JavaScript code.",
51
- "homepage": "https://github.com/websharks/js-minifier",
52
- "keywords": [
53
- "JS",
54
- "compressor",
55
- "javascript",
56
- "websharks"
57
- ]
58
- },
59
- {
60
- "name": "websharks/css-minifier",
61
- "version": "dev-master",
62
- "version_normalized": "9999999-dev",
63
- "source": {
64
- "type": "git",
65
- "url": "https://github.com/websharks/css-minifier.git",
66
- "reference": "da1d0254c41e1f59c7337aa444d743e6056046ff"
67
- },
68
- "dist": {
69
- "type": "zip",
70
- "url": "https://api.github.com/repos/websharks/css-minifier/zipball/da1d0254c41e1f59c7337aa444d743e6056046ff",
71
- "reference": "da1d0254c41e1f59c7337aa444d743e6056046ff",
72
- "shasum": ""
73
- },
74
- "require": {
75
- "ext-mbstring": "*",
76
- "php": ">=5.3"
77
- },
78
- "time": "2015-08-21 03:19:25",
79
- "type": "library",
80
- "installation-source": "dist",
81
- "autoload": {
82
- "psr-4": {
83
- "WebSharks\\CssMinifier\\": "src/includes/classes"
84
- }
85
- },
86
- "notification-url": "https://packagist.org/downloads/",
87
- "license": [
88
- "GPL-3.0+"
89
- ],
90
- "authors": [
91
- {
92
- "name": "websharks",
93
- "homepage": "http://websharks-inc.com/",
94
- "role": "company"
95
- },
96
- {
97
- "name": "jaswsinc",
98
- "homepage": "http://jaswsinc.com/",
99
- "role": "developer"
100
- },
101
- {
102
- "name": "raamdev",
103
- "homepage": "http://raam.org/",
104
- "role": "developer"
105
- }
106
- ],
107
- "description": "Compresses CSS.",
108
- "homepage": "https://github.com/websharks/css-minifier",
109
- "keywords": [
110
- "compressor",
111
- "css",
112
- "websharks"
113
- ]
114
- },
115
- {
116
- "name": "websharks/html-compressor",
117
- "version": "161108",
118
- "version_normalized": "161108",
119
- "source": {
120
- "type": "git",
121
- "url": "https://github.com/websharks/html-compressor.git",
122
- "reference": "73a047734ab585cfaaa3e54526a484b788d768f5"
123
- },
124
- "dist": {
125
- "type": "zip",
126
- "url": "https://api.github.com/repos/websharks/html-compressor/zipball/73a047734ab585cfaaa3e54526a484b788d768f5",
127
- "reference": "73a047734ab585cfaaa3e54526a484b788d768f5",
128
- "shasum": ""
129
- },
130
- "require": {
131
- "ext-curl": "*",
132
- "ext-mbstring": "*",
133
- "ext-openssl": "*",
134
- "php": ">=5.3",
135
- "websharks/css-minifier": "dev-master",
136
- "websharks/js-minifier": "dev-master"
137
- },
138
- "time": "2016-11-08 20:56:04",
139
- "type": "library",
140
- "installation-source": "dist",
141
- "autoload": {
142
- "psr-4": {
143
- "WebSharks\\HtmlCompressor\\": "src/includes/classes"
144
- }
145
- },
146
- "notification-url": "https://packagist.org/downloads/",
147
- "license": [
148
- "GPL-3.0+"
149
- ],
150
- "authors": [
151
- {
152
- "name": "websharks",
153
- "homepage": "http://websharks-inc.com/",
154
- "role": "company"
155
- },
156
- {
157
- "name": "jaswsinc",
158
- "homepage": "http://jaswsinc.com/",
159
- "role": "developer"
160
- },
161
- {
162
- "name": "raamdev",
163
- "homepage": "http://raam.org/",
164
- "role": "developer"
165
- }
166
- ],
167
- "description": "Combines & compresses CSS/JS/HTML code.",
168
- "homepage": "https://github.com/websharks/html-compressor",
169
- "keywords": [
170
- "compressor",
171
- "html",
172
- "websharks"
173
- ]
174
- },
175
  {
176
  "name": "websharks/sharkicons",
177
  "version": "160221",
1
  [
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  {
3
  "name": "websharks/sharkicons",
4
  "version": "160221",
src/vendor/websharks/sharkicons/CHANGELOG.md DELETED
@@ -1,3 +0,0 @@
1
- ## v15xxxx
2
-
3
- - Initial release.
 
 
 
src/vendor/websharks/sharkicons/README.md DELETED
@@ -1,154 +0,0 @@
1
- ## WebSharks™ Icon Font (Sharkicons)
2
-
3
- Font containing WebSharks logos/icons + many others; including FontAwesome! See: [**DEMO**](http://websharks.github.io/sharkicons/demo.html)
4
-
5
- _Contains over 750 icons. Total file size: 212kb (compare to stand-alone FontAwesome @ 136kb)._
6
-
7
- [![](https://img.shields.io/github/license/websharks/sharkicons.svg)](https://github.com/websharks/sharkicons/blob/HEAD/LICENSE.txt)
8
- [![](https://img.shields.io/badge/made-w%2F_100%25_pure_awesome_sauce-AB815F.svg?label=made)](http://websharks-inc.com/)
9
- [![](https://img.shields.io/badge/by-WebSharks_Inc.-656598.svg?label=by)](http://www.websharks-inc.com/team/)
10
- [![](https://img.shields.io/github/release/websharks/sharkicons.svg?label=latest)](https://github.com/websharks/sharkicons/releases)
11
- [![](https://img.shields.io/packagist/v/websharks/sharkicons.svg?label=packagist)](https://packagist.org/packages/websharks/sharkicons)
12
- [![](https://img.shields.io/github/issues/websharks/sharkicons.svg?label=issues)](https://github.com/websharks/sharkicons/issues)
13
- [![](https://img.shields.io/github/forks/websharks/sharkicons.svg?label=forks)](https://github.com/websharks/sharkicons/network)
14
- [![](https://img.shields.io/github/stars/websharks/sharkicons.svg?label=stars)](https://github.com/websharks/sharkicons/stargazers)
15
- [![](https://img.shields.io/github/downloads/websharks/sharkicons/latest/total.svg?label=downloads)](https://github.com/websharks/sharkicons/releases)
16
- [![](https://img.shields.io/packagist/dt/websharks/sharkicons.svg?label=packagist)](https://packagist.org/packages/websharks/sharkicons)
17
-
18
- ---
19
-
20
- ![](assets/screenshot.png)
21
-
22
- ---
23
-
24
- ## Using Icons in HTML Markup
25
-
26
- ```html
27
- <link rel="stylesheet" type="text/css" href="/path/to/sharkicons/src/long-classes.min.css" />
28
- ```
29
-
30
- ```html
31
- <i class="sharkicon sharkicon-broom"></i>
32
- ```
33
-
34
- ---
35
-
36
- ## Short Classes (`si-` instead of `sharkicon-`)
37
-
38
- ```html
39
- <link rel="stylesheet" type="text/css" href="/path/to/sharkicons/src/short-classes.min.css" />
40
- ```
41
-
42
- ```html
43
- <i class="si si-broom"></i>
44
- ```
45
-
46
- ---
47
-
48
- ## Including Classes via SCSS
49
-
50
- _**Note:** Bourbon is a required dependency. See: <http://bourbon.io/> for details._
51
-
52
- ```scss
53
- @import '/path/to/bourbon';
54
- @import '/path/to/sharkicons/src/sharkicons';
55
- @include sharkicons-font('/path/to/sharkicons/src');
56
- @include sharkicon-short-classes;
57
- ```
58
-
59
- ---
60
-
61
- ## Custom Classes via SCSS (`prefix` instead of `si`)
62
-
63
- ```scss
64
- @import '/path/to/bourbon';
65
- @import '/path/to/sharkicons/src/sharkicons';
66
- @include sharkicons-font('/path/to/sharkicons/src');
67
- @include sharkicon-custom-classes(prefix);
68
- ```
69
-
70
- ---
71
-
72
- ## Scoping Classes via SCSS
73
-
74
- ```scss
75
- @import '/path/to/bourbon';
76
- @import '/path/to/sharkicons/src/sharkicons';
77
- @include sharkicons-font('/path/to/sharkicons/src');
78
-
79
- .my-product {
80
- @include sharkicon-short-classes;
81
- }
82
- ```
83
-
84
- ---
85
-
86
- ## Creating an Icon via SCSS
87
-
88
- _Note: you can do this without including the `sharkicon-[long|short]-classes` if you like._
89
-
90
- ```scss
91
- @import '/path/to/bourbon';
92
- @import '/path/to/sharkicons/src/sharkicons';
93
- @include sharkicons-font('/path/to/sharkicons/src');
94
- // @include sharkicon-short-classes;
95
-
96
- .my-product .my-icon {
97
- @include sharkicon(broom);
98
- }
99
- ```
100
-
101
- Equivalent to:
102
-
103
- ```css
104
- .my-product .my-icon::before {
105
- content: '\e000';
106
- font: normal normal normal 14px/1 sharkicons;
107
- text-rendering: optimizeLegibility;
108
- -webkit-font-smoothing: antialiased;
109
- font-smoothing: antialiased;
110
- display: inline-block;
111
- font-size: inherit;
112
- text-decoration: inherit;
113
- text-transform: none;
114
- }
115
- ```
116
-
117
- Alternatively, you can pass a second argument to `sharkicon()` to set the before/after specification. The default value is `before`. You might want to change it to `after` in some special case.
118
-
119
- ```scss
120
- @import '/path/to/bourbon';
121
- @import '/path/to/sharkicons/src/sharkicons';
122
- @include sharkicons-font('/path/to/sharkicons/src');
123
- // @include sharkicon-short-classes;
124
-
125
- .my-product .my-icon {
126
- @include sharkicon(broom, after);
127
- }
128
- ```
129
-
130
- Equivalent to:
131
-
132
- ```css
133
- .my-product .my-icon::after {
134
- content: '\e000';
135
- font: normal normal normal 14px/1 sharkicons;
136
- text-rendering: optimizeLegibility;
137
- -webkit-font-smoothing: antialiased;
138
- font-smoothing: antialiased;
139
- display: inline-block;
140
- font-size: inherit;
141
- text-decoration: inherit;
142
- text-transform: none;
143
- }
144
- ```
145
-
146
- ---
147
-
148
- ## Mapping An Icon Char via SCSS
149
-
150
- ```scss
151
- .my-product .my-icon:hover::after {
152
- content: map-get($sharkicons, broom);
153
- }
154
- ```
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/vendor/websharks/wp-php-rv/CHANGELOG.md DELETED
@@ -1,43 +0,0 @@
1
- ## v160824.6416
2
-
3
- - Bug fix. Array not initialized properly. See: #12
4
-
5
- ## v160712.42603
6
-
7
- - **Bug fix:** Required PHP extension checks failing.
8
- - **New Feature:** Now possible to require specific PHP functions too; e.g., `eval()`.
9
- - Updating to latest phing build system.
10
- - Updating dotfiles.
11
-
12
- ## v160531.14034
13
-
14
- - Adding phing build files.
15
-
16
- ## v160524
17
-
18
- - Adding support for an array of compatible operating systems.
19
- - Adding support for a minimum version of WordPress.
20
- - Adding support for a maximum version of WordPress.
21
-
22
- ## v160504
23
-
24
- - Adding support for required bits via `$GLOBALS['wp_php_rv']['bits'] = 64;`
25
-
26
- ![2016-05-04_23-42-50](https://cloud.githubusercontent.com/assets/1563559/15038648/fb5fb04e-1251-11e6-96d6-af1a563413f1.png)
27
-
28
- ## v160503
29
-
30
- - Enhancing display of notice.
31
- - Reorganizing functions into multiple files.
32
- - Backward compatibility was preserved in all cases.
33
-
34
- ![](https://github.com/websharks/wp-php-rv/raw/000000-dev/assets/screenshot.png)
35
-
36
- ## v160420
37
-
38
- - Adding `composer.json` and enhancing Composer integration.
39
- - General cleanup. No significant changes.
40
-
41
- ## v15xxxx
42
-
43
- - Initial release.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/vendor/websharks/wp-php-rv/README.md DELETED
@@ -1,124 +0,0 @@
1
- ## WP PHP vX.x+ (Version Check w/ Dashboard Notice)
2
-
3
- Stub for WordPress themes/plugins that require PHP vX.x+ (i.e. a minimum version that you define).
4
-
5
- ![](assets/screenshot.png)
6
-
7
- ---
8
-
9
- ### Example Usage in a Typical WordPress Theme/Plugin File
10
-
11
- ```php
12
- <?php
13
- /*
14
- Plugin Name: My Plugin
15
- Plugin URI: http://example.com/my-plugin
16
- Description: Example plugin.
17
- Author: Example Author.
18
- Version: 0.1-alpha
19
- Author URI: http://example.com
20
- Text Domain: my-plugin
21
- */
22
- $GLOBALS['wp_php_rv'] = '5.3'; // Require PHP vX.x+ (you configure this).
23
- if(require('wp-php-rv/src/includes/check.php')) // `true` if running PHP vX.x+.
24
- require dirname(__FILE__).'/my-plugin-code.php'; // It's OK to load your plugin.
25
- else wp_php_rv_notice(); // Creates a nice PHP vX.x+ dashboard notice for the site owner.
26
- ```
27
-
28
- ---
29
-
30
- ### Alternate Approach
31
-
32
- The `check.php` file will automatically return `true` upon using `include()` or `require()` in your scripts; i.e., iff the installation site is running PHP vX.x+ (as configured by `$GLOBALS['wp_php_rv']`). Otherwise it returns `false`. Therefore, the simplest way to run your check is to use `if(require('wp-php-rv/src/includes/check.php'))`. **However**, you could also choose to do it this way.
33
-
34
- ```php
35
- <?php
36
- $GLOBALS['wp_php_rv'] = '5.3'; // Require PHP vX.x+.
37
- require 'wp-php-rv/src/includes/check.php'; // Include.
38
-
39
- if(wp_php_rv()) // `true` if running PHP vX.x+.
40
- require dirname(__FILE__).'/my-plugin-code.php'; // It's OK to load your plugin.
41
- else wp_php_rv_notice(); // Creates a nice PHP vX.x+ dashboard notice for the site owner.
42
- ```
43
-
44
- ---
45
-
46
- ### Dashboard Notice that Calls your Software by Name
47
-
48
- ```php
49
- <?php
50
- $GLOBALS['wp_php_rv'] = '5.3'; // Require PHP vX.x+.
51
- if(require('wp-php-rv/src/includes/check.php')) // `true` if running PHP vX.x+.
52
- require dirname(__FILE__).'/my-plugin-code.php'; // It's OK to load your plugin.
53
- else wp_php_rv_notice('My Plugin'); // Dashboard notice mentions your software specifically.
54
- ```
55
-
56
- **Note:** If you omit the `$brand_name` argument, a default value is used instead. The default value is `ucwords('[calling file basedir]')`; e.g., if `/my-plugin/stub.php` calls `wp-php-rv/src/includes/check.php`, the default `$software_name` automatically becomes `My Plugin`. Nice!
57
-
58
- ---
59
-
60
- ### What if multiple themes/plugins use this?
61
-
62
- This is fine! :-) The `wp-php-rv/src/includes/check.php` file uses `function_exists()` as a wrapper; which allows it to be included any number of times, and by any number of plugins; and also from any number of locations. **The only thing to remember**, is that you MUST be sure to define `$GLOBALS['wp_php_rv']` each time; i.e., each time you `include('wp-php-rv/src/includes/check.php')` or `require('wp-php-rv/src/includes/check.php')`.
63
-
64
- The point here, is that `$GLOBALS['wp_php_rv']` defines a PHP version that is specific to your plugin requirements, so it should be defined explicitly by each plugin developer before they `include('wp-php-rv/src/includes/check.php')` or `require('wp-php-rv/src/includes/check.php')`.
65
-
66
- ---
67
-
68
- ### Can this just go at the top of my existing theme/plugin file?
69
-
70
- **No, there are two important things to remember.**
71
-
72
- 1. Don't forget to bundle a copy of the `websharks/wp-php-rv` repo with your theme/plugin. All you really need is the `/src` directory.
73
- 2. Don't leave your existing code in the same file. Use this in a stub file that checks for PHP vX.x+ first (as seen in the examples above), BEFORE loading your code which depends on PHP vX.x+. Why? If you put a PHP vX.x+ check at the top of an existing PHP file, and that particular PHP file happens to contain code which is only valid in PHP v5.2 (for instance), it may still trigger a syntax error. For this reason, you should move your code into a separate file and create a stub file that checks for the existence of PHP vX.x+ first.
74
-
75
- ---
76
-
77
- ### Can I test for required PHP extensions too?
78
-
79
- Yes, `$GLOBALS['wp_php_rv']` can be either a string with a required version, or an array with both a required version and a nested array of required PHP extensions. The easiest way to show how this works is by example (as seen below). Note that your array of required PHP extensions must be compatible with PHP's [`extension_loaded()`](http://php.net/manual/en/function.extension-loaded.php) function.
80
-
81
- ```php
82
- <?php
83
- $GLOBALS['wp_php_rv']['min'] = '5.3';
84
- $GLOBALS['wp_php_rv']['extensions'] = array('curl', 'mbstring');
85
-
86
- if(require('wp-php-rv/src/includes/check.php')) // `true` if running PHP vX.x+ w/ all required extensions.
87
- require dirname(__FILE__).'/my-plugin-code.php'; // It's OK to load your plugin.
88
- else wp_php_rv_notice('My Plugin'); // Dashboard notice mentions your software specifically.
89
- ```
90
-
91
- ---
92
-
93
- ### What else can I test for with this system?
94
-
95
- A compatible OS, a compatible PHP version, required bits, required PHP functions, required PHP extensions, and a compatible WP version.
96
-
97
- ```php
98
- <?php
99
- $GLOBALS['wp_php_rv']['os'] = 'nix'; // Requires a Unix-like OS.
100
- // This is one of two operating system identifiers (always in lowercase): `nix` or `win`
101
- // As far as WP PHP RV is concerned, their OS is either `nix` (Unix-like) or `win` (Windows).
102
- // If you only want to support Unix-like systems, set this to: `nix`, making Windows incompatible.
103
- // If you only want to support Windows systems, set this to: `win`, making others incompatible.
104
-
105
- $GLOBALS['wp_php_rv']['min'] = '5.3'; // Minimum PHP version.
106
- $GLOBALS['wp_php_rv']['max'] = '7.0.4'; // Max compatible PHP version, if applicable.
107
-
108
- $GLOBALS['wp_php_rv']['bits'] = 64; // e.g., 32 or 64 bit architecture.
109
- $GLOBALS['wp_php_rv']['functions'] = array('eval'); // Functions (or constructs).
110
- $GLOBALS['wp_php_rv']['extensions'] = array('curl', 'mbstring'); // See previous FAQ.
111
-
112
- $GLOBALS['wp_php_rv']['wp']['min'] = '4.2'; // Minimum WP version.
113
- $GLOBALS['wp_php_rv']['wp']['max'] = '4.5.2'; // Max compatible WP version, if applicable.
114
-
115
- if(require('wp-php-rv/src/includes/check.php')) // `true` if no issue.
116
- require dirname(__FILE__).'/my-plugin-code.php'; // It's OK to load your plugin.
117
- else wp_php_rv_notice('My Plugin'); // Dashboard notice mentions your software specifically.
118
- ```
119
-
120
- ---
121
-
122
- Copyright: © 2015 [WebSharks, Inc.](http://www.websharks-inc.com/bizdev/) (coded in the USA)
123
-
124
- Released under the terms of the [GNU General Public License](http://www.gnu.org/licenses/gpl-3.0.html).