<?php /** * @package Freemius * @copyright Copyright (c) 2015, Freemius, Inc. * @license https://www.gnu.org/licenses/gpl-3.0.html GNU General Public License Version 3 * @since 1.1.6 */ if ( ! defined( 'ABSPATH' ) ) { exit; } class FS_Cache_Manager { /** * @var FS_Option_Manager */ private $_options; /** * @var FS_Logger */ private $_logger; /** * @var FS_Cache_Manager[] */ private static $_MANAGERS = array(); /** * @author Vova Feldman (@svovaf) * @since 1.1.3 * * @param string $id */ private function __construct( $id ) { $this->_logger = FS_Logger::get_logger( WP_FS__SLUG . '_cach_mngr_' . $id, WP_FS__DEBUG_SDK, WP_FS__ECHO_DEBUG_SDK ); $this->_logger->entrance(); $this->_logger->log( 'id = ' . $id ); $this->_options = FS_Option_Manager::get_manager( $id, true, true, false ); } /** * @author Vova Feldman (@svovaf) * @since 1.1.6 * * @param $id * * @return FS_Cache_Manager */ static function get_manager( $id ) { $id = strtolower( $id ); if ( ! isset( self::$_MANAGERS[ $id ] ) ) { self::$_MANAGERS[ $id ] = new FS_Cache_Manager( $id ); } return self::$_MANAGERS[ $id ]; } /** * @author Vova Feldman (@svovaf) * @since 1.1.6 * * @return bool */ function is_empty() { $this->_logger->entrance(); return $this->_options->is_empty(); } /** * @author Vova Feldman (@svovaf) * @since 1.1.6 */ function clear() { $this->_logger->entrance(); $this->_options->clear( true ); } /** * Delete cache manager from DB. * * @author Vova Feldman (@svovaf) * @since 1.0.9 */ function delete() { $this->_options->delete(); } /** * Check if there's a cached item. * * @author Vova Feldman (@svovaf) * @since 1.1.6 * * @param string $key * * @return bool */ function has( $key ) { $cache_entry = $this->_options->get_option( $key, false ); return ( is_object( $cache_entry ) && isset( $cache_entry->timestamp ) && is_numeric( $cache_entry->timestamp ) ); } /** * Check if there's a valid cached item. * * @author Vova Feldman (@svovaf) * @since 1.1.6 * * @param string $key * @param null|int $expiration Since 1.2.2.7 * * @return bool */ function has_valid( $key, $expiration = null ) { $cache_entry = $this->_options->get_option( $key, false ); $is_valid = ( is_object( $cache_entry ) && isset( $cache_entry->timestamp ) && is_numeric( $cache_entry->timestamp ) && $cache_entry->timestamp > WP_FS__SCRIPT_START_TIME ); if ( $is_valid && is_numeric( $expiration ) && isset( $cache_entry->created ) && is_numeric( $cache_entry->created ) && $cache_entry->created + $expiration < WP_FS__SCRIPT_START_TIME ) { /** * Even if the cache is still valid, since we are checking for validity * with an explicit expiration period, if the period has past, return * `false` as if the cache is invalid. * * @since 1.2.2.7 */ $is_valid = false; } return $is_valid; } /** * @author Vova Feldman (@svovaf) * @since 1.1.6 * * @param string $key * @param mixed $default * * @return mixed */ function get( $key, $default = null ) { $this->_logger->entrance( 'key = ' . $key ); $cache_entry = $this->_options->get_option( $key, false ); if ( is_object( $cache_entry ) && isset( $cache_entry->timestamp ) && is_numeric( $cache_entry->timestamp ) ) { return $cache_entry->result; } return is_object( $default ) ? clone $default : $default; } /** * @author Vova Feldman (@svovaf) * @since 1.1.6 * * @param string $key * @param mixed $default * * @return mixed */ function get_valid( $key, $default = null ) { $this->_logger->entrance( 'key = ' . $key ); $cache_entry = $this->_options->get_option( $key, false ); if ( is_object( $cache_entry ) && isset( $cache_entry->timestamp ) && is_numeric( $cache_entry->timestamp ) && $cache_entry->timestamp > WP_FS__SCRIPT_START_TIME ) { return $cache_entry->result; } return is_object( $default ) ? clone $default : $default; } /** * @author Vova Feldman (@svovaf) * @since 1.1.6 * * @param string $key * @param mixed $value * @param int $expiration * @param int $created Since 2.0.0 Cache creation date. */ function set( $key, $value, $expiration = WP_FS__TIME_24_HOURS_IN_SEC, $created = WP_FS__SCRIPT_START_TIME ) { $this->_logger->entrance( 'key = ' . $key ); $cache_entry = new stdClass(); $cache_entry->result = $value; $cache_entry->created = $created; $cache_entry->timestamp = $created + $expiration; $this->_options->set_option( $key, $cache_entry, true ); } /** * Get cached record expiration, or false if not cached or expired. * * @author Vova Feldman (@svovaf) * @since 1.1.7.3 * * @param string $key * * @return bool|int */ function get_record_expiration( $key ) { $this->_logger->entrance( 'key = ' . $key ); $cache_entry = $this->_options->get_option( $key, false ); if ( is_object( $cache_entry ) && isset( $cache_entry->timestamp ) && is_numeric( $cache_entry->timestamp ) && $cache_entry->timestamp > WP_FS__SCRIPT_START_TIME ) { return $cache_entry->timestamp; } return false; } /** * Purge cached item. * * @author Vova Feldman (@svovaf) * @since 1.1.6 * * @param string $key */ function purge( $key ) { $this->_logger->entrance( 'key = ' . $key ); $this->_options->unset_option( $key, true ); } /** * Extend cached item caching period. * * @author Vova Feldman (@svovaf) * @since 2.0.0 * * @param string $key * @param int $expiration * * @return bool */ function update_expiration( $key, $expiration = WP_FS__TIME_24_HOURS_IN_SEC ) { $this->_logger->entrance( 'key = ' . $key ); $cache_entry = $this->_options->get_option( $key, false ); if ( ! is_object( $cache_entry ) || ! isset( $cache_entry->timestamp ) || ! is_numeric( $cache_entry->timestamp ) ) { return false; } $this->set( $key, $cache_entry->result, $expiration, $cache_entry->created ); return true; } /** * Set cached item as expired. * * @author Vova Feldman (@svovaf) * @since 1.2.2.7 * * @param string $key */ function expire( $key ) { $this->_logger->entrance( 'key = ' . $key ); $cache_entry = $this->_options->get_option( $key, false ); if ( is_object( $cache_entry ) && isset( $cache_entry->timestamp ) && is_numeric( $cache_entry->timestamp ) ) { // Set to expired. $cache_entry->timestamp = WP_FS__SCRIPT_START_TIME; $this->_options->set_option( $key, $cache_entry, true ); } } #-------------------------------------------------------------------------------- #region Migration #-------------------------------------------------------------------------------- /** * Migrate options from site level. * * @author Vova Feldman (@svovaf) * @since 2.0.0 */ function migrate_to_network() { $this->_options->migrate_to_network(); } #endregion }