- Small refractoring of code, merge tokens
- Completed block token
This commit is contained in:
		
							parent
							
								
									bf3816c3db
								
							
						
					
					
						commit
						ce4ef6351a
					
				| @ -21,6 +21,7 @@ class Builder | ||||
|             '%NAMESPACE%' => $context->namespace, | ||||
|             '%USE%' => ( $uses = $context->renderUses() ) ? "use $uses;" : false, | ||||
|             '%CLASSNAME%' => $context->className, | ||||
|             '%PATHNAME%' => $context->viewPath, | ||||
|             '%EXTENDS%' => $context->extendFrom ? "extends " . static::TEMPLATE_CLASSNAME_PREFIX . static::generateClassUID($context->extendFrom) : '', | ||||
|             '%EXTENDS_TEMPLATE%' => $context->extendFrom, | ||||
|             '%CONTENT%' => $compiledSource, | ||||
|  | ||||
| @ -4,7 +4,9 @@ namespace %NAMESPACE%; | ||||
| 
 | ||||
| %USE% | ||||
| 
 | ||||
| # %PATHNAME%
 | ||||
| class %CLASSNAME% %EXTENDS% { | ||||
|     public array $blockList = []; | ||||
| 
 | ||||
|     public array $sectionList = []; | ||||
| 
 | ||||
|  | ||||
| @ -2,7 +2,8 @@ | ||||
| 
 | ||||
| namespace Picea\Caching; | ||||
| 
 | ||||
| use Picea\Compiler\Context; | ||||
| use Picea\Builder, | ||||
|     Picea\Compiler\Context; | ||||
| 
 | ||||
| class Opcache implements Cache { | ||||
| 
 | ||||
| @ -11,10 +12,15 @@ class Opcache implements Cache { | ||||
|     protected string $cachePath = ""; | ||||
| 
 | ||||
|     protected array $compiled = []; | ||||
|      | ||||
|     protected ? Context $context; | ||||
| 
 | ||||
|     public function __construct(?string $cachePath = null) | ||||
|     public function __construct(?string $cachePath = null, ? Context $context) | ||||
|     { | ||||
|         $this->cachePath = $cachePath ?? sys_get_temp_dir(); | ||||
|         $this->context = $context; | ||||
|          | ||||
|         $this->registerNamespace($this->context->namespace); | ||||
|     } | ||||
| 
 | ||||
|     public function load(string $viewPath, ...$arguments) : object | ||||
| @ -29,10 +35,6 @@ class Opcache implements Cache { | ||||
| 
 | ||||
|         $compiledContext = $this->compiled[$viewPath]; | ||||
| 
 | ||||
|         if ( $compiledContext['extends'] ) { | ||||
|             $this->load($compiledContext['extends'], ...$arguments); | ||||
|         } | ||||
| 
 | ||||
|         $fullName = isset($compiledContext['namespace']) ? "\\{$compiledContext['namespace']}\\{$compiledContext['classname']}" : $compiledContext['classname']; | ||||
| 
 | ||||
|         return new $fullName(...$arguments); | ||||
| @ -40,7 +42,7 @@ class Opcache implements Cache { | ||||
| 
 | ||||
|     public function save(Context $context) : bool | ||||
|     { | ||||
|         $fileName = $context->compiledClassPath(); | ||||
|         $context->compiledClassPath(); | ||||
|         $this->validateCachePath(); | ||||
|         file_put_contents($this->cachePath($context->viewPath), $context->compiledSource); | ||||
| 
 | ||||
| @ -55,9 +57,15 @@ 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; | ||||
|         } | ||||
| 
 | ||||
|         | ||||
|          | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
| @ -73,8 +81,6 @@ class Opcache implements Cache { | ||||
|             throw new \RuntimeException( | ||||
|                 sprintf("Given cache path `%s` is not writeable by `%s`", $fullPath, static::class) | ||||
|             ); | ||||
| 
 | ||||
|             return false; | ||||
|         } | ||||
| 
 | ||||
|         return true; | ||||
| @ -82,6 +88,26 @@ class Opcache implements Cache { | ||||
| 
 | ||||
|     protected function cachePath(string $fileName = "") : string | ||||
|     { | ||||
|         return implode(DIRECTORY_SEPARATOR, array_filter([ $this->cachePath, $this->cacheFolder, $fileName ? str_replace([ "/", DIRECTORY_SEPARATOR ], "~", $fileName . ".php") : null ])); | ||||
|         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() . "/"; | ||||
|              | ||||
|             $len = strlen($prefix); | ||||
|              | ||||
|             if (strncmp($prefix, $class, $len) !== 0) { | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             $file = $baseDir . str_replace('\\', '/', substr($class, $len)) . '.php'; | ||||
| 
 | ||||
|             if ( file_exists($file) ) { | ||||
|                 require $file; | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -45,8 +45,12 @@ class Compiler | ||||
|         $this->sourceCode = preg_replace_callback($replace, function ($matches) use (&$context) { | ||||
|             $matches[2] = trim($matches[2]); | ||||
| 
 | ||||
|              | ||||
|              | ||||
|             list($token, $arguments) = array_pad(array_filter(explode(' ', $matches[2], 2), 'strlen'), 2, null); | ||||
| 
 | ||||
|              | ||||
|             $token = trim($token); | ||||
|              | ||||
|             # @TODO Refractor this parts to allows registration to the tag's name
 | ||||
|             if ( $this->tagList[$token] ?? false ) { | ||||
|                 return $this->tagList[$token]->parse($context, $arguments, $token); | ||||
|  | ||||
| @ -4,14 +4,20 @@ namespace Picea\ControlStructure; | ||||
| 
 | ||||
| class BlockToken implements ControlStructure { | ||||
| 
 | ||||
|     public array $token = [ "block", "arguments" ]; | ||||
|     public array $token = [ "arguments", "block", "endblock", "define", "slot", "endslot", "using" ]; | ||||
| 
 | ||||
|     public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) { | ||||
|        | ||||
|         static $slotDefinitions = []; | ||||
|          | ||||
|         switch($token) { | ||||
|             case "block": | ||||
|                 return "<?php echo \$___class__template->picea->inlineHtml(\$this, $arguments); ?>"; | ||||
|          | ||||
|                 $slotDefinitions[] = $this->slotDefinitions(); | ||||
|                  | ||||
|                 return "<?php \$___block = \Picea\ControlStructure\BlockToken::instanciateBlock($arguments); ?>"; | ||||
|              | ||||
|             case "endblock": | ||||
|                 return "<?php echo \$___block->render(\$___class__template); unset(\$___block); ?>"; | ||||
|              | ||||
|             case "arguments": | ||||
|                 $class = static::class; | ||||
|                  | ||||
| @ -26,10 +32,73 @@ class BlockToken implements ControlStructure { | ||||
|                             throw new \Exception('A block awaiting arguments `$arguments` instead received `' . implode(', ', array_map('gettype', \$inlineVariables)) . '`'); | ||||
|                         } | ||||
|                     ?>
 | ||||
|             PHP; | ||||
|         }    | ||||
|                 PHP; | ||||
|              | ||||
|             case "define": | ||||
|                 list($name, $definition) = array_pad(explode(',', $arguments, 2), 2, ""); | ||||
|                  | ||||
|                 end($slotDefinitions)->setDefinition(eval("return $name;"), $definition); | ||||
|                  | ||||
|                 return <<<PHP | ||||
|                     <?php \$this->defineSlot($name, function($definition) {}); ?>
 | ||||
|                 PHP; | ||||
|                      | ||||
|             case "slot": | ||||
|                 $def = end($slotDefinitions); | ||||
|                  | ||||
|                 list($name, $definition) = array_pad(explode(',', $arguments, 2), 2, ""); | ||||
|                  | ||||
|                 if ($def->hasDefinitions() ) { | ||||
|                     $slotName = eval("return $name;"); | ||||
|                     $def->currentSlot = $slotName; | ||||
|                     $def->setDefinitionVars($slotName, $definition); | ||||
|                      | ||||
|                     $definition = $def->printDefinition($slotName); | ||||
| 
 | ||||
|                     return <<<PHP | ||||
|                         <?php \$this->printSlot($name, function($definition, array \$___using = []) { extract(\$___using, \EXTR_SKIP); ?>
 | ||||
|                     PHP; | ||||
|                 } | ||||
|                 else { | ||||
|                     return <<<PHP | ||||
|                         <?php \$___block->slotIsSet($name) || \$___block->setSlot($name, function($definition, array \$___using = []) { extract(\$___using, \EXTR_SKIP); ?>
 | ||||
|                     PHP; | ||||
|                 } | ||||
|                      | ||||
|             case "endslot": | ||||
|                 $def =end($slotDefinitions); | ||||
|                  | ||||
|                 if ($def->hasDefinitions() ) { | ||||
|                     $definition = $def->getCurrentSlotDefinitionVars(); | ||||
|                      | ||||
|                     if ($definition) { | ||||
|                         $definition = "$definition,"; | ||||
|                     } | ||||
| 
 | ||||
|                     return <<<PHP | ||||
|                         <?php })->call(\$this, $definition \$this->using); ?>
 | ||||
|                     PHP; | ||||
|                 } | ||||
|                 else { | ||||
|                     return "<?php }); ?>"; | ||||
|                 } | ||||
|                  | ||||
|             case "using": | ||||
|                 return "<?php \$___block->setUsing($arguments); ?>"; | ||||
|         } | ||||
|     } | ||||
|      | ||||
|      | ||||
|     public function inlineHtml(? object $proxy, string $viewPath, ... $variables) { | ||||
|         return $this->renderHtml($viewPath, [ 'inlineVariables' => $variables ], $proxy); | ||||
|     } | ||||
|      | ||||
|     public static function parseSlotArguments(Callable $method) : array | ||||
|     { | ||||
|         #return 
 | ||||
|     } | ||||
|          | ||||
|          | ||||
|     public static function parseArguments(Callable $method, array $arguments) : array | ||||
|     { | ||||
|         try{ | ||||
| @ -42,9 +111,128 @@ class BlockToken implements ControlStructure { | ||||
|         $parameters = []; | ||||
|          | ||||
|         foreach((new \ReflectionFunction($method))->getParameters() as $key => $value) { | ||||
|             $parameters[ $value->getName() ] = $arguments[$key] ?? $value->getDefaultValue(); | ||||
|             if ( isset($arguments[$key]) ) { | ||||
|                 $parameters[ $value->getName() ] = $arguments[$key]; | ||||
|             } | ||||
|             elseif ( $value->isDefaultValueAvailable() ) { | ||||
|                 $parameters[ $value->getName() ] = $value->getDefaultValue(); | ||||
|             } | ||||
|             elseif ( $value->isVariadic() ) { | ||||
|                 $parameters[ $value->getName() ] = []; | ||||
|             } | ||||
|         } | ||||
|          | ||||
|         return $parameters; | ||||
|     } | ||||
|      | ||||
|     public static function slotDefinitions() { | ||||
|         return new class() { | ||||
|              | ||||
|             public array $definitions = []; | ||||
|              | ||||
|             public array $variables = []; | ||||
|              | ||||
|             public bool $rendering = false; | ||||
|              | ||||
|             public string $currentSlot; | ||||
|              | ||||
|             public function setDefinition(string $name, string $definition) : self  | ||||
|             { | ||||
|                 $this->definitions[$name] = $definition; | ||||
|                  | ||||
|                 return $this; | ||||
|             } | ||||
|              | ||||
|             public function setDefinitionVars(string $name, string $variables) : self | ||||
|             { | ||||
|                 $this->variables[$name] = $variables; | ||||
|                  | ||||
|                 return $this; | ||||
|             } | ||||
|              | ||||
|             public function getDefinitionVars(string $name) : string | ||||
|             { | ||||
|                 return $this->variables[$name] ?? ""; | ||||
|             } | ||||
|              | ||||
|             public function getCurrentSlotDefinitionVars() : string | ||||
|             { | ||||
|                 return $this->getDefinitionVars($this->currentSlot); | ||||
|             } | ||||
|              | ||||
|             public function hasDefinitions() : bool | ||||
|             { | ||||
|                 return count($this->definitions) > 0; | ||||
|             } | ||||
|              | ||||
|             public function printDefinition(string $name) : string | ||||
|             { | ||||
|                 if ( ! isset($this->definitions[$name]) ) { | ||||
|                     throw new \Exception("Slot definition for `$name` was not found. Have you defined it in your block header ?"); | ||||
|                 } | ||||
|                  | ||||
|                 return $this->definitions[$name]; | ||||
|             } | ||||
|              | ||||
|             public function render() : void | ||||
|             { | ||||
|                 $this->rendering = true; | ||||
|             } | ||||
|              | ||||
|         }; | ||||
|     } | ||||
|      | ||||
|     public static function instanciateBlock(string $viewPath, ... $arguments)  | ||||
|     { | ||||
|         return new class($viewPath, ...$arguments) { | ||||
|              | ||||
|             public bool $rendering = false; | ||||
|              | ||||
|             public string $viewPath; | ||||
|              | ||||
|             public array $using = []; | ||||
|              | ||||
|             public array $arguments = []; | ||||
|              | ||||
|             public array $slots = []; | ||||
|              | ||||
|             public array $definition = []; | ||||
|              | ||||
|             public function __construct(string $viewPath, ...$arguments) { | ||||
|                 $this->viewPath = $viewPath; | ||||
|                 $this->arguments = $arguments; | ||||
|             } | ||||
|              | ||||
|             public function render(object $classTemplate) : string | ||||
|             { | ||||
|                 $this->rendering = true; | ||||
|                  | ||||
|                 return $classTemplate->picea->inlineHtml($this, $this->viewPath, ...$this->arguments); | ||||
|             } | ||||
|              | ||||
|             public function setSlot(string $name, Callable $method) : void | ||||
|             { | ||||
|                 $this->slots[$name] = $method; | ||||
|             } | ||||
|              | ||||
|             public function defineSlot(string $name, Callable $method) : void | ||||
|             { | ||||
|                 $this->definition[$name] = $method; | ||||
|             } | ||||
|              | ||||
|             public function slotIsSet(string $name) : bool | ||||
|             { | ||||
|                 return ! empty($this->slots[$name]); | ||||
|             } | ||||
|              | ||||
|             public function printSlot(string $name, Callable $default) | ||||
|             { | ||||
|                 return $this->slotIsSet($name) ? $this->slots[$name] : $default; | ||||
|             } | ||||
|              | ||||
|             public function setUsing(array $variables) { | ||||
|                 $this->using = $variables; | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| } | ||||
| @ -1,13 +0,0 @@ | ||||
| <?php | ||||
| 
 | ||||
| namespace Picea\ControlStructure; | ||||
| 
 | ||||
| class ElseIfToken implements ControlStructure { | ||||
| 
 | ||||
|     public string $token = "elseif"; | ||||
| 
 | ||||
|     public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) { | ||||
|         return "<?php elseif ($arguments): ?>"; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -1,13 +0,0 @@ | ||||
| <?php | ||||
| 
 | ||||
| namespace Picea\ControlStructure; | ||||
| 
 | ||||
| class ElseToken implements ControlStructure { | ||||
| 
 | ||||
|     public string $token = "else"; | ||||
| 
 | ||||
|     public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) { | ||||
|         return "<?php else: ?>"; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -1,7 +0,0 @@ | ||||
| <?php | ||||
| 
 | ||||
| namespace Picea\ControlStructure; | ||||
| 
 | ||||
| class EndCaseToken extends BreakToken { | ||||
|     public string $token = "endcase"; | ||||
| } | ||||
| @ -1,13 +0,0 @@ | ||||
| <?php | ||||
| 
 | ||||
| namespace Picea\ControlStructure; | ||||
| 
 | ||||
| class EndIfToken implements ControlStructure { | ||||
| 
 | ||||
|     public string $token = "endif"; | ||||
| 
 | ||||
|     public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) { | ||||
|         return "<?php endif ?>"; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -1,18 +0,0 @@ | ||||
| <?php | ||||
| 
 | ||||
| namespace Picea\ControlStructure; | ||||
| 
 | ||||
| class EndSectionToken implements ControlStructure { | ||||
| 
 | ||||
|     public string $token = "endsection"; | ||||
| 
 | ||||
|     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"); | ||||
|         } | ||||
| 
 | ||||
|         $section = array_pop($context->sections); | ||||
|         $build = $context->extendFrom ? "" : "\$___class__template->renderSection({$section['name']});"; | ||||
|         return "<?php }]; $build?>"; | ||||
|     } | ||||
| } | ||||
| @ -1,12 +0,0 @@ | ||||
| <?php | ||||
| 
 | ||||
| namespace Picea\ControlStructure; | ||||
| 
 | ||||
| class EndSwitchToken implements ControlStructure { | ||||
| 
 | ||||
|     public string $token = "endswitch"; | ||||
| 
 | ||||
|     public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) { | ||||
|         return "<?php endswitch; ?>"; | ||||
|     } | ||||
| } | ||||
| @ -1,20 +0,0 @@ | ||||
| <?php | ||||
| 
 | ||||
| namespace Picea\ControlStructure; | ||||
| 
 | ||||
| class EndforToken implements ControlStructure { | ||||
| 
 | ||||
|     public string $token = "endfor"; | ||||
| 
 | ||||
|     public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) { | ||||
|         if ( end($context->iterationStack)['or'] === false ) { | ||||
|             $output = "<?php endfor; ?>"; | ||||
|         } | ||||
|         else { | ||||
|             $output = "<?php endif; ?>"; | ||||
|         } | ||||
| 
 | ||||
|         array_pop($context->iterationStack); | ||||
|         return $output; | ||||
|     } | ||||
| } | ||||
| @ -1,20 +0,0 @@ | ||||
| <?php | ||||
| 
 | ||||
| namespace Picea\ControlStructure; | ||||
| 
 | ||||
| class EndforeachToken implements ControlStructure { | ||||
| 
 | ||||
|     public string $token = "endforeach"; | ||||
| 
 | ||||
|     public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) { | ||||
|         if ( end($context->iterationStack)['or'] === false ) { | ||||
|             $output = "<?php endforeach; ?>"; | ||||
|         } | ||||
|         else { | ||||
|             $output = "<?php endif; ?>"; | ||||
|         } | ||||
| 
 | ||||
|         array_pop($context->iterationStack); | ||||
|         return $output; | ||||
|     } | ||||
| } | ||||
| @ -4,17 +4,32 @@ namespace Picea\ControlStructure; | ||||
| 
 | ||||
| class ForToken implements ControlStructure { | ||||
| 
 | ||||
|     public string $token = "for"; | ||||
|     public array $token = [ "for", "endfor" ]; | ||||
| 
 | ||||
|     public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) { | ||||
|         $uid = "$".uniqid("for_"); | ||||
|         switch($token) { | ||||
|             case "for": | ||||
|                 $uid = "$".uniqid("for_"); | ||||
| 
 | ||||
|         $context->iterationStack[] = [ | ||||
|             'or' => false, | ||||
|             'uid' => $uid, | ||||
|             'token' => 'endfor', | ||||
|         ]; | ||||
|                 $context->iterationStack[] = [ | ||||
|                     'or' => false, | ||||
|                     'uid' => $uid, | ||||
|                     'token' => 'endfor', | ||||
|                 ]; | ||||
| 
 | ||||
|         return "<?php for ($arguments): {$uid} = 1; ?>"; | ||||
|                 return "<?php for ($arguments): {$uid} = 1; ?>"; | ||||
|                  | ||||
|             case "endfor": | ||||
|                 if ( end($context->iterationStack)['or'] === false ) { | ||||
|                     $output = "<?php endfor; ?>"; | ||||
|                 } | ||||
|                 else { | ||||
|                     $output = "<?php endif; ?>"; | ||||
|                 } | ||||
| 
 | ||||
|                 array_pop($context->iterationStack); | ||||
| 
 | ||||
|                 return $output; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -4,23 +4,38 @@ namespace Picea\ControlStructure; | ||||
| 
 | ||||
| class ForeachToken implements ControlStructure { | ||||
| 
 | ||||
|     public string $token = "foreach"; | ||||
|     public array $token = [ "foreach", "endforeach" ]; | ||||
| 
 | ||||
|     public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) { | ||||
|         $name = "$".uniqid("foreach_"); | ||||
|          | ||||
|         $count = count($context->iterationStack ?? []); | ||||
|          | ||||
|         if ( $count > 0 ) { | ||||
|             $name .= "[" . $context->iterationStack[$count - 1]['uid'] . "]"; | ||||
|         } | ||||
|         switch($token) { | ||||
|             case "foreach": | ||||
|                 $name = "$".uniqid("foreach_"); | ||||
| 
 | ||||
|         $context->iterationStack[] = [ | ||||
|             'or' => false, | ||||
|             'uid' => $name, | ||||
|             'token' => 'endforeach', | ||||
|         ]; | ||||
|          | ||||
|         return "<?php foreach ($arguments): $name = ( $name ?? 0 ) + 1; ; ?>"; | ||||
|                 $count = count($context->iterationStack ?? []); | ||||
| 
 | ||||
|                 if ( $count > 0 ) { | ||||
|                     $name .= "[" . $context->iterationStack[$count - 1]['uid'] . "]"; | ||||
|                 } | ||||
| 
 | ||||
|                 $context->iterationStack[] = [ | ||||
|                     'or' => false, | ||||
|                     'uid' => $name, | ||||
|                     'token' => 'endforeach', | ||||
|                 ]; | ||||
| 
 | ||||
|                 return "<?php foreach ($arguments): $name = ( $name ?? 0 ) + 1; ; ?>"; | ||||
|                  | ||||
|             case "endforeach": | ||||
|                 if ( end($context->iterationStack)['or'] === false ) { | ||||
|                     $output = "<?php endforeach; ?>"; | ||||
|                 } | ||||
|                 else { | ||||
|                     $output = "<?php endif; ?>"; | ||||
|                 } | ||||
| 
 | ||||
|                 array_pop($context->iterationStack); | ||||
|                  | ||||
|                 return $output; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -4,10 +4,22 @@ namespace Picea\ControlStructure; | ||||
| 
 | ||||
| class IfToken implements ControlStructure { | ||||
| 
 | ||||
|     public string $token = "if"; | ||||
|     public array $token = [ "if", "else", "elseif", "endif" ]; | ||||
| 
 | ||||
|     public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) { | ||||
|         return "<?php if ($arguments): ?>"; | ||||
|         switch($token) { | ||||
|             case "if": | ||||
|                 return "<?php if ($arguments): ?>"; | ||||
| 
 | ||||
|             case "else": | ||||
|                 return "<?php else: ?>"; | ||||
|              | ||||
|             case "elseif": | ||||
|                 return "<?php elseif ($arguments): ?>"; | ||||
|                  | ||||
|             case "endif": | ||||
|                 return "<?php endif ?>"; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| } | ||||
|  | ||||
| @ -4,9 +4,24 @@ namespace Picea\ControlStructure; | ||||
| 
 | ||||
| class SectionToken implements ControlStructure { | ||||
| 
 | ||||
|     public string $token = "section"; | ||||
|     public array $token = [ "section", "endsection" ]; | ||||
| 
 | ||||
|     public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) { | ||||
|         switch($token) { | ||||
|             case "section": | ||||
|                 return $this->printSection($context, $arguments); | ||||
|                  | ||||
|             case "endsection": | ||||
|                 if ( empty($context->sections) ) { | ||||
|                     throw new \RuntimeException("A section closing tag {% endsection %} was found without an opening {% section %} tag"); | ||||
|                 } | ||||
| 
 | ||||
|                 return $this->printEndSection($context); | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     protected function printSection($context, ?string $arguments) : string | ||||
|     { | ||||
|         list($name, $options) = array_pad(explode(',', $arguments, 2), 2, null); | ||||
| 
 | ||||
|         if ( $options ?? false ) { | ||||
| @ -34,4 +49,11 @@ class SectionToken implements ControlStructure { | ||||
|                       \$___class__template->sectionList[$name]['$action'][] = [ 'order' => $order, 'callback' => function() use (\$picea, \$___class__template, \$___global_variables, \$___variables) { | ||||
|                           extract(\$___global_variables); extract(\$___variables, \EXTR_OVERWRITE); ?>";
 | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|     protected function printEndSection($context) : string | ||||
|     {             | ||||
|         $section = array_pop($context->sections); | ||||
|         $build = $context->extendFrom ? "" : "\$___class__template->renderSection({$section['name']});"; | ||||
|         return "<?php }]; $build?>"; | ||||
|     } | ||||
| } | ||||
| @ -4,10 +4,31 @@ namespace Picea\ControlStructure; | ||||
| 
 | ||||
| class SwitchToken implements ControlStructure { | ||||
| 
 | ||||
|     public string $token = "switch"; | ||||
|     public array $token = [ "switch", "case", "endswitch" ]; | ||||
| 
 | ||||
|     public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) { | ||||
|         $context->switchStack[] = true; | ||||
|         return "<?php switch($arguments):"; | ||||
|         switch($token) { | ||||
|             case "switch": | ||||
|                 $context->switchStack[] = true; | ||||
|                 return "<?php switch($arguments):"; | ||||
|              | ||||
|             case "case": | ||||
|                 $output = ""; | ||||
| 
 | ||||
|                 if ( $context->switchStack ) { | ||||
|                     array_pop($context->switchStack); | ||||
|                 } | ||||
|                 else { | ||||
|                     $output = "<?php "; | ||||
|                 } | ||||
| 
 | ||||
|                 return ( $output ?? "" ) . "case $arguments: ?>"; | ||||
|              | ||||
|             case "endcase": | ||||
|                 return "<?php break; ?>"; | ||||
|                  | ||||
|             case "endswitch": | ||||
|                 return "<?php endswitch; ?>";  | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -169,7 +169,6 @@ class UrlExtension implements Extension { | ||||
|                     $variable = $item[1]; | ||||
|                 } | ||||
|                  | ||||
|                  | ||||
|                 if ( array_key_exists($variable, $arguments) ) { | ||||
|                     $value = $arguments[ $item[1] ]; | ||||
|                 } | ||||
| @ -179,18 +178,16 @@ class UrlExtension implements Extension { | ||||
|                 else { | ||||
|                     $variable = $item[1]; | ||||
|                 } | ||||
|                  | ||||
|                  | ||||
|                 if ( array_key_exists($variable, $arguments) ) { | ||||
|                     $value = $arguments[ $item[1] ]; | ||||
|                 } | ||||
|                 else if ( isset($default) ) { | ||||
|                     $value = $default; | ||||
|                 } | ||||
|                 else { | ||||
|                     throw new \InvalidArgumentException("Argument `$variable` is missing within required route parameter(s)");                     | ||||
|                 }                 | ||||
|                  | ||||
| 
 | ||||
| #                if ( array_key_exists($variable, $arguments) ) {
 | ||||
| #                    $value = $arguments[ $item[1] ];
 | ||||
| #                }
 | ||||
| #                else if ( isset($default) ) {
 | ||||
| #                    $value = $default;
 | ||||
| #                }
 | ||||
| #                else {
 | ||||
| #                    throw new \InvalidArgumentException("Argument `$variable` is missing within required route parameter(s)");                    
 | ||||
| #                }
 | ||||
| 
 | ||||
|                 $search[ $item[0] ] = $value; | ||||
|                 unset($arguments[ $item[1] ]); | ||||
|  | ||||
| @ -45,29 +45,17 @@ class DefaultRegistrations implements LanguageRegistration | ||||
| 
 | ||||
|     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()); | ||||
|         $compiler->registerControlStructure(new \Picea\ControlStructure\BlockToken()); | ||||
|         $compiler->registerControlStructure(new \Picea\ControlStructure\ViewToken()); | ||||
|          | ||||
|  | ||||
| @ -127,7 +127,7 @@ class Picea implements LanguageRegistration | ||||
|         $tmpFolder = sys_get_temp_dir(); | ||||
|         $builder = $this->instanciateBuilder(); | ||||
|         $compiledSource = $this->compileSource($source); | ||||
|         list($namespace, $className, $compiledSource) = $builder->build($compiledSource['context'], $compiledSource['source']) ; | ||||
|         list($namespace, $className) = $builder->build($compiledSource['context'], $compiledSource['source']) ; | ||||
| 
 | ||||
|         $path = "$tmpFolder/$className.php"; | ||||
|         file_put_contents($path, $compiledSource); | ||||
| @ -141,15 +141,15 @@ class Picea implements LanguageRegistration | ||||
| 
 | ||||
|     public function fetchFromCache(string $viewPath, array $variables = [], ?object $proxy = null) : ?object | ||||
|     { | ||||
|         if ( $this->debug || ! $this->cache->compiled($viewPath) ) { | ||||
|         if ( ( true === $this->debug ) ||  (! $this->cache->compiled($viewPath))) { | ||||
|             $context = $this->compileView($viewPath); | ||||
|             $this->cache->save($context); | ||||
| 
 | ||||
|              | ||||
|             if ( $context->extendFrom ) { | ||||
|                 $this->fetchFromCache($context->extendFrom, $variables, $proxy); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|          | ||||
|         return $this->cache->load($viewPath, $this, $variables, $proxy); | ||||
|     } | ||||
| 
 | ||||
| @ -210,6 +210,7 @@ class Picea implements LanguageRegistration | ||||
|         $context = $builder->build($compiled['context'], $compiled['source']) ; | ||||
|         $context->classPath = $tmpFolder . DIRECTORY_SEPARATOR . $context->className . ".php"; | ||||
| 
 | ||||
|         | ||||
|         if ( $context->extendFrom ) { | ||||
|             $this->compileView($context->extendFrom); | ||||
|         } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user