Merge branch 'master' of https://git.mcnd.ca/mcndave/picea
This commit is contained in:
commit
3de5f46de6
|
@ -113,9 +113,7 @@ class Compiler
|
||||||
foreach($this->extensionList as $ext) {
|
foreach($this->extensionList as $ext) {
|
||||||
if ($ext instanceof FunctionExtension) {
|
if ($ext instanceof FunctionExtension) {
|
||||||
foreach ($ext->exportFunctions() as $name => $value) {
|
foreach ($ext->exportFunctions() as $name => $value) {
|
||||||
if ( is_string($value) ) {
|
$callable = is_string($value) ? fn(...$args) => call_user_func_array([ $ext, $value ], $args) : null;
|
||||||
$callable = fn(...$args) => call_user_func_array([ $ext, $value ], $args);
|
|
||||||
}
|
|
||||||
|
|
||||||
$context->pushFunction(is_numeric($name) ? $value : $name, $callable ?? $value);
|
$context->pushFunction(is_numeric($name) ? $value : $name, $callable ?? $value);
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@ class BlockToken implements ControlStructure {
|
||||||
}
|
}
|
||||||
catch(\TypeError \$ex) {
|
catch(\TypeError \$ex) {
|
||||||
throw new \Exception(
|
throw new \Exception(
|
||||||
sprintf('A block awaiting arguments `%s` instead received `%s` with values `%s`', '$arguments', implode(', ', array_map('gettype', \$inlineVariables)), json_encode(\$inlineVariables))
|
sprintf('A block awaiting arguments `%s` instead received `%s` with values `%s`', '$arguments', implode(', ', array_map('gettype', \$inlineVariables ?? [])), json_encode(\$inlineVariables))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
|
|
|
@ -23,7 +23,9 @@ class JsonExtension implements Extension, FunctionExtension {
|
||||||
return "<?php echo htmlentities(json_encode($arguments, {$this->flags}), ENT_QUOTES, 'UTF-8') ?>";
|
return "<?php echo htmlentities(json_encode($arguments, {$this->flags}), ENT_QUOTES, 'UTF-8') ?>";
|
||||||
}
|
}
|
||||||
|
|
||||||
return "<?php echo json_encode($arguments, $flag) ?>";
|
$cls = static::class;
|
||||||
|
|
||||||
|
return "<?php echo json_encode(\\$cls::utf8($arguments), $flag) ?>";
|
||||||
}
|
}
|
||||||
|
|
||||||
public function exportFunctions(): array
|
public function exportFunctions(): array
|
||||||
|
@ -35,4 +37,18 @@ class JsonExtension implements Extension, FunctionExtension {
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function utf8($src) {
|
||||||
|
|
||||||
|
if (is_array($src)) {
|
||||||
|
foreach ($src as $key => $value) {
|
||||||
|
$src[$key] = static::utf8($value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
elseif (is_string($src)) {
|
||||||
|
return mb_convert_encoding($src, "UTF-8", "UTF-8");
|
||||||
|
}
|
||||||
|
|
||||||
|
return $src;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ use Picea\Compiler\Context;
|
||||||
|
|
||||||
class LanguageExtension implements Extension, FunctionExtension {
|
class LanguageExtension implements Extension, FunctionExtension {
|
||||||
|
|
||||||
public array $tokens = [ "lang", "_", "language.set" ];
|
public array $tokens = [ "lang", "lang.raw", "_", "_.raw", "language.set" ];
|
||||||
|
|
||||||
public string $currentLanguage = "";
|
public string $currentLanguage = "";
|
||||||
|
|
||||||
|
@ -31,9 +31,15 @@ class LanguageExtension implements Extension, FunctionExtension {
|
||||||
return "<?php \$picea->compiler->getExtensionFromToken('$token')->currentLanguage = $arguments; ?>";
|
return "<?php \$picea->compiler->getExtensionFromToken('$token')->currentLanguage = $arguments; ?>";
|
||||||
|
|
||||||
case "lang":
|
case "lang":
|
||||||
|
return "<?php echo htmlspecialchars(\$picea->compiler->getExtensionFromToken('$token')->absoluteLang($arguments), \ENT_QUOTES, ini_get('default_charset'), true) ?>";
|
||||||
|
|
||||||
|
case "lang.raw":
|
||||||
return "<?php echo \$picea->compiler->getExtensionFromToken('$token')->absoluteLang($arguments) ?>";
|
return "<?php echo \$picea->compiler->getExtensionFromToken('$token')->absoluteLang($arguments) ?>";
|
||||||
|
|
||||||
case "_":
|
case "_":
|
||||||
|
return "<?php echo htmlspecialchars(\$picea->compiler->getExtensionFromToken('$token')->relativeLang($arguments), \ENT_QUOTES, ini_get('default_charset'), true) ?>";
|
||||||
|
|
||||||
|
case "_.raw":
|
||||||
return "<?php echo \$picea->compiler->getExtensionFromToken('$token')->relativeLang($arguments) ?>";
|
return "<?php echo \$picea->compiler->getExtensionFromToken('$token')->relativeLang($arguments) ?>";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,14 @@ use Picea\Compiler\Context;
|
||||||
|
|
||||||
class UrlExtension implements Extension {
|
class UrlExtension implements Extension {
|
||||||
|
|
||||||
|
public const URLIZE_PATTERN_URL = <<<PATTERN
|
||||||
|
~(?<!href=['"])https?://[\w/._\-&?]*(?!</a>)(?=[^\w/._\-&])~s
|
||||||
|
PATTERN;
|
||||||
|
|
||||||
|
public const URLIZE_PATTERN_EMAIL = <<<PATTERN
|
||||||
|
/(?:[a-z0-9!#$%&'*+\\/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+\\/=?^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])/
|
||||||
|
PATTERN;
|
||||||
|
|
||||||
protected string $urlBase;
|
protected string $urlBase;
|
||||||
|
|
||||||
protected string $assetToken;
|
protected string $assetToken;
|
||||||
|
@ -14,7 +22,7 @@ class UrlExtension implements Extension {
|
||||||
|
|
||||||
protected array $routesTarget;
|
protected array $routesTarget;
|
||||||
|
|
||||||
public array $tokens = [ "url" , "route", "asset", "url.current", "url.parameters", "slug" ];
|
public array $tokens = [ "url" , "route", "route.cacheless", "asset", "url.current", "url.parameters", "slug" ];
|
||||||
|
|
||||||
public function __construct(Context $context, string $urlBase = "", string $assetToken = "") {
|
public function __construct(Context $context, string $urlBase = "", string $assetToken = "") {
|
||||||
$this->urlBase = trim($urlBase, "/");
|
$this->urlBase = trim($urlBase, "/");
|
||||||
|
@ -54,6 +62,7 @@ class UrlExtension implements Extension {
|
||||||
$context->pushFunction("asset", [ $this, 'buildAssetUrl' ]);
|
$context->pushFunction("asset", [ $this, 'buildAssetUrl' ]);
|
||||||
$context->pushFunction("route", [ $this, 'buildRouteUrl' ]);
|
$context->pushFunction("route", [ $this, 'buildRouteUrl' ]);
|
||||||
$context->pushFunction("slug", [ $this, 'slug' ]);
|
$context->pushFunction("slug", [ $this, 'slug' ]);
|
||||||
|
$context->pushFunction("urlize", [ $this, 'urlize' ]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getRouteList(bool $full = false) : array
|
public function getRouteList(bool $full = false) : array
|
||||||
|
@ -66,25 +75,36 @@ class UrlExtension implements Extension {
|
||||||
return $url . ( $parameters ? "?" . http_build_query($parameters) : "" );
|
return $url . ( $parameters ? "?" . http_build_query($parameters) : "" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function urlize(string $string) : string
|
||||||
|
{
|
||||||
|
# Normal URL patterns
|
||||||
|
$string = preg_replace(static::URLIZE_PATTERN_URL, '<a href="$0" target="_blank" title="$0">$0</a>', $string);
|
||||||
|
|
||||||
|
# Email patterns
|
||||||
|
$string = preg_replace(static::URLIZE_PATTERN_EMAIL, '<a href="mailto:$0" title="$0">$0</a>', $string);
|
||||||
|
|
||||||
|
return $string;
|
||||||
|
}
|
||||||
|
|
||||||
public function currentUrl(array $parameters = []) : string
|
public function currentUrl(array $parameters = []) : string
|
||||||
{
|
{
|
||||||
return $this->buildUrl($this->uri(), $parameters);
|
return $this->buildUrl($this->uri(), $parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function buildUrl(string $uri = "", array $parameters = []) : string
|
public function buildUrl(string $uri = "", array $parameters = [], bool $appendVersion = false) : string
|
||||||
{
|
{
|
||||||
return $this->setUrlParameters($this->url() . "/" . ltrim($uri, "/"), $parameters);
|
return $this->setUrlParameters($this->url() . "/" . ltrim($uri, "/"), $appendVersion ? array_replace([ 'v' => $this->assetToken ], $parameters) : $parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function buildAssetUrl(string $uri, array $parameters = []) : string
|
public function buildAssetUrl(string $uri, array $parameters = [], bool $appendVersion = true) : string
|
||||||
{
|
{
|
||||||
return $this->buildUrl($uri, array_replace([ 'v' => $this->assetToken ], $parameters));
|
return $this->buildUrl($uri, $parameters, $appendVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function buildRouteUrl(string $name, array $parameters = []) : string
|
public function buildRouteUrl(string $name, array $parameters = [], bool $appendVersion = false) : string
|
||||||
{
|
{
|
||||||
if ( false !== ( $route = $this->routes[$name] ?? false ) ) {
|
if ( false !== ( $route = $this->routes[$name] ?? false ) ) {
|
||||||
return $this->buildUrl($this->prepareRoute($route['route'], $parameters), $parameters);
|
return $this->buildUrl($this->prepareRoute($route['route'], $parameters), $parameters, $appendVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
$routeList = json_encode($this->routes, \JSON_PRETTY_PRINT);
|
$routeList = json_encode($this->routes, \JSON_PRETTY_PRINT);
|
||||||
|
@ -193,7 +213,7 @@ class UrlExtension implements Extension {
|
||||||
list($variable, $default) = explode('=', $item[1]);
|
list($variable, $default) = explode('=', $item[1]);
|
||||||
}
|
}
|
||||||
elseif (strpos($item[1], ":") !== false) {
|
elseif (strpos($item[1], ":") !== false) {
|
||||||
list($variable, $type) = explode(':', $item[1]);
|
list($variable, ) = explode(':', $item[1]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$variable = $item[1];
|
$variable = $item[1];
|
||||||
|
@ -201,7 +221,6 @@ class UrlExtension implements Extension {
|
||||||
|
|
||||||
if ( array_key_exists($variable, $arguments) ) {
|
if ( array_key_exists($variable, $arguments) ) {
|
||||||
$value = $arguments[ $variable ];
|
$value = $arguments[ $variable ];
|
||||||
|
|
||||||
unset($arguments[ $variable ]);
|
unset($arguments[ $variable ]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -209,22 +228,12 @@ class UrlExtension implements Extension {
|
||||||
}
|
}
|
||||||
|
|
||||||
$search[ $item[0] ] = $value;
|
$search[ $item[0] ] = $value;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$route = str_replace(array_keys($search), array_values($search), $route);
|
$route = str_replace(array_keys($search), array_values($search), $route);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* @TODO - must also take into account that recursivity is possible here [/test[/another[/still]]],
|
|
||||||
* so the regex must be adjusted (or simply using another method could also be a possiblity)
|
|
||||||
* while(strpos($route, '[') !== false && strpos($route, ']') !== false ) {
|
|
||||||
if ( preg_match_all('~[(.*?)]~si', $route, $matches, PREG_SET_ORDER) ) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
$route = trim(str_replace([ '[', ']' ], '', $route), '/');
|
|
||||||
|
|
||||||
return $route;
|
return $route;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,6 @@ class DefaultRegistrations implements LanguageRegistration
|
||||||
|
|
||||||
public function registerSyntax(Compiler $compiler) : void
|
public function registerSyntax(Compiler $compiler) : void
|
||||||
{
|
{
|
||||||
$compiler->registerSyntax(new \Picea\Syntax\PhpTagToken());
|
|
||||||
$compiler->registerSyntax(new \Picea\Syntax\CommentToken());
|
$compiler->registerSyntax(new \Picea\Syntax\CommentToken());
|
||||||
$compiler->registerSyntax(new \Picea\Syntax\EchoRawToken());
|
$compiler->registerSyntax(new \Picea\Syntax\EchoRawToken());
|
||||||
$compiler->registerSyntax(new \Picea\Syntax\EchoSafeToken());
|
$compiler->registerSyntax(new \Picea\Syntax\EchoSafeToken());
|
||||||
|
@ -49,7 +48,6 @@ class DefaultRegistrations implements LanguageRegistration
|
||||||
$compiler->registerControlStructure(new \Picea\ControlStructure\SwitchToken());
|
$compiler->registerControlStructure(new \Picea\ControlStructure\SwitchToken());
|
||||||
$compiler->registerControlStructure(new \Picea\ControlStructure\DefaultToken());
|
$compiler->registerControlStructure(new \Picea\ControlStructure\DefaultToken());
|
||||||
$compiler->registerControlStructure(new \Picea\ControlStructure\BreakToken());
|
$compiler->registerControlStructure(new \Picea\ControlStructure\BreakToken());
|
||||||
$compiler->registerControlStructure(new \Picea\ControlStructure\ContinueToken());
|
|
||||||
$compiler->registerControlStructure(new \Picea\ControlStructure\ExtendsToken());
|
$compiler->registerControlStructure(new \Picea\ControlStructure\ExtendsToken());
|
||||||
$compiler->registerControlStructure(new \Picea\ControlStructure\SectionToken());
|
$compiler->registerControlStructure(new \Picea\ControlStructure\SectionToken());
|
||||||
$compiler->registerControlStructure(new \Picea\ControlStructure\FunctionToken());
|
$compiler->registerControlStructure(new \Picea\ControlStructure\FunctionToken());
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Picea\Syntax;
|
|
||||||
|
|
||||||
class PhpTagToken implements Syntax {
|
|
||||||
|
|
||||||
public string $tokenOpen = "\{\?";
|
|
||||||
|
|
||||||
public string $tokenClose = "\?\}";
|
|
||||||
|
|
||||||
public function parse(/*\Picae\Compiler\Context*/ &$context, string &$sourceCode)
|
|
||||||
{
|
|
||||||
$sourceCode = preg_replace_callback("#({$this->tokenOpen})(.*?)({$this->tokenClose})#s", function ($matches) {
|
|
||||||
return "<?php {$matches[2]} ?>";
|
|
||||||
}, $sourceCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in New Issue