- Added a new {% block ... %} token
- Added a new {% php ... %} token - Fixed a bug with an OR if foreach is empty
This commit is contained in:
parent
0e201b77f2
commit
404d1f4359
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
namespace Picea\ControlStructure;
|
||||
|
||||
class BlockToken implements ControlStructure {
|
||||
|
||||
public array $token = [ "block", "arguments" ];
|
||||
|
||||
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) {
|
||||
|
||||
switch($token) {
|
||||
case "block":
|
||||
return "<?php echo \$___class__template->picea->inlineHtml(\$this, $arguments); ?>";
|
||||
|
||||
case "arguments":
|
||||
$class = static::class;
|
||||
|
||||
return <<<PHP
|
||||
<?php
|
||||
try {
|
||||
extract( \\$class::parseArguments(function($arguments) {}, \$inlineVariables), \EXTR_OVERWRITE);
|
||||
|
||||
unset(\$inlineVariables);
|
||||
}
|
||||
catch(\TypeError \$ex) {
|
||||
throw new \Exception('A block awaiting arguments `$arguments` instead received `' . implode(', ', array_map('gettype', \$inlineVariables)) . '`');
|
||||
}
|
||||
?>
|
||||
PHP;
|
||||
}
|
||||
}
|
||||
|
||||
public static function parseArguments(Callable $method, array $arguments) : array
|
||||
{
|
||||
try{
|
||||
call_user_func_array($method, $arguments);
|
||||
}
|
||||
catch(\TypeError $ex) {
|
||||
throw $ex;
|
||||
}
|
||||
|
||||
$parameters = [];
|
||||
|
||||
foreach((new \ReflectionFunction($method))->getParameters() as $key => $value) {
|
||||
$parameters[ $value->getName() ] = $arguments[$key] ?? $value->getDefaultValue();
|
||||
}
|
||||
|
||||
return $parameters;
|
||||
}
|
||||
}
|
|
@ -7,14 +7,20 @@ class ForeachToken implements ControlStructure {
|
|||
public string $token = "foreach";
|
||||
|
||||
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) {
|
||||
$uid = "$".uniqid("foreach_");
|
||||
$name = "$".uniqid("foreach_");
|
||||
|
||||
$count = count($context->iterationStack ?? []);
|
||||
|
||||
if ( $count > 0 ) {
|
||||
$name .= "[" . $context->iterationStack[$count - 1]['uid'] . "]";
|
||||
}
|
||||
|
||||
$context->iterationStack[] = [
|
||||
'or' => false,
|
||||
'uid' => $uid,
|
||||
'uid' => $name,
|
||||
'token' => 'endforeach',
|
||||
];
|
||||
|
||||
return "<?php foreach ($arguments): {$uid} = 1; ?>";
|
||||
|
||||
return "<?php foreach ($arguments): $name = ( $name ?? 0 ) + 1; ; ?>";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,13 @@ class OrToken implements ControlStructure {
|
|||
|
||||
$key = count( $context->iterationStack ) - 1;
|
||||
$context->iterationStack[$key]['or'] = true;
|
||||
return "<?php {$context->iterationStack[$key]['token']}; if( false === ({$context->iterationStack[$key]['uid']} ?? false) ): ?>";
|
||||
|
||||
$name = $context->iterationStack[$key]['uid'];
|
||||
|
||||
#if ($key !== 0) {
|
||||
#}
|
||||
|
||||
return "<?php {$context->iterationStack[$key]['token']}; if( false === ($name ?? false) ): ?>";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,13 +2,35 @@
|
|||
|
||||
namespace Picea\Extension;
|
||||
|
||||
use Picea\Compiler\Context;
|
||||
|
||||
class JsonExtension implements Extension {
|
||||
|
||||
public string $token = "json";
|
||||
public array $token = [ "json", "json.pretty" ];
|
||||
|
||||
public int $flags = JSON_HEX_TAG | \JSON_HEX_APOS | \JSON_HEX_QUOT | \JSON_THROW_ON_ERROR;
|
||||
|
||||
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) {
|
||||
return "<?php echo json_encode($arguments, {$this->flags}) ?>";
|
||||
public function __construct(? Context $context = null) {
|
||||
if ($context) {
|
||||
$this->register($context);
|
||||
}
|
||||
}
|
||||
|
||||
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) {
|
||||
|
||||
$flag = $this->flags;
|
||||
|
||||
if ( $token === "json.pretty" ) {
|
||||
$flag = \JSON_PRETTY_PRINT;
|
||||
}
|
||||
|
||||
return "<?php echo json_encode($arguments, $flag) ?>";
|
||||
}
|
||||
|
||||
public function register(Context $context) : void
|
||||
{
|
||||
$context->pushFunction("json", function($arguments, ? int $flags = null) {
|
||||
return json_encode($arguments, \JSON_FORCE_OBJECT);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
|
||||
namespace Picea\Extension;
|
||||
|
||||
class PhpExtension implements Extension {
|
||||
|
||||
public array $token = [ "php" ];
|
||||
|
||||
public function parse(/*\Picae\Compiler\Context*/ &$context, ?string $arguments, string $token) {
|
||||
return "<?php $arguments ?>";
|
||||
}
|
||||
}
|
|
@ -12,7 +12,7 @@ class UrlExtension implements Extension {
|
|||
|
||||
protected array $routes;
|
||||
|
||||
public array $tokens = [ "url" , "route", "asset" ];
|
||||
public array $tokens = [ "url" , "route", "asset", "url.parameters" ];
|
||||
|
||||
public function __construct(Context $context, string $urlBase = "", string $assetToken = "") {
|
||||
$this->urlBase = trim($urlBase, "/");
|
||||
|
@ -31,6 +31,9 @@ class UrlExtension implements Extension {
|
|||
|
||||
case "url":
|
||||
return "<?php echo \$picea->compiler->getExtensionFromToken('$token')->buildUrl($arguments) ?>";
|
||||
|
||||
case "url.parameters":
|
||||
return "<?php echo \$picea->compiler->getExtensionFromToken('$token')->setUrlParameters($arguments) ?>";
|
||||
}
|
||||
|
||||
return null;
|
||||
|
@ -43,11 +46,16 @@ class UrlExtension implements Extension {
|
|||
$context->pushFunction("route", [ $this, 'buildRouteUrl' ]);
|
||||
}
|
||||
|
||||
public function buildUrl(string $uri = "", array $parameters = []) : string
|
||||
public function setUrlParameters(string $url = "", array $parameters = []) : string
|
||||
{
|
||||
return $this->url() . "/" . ltrim($uri, "/") . ( $parameters ? "?" . http_build_query($parameters) : "" );
|
||||
return $url . ( $parameters ? "?" . http_build_query($parameters) : "" );
|
||||
}
|
||||
|
||||
public function buildUrl(string $uri = "", array $parameters = []) : string
|
||||
{
|
||||
return $this->setUrlParameters($this->url() . "/" . ltrim($uri, "/"), $parameters);
|
||||
}
|
||||
|
||||
public function buildAssetUrl(string $uri, array $parameters = []) : string
|
||||
{
|
||||
return $this->buildUrl($uri, array_replace([ 'v' => $this->assetToken ], $parameters));
|
||||
|
|
|
@ -4,6 +4,8 @@ namespace Picea\Language;
|
|||
|
||||
use Picea\Compiler;
|
||||
|
||||
use Picea\Compiler\Context;
|
||||
|
||||
class DefaultRegistrations implements LanguageRegistration
|
||||
{
|
||||
protected array $extensions;
|
||||
|
@ -12,8 +14,11 @@ class DefaultRegistrations implements LanguageRegistration
|
|||
|
||||
protected array $controlStructures;
|
||||
|
||||
public function __construct(array $extensions = [], array $syntaxes = [], array $controlStructure = [])
|
||||
protected ? Context $context;
|
||||
|
||||
public function __construct(? Context $context = null, array $extensions = [], array $syntaxes = [], array $controlStructure = [])
|
||||
{
|
||||
$this->context = $context;
|
||||
$this->extensions = $extensions;
|
||||
$this->syntaxes = $syntaxes;
|
||||
$this->controlStructures = $controlStructure;
|
||||
|
@ -63,6 +68,7 @@ class DefaultRegistrations implements LanguageRegistration
|
|||
$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());
|
||||
|
||||
foreach($this->controlStructures ?? [] as $controlStructure) {
|
||||
|
@ -72,7 +78,7 @@ class DefaultRegistrations implements LanguageRegistration
|
|||
|
||||
public function registerExtension(Compiler $compiler) : void
|
||||
{
|
||||
$compiler->registerExtension(new \Picea\Extension\JsonExtension());
|
||||
$compiler->registerExtension(new \Picea\Extension\JsonExtension($this->context));
|
||||
$compiler->registerExtension(new \Picea\Extension\AssetExtension());
|
||||
|
||||
foreach($this->extensions ?? [] as $extension) {
|
||||
|
|
|
@ -33,24 +33,24 @@ class Request implements Extension {
|
|||
$context->pushFunction("post", [ $this, 'post' ]);
|
||||
}
|
||||
|
||||
public function cookie(? string $variableName = null)
|
||||
public function cookie(? string $variableName = null, $default = null)
|
||||
{
|
||||
return $variableName === null ? $this->request->getCookieParams() : static::arrayGet($this->request->getCookieParams(), $variableName);
|
||||
return $variableName === null ? $this->request->getCookieParams() : static::arrayGet($this->request->getCookieParams(), $variableName) ?? $default;
|
||||
}
|
||||
|
||||
public function get(? string $variableName = null)
|
||||
public function get(? string $variableName = null, $default = null)
|
||||
{
|
||||
return $variableName === null ? $this->request->getQueryParams() : static::arrayGet($this->request->getQueryParams(), $variableName);
|
||||
return $variableName === null ? $this->request->getQueryParams() : static::arrayGet($this->request->getQueryParams(), $variableName) ?? $default;
|
||||
}
|
||||
|
||||
public function post(? string $variableName = null)
|
||||
public function post(? string $variableName = null, $default = null)
|
||||
{
|
||||
return $variableName === null ? $this->request->getParsedBody() : static::arrayGet($this->request->getParsedBody(), $variableName);
|
||||
return $variableName === null ? $this->request->getParsedBody() : static::arrayGet($this->request->getParsedBody(), $variableName) ?? $default;
|
||||
}
|
||||
|
||||
public function server(? string $variableName = null)
|
||||
public function server(? string $variableName = null, $default = null)
|
||||
{
|
||||
return $variableName === null ? $this->request->getServerParams() : static::arrayGet($this->request->getServerParams(), $variableName);
|
||||
return $variableName === null ? $this->request->getServerParams() : static::arrayGet($this->request->getServerParams(), $variableName) ?? $default;
|
||||
}
|
||||
|
||||
public static function arrayGet(array $array, string $path, string $delimiter = '.')
|
||||
|
|
|
@ -57,7 +57,18 @@ class Picea implements LanguageRegistration
|
|||
|
||||
return $object();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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, ... $variables) {
|
||||
return $this->renderHtml($viewPath, [ 'inlineVariables' => $variables ], $proxy);
|
||||
}
|
||||
|
||||
public function renderContext(Compiler\Context $context) : object
|
||||
{
|
||||
if ( null === $object = $this->contextFromCache($context) ) {
|
||||
|
|
Loading…
Reference in New Issue