File "OptimizerCache.php"
Full Path: /home/aiclgcwq/photonindustriespvt.com/wp-content/plugins/tenweb-speed-optimizer/includes/OptimizerCache.php
File size: 14.19 KB
MIME-type: text/x-php
Charset: utf-8
<?php
namespace TenWebOptimizer;
/*
* Handles disk-cache-related operations.
*/
if (!defined('ABSPATH')) {
exit;
}
class OptimizerCache
{
/**
* Cache filename.
*
* @var string
*/
private $filename;
/**
* Cache directory path (with a trailing slash).
*
* @var string
*/
private $cachedir;
/**
* Whether gzipping is done by the web server or us.
* True => we don't gzip, the web server does it.
* False => we do it ourselves.
*
* @var bool
*/
private $nogzip;
private $hashes;
private $ext;
private $media;
/**
* Ctor.
*
* @param string $md5 hash
* @param string $ext extension
*/
public function __construct($post_id = null, $ext = 'php', $media = 'all', $name_prefix = '')
{
if (!isset($post_id)) {
$post_id = OptimizerUtils::get_current_post_info();
}
if (empty($name_prefix)) {
$name_prefix = 'aggregated';
}
$this->media = $media;
$this->cachedir = TWO_CACHE_DIR;
$this->nogzip = TWO_CACHE_NOGZIP;
$this->ext = $ext;
if (!$this->nogzip) {
$this->filename = TWO_CACHEFILE_PREFIX . $post_id . 'gzip.php';
} else {
if (in_array($ext, ['js', 'css'])) {
if ($media !== 'all') {
if (!empty($media)) {
$name_prefix .= '_' . md5($media) . '_delay';
} else {
$name_prefix .= '_delay';
}
}
$this->filename = $ext . '/' . TWO_CACHEFILE_PREFIX . $post_id . '_' . $name_prefix . '.min.' . $ext;
} elseif ($ext === 'critical') {
$this->filename = $ext . '/' . TWO_CACHEFILE_PREFIX . $post_id . '_' . $name_prefix . '.css';
} elseif ($ext === 'font') {
$this->filename = 'critical/' . TWO_CACHEFILE_PREFIX . $post_id . '_' . $name_prefix . '.json';
} else {
$this->filename = TWO_CACHEFILE_PREFIX . $post_id . '.' . $ext;
}
}
}
//todo remove first version cache logic
/**
* Check whether it is a GET REQUEST
*/
public static function isGetRequest()
{
return isset($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] === 'GET';
}
/**
* Returns true if the cached file exists on disk.
*
* @return bool
*/
public function check()
{
static $files = [];
$files[] = $this->filename;
if (
!is_dir($this->cachedir) &&
!mkdir($concurrentDirectory = $this->cachedir, 0777, true) && // phpcs:ignore
!is_dir($concurrentDirectory) &&
!is_writable($concurrentDirectory) // phpcs:ignore
) {
return false;
}
file_put_contents($this->cachedir . '_all_cache_files.txt', json_encode($files)); // phpcs:ignore
return file_exists($this->cachedir . $this->filename);
}
/**
* Returns cache contents if they exist, false otherwise.
*
* @return string|false
*/
public function retrieve()
{
if ($this->check()) {
if (false == $this->nogzip) {
return file_get_contents($this->cachedir . $this->filename . '.none');
}
return file_get_contents($this->cachedir . $this->filename); // phpcs:ignore
}
return false;
}
/**
* Stores given $data in cache.
*
* @param string $data data to cache
* @param string $mime mimetype
*
* @return void
*/
public function cache($data, $mime)
{
self::check_and_create_dirs();
if ($this->nogzip === false) {
// We handle gzipping ourselves.
$file = 'default.php';
$phpcode = file_get_contents(TENWEB_SO_PLUGIN_DIR . 'config/' . $file);
$phpcode = str_replace(['%%CONTENT%%', 'exit;'], [$mime, ''], $phpcode);
@file_put_contents($this->cachedir . $this->filename, $phpcode); // phpcs:ignore
@file_put_contents($this->cachedir . $this->filename . '.none', $data); // phpcs:ignore
} else {
// Write code to cache without doing anything else.
@file_put_contents($this->cachedir . $this->filename, $data); // phpcs:ignore
}
if (!empty($this->hashes)) {
$cacheFile = $this->cachedir . '_cached.json';
$oldData = '';
if (file_exists($cacheFile)) {
$oldData = json_decode(file_get_contents($cacheFile), true); // phpcs:ignore
}
if (empty($oldData)) {
$oldData = [];
}
$oldData[$this->filename] = ['media' => $this->media, 'hashes' => $this->hashes];
@file_put_contents($cacheFile, json_encode($oldData)); // phpcs:ignore
}
}
public static function getFileCacheSructure()
{
$cacheFile = TWO_CACHE_DIR . '_cached.json';
if (file_exists($cacheFile)) {
return json_decode(file_get_contents($cacheFile), true); // phpcs:ignore
}
return [];
}
public static function filterThroughCache($scripts)
{
$cachedFiles = OptimizerCache::getFileCacheSructure();
$result = [
'code' => [],
'scripts' => $scripts
];
foreach ($cachedFiles as $key => $files) {
$scriptsToRemove = [];
if (isset($files['hashes'])) {
foreach ($files['hashes'] as $i => $file) {
if (isset($scripts[$file])) {
$scriptsToRemove[] = $file;
unset($files['hashes'][$i]);
}
}
if (empty($files['hashes'])) {
if (empty($result['code'][$files['media']])) {
$result['code'][$files['media']] = '';
}
$result['code'][$files['media']] .= file_get_contents(TWO_CACHE_DIR . $key); // phpcs:ignore
$result['scripts'] = array_diff_key($result['scripts'], array_flip($scriptsToRemove));
}
}
}
return $result;
}
/**
* Get cache filename.
*
* @return string
*/
public function getname($flag = false)
{
if ($flag) {
return $this->filename;
}
$date = time();
return $this->filename . '?date=' . $date;
}
protected static function is_valid_cache_file($dir, $file)
{
//check if is valid file
return '.' !== $file && '..' !== $file && false !== strpos($file, TWO_CACHEFILE_PREFIX)
&& is_file($dir . $file);
}
/**
* Clears contents of TWO_CACHE_DIR.
*
* @return void
*/
protected static function clear_cache_classic()
{
$contents = self::get_cache_contents();
foreach ($contents as $name => $files) {
$dir = rtrim(TWO_CACHE_DIR . $name, '/') . '/';
foreach ($files as $file) {
if (self::is_valid_cache_file($dir, $file)) {
@unlink($dir . $file); // @codingStandardsIgnoreLine
}
}
}
@unlink(TWO_CACHE_DIR . '/.htaccess'); // @codingStandardsIgnoreLine
}
/**
* Recursively deletes the specified pathname (file/directory) if possible.
* Returns true on success, false otherwise.
*
* @param string $pathname pathname to remove
*
* @return bool
*/
protected static function rmdir($pathname)
{
$files = self::get_dir_contents($pathname);
foreach ($files as $file) {
$path = $pathname . '/' . $file;
if (is_dir($path)) {
self::rmdir($path);
} else {
unlink($path); // phpcs:ignore
}
}
return rmdir($pathname); // phpcs:ignore
}
/**
* Clears contents of TWO_CACHE_DIR by renaming the current
* cache directory into a new one with a unique name and then
* re-creating the default (empty) cache directory.
*
* @return bool returns true when everything is done successfully, false otherwise
*/
protected static function clear_cache_via_rename()
{
$ok = false;
$dir = self::get_pathname_base();
$new_name = self::get_unique_name();
// Makes sure the new pathname is on the same level...
$new_pathname = dirname($dir) . '/' . $new_name;
$renamed = @rename($dir, $new_pathname); // @codingStandardsIgnoreLine
return $ok;
}
/**
* Returns a (hopefully) unique new cache folder name for renaming purposes.
*
* @return string
*/
protected static function get_unique_name()
{
$prefix = self::get_advanced_cache_clear_prefix();
return uniqid($prefix, true);
}
/**
* Get cache prefix name used in advanced cache clearing mode.
*
* @return string
*/
protected static function get_advanced_cache_clear_prefix()
{
$pathname = self::get_pathname_base();
$basename = basename($pathname);
return $basename . '-';
}
/**
* Returns an array of file and directory names found within
* the given $pathname without '.' and '..' elements.
*
* @param string $pathname pathname
*
* @return array
*/
protected static function get_dir_contents($pathname)
{
return array_slice(scandir($pathname), 2);
}
/**
* Wipes directories which were created as part of the fast cache clearing
* routine (which renames the current cache directory into a new one with
* a custom-prefixed unique name).
*
* @return bool
*/
public static function delete_advanced_cache_clear_artifacts()
{
$dir = self::get_pathname_base();
$prefix = self::get_advanced_cache_clear_prefix();
$parent = dirname($dir);
$ok = false;
// Returns the list of files without '.' and '..' elements.
$files = self::get_dir_contents($parent);
if (is_array($files) && !empty($files)) {
foreach ($files as $file) {
$path = $parent . '/' . $file;
$prefixed = (false !== strpos($path, $prefix));
// Removing only our own (prefixed) directories...
if (is_dir($path) && $prefixed) {
$ok = self::rmdir($path);
}
}
}
return $ok;
}
public static function get_path($getBase = true)
{
$pathname = self::get_pathname_base();
if (is_multisite()) {
$blog_id = get_current_blog_id();
$pathname .= $blog_id . '/';
}
if ($getBase) {
return $pathname;
}
return $pathname;
}
/**
* Returns the base path of our cache directory.
*
* @return string
*/
protected static function get_pathname_base()
{
return WP_CONTENT_DIR . TENWEB_SO_CACHE_CHILD_DIR;
}
protected static function get_cache_contents()
{
$contents = [];
foreach (['', 'js', 'css'] as $dir) {
$contents[$dir] = scandir(TWO_CACHE_DIR . $dir);
}
return $contents;
}
/**
* Performs a scan of cache directory contents and returns an array
* with 3 values: count, size, timestamp.
* count = total number of found files
* size = total filesize (in bytes) of found files
* timestamp = unix timestamp when the scan was last performed/finished.
*
* @return array
*/
protected static function stats_scan()
{
$count = 0;
$size = 0;
// Scan everything in our cache directories.
foreach (self::get_cache_contents() as $name => $files) {
$dir = rtrim(TWO_CACHE_DIR . $name, '/') . '/';
foreach ($files as $file) {
if (self::is_valid_cache_file($dir, $file)) {
if (TWO_CACHE_NOGZIP && (false !== strpos($file, '.js') || false !== strpos($file, '.css') || false !== strpos($file, '.img') || false !== strpos($file, '.txt'))) {
// Web server is gzipping, we count .js|.css|.img|.txt files.
$count++;
} elseif (!TWO_CACHE_NOGZIP && false !== strpos($file, '.none')) {
// We are gzipping ourselves via php, counting only .none files.
$count++;
}
$size += filesize($dir . $file);
}
}
}
return [$count, $size, time()];
}
/**
* Checks if cache dirs exist and create if not.
* Returns false if not succesful.
*
* @return bool
*/
public static function check_and_create_dirs()
{
if (!defined('TWO_CACHE_DIR')) {
// We didn't set a cache.
return false;
}
foreach (['', 'js', 'css', 'critical'] as $dir) {
if (!self::check_cache_dir(TWO_CACHE_DIR . $dir)) {
return false;
}
}
return true;
}
/**
* Ensures the specified `$dir` exists and is writeable.
* Returns false if that's not the case.
*
* @param string $dir directory to check/create
*
* @return bool
*/
protected static function check_cache_dir($dir)
{
// Try creating the dir if it doesn't exist.
if (!file_exists($dir)) {
if (!mkdir($dir, 0777, true) && !is_dir($dir)) { // phpcs:ignore
return false;
} // @codingStandardsIgnoreLine
if (!file_exists($dir)) {
return false;
}
}
// If we still cannot write, bail.
if (!is_writable($dir)) { // phpcs:ignore
return false;
}
// Create an index.html in there to avoid prying eyes!
$idx_file = rtrim($dir, '/\\') . '/index.html';
if (!is_file($idx_file)) {
@file_put_contents($idx_file, '<html><head><meta name="robots" content="noindex, nofollow"></head><body></body></html>'); // phpcs:ignore
}
return true;
}
}