2019-09-10 06:27:33 +02:00
< ? php
/**
* $Desc $
*
* @ version $Id $
* @ package opalestate
* @ author Opal Team < info @ wpopal . com >
* @ 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.
2019-11-04 02:28:41 +01:00
// Give_Cron::add_weekly_event( array( $this, 'delete_all_expired' ) );
2019-09-10 06:27:33 +02:00
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 ) ) {
?>
< div class = " error " >
< p >< ? php echo wp_kses_post ( sprintf ( esc_html__ ( 'In order for <strong>database caching</strong> to work with Give you must add %1$s to the "Ignored query stems" option in <a href="%2$s">W3 Total Cache settings</a>.' , 'opalestate-pro' ), '<code>opalestate</code>' , esc_url ( admin_url ( 'admin.php?page=w3tc_dbcache#dbcache_reject_sql' ) ) ) ); ?> </p>
</ div >
< ? php
}
}
/**
* Get cache key .
*
* @ since 1.8 . 7
*
* @ param string $action Cache key prefix .
* @ param array $query_args ( optional ) Query array .
* @ param bool $is_prefix
*
* @ return string
*/
public static function get_key ( $action , $query_args = null , $is_prefix = true ) {
// Bailout.
if ( empty ( $action ) ) {
return new WP_Error ( 'opalestate_invalid_cache_key_action' , esc_html__ ( 'Do not pass empty action to generate cache key.' , 'opalestate-pro' ) );
}
// Set cache key.
$cache_key = $is_prefix ? " opalestate_cache_ { $action } " : $action ;
// Bailout.
if ( ! empty ( $query_args ) ) {
$cache_key = " { $cache_key } _ " . substr ( md5 ( serialize ( $query_args ) ), 0 , 15 );
}
/**
* Filter the cache key name .
*
* @ since 2.0
*/
return apply_filters ( 'opalestate_get_cache_key' , $cache_key , $action , $query_args );
}
/**
* Get cache .
*
* @ since 1.8 . 7
*
* @ param string $cache_key
* @ param bool $custom_key
* @ param mixed $query_args
*
* @ return mixed
*/
public static function get ( $cache_key , $custom_key = false , $query_args = array () ) {
if ( ! self :: is_valid_cache_key ( $cache_key ) ) {
if ( empty ( $cache_key ) ) {
return new WP_Error ( 'opalestate_empty_cache_key' , esc_html__ ( 'Do not pass invalid empty cache key' , 'opalestate-pro' ) );
} elseif ( ! $custom_key ) {
return new WP_Error ( 'opalestate_invalid_cache_key' , esc_html__ ( 'Cache key format should be opalestate_cache_*' , 'opalestate-pro' ) );
}
$cache_key = self :: get_key ( $cache_key , $query_args );
}
$option = get_option ( $cache_key );
// Backward compatibility (<1.8.7).
if ( ! is_array ( $option ) || empty ( $option ) || ! array_key_exists ( 'expiration' , $option ) ) {
return $option ;
}
// Get current time.
$current_time = current_time ( 'timestamp' , 1 );
if ( empty ( $option [ 'expiration' ] ) || ( $current_time < $option [ 'expiration' ] ) ) {
$option = $option [ 'data' ];
} else {
$option = false ;
}
return $option ;
}
/**
* Set cache .
*
* @ since 1.8 . 7
*
* @ param string $cache_key
* @ param mixed $data
* @ param int | null $expiration Timestamp should be in GMT format .
* @ param bool $custom_key
* @ param mixed $query_args
*
* @ return mixed
*/
public static function set ( $cache_key , $data , $expiration = null , $custom_key = false , $query_args = array () ) {
if ( ! self :: is_valid_cache_key ( $cache_key ) ) {
if ( ! $custom_key ) {
return new WP_Error ( 'opalestate_invalid_cache_key' , esc_html__ ( 'Cache key format should be opalestate_cache_*' , 'opalestate-pro' ) );
}
$cache_key = self :: get_key ( $cache_key , $query_args );
}
$option_value = array (
'data' => $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 ();