From 404d1f43597dc364264ec95458e11ffcc31047fc Mon Sep 17 00:00:00 2001 From: Dave Mc Nicoll Date: Mon, 30 Mar 2020 12:13:02 -0400 Subject: [PATCH] - Added a new {% block ... %} token - Added a new {% php ... %} token - Fixed a bug with an OR if foreach is empty --- src/ControlStructure/BlockToken.php | 50 +++++++++++++++++++++++++++ src/ControlStructure/ForeachToken.php | 14 +++++--- src/ControlStructure/OrToken.php | 8 ++++- src/Extension/JsonExtension.php | 28 +++++++++++++-- src/Extension/PhpExtension.php | 12 +++++++ src/Extension/UrlExtension.php | 14 ++++++-- src/Language/DefaultRegistrations.php | 10 ++++-- src/Method/Request.php | 16 ++++----- src/Picea.php | 13 ++++++- 9 files changed, 143 insertions(+), 22 deletions(-) create mode 100644 src/ControlStructure/BlockToken.php create mode 100644 src/Extension/PhpExtension.php diff --git a/src/ControlStructure/BlockToken.php b/src/ControlStructure/BlockToken.php new file mode 100644 index 0000000..5dee4cb --- /dev/null +++ b/src/ControlStructure/BlockToken.php @@ -0,0 +1,50 @@ +picea->inlineHtml(\$this, $arguments); ?>"; + + case "arguments": + $class = static::class; + + return << + 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; + } +} \ No newline at end of file diff --git a/src/ControlStructure/ForeachToken.php b/src/ControlStructure/ForeachToken.php index 09c833c..1403dcd 100644 --- a/src/ControlStructure/ForeachToken.php +++ b/src/ControlStructure/ForeachToken.php @@ -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 ""; + + return ""; } } diff --git a/src/ControlStructure/OrToken.php b/src/ControlStructure/OrToken.php index 7f9490d..f562a41 100644 --- a/src/ControlStructure/OrToken.php +++ b/src/ControlStructure/OrToken.php @@ -13,7 +13,13 @@ class OrToken implements ControlStructure { $key = count( $context->iterationStack ) - 1; $context->iterationStack[$key]['or'] = true; - return "iterationStack[$key]['token']}; if( false === ({$context->iterationStack[$key]['uid']} ?? false) ): ?>"; + + $name = $context->iterationStack[$key]['uid']; + + #if ($key !== 0) { + #} + + return "iterationStack[$key]['token']}; if( false === ($name ?? false) ): ?>"; } } diff --git a/src/Extension/JsonExtension.php b/src/Extension/JsonExtension.php index 607f842..ef90bbf 100644 --- a/src/Extension/JsonExtension.php +++ b/src/Extension/JsonExtension.php @@ -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 "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 ""; + } + + public function register(Context $context) : void + { + $context->pushFunction("json", function($arguments, ? int $flags = null) { + return json_encode($arguments, \JSON_FORCE_OBJECT); + }); + } } diff --git a/src/Extension/PhpExtension.php b/src/Extension/PhpExtension.php new file mode 100644 index 0000000..6c363e0 --- /dev/null +++ b/src/Extension/PhpExtension.php @@ -0,0 +1,12 @@ +"; + } +} diff --git a/src/Extension/UrlExtension.php b/src/Extension/UrlExtension.php index 990b737..b42cc79 100644 --- a/src/Extension/UrlExtension.php +++ b/src/Extension/UrlExtension.php @@ -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 "compiler->getExtensionFromToken('$token')->buildUrl($arguments) ?>"; + + case "url.parameters": + return "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)); diff --git a/src/Language/DefaultRegistrations.php b/src/Language/DefaultRegistrations.php index 4a5989c..05b1e04 100644 --- a/src/Language/DefaultRegistrations.php +++ b/src/Language/DefaultRegistrations.php @@ -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) { diff --git a/src/Method/Request.php b/src/Method/Request.php index f42df6e..f3d5604 100644 --- a/src/Method/Request.php +++ b/src/Method/Request.php @@ -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 = '.') diff --git a/src/Picea.php b/src/Picea.php index 0a44531..45daa28 100644 --- a/src/Picea.php +++ b/src/Picea.php @@ -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) ) {