From 4bd4cddbff50467316ba02b85538bb7b3939e93d Mon Sep 17 00:00:00 2001 From: Dave Mc Nicoll Date: Tue, 29 Nov 2022 19:46:40 +0000 Subject: [PATCH] - Cleaned up a bit and added some methods to give Lean/Console more flexibility --- src/Builder.php | 2 +- src/Caching/Cache.php | 5 ++++ src/Caching/Opcache.php | 28 ++++++++++++++-------- src/Extension/UrlExtension.php | 4 ++-- src/FileFetcher.php | 44 ++++++++++++++++++++++++++++++---- src/Picea.php | 19 +++++++++------ src/Syntax/EchoSafeToken.php | 2 +- 7 files changed, 78 insertions(+), 26 deletions(-) diff --git a/src/Builder.php b/src/Builder.php index 69c2930..a541802 100644 --- a/src/Builder.php +++ b/src/Builder.php @@ -4,7 +4,7 @@ namespace Picea; class Builder { - const TEMPLATE_CLASSNAME_PREFIX = "PiceaTemplate_"; + public const TEMPLATE_CLASSNAME_PREFIX = "PiceaTemplate_"; protected string $templatePath = ""; diff --git a/src/Caching/Cache.php b/src/Caching/Cache.php index 0cfc2f4..73e54f4 100644 --- a/src/Caching/Cache.php +++ b/src/Caching/Cache.php @@ -29,4 +29,9 @@ interface Cache { * @return bool */ public function save(Context $context) : bool; + + /** + * Purge path cache + */ + public function purge() : void; } diff --git a/src/Caching/Opcache.php b/src/Caching/Opcache.php index 87319c7..516fd4e 100644 --- a/src/Caching/Opcache.php +++ b/src/Caching/Opcache.php @@ -2,8 +2,7 @@ namespace Picea\Caching; -use Picea\Builder, - Picea\Compiler\Context; +use Picea\ { Builder, Compiler\Context }; class Opcache implements Cache { @@ -57,11 +56,7 @@ class Opcache implements Cache { if ( file_exists($path = $this->cachePath($viewPath)) ) { $this->compiled[$viewPath] = include($path); - - # if ( $this->compiled[$viewPath]['extends'] ?? false ) { - # $this->compiled($this->compiled[$viewPath]['extends']); - # } - + return true; } @@ -86,7 +81,7 @@ class Opcache implements Cache { return true; } - protected function cachePath(string $fileName = "") : string + 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 ])); } @@ -95,7 +90,7 @@ class Opcache implements Cache { spl_autoload_register(function ($class) use ($namespace) { $prefix = "$namespace\\"; - $baseDir = $this->cachePath() . "/"; + $baseDir = $this->cachePath() . DIRECTORY_SEPARATOR; $len = strlen($prefix); @@ -103,11 +98,24 @@ class Opcache implements Cache { return; } - $file = $baseDir . str_replace('\\', '/', substr($class, $len)) . '.php'; + $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); + } + } } diff --git a/src/Extension/UrlExtension.php b/src/Extension/UrlExtension.php index ce2ca0b..5fcb9cb 100644 --- a/src/Extension/UrlExtension.php +++ b/src/Extension/UrlExtension.php @@ -102,7 +102,7 @@ class UrlExtension implements Extension { public static function slug(string $text, string $separator = '-') : string { - return str_replace('-', $separator, \Transliterator::createFromRules(':: Any-Latin;:: NFD;:: [:Nonspacing Mark:] Remove;:: NFC;:: [:Punctuation:] Remove;:: Lower();[:Separator:] > \'-\'')->transliterate(str_replace('-', ' ', $text))); + return trim(str_replace('-', $separator, \Transliterator::createFromRules(':: Any-Latin;:: NFD;:: [:Nonspacing Mark:] Remove;:: NFC;:: [:Punctuation:] Remove;:: Lower();[:Separator:] > \'-\'')->transliterate(str_replace('-', ' ', $text))), '-'); } public function registerRoute(string $name, string $route, string $class, string $method, array $routeMethods) : void @@ -179,7 +179,7 @@ class UrlExtension implements Extension { ])) || isset($_SERVER['HTTP_X_ARR_SSL']); return $https - || ( "443" === ( $_SERVER['SERVER_PORT'] ?? "" ) ) + || ( "443" === ( $_SERVER['SERVER_PORT'] ?? "" ) ) || ( "443" === ( $_SERVER['HTTP_X_FORWARDED_PORT'] ?? "" ) ) || ( "off" !== ( strtolower($_SERVER['HTTPS'] ?? $_SERVER['HTTP_X_FORWARDED_SSL'] ?? $_SERVER['X-Forwarded-Ssl'] ?? "off")) ); } diff --git a/src/FileFetcher.php b/src/FileFetcher.php index ec4b760..46e87ff 100644 --- a/src/FileFetcher.php +++ b/src/FileFetcher.php @@ -2,6 +2,8 @@ namespace Picea; +use RecursiveIteratorIterator, RecursiveDirectoryIterator; + class FileFetcher { protected array $folderList = []; @@ -12,13 +14,13 @@ class FileFetcher public function __construct(?array $folderList = null) { if ( $folderList !== null ) { - $this->folderList = $folderList; + $this->addFolders($folderList); } } public function addFolder(string $folder, int $order = 100) : void { - $folder = rtrim($folder, DIRECTORY_SEPARATOR); + $folder = $this->normalizeFolder($folder); $this->folderList[$folder] = [ 'path' => $folder, @@ -28,7 +30,14 @@ class FileFetcher public function addFolders(array $folderList) : void { - $this->folderList = array_replace($this->folderList, $folderList); + foreach($folderList as $folder) { + $this->addFolder($folder['path'], $folder['order']); + } + } + + protected function normalizeFolder(string $path) : string + { + return rtrim($path, '/\\'); } public function folderList(?array $set = null) : ?array @@ -40,7 +49,7 @@ class FileFetcher { usort($this->folderList, fn($a, $b) => $a['order'] <=> $b['order']); - foreach($this->folderList as $folder) { + foreach($this->folderList() as $folder) { foreach($this->supportedExtensionList as $extension) { $file = $folder['path'] . DIRECTORY_SEPARATOR . "$fileName.$extension"; $file = str_replace([ '\\', '/' ], DIRECTORY_SEPARATOR, $file); @@ -56,7 +65,7 @@ class FileFetcher } # Fallback on full-path - foreach($this->folderList as $folder) { + foreach($this->folderList() as $folder) { $file = $folder['path'] . DIRECTORY_SEPARATOR . $fileName; $file = str_replace([ '\\', '/' ], DIRECTORY_SEPARATOR, $file); @@ -72,6 +81,30 @@ class FileFetcher throw new \RuntimeException("Given view file `$fileName` can not be found within given folder list.."); } + public function getFileList() : array + { + usort($this->folderList, fn($a, $b) => $a['order'] <=> $b['order']); + + $list = []; + + foreach($this->folderList() as $folder) { + $path = $folder['path'] . "/"; + $list[$path] = []; + + if ( \file_exists($path) ) { + $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::SELF_FIRST, RecursiveIteratorIterator::CATCH_GET_CHILD); + + foreach ($iterator as $file) { + if ($file->isFile() && in_array($file->getExtension(), $this->supportedExtensionList)) { + $list[$path][] = $file; + } + } + } + } + + return $list; + } + public function getFilePath(string $fileName) : string { return $this->findFile($fileName); @@ -81,4 +114,5 @@ class FileFetcher { return file_get_contents($this->getFilePath($fileName)); } + } diff --git a/src/Picea.php b/src/Picea.php index 201ced9..8ab24e6 100644 --- a/src/Picea.php +++ b/src/Picea.php @@ -73,8 +73,8 @@ class Picea implements LanguageRegistration return call_user_func($this->gatherTemplateObject($viewPath, $variables, $proxy)); } catch(\Throwable $ex) { - # Temporary class for an experiment throw $ex; + # Temporary class for an experiment on retrieving more accurate debug info throw new class($object, $this, "An error occurred trying to render HTML view `$viewPath` : " . $ex->getMessage(), 911, $ex) extends \Exception { protected Picea $picea; @@ -124,23 +124,28 @@ class Picea implements LanguageRegistration /** * Method used by Block and View tokens - * @param object $proxy - * @param string $viewPath - * @param array $variables - * @return type */ public function inlineHtml(? object $proxy, string $viewPath, array $variables) { return $this->renderHtml($viewPath, $this->globalVariables + $variables, $proxy); } + /** + * Allows block to be called from templates + */ public function inlineBlock(? object $proxy, string $viewPath, ... $variables) { return $this->renderHtml($viewPath, [ 'inlineVariables' => $variables, 'globalVariables' => $this->globalVariables ], $proxy); } - + + /** + * Push view content inline + */ public function inlineContent(string $viewPath) { return $this->fileFetcher->getFileContent($viewPath); } - + + /** + * Renders a compile context + */ public function renderContext(Compiler\Context $context) : object { if ( null === $object = $this->contextFromCache($context) ) { diff --git a/src/Syntax/EchoSafeToken.php b/src/Syntax/EchoSafeToken.php index 1b832b4..47f15c5 100644 --- a/src/Syntax/EchoSafeToken.php +++ b/src/Syntax/EchoSafeToken.php @@ -23,7 +23,7 @@ class EchoSafeToken implements Syntax { $sourceCode = preg_replace_callback("#({$this->tokenOpen})(.*?)({$this->tokenClose})#s", function ($matches) { $line = trim($matches[2], " \t\n\r\0\x0B;"); - return "flag}, '{$this->encoding}', " . ($this->doubleEncode ? "true" : "false") . ") ?>"; + return "flag}, '{$this->encoding}', " . ($this->doubleEncode ? "true" : "false") . ") ?>"; }, $sourceCode); }