diff --git a/changelog.txt b/changelog.txt index 6c157a8..e76565e 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,4 +1,29 @@ += v22.07.04 (2023-03-01) = + +- Fixed: Advanced Post Cache -> Only visible to wp < 6.1.1 as it is already implemented in wp core (WP_Query caching). +- Fixed: Filesystem::shutdown_cleanup() -> Avoid cleanup on shutdown if a file is empty. +- Fixed: Plugin::register_plugin_hooks() -> Do not load the CronAgent class if cronbot is disabled. +- Fixed: TermCount() -> Invalid usage of clean_term_cache. +- Fixed: WP_Object_Cache::$cache_hits, WP_Object_Cache::$cache_misses -> Retain same as non persistent. +- Fixed: Prevent performance-lab from overwriting the object cache drop-in. +- Fixed: Becache::export_alloptions() -> Only export option with autoload 'yes' and not transient. +- Fixed: Becache::store_cache() -> Miss match array_serialize. +- Added: WP_Object_Cache::$persistent_cache_hits -> Stats hits from cache file. +- Added: Tweaks::wpquery() -> wp_allow_query_attachment_by_filename for wp > 6.0.1. +- Added: Configuration -> Cache Options, Retain Transients in Db. +- Added: Configuration -> Optimisations, Limit Bulk Edit Actions. +- Added: Configuration -> Wp Tweaks, Deactivate Post Via Email. +- Added: DOCKET_CACHE_TRANSIENTDB constant to enable retaining Transients in the database. +- Added: DOCKET_CACHE_IGNORED_TRANSIENTDB constant. A list of cache keys that remain in the object cache instead of the db. +- Added: DOCKET_CACHE_POSTVIAEMAIL constant to enable deactivation Post Via Email. +- Added: DOCKET_CACHE_LIMITBULKEDIT constant to enable Limit Bulk Edit Actions. +- Added: DOCKET_CACHE_LIMITBULKEDIT_LIMIT constant to change bulk edit limit. By default it is set as 100.. +- Changed: Advanced Post Cache, some part of the code has been moved to Tweaks::wpquery(). +- Removed: WP_Object_Cache::is_data_uptodate() -> No longer needed. +- Updated: Symfony component -> symfony/var-exporter v5.4.21. + = v22.07.03 (2023-02-07) = + - Fixed: Tweaks::woocommerce_misc() -> Check if action_scheduler_migration_status is complete to prevent the list on the Scheduled Actions page from disappearing. - Fixed: Tweaks::woocommerce_widget_remove() -> The classic widget is not disabled. - Fixed: Plugin::get_precache_maxfile() -> Invalid constant, replace maxfile with precache_maxfile. @@ -29,6 +54,7 @@ Thanks to Kevin Shenk of Avunu LLC for providing access to the staging server for testing purposes. = v22.07.02 (2022-12-10) = + - Fixed: Tweaks::cache_http_response() -> Default TTL. - Fixed: Tweaks::wpservehappy() -> missing array key. - Added: wp_cache_supports() function. @@ -38,25 +64,30 @@ Thanks to Kevin Shenk of Avunu LLC for providing access to the staging server fo - Tested up to 6.1. = v22.07.01 (2022-07-15) = + - Fixed: Plugin:cleanuppost() -> Invalid index for trashbin. - Fixed: MoCache() -> Add $entries, $headers properties to avoid warning on get_translations_for_domain. - Updated: Symfony component -> symfony/var-exporter. = v21.08.11 (2022-05-30) = + - Fixed: Avoid calling Filesystem::close_buffer() if a process involved accessing a disk. - Fixed: Removed handling stale cache on shutdown. - Added: Garbage Collector Status -> Cleanup Stale Cache. - Improved: Collected stale cache will be handled by Garbage Collector. = v21.08.10 (2022-05-20) = + - Changed: Disable "CHUNKCACHEDIR" by default. Let's users choose it depending on their hosting environment. = v21.08.09 (2022-05-20) = + - Fixed: WP_Object_Cache::maybe_expire() -> missing preg_match parameter. Thanks to @carmpocalypse for bug report. = v21.08.08 (2022-05-19) = + - Fixed: Don't remove cron event without a hook, let's WordPress handles it. - Fixed: WP_Object_Cache::dc_close() -> Only run one time per instance. - Fixed: WP_Object_Cache::maybe_expire() -> Check cache key. @@ -64,6 +95,7 @@ Thanks to @carmpocalypse for bug report. - Changed: Disable "Auto Remove Stale Cache" by default. Let's users choose it depending on their cpu/storage speeds limit. = v21.08.07 (2022-05-13) = + - Fixed: Tweaks::wpembed() -> body_class missing seconds arguments that require by some themes. - Fixed: Tweaks::wpembed() -> Disable body_class filter, cause unpredictable syntax error on some themes. diff --git a/credits.txt b/credits.txt index 238f43c..04168ba 100644 --- a/credits.txt +++ b/credits.txt @@ -1,17 +1,22 @@ The portion of following projects has been used in Docket Cache. Thank you for all the great works!. List in alphabetical order: -1) Advanced Post Cache - https://github.com/Automattic/vip-go-mu-plugins-built/blob/master/advanced-post-cache/advanced-post-cache.php. - -2) Lightweight Term Count Update - https://github.com/Automattic/lightweight-term-count-update. +1) EventList(): includes/src/EventList.php + - plugins/wp-crontrol/src/event-list-table.php + - plugins/wp-crontrol/src/event.php + - plugins/query-monitor/classes/Util.php -3) MonoDB - https://github.com/nawawi/MonoDB +1) LimitBulkedit(): includes/src/LimitBulkedit.php + https://github.com/Automattic/vip-go-mu-plugins/blob/develop/performance/bulk-edit.php -4) Software Testing Isometric Banner Functional Test - Designed by upklyak / Freepik -- http://www.freepik.com +2) PostCache(): includes/src/PostCache.php + https://github.com/Automattic/vip-go-mu-plugins-built/blob/master/advanced-post-cache/advanced-post-cache.php. -5) Symfony VarExporter Component +3) Filesystem::export_var(): include/src/Filesystem.php https://github.com/symfony/var-exporter + +4) TermCount(): includes/src/TermCount.php + https://github.com/Automattic/lightweight-term-count-update. + +-- +Updated: 26-Feb-2023 diff --git a/dist/docket-cache.zip b/dist/docket-cache.zip index ad21303..c665364 100644 Binary files a/dist/docket-cache.zip and b/dist/docket-cache.zip differ diff --git a/docket-cache.php b/docket-cache.php index 9fb6c8a..c468a3b 100644 --- a/docket-cache.php +++ b/docket-cache.php @@ -12,8 +12,8 @@ * @wordpress-plugin * Plugin Name: Docket Cache * Plugin URI: https://docketcache.com/?utm_source=wp-plugins&utm_campaign=plugin-uri&utm_medium=wp-dash - * Version: 22.07.03 - * VerPrev: 22.07.02 + * Version: 22.07.04 + * VerPrev: 22.07.03 * Description: A persistent object cache stored as a plain PHP code, accelerates caching with OPcache backend. * GitHub Plugin URI: https://github.com/nawawi/docket-cache * Author: Nawawi Jamili diff --git a/includes/admin/config.php b/includes/admin/config.php index 0035253..ef04de4 100644 --- a/includes/admin/config.php +++ b/includes/admin/config.php @@ -24,22 +24,18 @@ - tooltip('cronbot'); -?> + opt_title('cronbot'); ?> - config_select_bool('cronbot'); ?> + config_select_bool_e('cronbot'); ?> - tooltip('opcviewer'); -?> + opt_title('opcviewer'); ?> - config_select_bool('opcviewer'); ?> + config_select_bool_e('opcviewer'); ?> @@ -47,12 +43,10 @@ - tooltip('log'); -?> + opt_title('log'); ?> - config_select_bool('log'); ?> + config_select_bool_e('log'); ?> @@ -60,43 +54,50 @@ + - tooltip('advcpost'); ?> + opt_title('advcpost'); ?> - config_select_bool('advcpost'); ?> + config_select_bool_e('advcpost'); ?> vcf()->is_dctrue('advcpost')) : ?> - tooltip('advpost_posttype_all'); ?> + opt_title('advpost_posttype_all'); ?> - config_select_bool('advpost_posttype_all'); ?> + config_select_bool_e('advpost_posttype_all'); ?> - + - tooltip('precache'); ?> + opt_title('precache'); ?> - config_select_bool('precache'); ?> + config_select_bool_e('precache'); ?> - tooltip('menucache'); ?> + opt_title('menucache'); ?> - config_select_bool('menucache'); ?> + config_select_bool_e('menucache'); ?> - tooltip('mocache'); ?> + opt_title('mocache'); ?> - config_select_bool('mocache'); ?> + config_select_bool_e('mocache'); ?> - tooltip('preload'); ?> + opt_title('preload'); ?> + + config_select_bool_e('preload'); ?> + + + + opt_title('transientdb'); ?> - config_select_bool('preload'); ?> + config_select_bool_e('transientdb'); ?> @@ -105,50 +106,56 @@ - tooltip('optwpquery'); ?> + opt_title('optwpquery'); ?> - config_select_bool('optwpquery'); ?> + config_select_bool_e('optwpquery'); ?> - tooltip('optermcount'); ?> + opt_title('optermcount'); ?> - config_select_bool('optermcount'); ?> + config_select_bool_e('optermcount'); ?> - tooltip('cronoptmzdb'); ?> + opt_title('cronoptmzdb'); ?> config_select_set( - 'cronoptmzdb', - [ - 'default' => __('Default', 'docket-cache'), - 'daily' => __('Daily', 'docket-cache'), - 'weekly' => __('Weekly', 'docket-cache'), - 'monthly' => __('Monthly', 'docket-cache'), - 'never' => __('Never', 'docket-cache'), - ] -); + $this->config_select_set_e( + 'cronoptmzdb', + [ + 'default' => __('Default', 'docket-cache'), + 'daily' => __('Daily', 'docket-cache'), + 'weekly' => __('Weekly', 'docket-cache'), + 'monthly' => __('Monthly', 'docket-cache'), + 'never' => __('Never', 'docket-cache'), + ] + ); ?> - tooltip('wpoptaload'); ?> + opt_title('wpoptaload'); ?> - config_select_bool('wpoptaload'); ?> + config_select_bool_e('wpoptaload'); ?> - tooltip('postmissedschedule'); ?> + opt_title('postmissedschedule'); ?> - config_select_bool('postmissedschedule'); ?> + config_select_bool_e('postmissedschedule'); ?> + + + + opt_title('limitbulkedit'); ?> + + config_select_bool_e('limitbulkedit'); ?> - tooltip('misc_tweaks'); ?> + opt_title('misc_tweaks'); ?> - config_select_bool('misc_tweaks'); ?> + config_select_bool_e('misc_tweaks'); ?> @@ -157,45 +164,45 @@ - tooltip('wootweaks'); ?> + opt_title('wootweaks'); ?> - config_select_bool('wootweaks'); ?> + config_select_bool_e('wootweaks'); ?> - tooltip('wooadminoff'); ?> + opt_title('wooadminoff'); ?> - config_select_bool('wooadminoff'); ?> + config_select_bool_e('wooadminoff'); ?> - tooltip('woowidgetoff'); ?> + opt_title('woowidgetoff'); ?> - config_select_bool('woowidgetoff'); ?> + config_select_bool_e('woowidgetoff'); ?> - tooltip('woowpdashboardoff'); ?> + opt_title('woowpdashboardoff'); ?> - config_select_bool('woowpdashboardoff'); ?> + config_select_bool_e('woowpdashboardoff'); ?> - tooltip('wooextensionpageoff'); ?> + opt_title('wooextensionpageoff'); ?> - config_select_bool('wooextensionpageoff'); ?> + config_select_bool_e('wooextensionpageoff'); ?> - tooltip('woocartfragsoff'); ?> + opt_title('woocartfragsoff'); ?> - config_select_bool('woocartfragsoff'); ?> + config_select_bool_e('woocartfragsoff'); ?> - tooltip('wooaddtochartcrawling'); ?> + opt_title('wooaddtochartcrawling'); ?> - config_select_bool('wooaddtochartcrawling'); ?> + config_select_bool_e('wooaddtochartcrawling'); ?> @@ -204,82 +211,88 @@ - tooltip('headerjunk'); ?> + opt_title('headerjunk'); ?> - config_select_bool('headerjunk'); ?> + config_select_bool_e('headerjunk'); ?> - tooltip('pingback'); ?> + opt_title('pingback'); ?> - config_select_bool('pingback'); ?> + config_select_bool_e('pingback'); ?> - tooltip('wpemoji'); ?> + opt_title('wpemoji'); ?> - config_select_bool('wpemoji'); ?> + config_select_bool_e('wpemoji'); ?> - tooltip('wpfeed'); ?> + opt_title('wpfeed'); ?> - config_select_bool('wpfeed'); ?> + config_select_bool_e('wpfeed'); ?> - tooltip('wpembed'); ?> + opt_title('wpembed'); ?> - config_select_bool('wpembed'); ?> + config_select_bool_e('wpembed'); ?> - tooltip('wplazyload'); ?> + opt_title('wplazyload'); ?> - config_select_bool('wplazyload'); ?> + config_select_bool_e('wplazyload'); ?> - tooltip('wpsitemap'); ?> + opt_title('wpsitemap'); ?> - config_select_bool('wpsitemap'); ?> + config_select_bool_e('wpsitemap'); ?> - tooltip('wpapppassword'); ?> + opt_title('wpapppassword'); ?> - config_select_bool('wpapppassword'); ?> + config_select_bool_e('wpapppassword'); ?> - tooltip('wpdashboardnews'); ?> + opt_title('wpdashboardnews'); ?> + + config_select_bool_e('wpdashboardnews'); ?> + + + + opt_title('postviaemail'); ?> - config_select_bool('wpdashboardnews'); ?> + config_select_bool_e('postviaemail'); ?> - tooltip('wpbrowsehappy'); ?> + opt_title('wpbrowsehappy'); ?> - config_select_bool('wpbrowsehappy'); ?> + config_select_bool_e('wpbrowsehappy'); ?> - tooltip('wpservehappy'); ?> + opt_title('wpservehappy'); ?> - config_select_bool('wpservehappy'); ?> + config_select_bool_e('wpservehappy'); ?> - tooltip('limithttprequest'); ?> + opt_title('limithttprequest'); ?> - config_select_bool('limithttprequest'); ?> + config_select_bool_e('limithttprequest'); ?> - tooltip('httpheadersexpect'); ?> + opt_title('httpheadersexpect'); ?> - config_select_bool('httpheadersexpect'); ?> + config_select_bool_e('httpheadersexpect'); ?> @@ -290,10 +303,10 @@ - tooltip('rtpostautosave'); ?> + opt_title('rtpostautosave'); ?> config_select_set( +$this->config_select_set_e( 'rtpostautosave', [ 'default' => __('Default', 'docket-cache'), @@ -307,10 +320,10 @@ - tooltip('rtpostrevision'); ?> + opt_title('rtpostrevision'); ?> config_select_set( + $this->config_select_set_e( 'rtpostrevision', [ 'default' => __('Default', 'docket-cache'), @@ -324,10 +337,10 @@ - tooltip('rtpostemptytrash'); ?> + opt_title('rtpostemptytrash'); ?> config_select_set( + $this->config_select_set_e( 'rtpostemptytrash', [ 'default' => __('Default', 'docket-cache'), @@ -341,10 +354,10 @@ - tooltip('rtimageoverwrite'); ?> + opt_title('rtimageoverwrite'); ?> config_select_set( + $this->config_select_set_e( 'rtimageoverwrite', [ 'default' => __('Default', 'docket-cache'), @@ -357,10 +370,10 @@ - tooltip('rtwpcoreupdate'); ?> + opt_title('rtwpcoreupdate'); ?> config_select_set( + $this->config_select_set_e( 'rtwpcoreupdate', [ 'default' => __('Default', 'docket-cache'), @@ -373,10 +386,10 @@ - tooltip('rtpluginthemeeditor'); ?> + opt_title('rtpluginthemeeditor'); ?> config_select_set( + $this->config_select_set_e( 'rtpluginthemeeditor', [ 'default' => __('Default', 'docket-cache'), @@ -389,10 +402,10 @@ - tooltip('rtpluginthemeinstall'); ?> + opt_title('rtpluginthemeinstall'); ?> config_select_set( + $this->config_select_set_e( 'rtpluginthemeinstall', [ 'default' => __('Default', 'docket-cache'), @@ -405,10 +418,10 @@ - tooltip('rtconcatenatescripts'); ?> + opt_title('rtconcatenatescripts'); ?> config_select_set( + $this->config_select_set_e( 'rtconcatenatescripts', [ 'default' => __('Default', 'docket-cache'), @@ -421,10 +434,10 @@ - tooltip('rtdisablewpcron'); ?> + opt_title('rtdisablewpcron'); ?> config_select_set( + $this->config_select_set_e( 'rtdisablewpcron', [ 'default' => __('Default', 'docket-cache'), @@ -440,10 +453,10 @@ $rtwpdebug_default = !empty($GLOBALS[$this->vcf()->px('rtwpdebug_false')]) && WP_DEBUG ? 'on' : $this->vcf()->dcvalue('rtwpdebug'); ?> - >tooltip('rtwpdebug'); ?> + >opt_title('rtwpdebug'); ?> config_select_set( + $this->config_select_set_e( 'rtwpdebug', [ 'default' => __('Default', 'docket-cache'), @@ -457,10 +470,10 @@ - tooltip('rtwpdebugdisplay'); ?> + opt_title('rtwpdebugdisplay'); ?> config_select_set( + $this->config_select_set_e( 'rtwpdebugdisplay', [ 'default' => __('Default', 'docket-cache'), @@ -477,10 +490,10 @@ $error_log = \ini_get('error_log'); ?> - tooltip('rtwpdebuglog'); ?> + opt_title('rtwpdebuglog'); ?> config_select_set( + $this->config_select_set_e( 'rtwpdebuglog', [ 'default' => __('Default', 'docket-cache'), @@ -506,7 +519,7 @@ - tooltip('maxfile'); ?> + opt_title('maxfile'); ?> config_select_set( +$this->config_select_set_e( 'maxfile', [ 'default' => __('Default', 'docket-cache'), @@ -535,7 +548,7 @@ - tooltip('maxsize_disk'); ?> + opt_title('maxsize_disk'); ?> config_select_set( +$this->config_select_set_e( 'maxsize_disk', [ 'default' => __('Default', 'docket-cache'), @@ -564,36 +577,36 @@ - tooltip('chunkcachedir'); ?> + opt_title('chunkcachedir'); ?> - config_select_bool('chunkcachedir'); ?> + config_select_bool_e('chunkcachedir'); ?> - tooltip('maxfile_livecheck'); ?> + opt_title('maxfile_livecheck'); ?> - config_select_bool('maxfile_livecheck'); ?> + config_select_bool_e('maxfile_livecheck'); ?> - tooltip('flush_stalecache'); ?> + opt_title('flush_stalecache'); ?> - config_select_bool('flush_stalecache'); ?> + config_select_bool_e('flush_stalecache'); ?> - tooltip('stalecache_ignore'); ?> + opt_title('stalecache_ignore'); ?> - config_select_bool('stalecache_ignore'); ?> + config_select_bool_e('stalecache_ignore'); ?> */ ?> - tooltip('emptycache_ignore'); ?> + opt_title('emptycache_ignore'); ?> - config_select_bool('emptycache_ignore'); ?> + config_select_bool_e('emptycache_ignore'); ?> @@ -602,27 +615,27 @@ - tooltip('pageloader'); ?> + opt_title('pageloader'); ?> - config_select_bool('pageloader'); ?> + config_select_bool_e('pageloader'); ?> - tooltip('stats'); ?> + opt_title('stats'); ?> - config_select_bool('stats'); ?> + config_select_bool_e('stats'); ?> - tooltip('gcaction'); ?> + opt_title('gcaction'); ?> - config_select_bool('gcaction'); ?> + config_select_bool_e('gcaction'); ?> - tooltip('flushaction'); ?> + opt_title('flushaction'); ?> - config_select_bool('flushaction'); ?> + config_select_bool_e('flushaction'); ?> @@ -631,27 +644,27 @@ - tooltip('autoupdate_toggle'); ?> + opt_title('autoupdate_toggle'); ?> - config_select_bool('autoupdate_toggle'); ?> + config_select_bool_e('autoupdate_toggle'); ?> - tooltip('checkversion'); ?> + opt_title('checkversion'); ?> - config_select_bool('checkversion'); ?> + config_select_bool_e('checkversion'); ?> - tooltip('flush_shutdown'); ?> + opt_title('flush_shutdown'); ?> - config_select_bool('flush_shutdown'); ?> + config_select_bool_e('flush_shutdown'); ?> - tooltip('opcshutdown'); ?> + opt_title('opcshutdown'); ?> - config_select_bool('opcshutdown'); ?> + config_select_bool_e('opcshutdown'); ?> diff --git a/includes/admin/docket.js b/includes/admin/docket.js index 66d603e..cd72c4e 100644 --- a/includes/admin/docket.js +++ b/includes/admin/docket.js @@ -85,6 +85,12 @@ } ); + var close_notice = function() { + $selector.find( 'div.is-dismissible' ) + .find( 'button.notice-dismiss' ) + .trigger( 'click' ); + }; + window.dospinner = false; var spinner = function() { if ( !window.dospinner ) { @@ -170,6 +176,8 @@ .on( 'change.dc-select-config', function() { + close_notice(); + window.dospinner = true; spinner(); var $self = $( this ); var link = $self.children( 'option:selected' ) diff --git a/includes/cache.php b/includes/cache.php index b32362c..464bfc9 100644 --- a/includes/cache.php +++ b/includes/cache.php @@ -42,6 +42,13 @@ class WP_Object_Cache */ public $cache_misses = 0; + /** + * The amount of times the cached data was fetched from the cache file. + * + * @var int + */ + public $persistent_cache_hits = 0; + /** * List of global cache groups. * @@ -75,7 +82,7 @@ class WP_Object_Cache * * @var array */ - protected $bypass_precache = []; + private $bypass_precache = []; /** * The blog prefix to prepend to keys in non-global groups. @@ -231,6 +238,20 @@ class WP_Object_Cache */ private $ignore_emptycache = false; + /** + * Store Transients in DB. + * + * @var bool + */ + private $use_transientdb = false; + + /** + * List of transient exclude from store in DB. + * + * @var array + */ + private $bypass_transientdb = []; + /** * Sets up object properties. */ @@ -269,12 +290,12 @@ protected function _exists($key, $group, $force = false) $is_exists = !$force && !empty($this->cache) && isset($this->cache[$group]) && (isset($this->cache[$group][$key]) || \array_key_exists($key, $this->cache[$group])); if (!$is_exists && !$this->is_non_persistent_groups($group) && !$this->is_non_persistent_keys($key) && !$this->is_non_persistent_groupkey($group, $key) && !$this->is_stalecache_ignored($key, $group)) { - $data = $this->dc_get($key, $group, false); + $data = $this->dc_get($key, $group, false, $codestub_false); if (false !== $data) { $is_exists = true; $this->cache[$group][$key] = $data; - if ($this->is_precache && !$this->fs()->suspend_cache_write() && !$this->is_bypass_precache($group, $key)) { + if ($this->is_precache && !$codestub_false && !$this->fs()->suspend_cache_write() && !$this->is_bypass_precache($group, $key)) { if (empty($this->precache[$group])) { $this->precache[$group][$key] = 1; } elseif (\count($this->precache[$group]) < $this->precache_maxkey && \count($this->precache) < $this->precache_maxgroup) { @@ -461,7 +482,7 @@ public function set_multiple(array $data, $group = '', $expire = 0) * * @return mixed|false the cache contents on success, false on failure to retrieve contents */ - public function get($key, $group = 'default', $force = false, &$found = null) + public function get($key, $group = 'default', $force = false, &$found = null, $doing_precache = false) { if (!$this->is_valid_key($key)) { return false; @@ -474,6 +495,9 @@ public function get($key, $group = 'default', $force = false, &$found = null) $cache_key = $this->dc_key($key, $group); if ($this->_exists($cache_key, $group, $force)) { + if (!$doing_precache) { + ++$this->cache_hits; + } $found = true; if (\is_object($this->cache[$group][$cache_key])) { return clone $this->cache[$group][$cache_key]; @@ -483,6 +507,9 @@ public function get($key, $group = 'default', $force = false, &$found = null) } $found = false; + if (!$doing_precache) { + ++$this->cache_misses; + } return false; } @@ -535,10 +562,7 @@ public function delete($key, $group = 'default', $deprecated = false) unset($this->cache[$group][$key]); unset($this->precache[$group][$key]); - $this->dc_remove($key, $group); - - // always true - return true; + return $this->dc_remove($key, $group); } /** @@ -698,6 +722,7 @@ public function stats() $ret = ''; $ret .= '

'; $ret .= "Cache Hits: {$this->cache_hits}
"; + $ret .= "Persistent Cache Hits: {$this->persistent_cache_hits}
"; $ret .= "Cache Misses: {$this->cache_misses}
"; $ret .= '

'; $ret .= '