122 lines
3.3 KiB
PHP
122 lines
3.3 KiB
PHP
<?php
|
|
|
|
namespace Picea\Caching;
|
|
|
|
use Picea\ { Builder, Compiler\Context };
|
|
|
|
class Opcache implements Cache {
|
|
|
|
protected string $cacheFolder = "picea";
|
|
|
|
protected string $cachePath = "";
|
|
|
|
protected array $compiled = [];
|
|
|
|
protected null|Context $context;
|
|
|
|
public function __construct(?string $cachePath = null, null|Context $context = null)
|
|
{
|
|
$this->cachePath = $cachePath ?? sys_get_temp_dir();
|
|
$this->context = $context;
|
|
|
|
$this->registerNamespace($this->context->namespace);
|
|
}
|
|
|
|
public function load(string $viewPath, ...$arguments) : object
|
|
{
|
|
if ( empty($viewPath) ) {
|
|
throw new \RuntimeException("Given view path is empty.");
|
|
}
|
|
|
|
if ( ! $this->compiled($viewPath) ) {
|
|
throw new \RuntimeException("You must compile your view `$viewPath` before trying to load it.");
|
|
}
|
|
|
|
$compiledContext = $this->compiled[$viewPath];
|
|
|
|
$fullName = isset($compiledContext['namespace']) ? "\\{$compiledContext['namespace']}\\{$compiledContext['classname']}" : ($compiledContext['classname'] ?? $viewPath);
|
|
|
|
return new $fullName(...$arguments);
|
|
}
|
|
|
|
public function save(Context $context) : bool
|
|
{
|
|
$context->compiledClassPath();
|
|
$this->validateCachePath();
|
|
file_put_contents($this->cachePath($context->viewPath), $context->compiledSource);
|
|
|
|
return false;
|
|
}
|
|
|
|
public function compiled(string $viewPath) : bool
|
|
{
|
|
if ( false !== ( $this->compiled[$viewPath] ?? false ) ) {
|
|
return true;
|
|
}
|
|
|
|
if ( file_exists($path = $this->cachePath($viewPath)) ) {
|
|
$this->compiled[$viewPath] = include($path);
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
return false;
|
|
}
|
|
|
|
protected function validateCachePath() : bool
|
|
{
|
|
$fullPath = $this->cachePath();
|
|
|
|
if ( ! file_exists($fullPath) ) {
|
|
mkdir($fullPath, 0750, true);
|
|
}
|
|
|
|
if ( ! is_writeable($fullPath) ) {
|
|
throw new \RuntimeException(
|
|
sprintf("Given cache path `%s` is not writeable by `%s`", $fullPath, static::class)
|
|
);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public function cachePath(string $fileName = "") : string
|
|
{
|
|
return implode(DIRECTORY_SEPARATOR, array_filter([ $this->cachePath, $this->cacheFolder, $fileName ? str_replace([ "/", DIRECTORY_SEPARATOR ], "~", Builder::generateClassName($fileName) . ".php") : null ]));
|
|
}
|
|
|
|
public function registerNamespace(string $namespace) {
|
|
spl_autoload_register(function ($class) use ($namespace) {
|
|
$prefix = "$namespace\\";
|
|
|
|
$baseDir = $this->cachePath() . DIRECTORY_SEPARATOR;
|
|
|
|
$len = strlen($prefix);
|
|
|
|
if (strncmp($prefix, $class, $len) !== 0) {
|
|
return;
|
|
}
|
|
|
|
$file = $baseDir . str_replace('\\', DIRECTORY_SEPARATOR, substr($class, $len)) . '.php';
|
|
|
|
if ( file_exists($file) ) {
|
|
require $file;
|
|
}
|
|
});
|
|
}
|
|
|
|
public function getFilelist() : array
|
|
{
|
|
return glob($this->cachePath() . DIRECTORY_SEPARATOR . Builder::TEMPLATE_CLASSNAME_PREFIX . "*");
|
|
}
|
|
|
|
public function purge() : void
|
|
{
|
|
foreach($this->getFilelist() as $dir)
|
|
{
|
|
dump($dir);
|
|
}
|
|
}
|
|
}
|