- Fixed a bug that appeared deeper when rendering a block inside the slot of another block
This commit is contained in:
		
							parent
							
								
									934643214e
								
							
						
					
					
						commit
						d22d26c9c8
					
				| @ -8,17 +8,22 @@ class BlockToken implements ControlStructure { | |||||||
| 
 | 
 | ||||||
|     public function parse(\Picea\Compiler\Context &$context, ?string $arguments, string $token, array $options = []) : string |     public function parse(\Picea\Compiler\Context &$context, ?string $arguments, string $token, array $options = []) : string | ||||||
|     { |     { | ||||||
|  |         static $depth = 0; | ||||||
|         static $slotDefinitions = []; |         static $slotDefinitions = []; | ||||||
| 
 | 
 | ||||||
|  |         # dump($depth, $token, $arguments, $slotDefinitions);
 | ||||||
|  | 
 | ||||||
|         switch($token) { |         switch($token) { | ||||||
|             case "block": |             case "block": | ||||||
|                 $slotDefinitions[] = $this->slotDefinitions(); |                 $slotDefinitions[] = $this->slotDefinitions(); | ||||||
|                  |                 $depth++; | ||||||
|  | 
 | ||||||
|                 return "<?php \$___block = \Picea\ControlStructure\BlockToken::instanciateBlock($arguments); ?>"; |                 return "<?php \$___block = \Picea\ControlStructure\BlockToken::instanciateBlock($arguments); ?>"; | ||||||
|              | 
 | ||||||
|             case "endblock": |             case "endblock": | ||||||
|  |                 $depth--; | ||||||
|                 return "<?php echo \$___block->render(\$___class__template); unset(\$___block); ?>"; |                 return "<?php echo \$___block->render(\$___class__template); unset(\$___block); ?>"; | ||||||
|              | 
 | ||||||
|             case "arguments": |             case "arguments": | ||||||
|                 $class = static::class; |                 $class = static::class; | ||||||
| 
 | 
 | ||||||
| @ -36,19 +41,19 @@ class BlockToken implements ControlStructure { | |||||||
|                         } |                         } | ||||||
|                     /*%EXCEPTION_LINE_BASE%*/?>
 |                     /*%EXCEPTION_LINE_BASE%*/?>
 | ||||||
|                 PHP; |                 PHP; | ||||||
|              | 
 | ||||||
|             case "define": |             case "define": | ||||||
|                 list($name, $definition) = array_pad(explode(',', $arguments, 2), 2, ""); |                 list($name, $definition) = array_pad(explode(',', $arguments, 2), 2, ""); | ||||||
|                  | 
 | ||||||
|                 end($slotDefinitions)->setDefinition(eval("return $name;"), $definition); |                 ( $slotDefinitions[$depth] ?? end($slotDefinitions) )->setDefinition(eval("return $name;"), $definition); | ||||||
|                  | 
 | ||||||
|                 return <<<PHP |                 return <<<PHP | ||||||
|                 <?php \$this->defineSlot($name, function($definition) {}); ?>
 |                 <?php \$this->defineSlot($name, function($definition) {}); ?>
 | ||||||
|                 PHP; |                 PHP; | ||||||
|                      | 
 | ||||||
|             case "slot": |             case "slot": | ||||||
|                 $def = end($slotDefinitions); |                 $def = ( $slotDefinitions[$depth] ?? end($slotDefinitions) ); | ||||||
|                  | 
 | ||||||
|                 list($name, $definition) = array_pad(explode(',', $arguments, 2), 2, ""); |                 list($name, $definition) = array_pad(explode(',', $arguments, 2), 2, ""); | ||||||
| 
 | 
 | ||||||
|                 $loops = count($context->iterationStack ?? []) ? ",". implode(', ', array_filter(array_column($context->iterationStack, 'uid'), fn($e) => strpos($e, '[') === false)) : null; |                 $loops = count($context->iterationStack ?? []) ? ",". implode(', ', array_filter(array_column($context->iterationStack, 'uid'), fn($e) => strpos($e, '[') === false)) : null; | ||||||
| @ -57,7 +62,7 @@ class BlockToken implements ControlStructure { | |||||||
|                     $slotName = eval("return $name;"); |                     $slotName = eval("return $name;"); | ||||||
|                     $def->currentSlot = $slotName; |                     $def->currentSlot = $slotName; | ||||||
|                     $def->setDefinitionVars($slotName, $definition); |                     $def->setDefinitionVars($slotName, $definition); | ||||||
|                      | 
 | ||||||
|                     $definition = $def->printDefinition($slotName); |                     $definition = $def->printDefinition($slotName); | ||||||
| 
 | 
 | ||||||
|                     if ($definition) { |                     if ($definition) { | ||||||
| @ -72,18 +77,18 @@ class BlockToken implements ControlStructure { | |||||||
|                     if ($definition) { |                     if ($definition) { | ||||||
|                         $definition .= ","; |                         $definition .= ","; | ||||||
|                     } |                     } | ||||||
|                      | 
 | ||||||
|                     return <<<PHP |                     return <<<PHP | ||||||
|                     <?php (\$___block ?? \$this)->slotIsSet($name) || \$___block->setSlot($name, function($definition array \$___using = []) use (\$picea $loops) { extract(\$___using, \EXTR_SKIP); ?>
 |                     <?php (\$___block ?? \$this)->slotIsSet($name) || (\$___block ?? \$this)->setSlot($name, function($definition array \$___using = []) use (\$picea $loops) { extract(\$___using, \EXTR_SKIP); ?>
 | ||||||
|                     PHP; |                     PHP; | ||||||
|                 } |                 } | ||||||
|                      | 
 | ||||||
|             case "endslot": |             case "endslot": | ||||||
|                 $def =end($slotDefinitions); |                 $def = ( $slotDefinitions[$depth] ?? end($slotDefinitions) ); | ||||||
|                  | 
 | ||||||
|                 if ($def->hasDefinitions() ) { |                 if ($def->hasDefinitions() ) { | ||||||
|                     $definition = $def->getCurrentSlotDefinitionVars(); |                     $definition = $def->getCurrentSlotDefinitionVars(); | ||||||
|                      | 
 | ||||||
|                     if ($definition) { |                     if ($definition) { | ||||||
|                         $definition .= ","; |                         $definition .= ","; | ||||||
|                     } |                     } | ||||||
| @ -95,23 +100,23 @@ class BlockToken implements ControlStructure { | |||||||
|                 else { |                 else { | ||||||
|                     return "<?php }); ?>"; |                     return "<?php }); ?>"; | ||||||
|                 } |                 } | ||||||
|                  | 
 | ||||||
|             case "using": |             case "using": | ||||||
|                 return "<?php \$___block->setUsing($arguments); ?>"; |                 return "<?php \$___block->setUsing($arguments); ?>"; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|      | 
 | ||||||
|      | 
 | ||||||
|     public function inlineHtml(? object $proxy, string $viewPath, ... $variables) { |     public function inlineHtml(? object $proxy, string $viewPath, ... $variables) { | ||||||
|         return $this->renderHtml($viewPath, [ 'inlineVariables' => $variables ], $proxy); |         return $this->renderHtml($viewPath, [ 'inlineVariables' => $variables ], $proxy); | ||||||
|     } |     } | ||||||
|      | 
 | ||||||
|     public static function parseSlotArguments(Callable $method) : array |     public static function parseSlotArguments(Callable $method) : array | ||||||
|     { |     { | ||||||
|         #return 
 |         #return
 | ||||||
|     } |     } | ||||||
|          | 
 | ||||||
|          | 
 | ||||||
|     public static function parseArguments(Callable $method, array $arguments) : array |     public static function parseArguments(Callable $method, array $arguments) : array | ||||||
|     { |     { | ||||||
|         try{ |         try{ | ||||||
| @ -119,10 +124,10 @@ class BlockToken implements ControlStructure { | |||||||
|         } |         } | ||||||
|         catch(\TypeError $ex) { |         catch(\TypeError $ex) { | ||||||
|             throw $ex; |             throw $ex; | ||||||
|         }  |         } | ||||||
|          | 
 | ||||||
|         $parameters = []; |         $parameters = []; | ||||||
|          | 
 | ||||||
|         foreach((new \ReflectionFunction($method))->getParameters() as $key => $value) { |         foreach((new \ReflectionFunction($method))->getParameters() as $key => $value) { | ||||||
|             if ( isset($arguments[$key]) ) { |             if ( isset($arguments[$key]) ) { | ||||||
|                 $parameters[ $value->getName() ] = $arguments[$key]; |                 $parameters[ $value->getName() ] = $arguments[$key]; | ||||||
| @ -137,114 +142,114 @@ class BlockToken implements ControlStructure { | |||||||
|                 $parameters[ $value->getName() ] = null; |                 $parameters[ $value->getName() ] = null; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|          | 
 | ||||||
|         return $parameters; |         return $parameters; | ||||||
|     } |     } | ||||||
|      | 
 | ||||||
|     public static function slotDefinitions() { |     public static function slotDefinitions() { | ||||||
|         return new class() { |         return new class() { | ||||||
|              | 
 | ||||||
|             public array $definitions = []; |             public array $definitions = []; | ||||||
|              | 
 | ||||||
|             public array $variables = []; |             public array $variables = []; | ||||||
|              | 
 | ||||||
|             public bool $rendering = false; |             public bool $rendering = false; | ||||||
|              | 
 | ||||||
|             public string $currentSlot; |             public string $currentSlot; | ||||||
|              | 
 | ||||||
|             public function setDefinition(string $name, string $definition) : self  |             public function setDefinition(string $name, string $definition) : self | ||||||
|             { |             { | ||||||
|                 $this->definitions[$name] = $definition; |                 $this->definitions[$name] = $definition; | ||||||
|                  | 
 | ||||||
|                 return $this; |                 return $this; | ||||||
|             } |             } | ||||||
|              | 
 | ||||||
|             public function setDefinitionVars(string $name, string $variables) : self |             public function setDefinitionVars(string $name, string $variables) : self | ||||||
|             { |             { | ||||||
|                 $this->variables[$name] = $variables; |                 $this->variables[$name] = $variables; | ||||||
|                  | 
 | ||||||
|                 return $this; |                 return $this; | ||||||
|             } |             } | ||||||
|              | 
 | ||||||
|             public function getDefinitionVars(string $name) : string |             public function getDefinitionVars(string $name) : string | ||||||
|             { |             { | ||||||
|                 return $this->variables[$name] ?? ""; |                 return $this->variables[$name] ?? ""; | ||||||
|             } |             } | ||||||
|              | 
 | ||||||
|             public function getCurrentSlotDefinitionVars() : string |             public function getCurrentSlotDefinitionVars() : string | ||||||
|             { |             { | ||||||
|                 return $this->getDefinitionVars($this->currentSlot); |                 return $this->getDefinitionVars($this->currentSlot); | ||||||
|             } |             } | ||||||
|              | 
 | ||||||
|             public function hasDefinitions() : bool |             public function hasDefinitions() : bool | ||||||
|             { |             { | ||||||
|                 return count($this->definitions) > 0; |                 return count($this->definitions) > 0; | ||||||
|             } |             } | ||||||
|              | 
 | ||||||
|             public function printDefinition(string $name) : string |             public function printDefinition(string $name) : string | ||||||
|             { |             { | ||||||
|                 if ( ! isset($this->definitions[$name]) ) { |                 if ( ! isset($this->definitions[$name]) ) { | ||||||
|                     throw new \Exception("Slot definition for `$name` was not found. Have you defined it in your block header using something like '{% define \"$name\", ...\$arguments %}' ?");
 |                     throw new \Exception("Slot definition for `$name` was not found. Have you defined it in your block header using something like '{% define \"$name\", ...\$arguments %}' ?");
 | ||||||
|                 } |                 } | ||||||
|                  | 
 | ||||||
|                 return $this->definitions[$name]; |                 return $this->definitions[$name]; | ||||||
|             } |             } | ||||||
|              | 
 | ||||||
|             public function render() : void |             public function render() : void | ||||||
|             { |             { | ||||||
|                 $this->rendering = true; |                 $this->rendering = true; | ||||||
|             } |             } | ||||||
|         }; |         }; | ||||||
|     } |     } | ||||||
|      | 
 | ||||||
|     public static function instanciateBlock(string $viewPath, ... $arguments)  |     public static function instanciateBlock(string $viewPath, ... $arguments) | ||||||
|     { |     { | ||||||
|         return new class($viewPath, ...$arguments) { |         return new class($viewPath, ...$arguments) { | ||||||
|              | 
 | ||||||
|             public bool $rendering = false; |             public bool $rendering = false; | ||||||
|              | 
 | ||||||
|             public string $viewPath; |             public string $viewPath; | ||||||
|              | 
 | ||||||
|             public array $using = []; |             public array $using = []; | ||||||
|              | 
 | ||||||
|             public array $arguments = []; |             public array $arguments = []; | ||||||
|              | 
 | ||||||
|             public array $slots = []; |             public array $slots = []; | ||||||
|              | 
 | ||||||
|             public array $definition = []; |             public array $definition = []; | ||||||
|              | 
 | ||||||
|             public function __construct(string $viewPath, ...$arguments) { |             public function __construct(string $viewPath, ...$arguments) { | ||||||
|                 $this->viewPath = $viewPath; |                 $this->viewPath = $viewPath; | ||||||
|                 $this->arguments = $arguments; |                 $this->arguments = $arguments; | ||||||
|             } |             } | ||||||
|              | 
 | ||||||
|             public function render(object $classTemplate) : string |             public function render(object $classTemplate) : string | ||||||
|             { |             { | ||||||
|                 $this->rendering = true; |                 $this->rendering = true; | ||||||
| 
 | 
 | ||||||
|                 return $classTemplate->picea->inlineBlock($this, $this->viewPath, ...$this->arguments); |                 return $classTemplate->picea->inlineBlock($this, $this->viewPath, ...$this->arguments); | ||||||
|             } |             } | ||||||
|              | 
 | ||||||
|             public function setSlot(string $name, Callable $method) : void |             public function setSlot(string $name, Callable $method) : void | ||||||
|             { |             { | ||||||
|                 $this->slots[$name] = $method; |                 $this->slots[$name] = $method; | ||||||
|             } |             } | ||||||
|              | 
 | ||||||
|             public function defineSlot(string $name, Callable $method) : void |             public function defineSlot(string $name, Callable $method) : void | ||||||
|             { |             { | ||||||
|                 $this->definition[$name] = $method; |                 $this->definition[$name] = $method; | ||||||
|             } |             } | ||||||
|              | 
 | ||||||
|             public function slotIsSet(string $name) : bool |             public function slotIsSet(string $name) : bool | ||||||
|             { |             { | ||||||
|                 return ! empty($this->slots[$name]); |                 return ! empty($this->slots[$name]); | ||||||
|             } |             } | ||||||
|              | 
 | ||||||
|             public function printSlot(string $name, Callable $default) |             public function printSlot(string $name, Callable $default) | ||||||
|             { |             { | ||||||
|                 return $this->slotIsSet($name) ? $this->slots[$name] : $default; |                 return $this->slotIsSet($name) ? $this->slots[$name] : $default; | ||||||
|             } |             } | ||||||
|              | 
 | ||||||
|             public function setUsing(array $variables) { |             public function setUsing(array $variables) { | ||||||
|                 $this->using = $variables; |                 $this->using = $variables; | ||||||
|             } |             } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user