174 lines
6.4 KiB
PHP
174 lines
6.4 KiB
PHP
|
<?php
|
||
|
|
||
|
namespace App;
|
||
|
|
||
|
use Utils\Utils;
|
||
|
|
||
|
class Cache {
|
||
|
|
||
|
private $currentDir;
|
||
|
private $counter = [];
|
||
|
private $fileName = '../cache/cache.json';
|
||
|
private $fileCache;
|
||
|
private $currentConfig;
|
||
|
private $saveConfig;
|
||
|
|
||
|
/**
|
||
|
* Initializes the object with a directory path and configuration settings, managing cache as needed.
|
||
|
*
|
||
|
* This constructor checks if the provided directory path is authorized. If it is, the constructor
|
||
|
* proceeds to handle caching based on the provided configuration. If caching is disabled, any existing
|
||
|
* cache file is deleted. The method also compares the current configuration with a saved version
|
||
|
* to detect changes.
|
||
|
*
|
||
|
* @param string $dir The current directory path to be set.
|
||
|
* @param array $config Configuration settings to be used by the object, including cache management options.
|
||
|
*
|
||
|
* @throws \Exception If an unauthorized access attempt is detected.
|
||
|
*/
|
||
|
function __construct(string $dir, array $config) {
|
||
|
if (!Utils::isPathAuthorized($dir)) {
|
||
|
die("ERROR 03: Unauthorized access!");
|
||
|
}
|
||
|
|
||
|
$this->currentDir = $dir;
|
||
|
|
||
|
if (!is_dir('../cache/html')) {
|
||
|
mkdir('../cache/html', 0700);
|
||
|
}
|
||
|
|
||
|
if ($config['disableCache'] && file_exists($this->fileName)) {
|
||
|
unlink($this->fileName);
|
||
|
}
|
||
|
|
||
|
if (file_exists($this->fileName)) {
|
||
|
$cacheFile = json_decode(file_get_contents($this->fileName), true);
|
||
|
} else {
|
||
|
$cacheFile = [];
|
||
|
}
|
||
|
|
||
|
$this->currentConfig = md5(json_encode($config));
|
||
|
if (isset($cacheFile['config'])) {
|
||
|
$this->saveConfig = $cacheFile['config'];
|
||
|
}
|
||
|
|
||
|
$this->fileCache = $cacheFile;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Counts the number of files and directories in the current directory.
|
||
|
*
|
||
|
* This method iterates over the contents of the current directory, counting
|
||
|
* both files and subdirectories (excluding `.` and `..`). The total count is
|
||
|
* stored in an internal array indexed by the directory path and is also returned.
|
||
|
* If the directory cannot be opened, an exception is thrown.
|
||
|
*
|
||
|
* @return array An associative array where the key is the directory path and the value is the count of files and directories.
|
||
|
*
|
||
|
* @throws \Exception If the directory cannot be opened for reading.
|
||
|
*/
|
||
|
public function countDirsAndFiles(): array {
|
||
|
$counter = 0;
|
||
|
if (is_dir($this->currentDir) && $handle = opendir($this->currentDir)) {
|
||
|
while (false !== ($file = readdir($handle))) {
|
||
|
if ($file === "." || $file === "..") {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if (is_file($this->currentDir . '/' . $file) || is_dir($this->currentDir . '/' . $file)) {
|
||
|
$counter++;
|
||
|
}
|
||
|
}
|
||
|
closedir($handle);
|
||
|
$this->counter[$this->currentDir] = $counter;
|
||
|
return $this->counter;
|
||
|
} else {
|
||
|
throw new \Exception("ERROR: Could not open directory for reading: " . $this->currentDir);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Checks if the number of files and directories in the current directory has changed.
|
||
|
*
|
||
|
* This method compares the current count of files and directories with a cached count.
|
||
|
* If the counts differ, it updates the cache with the new count and returns `true`,
|
||
|
* indicating that a change has occurred. Otherwise, it returns `false`.
|
||
|
*
|
||
|
* @return bool `true` if the count of files and directories has changed and the cache is updated; `false` otherwise.
|
||
|
*/
|
||
|
public function changeFile(): bool {
|
||
|
if (isset($this->fileCache[$this->currentDir])) {
|
||
|
if ($this->counter[$this->currentDir] !== $this->fileCache[$this->currentDir]) {
|
||
|
$this->fileCache = array_merge($this->fileCache, $this->counter);
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Checks if the current configuration has changed compared to the saved configuration.
|
||
|
*
|
||
|
* This method compares the current configuration with a previously saved configuration.
|
||
|
* If they differ, it updates the cache with the current configuration and returns `true`,
|
||
|
* indicating that a change has occurred. Otherwise, it returns `false`.
|
||
|
*
|
||
|
* @return bool `true` if the configuration has changed and the cache is updated; `false` otherwise.
|
||
|
*/
|
||
|
public function changeConf(): bool {
|
||
|
if ($this->currentConfig !== $this->saveConfig) {
|
||
|
$this->fileCache['config'] = $this->currentConfig;
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Saves the current file cache to a file in JSON format.
|
||
|
*
|
||
|
* This method serializes the file cache to a JSON string with pretty printing, unescaped slashes,
|
||
|
* and unescaped Unicode characters. It then writes this JSON data to the specified file.
|
||
|
* If the JSON encoding fails or if the file write operation fails, an exception is thrown.
|
||
|
*
|
||
|
* @throws \Exception If JSON encoding fails or if writing to the file fails.
|
||
|
*
|
||
|
* @return void
|
||
|
*/
|
||
|
public function save(): void {
|
||
|
$jsonData = json_encode($this->fileCache, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
|
||
|
|
||
|
if ($jsonData === false) {
|
||
|
throw new \Exception("Failed to encode data to JSON: " . json_last_error_msg());
|
||
|
}
|
||
|
|
||
|
if (file_put_contents($this->fileName, $jsonData) === false) {
|
||
|
throw new \Exception("Failed to write data to file: " . $this->fileName);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Clears the HTML cache by deleting all cached files.
|
||
|
*
|
||
|
* This method retrieves all `.html` files in the cache directory and deletes them.
|
||
|
* If the cache directory cannot be read or if any file deletion fails, an exception is thrown.
|
||
|
*
|
||
|
* @throws \Exception If the cache directory cannot be read or if a file cannot be deleted.
|
||
|
*
|
||
|
* @return void
|
||
|
*/
|
||
|
public function clearCache(): void {
|
||
|
$files = glob("../cache/html/*.html");
|
||
|
if ($files === false) {
|
||
|
throw new \Exception("Failed to read cache directory.");
|
||
|
}
|
||
|
|
||
|
foreach ($files as $file) {
|
||
|
if (is_file($file)) {
|
||
|
if (!unlink($file)) {
|
||
|
throw new \Exception("Failed to delete file: " . $file);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|