| Current Path : /home/ereika83/www/wp-content/plugins/wpmu-dev-seo/includes/core/sitemaps/ |
| Current File : /home/ereika83/www/wp-content/plugins/wpmu-dev-seo/includes/core/sitemaps/class-cache.php |
<?php
/**
* Cache class for handling sitemap caching in SmartCrawl.
*
* @package SmartCrawl
*/
namespace SmartCrawl\Sitemaps;
use SmartCrawl\Logger;
use SmartCrawl\Singleton;
/**
* Class Cache
*
* Handles the caching of sitemaps.
*/
class Cache {
const CACHE_FILE_NAME_FORMAT = '%s-sitemap%d.xml';
const CACHE_PRISTINE_OPTION = 'wds_sitemap_cache_pristine';
use Singleton;
/**
* Sets the cached sitemap.
*
* @param string $type The type of the sitemap.
* @param int $page The page number of the sitemap.
* @param string $sitemap The sitemap content.
*
* @return bool True if the sitemap was cached successfully, false otherwise.
*/
public function set_cached( $type, $page, $sitemap ) {
return $this->write_to_cache_file(
$this->cache_file_name( $type, $page ),
$sitemap
);
}
/**
* Retrieves the cached sitemap.
*
* @param string $type The type of the sitemap.
* @param int $page The page number of the sitemap.
*
* @return string|false The cached sitemap content or false if not found.
*/
public function get_cached( $type, $page ) {
if ( $this->is_cache_pristine() ) {
return $this->get_from_cache_file( $this->cache_file_name( $type, $page ) );
}
$this->drop_cache();
return false;
}
/**
* Drops the sitemap cache.
*
* @return bool True if the cache was dropped successfully, false otherwise.
*/
public function drop_cache() {
$file_system = $this->fs_direct();
$cache_dir = $this->get_cache_dir();
if ( empty( $cache_dir ) ) {
Logger::error( 'Sitemap cache could not be dropped because it does not exist' );
return false;
}
$removed = $file_system->rmdir( $cache_dir, true );
if ( ! $removed ) {
Logger::error( 'Sitemap cache directory could not be removed' );
return false;
}
$this->set_cache_pristine( true ); // An empty cache is a pristine cache.
Logger::info( 'Sitemap cache dropped' );
return true;
}
/**
* Retrieves the filesystem direct instance.
*
* @return \WP_Filesystem_Direct The filesystem direct instance.
*/
private function fs_direct() {
if ( ! class_exists( '\WP_Filesystem_Direct', false ) ) {
require_once ABSPATH . 'wp-admin/includes/class-wp-filesystem-base.php';
require_once ABSPATH . 'wp-admin/includes/class-wp-filesystem-direct.php';
}
return new \WP_Filesystem_Direct( null );
}
/**
* Generates the cache file name.
*
* @param string $type The type of the sitemap.
* @param int $page The page number of the sitemap.
*
* @return string The generated cache file name.
*/
private function cache_file_name( $type, $page ) {
$file_name = sprintf( self::CACHE_FILE_NAME_FORMAT, $type, $page );
return apply_filters( 'wds_sitemap_cache_file_name', $file_name, $type, $page );
}
/**
* Writes content to a cache file.
*
* @param string $filename The name of the cache file.
* @param string $contents The content to write to the cache file.
*
* @return bool True if the content was written successfully, false otherwise.
*/
private function write_to_cache_file( $filename, $contents ) {
$path = $this->get_cache_dir( $filename );
if (
empty( $path )
|| ! \smartcrawl_file_put_contents( $path, $contents, LOCK_EX )
) {
Logger::error( "Failed writing sitemap cache file to [$path]" );
return false;
}
Logger::info( "Added file to sitemap cache: [$path]" );
return true;
}
/**
* Get content from a cache file.
*
* @param string $filename The name of the cache file.
*
* @return string|false The content of the cache file or false if not found.
*/
private function get_from_cache_file( $filename ) {
$path = $this->get_cache_dir( $filename );
if ( ! empty( $path ) && file_exists( $path ) ) {
Logger::info( "Sitemap file read from cache: [$path]" );
return \smartcrawl_file_get_contents( $path );
}
Logger::info( "Sitemap file not found in cache: [$path]" );
return false;
}
/**
* Retrieves the cache directory.
*
* @param string $postfix The postfix to append to the cache directory.
*
* @return false|string The cache directory path or false if it could not be created.
*/
public function get_cache_dir( $postfix = '' ) {
$path = \smartcrawl_uploads_dir();
$path = "{$path}sitemap/";
// Attempt to create the dir in case it doesn't already exist.
$dir_exists = wp_mkdir_p( $path );
if ( ! $dir_exists ) {
Logger::error( "Sitemap cache directory could not be created at [$path]" );
return false;
}
return "$path$postfix";
}
/**
* Checks if the cache is pristine.
*
* @return bool True if the cache is pristine, false otherwise.
*/
public function is_cache_pristine() {
return in_array(
get_current_blog_id(),
$this->get_sitemap_pristine_option(),
true
);
}
/**
* Invalidates the cache.
*
* @return void
*/
public function invalidate() {
$this->set_cache_pristine( false );
}
/**
* Sets the cache pristine option.
*
* @param bool $value The value to set for the cache pristine option.
*
* @return void
*/
private function set_cache_pristine( $value ) {
$pristine = $this->get_sitemap_pristine_option();
$current_site_id = get_current_blog_id();
if ( $value ) {
if ( ! in_array( $current_site_id, $pristine, true ) ) {
$pristine[] = $current_site_id;
$this->update_sitemap_pristine_option( $pristine );
}
} elseif ( ! is_multisite() ) {
// The single site is out of date now so drop everything.
$this->delete_sitemap_pristine_option();
} else {
$this->update_sitemap_pristine_option(
array_diff( $pristine, array( $current_site_id ) )
);
}
}
/**
* Retrieves the sitemap pristine option.
*
* @return array The sitemap pristine option.
*/
private function get_sitemap_pristine_option() {
$value = get_site_option( self::CACHE_PRISTINE_OPTION, array() );
return is_array( $value )
? $value
: array();
}
/**
* Updates the sitemap pristine option.
*
* @param array $value The value to update the sitemap pristine option with.
*
* @return bool True if the option was updated successfully, false otherwise.
*/
private function update_sitemap_pristine_option( $value ) {
return update_site_option( self::CACHE_PRISTINE_OPTION, $value );
}
/**
* Deletes the sitemap pristine option.
*
* @return bool True if the option was deleted successfully, false otherwise.
*/
private function delete_sitemap_pristine_option() {
return delete_site_option( self::CACHE_PRISTINE_OPTION );
}
/**
* Checks if the cache directory is writable.
*
* @return bool True if the cache directory is writable, false otherwise.
*/
public function is_writable() {
return is_writeable( $this->get_cache_dir() );
}
/**
* Checks if the index sitemap is cached.
*
* @return bool True if the index sitemap is cached, false otherwise.
*/
public function is_index_cached() {
if ( ! $this->is_cache_pristine() ) {
// If cache is not pristine, we don't care if the file exists or not.
return false;
}
$file_name = $this->cache_file_name( Front::SITEMAP_TYPE_INDEX, 0 );
$path = $this->get_cache_dir( $file_name );
return ! empty( $path ) && file_exists( $path );
}
}