- WIP on RAW token

- WIP on caching interface
- Work done on easing template rendering for the controller
This commit is contained in:
mcndave committed 2019-10-04 08:38:11 -04:00
1 parent f8e3dbd60f
commit bcd49884fc
37 files changed
+381 -107

No files matched your search

+4 -4
View File
@@ -10,12 +10,12 @@ class %CLASSNAME% %EXTENDS% {
protected array $__variables_list = [];
public function output() : void
public final function __output() : void
{
extract($this->__variables_list); ?>%CONTENT%<?php
}
public function __renderSection($name) : void
public final function __renderSection($name) : void
{
foreach([ 'prepend', 'default', 'append' ] as $item) {
usort($this->__section_list[$name][$item], fn($a, $b) => $a['order'] <=> $b['order']);
@@ -30,9 +30,9 @@ class %CLASSNAME% %EXTENDS% {
}
}
public function __renderTemplate() {
public final function __invoke() {
ob_start();
$this->output();
$this->__output();
return ob_get_clean();
}
}
+11
View File
@@ -0,0 +1,11 @@
<?php
namespace Picea\Caching;
interface Cache {
public function handle(string $fileName) : bool;
public function load();
}
+7 -17
View File
@@ -2,31 +2,21 @@
namespace Picea\Caching;
class Memory {
class Memory implements Cache {
protected string $cachePath = "";
public function __construct(string $cachePath)
public function handle(string $fileName) : bool
{
$this->cachePath = $cachePath;
}
public function loadFile(string $fileName) : bool
{
if ( file_exists($path = $this->filePath($fileName)) ) {
require_once($path);
}
#if ( file_exists($path = $this->filePath($fileName)) ) {
# require_once($path);
#}
return false;
}
public function load() {}
public function saveFile(string $fileName) : bool
{
}
public function filePath(string $fileName) : string
{
return $this->cachePath . $fileName;
}
}
+23 -4
View File
@@ -2,16 +2,16 @@
namespace Picea\Caching;
class Opcache {
class Opcache implements Cache {
protected string $cachePath = "";
public function __construct(string $cachePath)
public function __construct(?string $cachePath = null)
{
$this->cachePath = $cachePath;
$this->cachePath = $cachePath ?? sys_get_temp_dir();
}
public function loadFile(string $fileName) : bool
public function handle(string $fileName) : bool
{
if ( file_exists($path = $this->filePath($fileName)) ) {
require_once($path);
@@ -23,6 +23,8 @@ class Opcache {
public function saveFile(string $fileName, string $content) : bool
{
$this->validateCachePath();
file_put_contents($this->filePath($fileName), $content);
return false;
@@ -32,4 +34,21 @@ class Opcache {
{
return $this->cachePath . $fileName;
}
protected function validateCachePath() : bool
{
if ( ! file_exists($this->cachePath) ) {
mkdir($this->cachePath, 0750, true);
}
if ( ! is_writeable($this->cachePath) ) {
throw new \RuntimeException(
sprintf("Given cache path `%s` is not writeable by `%s`", $this->cachePath, static::class)
);
return false;
}
return true;
}
}
+25 -9
View File
@@ -2,6 +2,8 @@
namespace Picea;
use Picea\Language\LanguageRegistration;
class Compiler
{
protected string $sourceCode = "";
@@ -16,8 +18,16 @@ class Compiler
protected array $extensionList = [];
protected ? LanguageRegistration $languageRegistration;
public function __construct(?LanguageRegistration $languageRegistration = null)
{
$this->languageRegistration = $languageRegistration;
}
public function compile(Compiler\Context $context) : string
{
$this->languageRegistration->registerAll($this);
$context->compiler = $this;
/**
@@ -39,7 +49,7 @@ class Compiler
# @TODO Refractor this parts to allows registration to the tag's name
if ( $this->tagList[$token] ?? false ) {
return $this->tagList[$token]->parse($context, $arguments);
return $this->tagList[$token]->parse($context, $arguments, $token);
}
elseif ( $this->extensionList[$token] ?? false ) {
return $this->extensionList[$token]->parse($context, $arguments, $token);
@@ -59,12 +69,6 @@ class Compiler
return $this;
}
public function registerExtension(Extension\Extension $extension) : self
{
$this->extensionList[$extension->token] = $extension;
return $this;
}
public function registerCaching(CachingStrategy $cachingStrategy) : self
{
return $this;
@@ -72,13 +76,25 @@ class Compiler
public function registerSyntax(Syntax\Syntax $syntaxObject) : self
{
$this->syntaxObjectList[] = $syntaxObject;
$this->syntaxObjectList[get_class($syntaxObject)] = $syntaxObject;
return $this;
}
public function registerControlStructure(ControlStructure\ControlStructure $controlStructureObject) : self
{
$this->tagList[$controlStructureObject->token] = $controlStructureObject;
foreach($controlStructureObject->tokens ?? (array) $controlStructureObject->token as $token) {
$this->tagList[$token] = $controlStructureObject;
}
return $this;
}
public function registerExtension(Extension\Extension $extension) : self
{
foreach($extension->tokens ?? (array) $extension->token as $token) {
$this->extensionList[$token] = $extension;
}
return $this;
}
}
+5
View File
@@ -41,4 +41,9 @@ abstract class Context {
{
return implode(",", $context->useStack ?? []);
}
public function variables(array $variables) : void
{
$this->variables = $variables;
}
}
+1 -1
View File
@@ -6,7 +6,7 @@ class BreakToken implements ControlStructure {
public string $token = "break";
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments) {
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) {
return "<?php break; ?>";
}
+1 -1
View File
@@ -6,7 +6,7 @@ class CaseToken implements ControlStructure {
public string $token = "case";
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments) {
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) {
$output = "";
if ( $context->switchStack ) {
+1 -1
View File
@@ -3,5 +3,5 @@
namespace Picea\ControlStructure;
interface ControlStructure {
public function parse(\Picae\Compiler\Context &$context, string $sourceCode);
public function parse(\Picae\Compiler\Context &$context, string $sourceCode, string $token);
}
+1 -1
View File
@@ -6,7 +6,7 @@ class DefaultToken implements ControlStructure {
public string $token = "default";
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments) {
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) {
$output = "";
if ( $context->switchStack ) {
+1 -1
View File
@@ -6,7 +6,7 @@ class ElseIfToken implements ControlStructure {
public string $token = "elseif";
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments) {
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) {
return "<?php elseif ($arguments): ?>";
}
+1 -1
View File
@@ -6,7 +6,7 @@ class ElseToken implements ControlStructure {
public string $token = "else";
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments) {
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) {
return "<?php else: ?>";
}
+1 -1
View File
@@ -6,7 +6,7 @@ class EndIfToken implements ControlStructure {
public string $token = "endif";
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments) {
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) {
return "<?php endif ?>";
}
+12
View File
@@ -0,0 +1,12 @@
<?php
namespace Picea\ControlStructure;
class EndRawToken implements ControlStructure {
public string $token = "endraw";
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) {
}
}
+1 -1
View File
@@ -6,7 +6,7 @@ class EndSectionToken implements ControlStructure {
public string $token = "endsection";
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments) {
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) {
if ( empty($context->sections) ) {
throw new \RuntimeException("A section closing tag {% endsection %} was found without an opening {% section %} tag");
}
+1 -1
View File
@@ -6,7 +6,7 @@ class EndSwitchToken implements ControlStructure {
public string $token = "endswitch";
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments) {
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) {
return "<?php endswitch; ?>";
}
}
+1 -1
View File
@@ -6,7 +6,7 @@ class EndforToken implements ControlStructure {
public string $token = "endfor";
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments) {
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) {
if ( end($context->iterationStack)['or'] === false ) {
$output = "<?php endfor; ?>";
}
+1 -1
View File
@@ -6,7 +6,7 @@ class EndforeachToken implements ControlStructure {
public string $token = "endforeach";
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments) {
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) {
if ( end($context->iterationStack)['or'] === false ) {
$output = "<?php endforeach; ?>";
}
+1 -1
View File
@@ -6,7 +6,7 @@ class ExtendsToken implements ControlStructure {
public string $token = "extends";
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $path) {
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $path, string $token) {
# Triming string's quotes
$path = trim($path, "\"\' \t");
+1 -1
View File
@@ -6,7 +6,7 @@ class ForToken implements ControlStructure {
public string $token = "for";
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments) {
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) {
$uid = "$".uniqid("for_");
$context->iterationStack[] = [
+1 -1
View File
@@ -6,7 +6,7 @@ class ForeachToken implements ControlStructure {
public string $token = "foreach";
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments) {
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) {
$uid = "$".uniqid("foreach_");
$context->iterationStack[] = [
+1 -1
View File
@@ -6,7 +6,7 @@ class IfToken implements ControlStructure {
public string $token = "if";
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments) {
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) {
return "<?php if ($arguments): ?>";
}
+1 -1
View File
@@ -6,7 +6,7 @@ class NamespaceToken implements ControlStructure {
public string $token = "namespace";
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments) {
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) {
$context->namespace = $arguments;
return "";
}
+1 -1
View File
@@ -6,7 +6,7 @@ class OrToken implements ControlStructure {
public string $token = "or";
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments) {
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) {
if ( empty($context->iterationStack) ) {
throw new \LogicException("Token `or` was used outside of iterator. Make sure your `for` or `foreach` declaration are properly made.");
}
+12
View File
@@ -0,0 +1,12 @@
<?php
namespace Picea\ControlStructure;
class RawToken implements ControlStructure {
public string $token = "raw";
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) {
}
}
+1 -1
View File
@@ -6,7 +6,7 @@ class SectionToken implements ControlStructure {
public string $token = "section";
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments) {
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) {
list($name, $options) = array_pad(explode(',', $arguments), 2, null);
if ( $options ?? false ) {
+1 -1
View File
@@ -6,7 +6,7 @@ class SwitchToken implements ControlStructure {
public string $token = "switch";
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments) {
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) {
$context->switchStack[] = true;
return "<?php switch($arguments):";
}
+1 -1
View File
@@ -6,7 +6,7 @@ class UseToken implements ControlStructure {
public string $token = "use";
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments) {
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) {
$context->useStack[] = $arguments;
return "";
}
+1 -1
View File
@@ -6,7 +6,7 @@ class ViewToken implements ControlStructure {
public string $token = "view";
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments) {
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) {
#$context->switchStack[] = true;
#return "<?php switch($arguments):";
}
+36
View File
@@ -0,0 +1,36 @@
<?php
namespace Picea\Extension;
trait ExtensionTrait {
protected function parseOptions(?string $options) : array
{
if ( $options ?? false ) {
$attributes = eval("return $options;");
if ( ! is_array($attributes) ) {
throw new InvalidArgumentException("Given options `$options` is not a valid attributes array.");
}
return $attributes;
}
return [];
}
protected function trim(string $value) : string
{
$value = trim($value, " \t");
if ( in_array(substr($value, 0, 1), [ "'", '"' ]) ) {
if ( ! in_array(substr($value, strlen($value) - 1), [ "'", '"' ]) ) {
throw new \InvalidArgumentException("Given argument `$value` string is not closed");
}
return substr($value, 1, -1);
}
return $value;
}
}
+55
View File
@@ -0,0 +1,55 @@
<?php declare(strict_types=1);
namespace Picea\Language;
use Picea\Compiler;
class DefaultRegistrations implements LanguageRegistration
{
public function registerAll(Compiler $compiler) : void
{
$this->registerSyntax($compiler);
$this->registerControlStructure($compiler);
$this->registerExtension($compiler);
}
public function registerSyntax(Compiler $compiler) : void
{
$compiler->registerSyntax(new \Picea\Syntax\PhpTagToken());
$compiler->registerSyntax(new \Picea\Syntax\CommentToken());
$compiler->registerSyntax(new \Picea\Syntax\EchoRawToken());
$compiler->registerSyntax(new \Picea\Syntax\EchoSafeToken());
}
public function registerControlStructure(Compiler $compiler) : void
{
# @TODO -- a rewrite on the compiler has to be done to accept this kind of functionnality
# $compiler->registerControlStructure(new \Picea\ControlStructure\RawToken());
# $compiler->registerControlStructure(new \Picea\ControlStructure\EndRawToken());
$compiler->registerControlStructure(new \Picea\ControlStructure\NamespaceToken());
$compiler->registerControlStructure(new \Picea\ControlStructure\UseToken());
$compiler->registerControlStructure(new \Picea\ControlStructure\IfToken());
$compiler->registerControlStructure(new \Picea\ControlStructure\ElseToken());
$compiler->registerControlStructure(new \Picea\ControlStructure\ElseIfToken());
$compiler->registerControlStructure(new \Picea\ControlStructure\EndIfToken());
$compiler->registerControlStructure(new \Picea\ControlStructure\ForeachToken());
$compiler->registerControlStructure(new \Picea\ControlStructure\ForToken());
$compiler->registerControlStructure(new \Picea\ControlStructure\OrToken());
$compiler->registerControlStructure(new \Picea\ControlStructure\EndforeachToken());
$compiler->registerControlStructure(new \Picea\ControlStructure\EndforToken());
$compiler->registerControlStructure(new \Picea\ControlStructure\SwitchToken());
$compiler->registerControlStructure(new \Picea\ControlStructure\CaseToken());
$compiler->registerControlStructure(new \Picea\ControlStructure\DefaultToken());
$compiler->registerControlStructure(new \Picea\ControlStructure\BreakToken());
$compiler->registerControlStructure(new \Picea\ControlStructure\EndCaseToken());
$compiler->registerControlStructure(new \Picea\ControlStructure\EndSwitchToken());
$compiler->registerControlStructure(new \Picea\ControlStructure\ExtendsToken());
$compiler->registerControlStructure(new \Picea\ControlStructure\SectionToken());
$compiler->registerControlStructure(new \Picea\ControlStructure\EndSectionToken());
}
public function registerExtension(Compiler $compiler) : void
{
$compiler->registerExtension(new \Picea\Extension\JsonExtension());
}
}
+14
View File
@@ -0,0 +1,14 @@
<?php declare(strict_types=1);
namespace Picea\Language;
use Picea\Compiler;
interface LanguageRegistration
{
public function registerSyntax(Compiler $compiler) : void;
public function registerControlStructure(Compiler $compiler) : void;
public function registerExtension(Compiler $compiler) : void;
}
+61 -50
View File
@@ -2,16 +2,56 @@
namespace Picea;
class Picea
use Closure;
use Picea\Language\LanguageRegistration;
use Psr\Http\Message\ResponseInterface;
class Picea implements LanguageRegistration
{
const DEFAULT_BUILDER_TEMPLATE = "/Builder/ClassTemplate.php";
public Compiler\Context $context;
public Compiler $compiler;
public function __construct(?Context $context = null, ?Compiler $compiler = null)
{
public LanguageRegistration $languageRegistration;
public string $builderTemplatePath;
public Closure $responseHtml;
public Caching\Cache $cache;
public function __construct(
?Closure $responseHtml = null,
?Cache $cache = null,
?Context $context = null,
?Compiler $compiler = null,
?LanguageRegistration $languageRegistration = null,
?string $builderTemplatePath = null
){
$this->response = $responseHtml;
$this->cache = $cache ?? new Caching\Memory("");
$this->context = $context ?? new Compiler\BaseContext();
$this->compiler = $compiler ?: $this->instanciateCompiler();
$this->compiler = $compiler ?? $this->instanciateCompiler();
$this->languageRegistration = $languageRegistration ?? new Language\DefaultRegistrations();
$this->builderTemplatePath = $builderTemplatePath ?? dirname(__FILE__) . static::DEFAULT_BUILDER_TEMPLATE;
}
public function outputHtml(string $viewPath, array $variables) : ResponseInterface
{
if ( $this->response ?? false ) {
if ( false === $content = $this->cache->handle($viewPath) ) {
# if ( )
}
$source = $this->compileSource($source ?? "test");
$response = $this->response;
return $response("abc");
}
throw new \InvalidArgumentException("No \Psr\Http\Message\ResponseInterface closure provided. Please provide one using the constructor or assinging it to the class variable `responseHtml`.");
}
public function compileSource(string $source) : array
@@ -27,11 +67,11 @@ class Picea
public function compileFile(string $filePath) : array
{
if (! file_exists($filePath) ) {
throw new \InvalidArgumentException("File `$filePath` cannot be found or it is a permission problem");
throw new \InvalidArgumentException("File `$filePath` cannot be found or there is a permission problem.");
}
if ( false === $fileContent = file_get_contents($filePath) ) {
throw new \ErrorException("Given file could not be opened `$filePath`. This could indicate a permission misconfiguration on your file or folder");
throw new \ErrorException("Given file could not be opened `$filePath`. This could indicate a permission misconfiguration on your file or folder.");
}
$this->compiler->loadSourceCode($fileContent);
@@ -64,64 +104,35 @@ class Picea
}
public function instanciateCompiler(string $sourceCode = "") : Compiler
public function instanciateCompiler() : Compiler
{
$compiler = new Compiler();
$compiler->loadSourceCode($sourceCode);
$this->registerSyntax($compiler)
->registerControlStructure($compiler)
->registerExtension($compiler);
return $compiler;
return new Compiler($this->languageRegistration);
}
public function instanciateBuilder() : Builder
{
$builder = new Builder(dirname(__FILE__) . "/Builder/ClassTemplate.php");
return $builder;
return new Builder($this->builderTemplatePath);
}
protected function registerSyntax(Compiler $compiler) : self
public function registerAll(Compiler $compiler) : void
{
$compiler->registerSyntax( new \Picea\Syntax\PhpTagToken() );
$compiler->registerSyntax( new \Picea\Syntax\CommentToken() );
$compiler->registerSyntax( new \Picea\Syntax\EchoRawToken() );
$compiler->registerSyntax( new \Picea\Syntax\EchoSafeToken() );
return $this;
$this->registerSyntax($compiler);
$this->registerControlStructure($compiler);
$this->registerExtension($compiler);
}
protected function registerControlStructure(Compiler $compiler) : self
public function registerSyntax(Compiler $compiler) : void
{
$compiler->registerControlStructure(new \Picea\ControlStructure\NamespaceToken());
$compiler->registerControlStructure(new \Picea\ControlStructure\UseToken());
$compiler->registerControlStructure(new \Picea\ControlStructure\IfToken());
$compiler->registerControlStructure(new \Picea\ControlStructure\ElseToken());
$compiler->registerControlStructure(new \Picea\ControlStructure\ElseIfToken());
$compiler->registerControlStructure(new \Picea\ControlStructure\EndIfToken());
$compiler->registerControlStructure(new \Picea\ControlStructure\ForeachToken());
$compiler->registerControlStructure(new \Picea\ControlStructure\ForToken());
$compiler->registerControlStructure(new \Picea\ControlStructure\OrToken());
$compiler->registerControlStructure(new \Picea\ControlStructure\EndforeachToken());
$compiler->registerControlStructure(new \Picea\ControlStructure\EndforToken());
$compiler->registerControlStructure(new \Picea\ControlStructure\SwitchToken());
$compiler->registerControlStructure(new \Picea\ControlStructure\CaseToken());
$compiler->registerControlStructure(new \Picea\ControlStructure\DefaultToken());
$compiler->registerControlStructure(new \Picea\ControlStructure\BreakToken());
$compiler->registerControlStructure(new \Picea\ControlStructure\EndCaseToken());
$compiler->registerControlStructure(new \Picea\ControlStructure\EndSwitchToken());
$compiler->registerControlStructure(new \Picea\ControlStructure\ExtendsToken());
$compiler->registerControlStructure(new \Picea\ControlStructure\SectionToken());
$compiler->registerControlStructure(new \Picea\ControlStructure\EndSectionToken());
return $this;
$this->languageRegistration->registerSyntax($compiler);
}
protected function registerExtension(Compiler $compiler) : self
public function registerControlStructure(Compiler $compiler) : void
{
$compiler->registerExtension(new \Picea\Extension\JsonExtension());
$this->languageRegistration->registerControlStructure($compiler);
}
return $this;
public function registerExtension(Compiler $compiler) : void
{
$this->languageRegistration->registerExtension($compiler);
}
}
+2
View File
@@ -4,6 +4,8 @@ namespace Picea\Syntax;
class CommentToken implements Syntax {
public string $token = "#";
protected string $tokenOpen = "\{\#";
protected string $tokenClose = "\#\}";