sasae/src/Loader/SasaeFilesystemLoader.php
2023-08-24 22:31:36 +00:00

84 lines
2.4 KiB
PHP

<?php
namespace Sasae\Loader;
use InvalidArgumentException;
use Twig\Source;
use Twig\Error\LoaderError;
use Twig\Loader\LoaderInterface;
/**
* Provides a simpler Filesystem loader with mechanisms like namespaces omitted.
*/
class SasaeFilesystemLoader implements LoaderInterface {
private string $root;
/**
* @param string $path Base path to the templates directory.
*/
public function __construct(string $path) {
$path = realpath($path);
if($path === false)
throw new InvalidArgumentException('$path does not exist.');
$this->root = $path;
}
/**
* Returns the underlying path.
*
* @return string
*/
public function getPath(): string {
return $this->root;
}
/** @var array<string, string> */
private array $absPaths = [];
private function getAbsolutePath(string $path, bool $throw): string {
$cachePath = $path;
if(array_key_exists($cachePath, $this->absPaths))
return $this->absPaths[$cachePath];
if(pathinfo($path, PATHINFO_EXTENSION) === '')
$path = rtrim($path, '.') . '.twig';
$absPath = realpath($this->root . DIRECTORY_SEPARATOR . $path);
if($absPath === false) {
if(!$throw)
return '';
throw new LoaderError(sprintf('Could not find template "%s" in "%s".', $path, $this->root));
}
if(!str_starts_with($absPath, $this->root)) {
if(!$throw)
return '';
throw new LoaderError(sprintf('Attempting to load "%s" which is outside of the template directory.', $absPath));
}
return $this->absPaths[$cachePath] = $absPath;
}
public function getSourceContext(string $name): Source {
$path = $this->getAbsolutePath($name, true);
$body = file_get_contents($path);
if($body === false)
throw new LoaderError(sprintf('Was unable to read "%s"', $path));
return new Source($body, $name, $path);
}
public function getCacheKey(string $name): string {
return $this->getAbsolutePath($name, true);
}
public function isFresh(string $name, int $time): bool {
return filemtime($this->getAbsolutePath($name, true)) < $time;
}
public function exists(string $name) {
return $this->getAbsolutePath($name, false) !== '';
}
}