123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347 |
- <?php
- /**
- * WPSEO plugin file.
- *
- * @package WPSEO\XML_Sitemaps
- */
- /**
- * Handles sitemaps caching and invalidation.
- *
- * @since 3.2
- */
- class WPSEO_Sitemaps_Cache {
- /**
- * Holds the options that, when updated, should cause the cache to clear.
- *
- * @var array
- */
- protected static $cache_clear = [];
- /**
- * Mirror of enabled status for static calls.
- *
- * @var bool
- */
- protected static $is_enabled = false;
- /**
- * Holds the flag to clear all cache.
- *
- * @var bool
- */
- protected static $clear_all = false;
- /**
- * Holds the array of types to clear.
- *
- * @var array
- */
- protected static $clear_types = [];
- /**
- * Hook methods for invalidation on necessary events.
- */
- public function __construct() {
- add_action( 'init', [ $this, 'init' ] );
- add_action( 'deleted_term_relationships', [ __CLASS__, 'invalidate' ] );
- add_action( 'update_option', [ __CLASS__, 'clear_on_option_update' ] );
- add_action( 'edited_terms', [ __CLASS__, 'invalidate_helper' ], 10, 2 );
- add_action( 'clean_term_cache', [ __CLASS__, 'invalidate_helper' ], 10, 2 );
- add_action( 'clean_object_term_cache', [ __CLASS__, 'invalidate_helper' ], 10, 2 );
- add_action( 'user_register', [ __CLASS__, 'invalidate_author' ] );
- add_action( 'delete_user', [ __CLASS__, 'invalidate_author' ] );
- add_action( 'shutdown', [ __CLASS__, 'clear_queued' ] );
- }
- /**
- * Setup context for static calls.
- */
- public function init() {
- self::$is_enabled = $this->is_enabled();
- }
- /**
- * If cache is enabled.
- *
- * @since 3.2
- *
- * @return boolean
- */
- public function is_enabled() {
- /**
- * Filter if XML sitemap transient cache is enabled.
- *
- * @param bool $unsigned Enable cache or not, defaults to true.
- */
- return apply_filters( 'wpseo_enable_xml_sitemap_transient_caching', false );
- }
- /**
- * Retrieve the sitemap page from cache.
- *
- * @since 3.2
- *
- * @param string $type Sitemap type.
- * @param int $page Page number to retrieve.
- *
- * @return string|boolean
- */
- public function get_sitemap( $type, $page ) {
- $transient_key = WPSEO_Sitemaps_Cache_Validator::get_storage_key( $type, $page );
- if ( false === $transient_key ) {
- return false;
- }
- return get_transient( $transient_key );
- }
- /**
- * Get the sitemap that is cached.
- *
- * @param string $type Sitemap type.
- * @param int $page Page number to retrieve.
- *
- * @return null|WPSEO_Sitemap_Cache_Data Null on no cache found otherwise object containing sitemap and meta data.
- */
- public function get_sitemap_data( $type, $page ) {
- $sitemap = $this->get_sitemap( $type, $page );
- if ( empty( $sitemap ) ) {
- return null;
- }
- // Unserialize Cache Data object (is_serialized doesn't recognize classes).
- if ( is_string( $sitemap ) && 0 === strpos( $sitemap, 'C:24:"WPSEO_Sitemap_Cache_Data"' ) ) {
- $sitemap = unserialize( $sitemap );
- }
- // What we expect it to be if it is set.
- if ( $sitemap instanceof WPSEO_Sitemap_Cache_Data_Interface ) {
- return $sitemap;
- }
- return null;
- }
- /**
- * Store the sitemap page from cache.
- *
- * @since 3.2
- *
- * @param string $type Sitemap type.
- * @param int $page Page number to store.
- * @param string $sitemap Sitemap body to store.
- * @param bool $usable Is this a valid sitemap or a cache of an invalid sitemap.
- *
- * @return bool
- */
- public function store_sitemap( $type, $page, $sitemap, $usable = true ) {
- $transient_key = WPSEO_Sitemaps_Cache_Validator::get_storage_key( $type, $page );
- if ( false === $transient_key ) {
- return false;
- }
- $status = ( $usable ) ? WPSEO_Sitemap_Cache_Data::OK : WPSEO_Sitemap_Cache_Data::ERROR;
- $sitemap_data = new WPSEO_Sitemap_Cache_Data();
- $sitemap_data->set_sitemap( $sitemap );
- $sitemap_data->set_status( $status );
- return set_transient( $transient_key, $sitemap_data, DAY_IN_SECONDS );
- }
- /**
- * Delete cache transients for index and specific type.
- *
- * Always deletes the main index sitemaps cache, as that's always invalidated by any other change.
- *
- * @since 1.5.4
- * @since 3.2 Changed from function wpseo_invalidate_sitemap_cache() to method in this class.
- *
- * @param string $type Sitemap type to invalidate.
- *
- * @return void
- */
- public static function invalidate( $type ) {
- self::clear( [ $type ] );
- }
- /**
- * Helper to invalidate in hooks where type is passed as second argument.
- *
- * @since 3.2
- *
- * @param int $unused Unused term ID value.
- * @param string $type Taxonomy to invalidate.
- *
- * @return void
- */
- public static function invalidate_helper( $unused, $type ) {
- if (
- WPSEO_Options::get( 'noindex-' . $type ) === false ||
- WPSEO_Options::get( 'noindex-tax-' . $type ) === false
- ) {
- self::invalidate( $type );
- }
- }
- /**
- * Invalidate sitemap cache for authors.
- *
- * @param int $user_id User ID.
- *
- * @return bool True if the sitemap was properly invalidated. False otherwise.
- */
- public static function invalidate_author( $user_id ) {
- $user = get_user_by( 'id', $user_id );
- if ( $user === false ) {
- return false;
- }
- if ( 'user_register' === current_action() ) {
- update_user_meta( $user_id, '_yoast_wpseo_profile_updated', time() );
- }
- if ( empty( $user->roles ) || in_array( 'subscriber', $user->roles, true ) ) {
- return false;
- }
- self::invalidate( 'author' );
- return true;
- }
- /**
- * Invalidate sitemap cache for the post type of a post.
- *
- * Don't invalidate for revisions.
- *
- * @since 1.5.4
- * @since 3.2 Changed from function wpseo_invalidate_sitemap_cache_on_save_post() to method in this class.
- *
- * @param int $post_id Post ID to invalidate type for.
- *
- * @return void
- */
- public static function invalidate_post( $post_id ) {
- if ( wp_is_post_revision( $post_id ) ) {
- return;
- }
- self::invalidate( get_post_type( $post_id ) );
- }
- /**
- * Delete cache transients for given sitemaps types or all by default.
- *
- * @since 1.8.0
- * @since 3.2 Moved from WPSEO_Utils to this class.
- *
- * @param array $types Set of sitemap types to delete cache transients for.
- *
- * @return void
- */
- public static function clear( $types = [] ) {
- if ( ! self::$is_enabled ) {
- return;
- }
- // No types provided, clear all.
- if ( empty( $types ) ) {
- self::$clear_all = true;
- return;
- }
- // Always invalidate the index sitemap as well.
- if ( ! in_array( WPSEO_Sitemaps::SITEMAP_INDEX_TYPE, $types ) ) {
- array_unshift( $types, WPSEO_Sitemaps::SITEMAP_INDEX_TYPE );
- }
- foreach ( $types as $type ) {
- if ( ! in_array( $type, self::$clear_types ) ) {
- self::$clear_types[] = $type;
- }
- }
- }
- /**
- * Invalidate storage for cache types queued to clear.
- */
- public static function clear_queued() {
- if ( self::$clear_all ) {
- WPSEO_Sitemaps_Cache_Validator::invalidate_storage();
- self::$clear_all = false;
- self::$clear_types = [];
- return;
- }
- foreach ( self::$clear_types as $type ) {
- WPSEO_Sitemaps_Cache_Validator::invalidate_storage( $type );
- }
- self::$clear_types = [];
- }
- /**
- * Adds a hook that when given option is updated, the cache is cleared.
- *
- * @since 3.2
- *
- * @param string $option Option name.
- * @param string $type Sitemap type.
- */
- public static function register_clear_on_option_update( $option, $type = '' ) {
- self::$cache_clear[ $option ] = $type;
- }
- /**
- * Clears the transient cache when a given option is updated, if that option has been registered before.
- *
- * @since 3.2
- *
- * @param string $option The option name that's being updated.
- *
- * @return void
- */
- public static function clear_on_option_update( $option ) {
- if ( array_key_exists( $option, self::$cache_clear ) ) {
- if ( empty( self::$cache_clear[ $option ] ) ) {
- // Clear all caches.
- self::clear();
- }
- else {
- // Clear specific provided type(s).
- $types = (array) self::$cache_clear[ $option ];
- self::clear( $types );
- }
- }
- }
- }
|