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"; } ?>