* @copyright Copyright (C) 2019 wpopal.com. All Rights Reserved. * @license GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html * * @website http://www.wpopal.com * @support http://www.wpopal.com/support/forum.html */ if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly } class Opalestate_Cache { /** * Instance. * * @since 1.8.7 * @access private * @var Opalestate_Cache */ static private $instance; /** * Flag to check if caching enabled or not. * * @since 2.0 * @access private * @var */ private $is_cache; /** * Singleton pattern. * * @since 1.8.7 * @access private * Opalestate_Cache constructor. */ private function __construct() { } /** * Get instance. * * @since 1.8.7 * @access public * @return static */ public static function get_instance() { if ( ! isset( self::$instance ) && ! ( self::$instance instanceof Opalestate_Cache ) ) { self::$instance = new Opalestate_Cache(); } return self::$instance; } /** * Setup hooks. * * @since 1.8.7 * @access public */ public function setup() { // Currently enable cache only for backend. self::$instance->is_cache = ( defined( 'GIVE_CACHE' ) ? GIVE_CACHE : opalestate_is_setting_enabled( opalestate_get_option( 'cache', 'enabled' ) ) ) && is_admin(); // weekly delete all expired cache. Give_Cron::add_weekly_event( array( $this, 'delete_all_expired' ) ); add_action( 'save_post_opalestate_forms', array( $this, 'delete_form_related_cache' ) ); add_action( 'save_post_opalestate_payment', array( $this, 'delete_payment_related_cache' ) ); add_action( 'opalestate_deleted_opalestate-donors_cache', array( $this, 'delete_donor_related_cache' ), 10, 3 ); add_action( 'opalestate_deleted_opalestate-donations_cache', array( $this, 'delete_donations_related_cache' ), 10, 3 ); add_action( 'opalestate_save_settings_opalestate_settings', array( __CLASS__, 'flush_cache' ) ); add_action( 'wp', array( __CLASS__, 'prevent_caching' ) ); add_action( 'admin_notices', array( $this, '__notices' ) ); } /** * Prevent caching on certain pages * * @since 2.0.5 * @access public * @credit WooCommerce */ public static function prevent_caching() { if ( ! is_blog_installed() ) { return; } $page_ids = array_filter( array( opalestate_get_option( 'success_page' ), opalestate_get_option( 'failure_page' ), opalestate_get_option( 'history_page' ), ) ); if ( is_page( $page_ids ) || is_singular( 'opalestate_forms' ) ) { self::set_nocache_constants(); nocache_headers(); } } /** * Set constants to prevent caching by some plugins. * * @since 2.0.5 * @access public * @credit WooCommerce * * @param mixed $return Value to return. Previously hooked into a filter. * * @return mixed */ public static function set_nocache_constants( $return = true ) { return $return; } /** * Notices function. * * @since 2.0.5 * @access public * @credit WooCommerce */ public function __notices() { if ( ! function_exists( 'w3tc_pgcache_flush' ) || ! function_exists( 'w3_instance' ) ) { return; } $config = w3_instance( 'W3_Config' ); $enabled = $config->get_integer( 'dbcache.enabled' ); $settings = array_map( 'trim', $config->get_array( 'dbcache.reject.sql' ) ); if ( $enabled && ! in_array( 'opalestate-pro', $settings, true ) ) { ?>

database caching to work with Give you must add %1$s to the "Ignored query stems" option in W3 Total Cache settings.', 'opalestate-pro' ), 'opalestate', esc_url( admin_url( 'admin.php?page=w3tc_dbcache#dbcache_reject_sql' ) ) ) ); ?>

$data, 'expiration' => ! is_null( $expiration ) ? ( $expiration + current_time( 'timestamp', 1 ) ) : null, ); $result = update_option( $cache_key, $option_value, false ); return $result; } /** * Delete cache. * * Note: only for internal use * * @since 1.8.7 * * @param string|array $cache_keys * * @return bool|WP_Error */ public static function delete( $cache_keys ) { $result = true; $invalid_keys = array(); if ( ! empty( $cache_keys ) ) { $cache_keys = is_array( $cache_keys ) ? $cache_keys : array( $cache_keys ); foreach ( $cache_keys as $cache_key ) { if ( ! self::is_valid_cache_key( $cache_key ) ) { $invalid_keys[] = $cache_key; $result = false; } delete_option( $cache_key ); } } if ( ! $result ) { $result = new WP_Error( 'opalestate_invalid_cache_key', __( 'Cache key format should be opalestate_cache_*', 'opalestate-pro' ), $invalid_keys ); } return $result; } /** * Delete all logging cache. * * Note: only for internal use * * @since 1.8.7 * @access public * @global wpdb $wpdb * * @param bool $force If set to true then all cached values will be delete instead of only expired * * @return bool */ public static function delete_all_expired( $force = false ) { global $wpdb; $options = $wpdb->get_results( $wpdb->prepare( "SELECT option_name, option_value FROM {$wpdb->options} Where option_name LIKE '%%%s%%'", 'opalestate_cache' ), ARRAY_A ); // Bailout. if ( empty( $options ) ) { return false; } $current_time = current_time( 'timestamp', 1 ); // Delete log cache. foreach ( $options as $option ) { $option['option_value'] = maybe_unserialize( $option['option_value'] ); if ( ( ! self::is_valid_cache_key( $option['option_name'] ) || ! is_array( $option['option_value'] ) // Backward compatibility (<1.8.7). || ! array_key_exists( 'expiration', $option['option_value'] ) // Backward compatibility (<1.8.7). || empty( $option['option_value']['expiration'] ) || ( $current_time < $option['option_value']['expiration'] ) ) && ! $force ) { continue; } self::delete( $option['option_name'] ); } } /** * Get list of options like. * * Note: only for internal use * * @since 1.8.7 * @access public * * @param string $option_name * @param bool $fields * * @return array */ public static function get_options_like( $option_name, $fields = false ) { global $wpdb; $field_names = $fields ? 'option_name, option_value' : 'option_name'; if ( $fields ) { $options = $wpdb->get_results( $wpdb->prepare( "SELECT {$field_names } FROM {$wpdb->options} Where option_name LIKE '%%%s%%'", "opalestate_cache_{$option_name}" ), ARRAY_A ); } else { $options = $wpdb->get_col( $wpdb->prepare( "SELECT * FROM {$wpdb->options} Where option_name LIKE '%%%s%%'", "opalestate_cache_{$option_name}" ), 1 ); } if ( ! empty( $options ) && $fields ) { foreach ( $options as $index => $option ) { $option['option_value'] = maybe_unserialize( $option['option_value'] ); $options[ $index ] = $option; } } return $options; } /** * Check cache key validity. * * @since 1.8.7 * @access public * * @param $cache_key * * @return bool */ public static function is_valid_cache_key( $cache_key ) { $is_valid = ( false !== strpos( $cache_key, 'opalestate_cache_' ) ); /** * Filter the flag which tell about cache key valid or not * * @since 2.0 */ return apply_filters( 'opalestate_is_valid_cache_key', $is_valid, $cache_key ); } /** * Get cache from group * * @since 2.0 * @access public * * @param int $id * @param string $group * * @return mixed */ public static function get_group( $id, $group = '' ) { $cached_data = null; // Bailout. if ( self::$instance->is_cache && ! empty( $id ) ) { $group = self::$instance->filter_group_name( $group ); $cached_data = wp_cache_get( $id, $group ); $cached_data = false !== $cached_data ? $cached_data : null; } return $cached_data; } /** * Cache small chunks inside group * * @since 2.0 * @access public * * @param int $id * @param mixed $data * @param string $group * @param int $expire * * @return bool */ public static function set_group( $id, $data, $group = '', $expire = 0 ) { $status = false; // Bailout. if ( ! self::$instance->is_cache || empty( $id ) ) { return $status; } $group = self::$instance->filter_group_name( $group ); $status = wp_cache_set( $id, $data, $group, $expire ); return $status; } /** * Cache small db query chunks inside group * * @since 2.0 * @access public * * @param int $id * @param mixed $data * * @return bool */ public static function set_db_query( $id, $data ) { $status = false; // Bailout. if ( ! self::$instance->is_cache || empty( $id ) ) { return $status; } return self::set_group( $id, $data, 'opalestate-db-queries', 0 ); } /** * Get cache from group * * @since 2.0 * @access public * * @param string $id * * @return mixed */ public static function get_db_query( $id ) { return self::get_group( $id, 'opalestate-db-queries' ); } /** * Delete group cache * * @since 2.0 * @access public * * @param int|array $ids * @param string $group * @param int $expire * * @return bool */ public static function delete_group( $ids, $group = '', $expire = 0 ) { $status = false; // Bailout. if ( ! self::$instance->is_cache || empty( $ids ) ) { return $status; } $group_prefix = $group; $group = self::$instance->filter_group_name( $group ); // Delete single or multiple cache items from cache. if ( ! is_array( $ids ) ) { $status = wp_cache_delete( $ids, $group ); self::$instance->get_incrementer( true ); /** * Fire action when cache deleted for specific id. * * @since 2.0 * * @param string $ids * @param string $group * @param int $expire */ do_action( "opalestate_deleted_{$group_prefix}_cache", $ids, $group, $expire, $status ); } else { foreach ( $ids as $id ) { $status = wp_cache_delete( $id, $group ); self::$instance->get_incrementer( true ); /** * Fire action when cache deleted for specific id . * * @since 2.0 * * @param string $ids * @param string $group * @param int $expire */ do_action( "opalestate_deleted_{$group_prefix}_cache", $id, $group, $expire, $status ); } } return $status; } /** * Get unique incrementer. * * @see https://core.trac.wordpress.org/ticket/4476 * @see https://www.tollmanz.com/invalidation-schemes/ * * @since 2.0 * @access public * * @param bool $refresh * @param string $incrementer_key * * @return string */ public function get_incrementer( $refresh = false, $incrementer_key = 'opalestate-cache-incrementer-db-queries' ) { $incrementer_value = wp_cache_get( $incrementer_key ); if ( false === $incrementer_value || true === $refresh ) { $incrementer_value = (string) microtime( true ); wp_cache_set( $incrementer_key, $incrementer_value ); } return $incrementer_value; } /** * Flush cache on cache setting enable/disable * Note: only for internal use * * @since 2.0 * @access public * * @param bool $force Delete cache forcefully. * * @return bool */ public static function flush_cache( $force = false ) { return false; } /** * Filter the group name * * @since 2.0 * @access private * * @param $group * * @return mixed */ private function filter_group_name( $group ) { /** * Filter the group name * * @since 2.1.0 */ $filtered_group = apply_filters( 'opalestate_cache_filter_group_name', '', $group ); if ( empty( $filtered_group ) ) { switch ( $group ) { case 'opalestate-db-queries': $incrementer = self::$instance->get_incrementer(); break; default: $incrementer = self::$instance->get_incrementer( false, 'opalestate-cache-incrementer' ); } $current_blog_id = get_current_blog_id(); $filtered_group = "{$group}_{$current_blog_id}_{$incrementer}"; } return $filtered_group; } /** * Disable cache. * * @since 2.0 * @access public */ public static function disable() { self::get_instance()->is_cache = false; } /** * Enable cache. * * @since 2.0 * @access public */ public static function enable() { self::get_instance()->is_cache = true; } } // Initialize Opalestate_Cache::get_instance()->setup();