123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
<?php
class Cache {
private $cacheDir;
private $filesDir;
private $imgDir;
private $zipDir;
private $versionDb;
private $versionPdo = null;
public function __construct($indexerFilesDir) {
$this->cacheDir = $indexerFilesDir . '/cache';
$this->filesDir = $this->cacheDir . '/files';
$this->imgDir = $this->cacheDir . '/img';
$this->zipDir = $this->cacheDir . '/zip';
$this->versionDb = $this->cacheDir . '/version.sqlite';
if (!is_dir($this->cacheDir)) {
require_once dirname(__FILE__) . '/Initializer.php';
$initializer = new Initializer($indexerFilesDir);
$initializer->initializeCache(false);
}
$this->initialize();
}
private function initialize() {
$this->initializeVersionDb();
}
private function initializeVersionDb() {
if (!is_dir($this->cacheDir)) {
return;
}
try {
$this->versionPdo = new PDO('sqlite:' . $this->versionDb);
$this->versionPdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->versionPdo->exec("CREATE TABLE IF NOT EXISTS version_info (
key TEXT PRIMARY KEY,
value TEXT NOT NULL,
cached_at INTEGER NOT NULL
)");
if (file_exists($this->versionDb)) {
@chmod($this->versionDb, 0666);
}
} catch (Exception $e) {
$this->versionPdo = null;
}
}
private function generateHash($filePath, $additionalData = '') {
return md5($filePath . $additionalData . filemtime($filePath));
}
public function getFile($sourceFile, $viewType = 'code') {
$hash = $this->generateHash($sourceFile, $viewType);
$cachePath = $this->filesDir . '/' . $hash . '.cache';
if (file_exists($cachePath)) {
return file_get_contents($cachePath);
}
return null;
}
public function setFile($sourceFile, $content, $viewType = 'code') {
if (!is_dir($this->filesDir)) {
@mkdir($this->filesDir, 0777, true);
}
$hash = $this->generateHash($sourceFile, $viewType);
$cachePath = $this->filesDir . '/' . $hash . '.cache';
try {
file_put_contents($cachePath, $content);
@chmod($cachePath, 0666);
return $hash;
} catch (Exception $e) {
error_log("Cache file write error: " . $e->getMessage());
return false;
}
}
public function hasValidFile($sourceFile, $viewType = 'code') {
if (!file_exists($sourceFile)) {
return false;
}
$hash = $this->generateHash($sourceFile, $viewType);
$cachePath = $this->filesDir . '/' . $hash . '.cache';
if (!file_exists($cachePath)) {
return false;
}
return filemtime($cachePath) >= filemtime($sourceFile);
}
public function getImage($sourceFile, $maxWidth = null, $maxHeight = null) {
$additionalData = $maxWidth . 'x' . $maxHeight;
$hash = $this->generateHash($sourceFile, $additionalData);
$cachePath = $this->imgDir . '/' . $hash . '.cache';
if (file_exists($cachePath)) {
return file_get_contents($cachePath);
}
return null;
}
public function setImage($sourceFile, $imageData, $maxWidth = null, $maxHeight = null) {
if (!is_dir($this->imgDir)) {
@mkdir($this->imgDir, 0777, true);
}
$additionalData = $maxWidth . 'x' . $maxHeight;
$hash = $this->generateHash($sourceFile, $additionalData);
$cachePath = $this->imgDir . '/' . $hash . '.cache';
try {
file_put_contents($cachePath, $imageData);
@chmod($cachePath, 0666);
return $hash;
} catch (Exception $e) {
error_log("Cache image write error: " . $e->getMessage());
return false;
}
}
public function hasValidImage($sourceFile, $maxWidth = null, $maxHeight = null) {
if (!file_exists($sourceFile)) {
return false;
}
$additionalData = $maxWidth . 'x' . $maxHeight;
$hash = $this->generateHash($sourceFile, $additionalData);
$cachePath = $this->imgDir . '/' . $hash . '.cache';
if (!file_exists($cachePath)) {
return false;
}
return filemtime($cachePath) >= filemtime($sourceFile);
}
public function getImageDataUri($sourceFile, $maxWidth = null, $maxHeight = null, $mimeType = 'image/png') {
$imageData = $this->getImage($sourceFile, $maxWidth, $maxHeight);
if ($imageData) {
return 'data:' . $mimeType . ';base64,' . base64_encode($imageData);
}
return null;
}
public function setImageDataUri($sourceFile, $imageData, $maxWidth = null, $maxHeight = null, $mimeType = 'image/png') {
$hash = $this->setImage($sourceFile, $imageData, $maxWidth, $maxHeight);
if ($hash) {
return 'data:' . $mimeType . ';base64,' . base64_encode($imageData);
}
return null;
}
public function createZipTemp($folderName) {
if (!is_dir($this->zipDir)) {
@mkdir($this->zipDir, 0777, true);
}
$hash = md5($folderName . time() . bin2hex(random_bytes(8)));
$tempDir = $this->zipDir . '/' . $hash;
if (!is_dir($tempDir)) {
@mkdir($tempDir, 0777, true);
@chmod($tempDir, 0777);
}
return [
'hash' => $hash,
'path' => $tempDir
];
}
public function getZipPath($hash) {
return $this->zipDir . '/' . $hash . '.zip';
}
public function hasZip($hash) {
return file_exists($this->getZipPath($hash));
}
public function deleteZipTemp($hash) {
$tempDir = $this->zipDir . '/' . $hash;
if (is_dir($tempDir)) {
$this->deleteDirectory($tempDir);
}
}
public function deleteZip($hash) {
$zipPath = $this->getZipPath($hash);
if (file_exists($zipPath)) {
unlink($zipPath);
}
}
private function deleteDirectory($dir) {
if (!is_dir($dir)) return;
$files = glob($dir . '/*');
foreach ($files as $file) {
if (is_dir($file)) {
$this->deleteDirectory($file);
} else {
unlink($file);
}
}
rmdir($dir);
}
public function getVersionInfo() {
if (!$this->versionPdo) {
return null;
}
try {
$stmt = $this->versionPdo->prepare("SELECT value, cached_at FROM version_info WHERE key = 'remote_version_info'");
$stmt->execute();
$result = $stmt->fetch(PDO::FETCH_ASSOC);
if ($result) {
if (time() - $result['cached_at'] < 7200) {
return json_decode($result['value'], true);
}
}
return null;
} catch (Exception $e) {
error_log("Version info get error: " . $e->getMessage());
return null;
}
}
public function setVersionInfo($versionData) {
if (!$this->versionPdo) {
return false;
}
try {
$stmt = $this->versionPdo->prepare("INSERT OR REPLACE INTO version_info (key, value, cached_at) VALUES (?, ?, ?)");
$stmt->execute([
'remote_version_info',
json_encode($versionData),
time()
]);
return true;
} catch (Exception $e) {
error_log("Version info set error: " . $e->getMessage());
return false;
}
}
public function getStatistics() {
$stats = [
'files' => [
'count' => 0,
'size' => 0
],
'images' => [
'count' => 0,
'size' => 0
],
'zips' => [
'count' => 0,
'size' => 0
],
'total_size' => 0
];
$files = glob($this->filesDir . '/*.cache');
$stats['files']['count'] = count($files);
foreach ($files as $file) {
$stats['files']['size'] += filesize($file);
}
$images = glob($this->imgDir . '/*.cache');
$stats['images']['count'] = count($images);
foreach ($images as $image) {
$stats['images']['size'] += filesize($image);
}
$zips = glob($this->zipDir . '/*.zip');
$stats['zips']['count'] = count($zips);
foreach ($zips as $zip) {
$stats['zips']['size'] += filesize($zip);
}
$tempDirs = glob($this->zipDir . '/*', GLOB_ONLYDIR);
$stats['zips']['temp_dirs'] = count($tempDirs);
$stats['total_size'] = $stats['files']['size'] + $stats['images']['size'] + $stats['zips']['size'];
return $stats;
}
public function clearFiles() {
$deleted = 0;
$files = glob($this->filesDir . '/*.cache');
foreach ($files as $file) {
if (unlink($file)) {
$deleted++;
}
}
return $deleted;
}
public function clearImages() {
$deleted = 0;
$images = glob($this->imgDir . '/*.cache');
foreach ($images as $image) {
if (unlink($image)) {
$deleted++;
}
}
return $deleted;
}
public function clearZips() {
$deleted = 0;
$zips = glob($this->zipDir . '/*.zip');
foreach ($zips as $zip) {
if (unlink($zip)) {
$deleted++;
}
}
$tempDirs = glob($this->zipDir . '/*', GLOB_ONLYDIR);
foreach ($tempDirs as $dir) {
$this->deleteDirectory($dir);
$deleted++;
}
return $deleted;
}
public function clearVersionDb() {
$deleted = 0;
if (file_exists($this->versionDb)) {
if (@unlink($this->versionDb)) {
$deleted = 1;
$this->versionPdo = null;
}
}
return $deleted;
}
public function clearAll() {
$filesDeleted = $this->clearFiles();
$imagesDeleted = $this->clearImages();
$zipsDeleted = $this->clearZips();
$versionDbDeleted = $this->clearVersionDb();
return [
'files' => $filesDeleted,
'images' => $imagesDeleted,
'zips' => $zipsDeleted,
'version_db' => $versionDbDeleted,
'total' => $filesDeleted + $imagesDeleted + $zipsDeleted + $versionDbDeleted
];
}
public function getPaths() {
return [
'base' => $this->cacheDir,
'files' => $this->filesDir,
'images' => $this->imgDir,
'zips' => $this->zipDir,
'version_db' => $this->versionDb
];
}
public function formatBytes($bytes) {
$units = ['B', 'KB', 'MB', 'GB', 'TB'];
for ($i = 0; $bytes > 1024 && $i < count($units) - 1; $i++) {
$bytes /= 1024;
}
return round($bytes, 2) . ' ' . $units[$i];
}
}
if (!defined('INDEXER_FILES_ROOT_DIR')) {
define('INDEXER_FILES_ROOT_DIR', dirname(dirname(__FILE__)));
}
if (php_sapi_name() === 'cli') {
if ($argc < 2) {
displayHelp();
exit(1);
}
$command = strtolower($argv[1]);
$cache = null;
try {
$cache = new Cache(INDEXER_FILES_ROOT_DIR);
switch ($command) {
case 'help':
displayHelp();
break;
case 'clear-all-cache':
$results = $cache->clearAll();
echo " Successfully cleared all caches:\n";
echo " - Files cache items cleared: " . $results['files'] . "\n";
echo " - Image cache items cleared: " . $results['images'] . "\n";
echo " - Zip cache/temp items cleared: " . $results['zips'] . "\n";
echo " - Version DB file cleared: " . ($results['version_db'] ? '1' : '0') . "\n";
echo " Total items removed: " . $results['total'] . "\n";
break;
case 'clear-files-cache':
$count = $cache->clearFiles();
echo " Files cache cleared: $count file(s) removed.\n";
break;
case 'clear-img-cache':
$count = $cache->clearImages();
echo " Image cache cleared: $count image file(s) removed.\n";
break;
case 'clear-version-cache':
$count = $cache->clearVersionDb();
if ($count > 0) {
echo " Version DB cache cleared: version.sqlite file removed.\n";
} else {
echo " Version DB cache file (version.sqlite) was not found or could not be removed.\n";
}
break;
case 'stats':
$stats = $cache->getStatistics();
echo "\n Cache Statistics:\n";
echo "----------------------------------------\n";
echo "Total Size: " . $cache->formatBytes($stats['total_size']) . "\n";
echo "----------------------------------------\n";
echo "Files Cache:\n";
echo " Items: " . number_format($stats['files']['count']) . "\n";
echo " Size: " . $cache->formatBytes($stats['files']['size']) . "\n";
echo "Image Cache:\n";
echo " Items: " . number_format($stats['images']['count']) . "\n";
echo " Size: " . $cache->formatBytes($stats['images']['size']) . "\n";
echo "Zip Cache:\n";
echo " Zips: " . number_format($stats['zips']['count']) . " files\n";
echo " Temp Dirs: " . number_format($stats['zips']['temp_dirs']) . " directories\n";
echo " Size: " . $cache->formatBytes($stats['zips']['size']) . "\n";
echo "----------------------------------------\n";
break;
case 'show-paths':
$paths = $cache->getPaths();
echo "\n Cache Directory Paths:\n";
echo "--------------------------------------------------------\n";
echo "Base Cache Dir: " . $paths['base'] . "\n";
echo "Files Cache Dir: " . $paths['files'] . "\n";
echo "Image Cache Dir: " . $paths['images'] . "\n";
echo "Zip Cache Dir: " . $paths['zips'] . "\n";
echo "Version DB File: " . $paths['version_db'] . "\n";
echo "--------------------------------------------------------\n";
break;
default:
echo " Unknown command: '$command'.\n";
displayHelp();
exit(1);
}
} catch (Exception $e) {
fwrite(STDERR, " An error occurred: " . $e->getMessage() . "\n");
exit(1);
}
}
function displayHelp() {
global $argv;
$scriptName = basename($argv[0]);
echo "\n";
echo "Available Commands:\n";
echo " stats : Shows current cache statistics (size and item count).\n";
echo " show-paths : Shows the configured cache directory paths.\n";
echo " clear-all-cache : Clears all file, image, zip, and version database caches.\n";
echo " clear-files-cache : Clears only the file content caches.\n";
echo " clear-img-cache : Clears only the image/thumbnail caches.\n";
echo " clear-version-cache : Clears only the version info database (version.sqlite).\n";
echo "\n";
}
?>