1
0
mirror of https://github.com/flextype/flextype.git synced 2025-08-06 05:07:41 +02:00

feat(core): updates for #586 #585 #584

This commit is contained in:
Awilum
2022-09-09 15:59:43 +03:00
parent 7de0b86eed
commit 7f443bea9b
55 changed files with 796 additions and 461 deletions

View File

@@ -18,11 +18,11 @@ namespace Flextype\Entries\Directives;
use function Flextype\emitter;
use function Flextype\entries;
use function Flextype\expression;
use function Flextype\parsers;
use function Flextype\registry;
use function Flextype\collection;
// Directive: [[ ]]
// Directive: [[ ]] [% %] [# #]
emitter()->addListener('onEntriesFetchSingleField', static function (): void {
if (! registry()->get('flextype.settings.entries.directives.expressions.enabled')) {
return;
@@ -32,22 +32,15 @@ emitter()->addListener('onEntriesFetchSingleField', static function (): void {
return;
}
$selfQuote = fn ($text) => preg_replace('/(.)/us', '\\\\$0', $text);
$openingTag = registry()->get('flextype.settings.entries.directives.expressions.opening_tag');
$closingTag = registry()->get('flextype.settings.entries.directives.expressions.closing_tag');
$field = entries()->registry()->get('methods.fetch.field');
// Convert entry fields to vars.
foreach (json_decode(json_encode((object) entries()->registry()->get('methods.fetch.result')), false) as $key => $value) {
$vars[$key] = $value;
}
if (is_string($field['value'])) {
$field['value'] = preg_replace_callback('/' . $selfQuote($openingTag) . ' (.*?) ' . $selfQuote($closingTag) . '/s', function ($matches) {
// Prepare vars
foreach (json_decode(json_encode((object) entries()->registry()->get('methods.fetch.result')), false) as $key => $value) {
$vars[$key] = $value;
}
return expression()->evaluate($matches[1], $vars);
}, $field['value']);
$field['value'] = parsers()->expressions()->parse($field['value'], $vars);
}
entries()->registry()->set('methods.fetch.field.key', $field['key']);

View File

@@ -33,7 +33,7 @@ use function Flextype\serializers;
use function Glowy\Strings\strings;
use function Flextype\filterCollection;
use function Flextype\collection;
use function Flextype\expression;
use function Flextype\parsers;
class Entries
{
@@ -82,9 +82,8 @@ class Entries
$this->setRegistry($registry);
$this->setOptions($options);
$this->initExpressions(registry()->get('flextype.settings.entries.expressions'));
$this->initDirectives(registry()->get('flextype.settings.entries.directives'));
$this->initMacros(registry()->get('flextype.settings.entries.macros'));
$this->registerDirectives(registry()->get('flextype.settings.entries.directives'));
$this->registerMacros(registry()->get('flextype.settings.entries.macros'));
$this->loadCollectionsEvents();
$this->loadCollectionsFields();
}
@@ -100,16 +99,29 @@ class Entries
*/
private function removeSystemFields($data)
{
$result = [];
if (is_array($data)) {
if (boolval(arrays($data)->get('macros.debug', registry()->get('flextype.settings.entries.macros.debug'))) === false) {
unset($data['macros']);
}
if (boolval(arrays($data)->get('vars.debug', registry()->get('flextype.settings.entries.vars.debug'))) === false) {
unset($data['vars']);
foreach ($data as $key => $value) {
// remove hidden fields
if (strings($key)->startsWith('_')) {
continue;
}
// remove macros fields
if ($key == 'macros') {
if (isset($value['debug']) && $value['debug'] == 'true') {
// display macros...
} else {
continue;
}
}
$result[$key] = $value;
}
}
return $data;
return $result;
}
/**
@@ -119,7 +131,7 @@ class Entries
*
* @access public
*/
public function initMacros(array $macros): void
public function registerMacros(array $macros): void
{
foreach ($macros as $key => $value) {
if ($key == 'debug') {
@@ -139,7 +151,7 @@ class Entries
*
* @access public
*/
public function initDirectives(array $directives): void
public function registerDirectives(array $directives): void
{
foreach ($directives as $key => $value) {
if (filesystem()->file(FLEXTYPE_ROOT_DIR . '/' . $value['path'])->exists()) {
@@ -148,38 +160,6 @@ class Entries
}
}
/**
* Init Expressions
*
* @param array $expressions Expressions to init.
*
* @return void
*/
public function initExpressions(array $expressions): void
{
if (count($expressions) <= 0) {
return;
}
foreach ($expressions as $expression) {
if (! isset($expression['enabled'])) {
continue;
}
if (! $expression['enabled']) {
continue;
}
if (! strings($expression['class'])->endsWith('Expression')) {
continue;
}
if (class_exists($expression['class'])) {
expression()->registerProvider(new $expression['class']());
}
}
}
/**
* Load events for current collection.
*

View File

@@ -1,30 +0,0 @@
<?php
declare(strict_types=1);
/**
* Flextype - Hybrid Content Management System with the freedom of a headless CMS
* and with the full functionality of a traditional CMS!
*
* Copyright (c) Sergey Romanenko (https://awilum.github.io)
*
* Licensed under The MIT License.
*
* For full copyright and license information, please see the LICENSE
* Redistributions of files must retain the above copyright notice.
*/
namespace Flextype\Entries\Expressions;
use Symfony\Component\ExpressionLanguage\ExpressionFunction;
use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;
use function Flextype\entries;
class FieldExpression implements ExpressionFunctionProviderInterface
{
public function getFunctions()
{
return [new ExpressionFunction('field', static fn (string $field) => "\Flextype\entries()->registry()->get('methods.fetch.result.' . $field . ')'", static fn ($arguments, string $field) => entries()->registry()->get('methods.fetch.result.' . $field))];
}
}

View File

@@ -1,84 +0,0 @@
<?php
declare(strict_types=1);
/**
* Flextype - Hybrid Content Management System with the freedom of a headless CMS
* and with the full functionality of a traditional CMS!
*
* Copyright (c) Sergey Romanenko (https://awilum.github.io)
*
* Licensed under The MIT License.
*
* For full copyright and license information, please see the LICENSE
* Redistributions of files must retain the above copyright notice.
*/
namespace Flextype\Entries\Expressions;
use Symfony\Component\ExpressionLanguage\ExpressionFunction;
use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;
use function Flextype\entries;
use function Glowy\Strings\strings;
class VarExpression implements ExpressionFunctionProviderInterface
{
public function getFunctions()
{
return [
new ExpressionFunction('var',
static function (string $var) {
$var = strings($var)->stripQuotes()->toString();
$code = "\Flextype\\entries()->registry()->get('methods.fetch.result.$var');";
return $code;
},
static function ($arguments, string $var) {
return entries()->registry()->get('methods.fetch.result.vars.' . $var);
}
),
new ExpressionFunction('set',
static function (string $var, $value) {
$var = strings($var)->stripQuotes()->toString();
$value = strings($value)->stripQuotes()->toString();
$code = "\Flextype\\entries()->registry()->set('methods.fetch.result.$var', '$value');";
return $code;
},
static function ($arguments, string $var, $value) {
entries()->registry()->set('methods.fetch.result.' . $var, $value);
}
),
new ExpressionFunction('get',
static function (string $var, $default = '') {
$var = strings($var)->stripQuotes()->toString();
$default = strings($default)->stripQuotes()->toString();
$code = "\Flextype\\entries()->registry()->get('methods.fetch.result.$var'" . ($default ? ", '$default'" : '') . ");";
return $code;
},
static function ($arguments, string $var, $default = '') {
return entries()->registry()->get('methods.fetch.result.' . $var, $default);
}
),
new ExpressionFunction('delete',
static function (string $var) {
$var = strings($var)->stripQuotes()->toString();
$code = "\Flextype\\entries()->registry()->delete('methods.fetch.result.$var');";
return $code;
},
static function ($arguments, string $var) {
entries()->registry()->delete('methods.fetch.result.' . $var);
}
),
new ExpressionFunction('unset',
static function (string $var) {
$var = strings($var)->stripQuotes()->toString();
$code = "\Flextype\\entries()->registry()->set('methods.fetch.result.$var', null);";
return $code;
},
static function ($arguments, string $var) {
entries()->registry()->set('methods.fetch.result.' . $var, null);
}
),
];
}
}

View File

@@ -0,0 +1,277 @@
<?php
declare(strict_types=1);
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Flextype\Parsers;
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
use Symfony\Component\ExpressionLanguage\ExpressionFunction;
use Symfony\Component\ExpressionLanguage\Lexer;
use Symfony\Component\ExpressionLanguage\Parser;
use Symfony\Component\ExpressionLanguage\Compiler;
use Symfony\Component\ExpressionLanguage\ParsedExpression;
use function Glowy\Strings\strings;
use function Flextype\registry;
use function Flextype\cache;
use function Flextype\entries;
// Help opcache.preload discover always-needed symbols
class_exists(ParsedExpression::class);
final class Expressions
{
/**
* Expressions instance.
*/
private static ?Expressions $instance = null;
private Lexer $lexer;
private Parser $parser;
private Compiler $compiler;
protected array $functions = [];
/**
* @param ExpressionFunctionProviderInterface[] $providers
*/
protected function __construct()
{
// Register default php functions
$this->addFunction(ExpressionFunction::fromPhp('constant'));
// Register the expressions providers
$this->registerExpressions(registry()->get('flextype.settings.parsers.expressions.expressions'));
}
/**
* Expressions should not be cloneable.
*/
protected function __clone()
{
throw new Exception('Cannot clone a Expressions.');
}
/**
* Expressions should not be restorable from strings.
*/
public function __wakeup(): void
{
throw new Exception('Cannot unserialize a Expressions.');
}
/**
* Gets the instance via lazy initialization (created on first usage).
*/
public static function getInstance(): Expressions
{
if (static::$instance === null) {
static::$instance = new self();
}
return static::$instance;
}
/**
* Compiles an expression source code.
*/
public function compile(Expression|string $expression, array $names = []): string
{
return $this->getCompiler()->compile($this->parseExpression($expression, $names)->getNodes())->getSource();
}
/**
* Evaluate an expression.
*/
public function eval(Expression|string $expression, array $values = []): mixed
{
return $this->parseExpression($expression, array_keys($values))->getNodes()->evaluate($this->functions, $values);
}
/**
* Fallback method to evaluate an expression.
*/
public function evaluate(Expression|string $expression, array $values = []): mixed
{
return $this->eval($expression, $values);
}
/**
* Parses text to evaluate or compile expressions.
*/
public function parse(Expression|string $string, array $values = [], bool $compile = false)
{
if ($string instanceof Expression) {
return $string;
}
$selfQuote = fn ($string) => preg_replace('/(.)/us', '\\\\$0', $string);
$openingVariableTag = registry()->get('flextype.settings.parsers.expressions.opening_variable_tag');
$closingVariableTag = registry()->get('flextype.settings.parsers.expressions.closing_variable_tag');
$openingBlockTag = registry()->get('flextype.settings.parsers.expressions.opening_block_tag');
$closingBlockTag = registry()->get('flextype.settings.parsers.expressions.closing_block_tag');
$openingCommentTag = registry()->get('flextype.settings.parsers.expressions.opening_comment_tag');
$closingCommentTag = registry()->get('flextype.settings.parsers.expressions.closing_comment_tag');
// [# #] - comments
$string = preg_replace_callback('/' . $selfQuote($openingCommentTag) . ' (.*?) ' . $selfQuote($closingCommentTag) . '/sx', function ($matches) use ($values, $compile, $string) {
return '';
}, $string);
// [% %] - blocks
$string = preg_replace_callback('/' . $selfQuote($openingBlockTag) . ' (.*?) ' . $selfQuote($closingBlockTag) . '/sx', function ($matches) use ($values, $compile, $string) {
$this->{$compile ? 'compile' : 'eval'}($matches[1], $values);
return '';
}, $string);
// [[ ]] - variables
$string = preg_replace_callback('/' . $selfQuote($openingVariableTag) . ' (.*?) ' . $selfQuote($closingVariableTag) . '/sx', function ($matches) use ($values, $compile) {
return $this->{$compile ? 'compile' : 'eval'}($matches[1], $values);
}, $string);
return $string;
}
/**
* Parses an expression.
*/
public function parseExpression(Expression|string $expression, array $names): ParsedExpression
{
if ($expression instanceof ParsedExpression) {
return $expression;
}
if (registry()->get('flextype.settings.parsers.expressions.cache.enabled') === true &&
registry()->get('flextype.settings.cache.enabled') === true) {
$cacheItem = $this->getExpressionCacheID($expression, $names);
if (! cache()->has($cacheItem)) {
$parsedExpression = new ParsedExpression((string) $expression, $this->getParser()->parse($this->getLexer()->tokenize((string) $expression), $names));
cache()->set($cacheItem, $parsedExpression);
return $parsedExpression;
} else {
return cache()->get($cacheItem);
}
}
return new ParsedExpression((string) $expression, $this->getParser()->parse($this->getLexer()->tokenize((string) $expression), $names));
}
/**
* Validates the syntax of an expression.
*
* @param array|null $names The list of acceptable variable names in the expression, or null to accept any names
*
* @throws SyntaxError When the passed expression is invalid
*/
public function lint(Expression|string $expression, ?array $names): void
{
if ($expression instanceof ParsedExpression) {
return;
}
$this->getParser()->lint($this->getLexer()->tokenize((string) $expression), $names);
}
/**
* Registers a function.
*
* @param callable $compiler A callable able to compile the function
* @param callable $evaluator A callable able to evaluate the function
*
* @throws \LogicException when registering a function after calling evaluate(), compile() or parse()
*
* @see ExpressionFunction
*/
public function register(string $name, callable $compiler, callable $evaluator)
{
if (isset($this->parser)) {
throw new \LogicException('Registering functions after calling evaluate(), compile() or parse() is not supported.');
}
$this->functions[$name] = ['compiler' => $compiler, 'evaluator' => $evaluator];
}
public function addFunction(ExpressionFunction $function)
{
$this->register($function->getName(), $function->getCompiler(), $function->getEvaluator());
}
public function registerProvider($provider)
{
foreach ($provider->getFunctions() as $function) {
$this->addFunction($function);
}
}
public function registerExpressions(array $expressions) {
if (count($expressions) >= 0) {
foreach ($expressions as $expression) {
if (! isset($expression['enabled'])) {
continue;
}
if (! $expression['enabled']) {
continue;
}
if (! strings($expression['class'])->endsWith('Expression')) {
continue;
}
if (class_exists($expression['class'])) {
$this->registerProvider(new $expression['class']());
}
}
}
}
private function getLexer(): Lexer
{
return $this->lexer ??= new Lexer();
}
private function getParser(): Parser
{
return $this->parser ??= new Parser($this->functions);
}
private function getCompiler(): Compiler
{
$this->compiler ??= new Compiler($this->functions);
return $this->compiler->reset();
}
public function getExpressionCacheID(Expression|string $expression, array $names, string $string = ''): string
{
if ($expression instanceof ParsedExpression) {
return '';
}
// Go through...
asort($names);
$cacheKeyItems = [];
foreach ($names as $nameKey => $name) {
$cacheKeyItems[] = \is_int($nameKey) ? $name : $nameKey.':'.$name;
}
// Create Unique Cache ID for Expression
return md5('expression' . $string . rawurlencode($expression.'//'.implode('|', $cacheKeyItems)));
}
}

View File

@@ -14,7 +14,7 @@ declare(strict_types=1);
* Redistributions of files must retain the above copyright notice.
*/
namespace Flextype\Entries\Expressions;
namespace Flextype\Parsers\Expressions;
use Symfony\Component\ExpressionLanguage\ExpressionFunction;
use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;

View File

@@ -14,7 +14,7 @@ declare(strict_types=1);
* Redistributions of files must retain the above copyright notice.
*/
namespace Flextype\Entries\Expressions;
namespace Flextype\Parsers\Expressions;
use Symfony\Component\ExpressionLanguage\ExpressionFunction;
use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;

View File

@@ -14,7 +14,7 @@ declare(strict_types=1);
* Redistributions of files must retain the above copyright notice.
*/
namespace Flextype\Entries\Expressions;
namespace Flextype\Parsers\Expressions;
use Symfony\Component\ExpressionLanguage\ExpressionFunction;
use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;

View File

@@ -14,7 +14,7 @@ declare(strict_types=1);
* Redistributions of files must retain the above copyright notice.
*/
namespace Flextype\Entries\Expressions;
namespace Flextype\Parsers\Expressions;
use Symfony\Component\ExpressionLanguage\ExpressionFunction;
use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;

View File

@@ -14,7 +14,7 @@ declare(strict_types=1);
* Redistributions of files must retain the above copyright notice.
*/
namespace Flextype\Entries\Expressions;
namespace Flextype\Parsers\Expressions;
use Symfony\Component\ExpressionLanguage\ExpressionFunction;
use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;

View File

@@ -14,7 +14,7 @@ declare(strict_types=1);
* Redistributions of files must retain the above copyright notice.
*/
namespace Flextype\Entries\Expressions;
namespace Flextype\Parsers\Expressions;
use Glowy\Arrays\Arrays;
use Glowy\Macroable\Macroable;
@@ -49,7 +49,7 @@ class EntriesExpressionsMethods
*/
public function fetch(string $id, array $options = []): \Glowy\Arrays\Arrays
{
if (! registry()->get('flextype.settings.entries.expressions.entries.fetch.enabled')) {
if (! registry()->get('flextype.settings.parsers.expressions.expressions.entries.fetch.enabled')) {
return collection();
}
@@ -74,7 +74,7 @@ class EntriesExpressionsMethods
*/
public function registry(): \Glowy\Arrays\Arrays
{
if (! registry()->get('flextype.settings.entries.expressions.entries.registry.enabled')) {
if (! registry()->get('flextype.settings.parsers.expressions.expressions.entries.registry.enabled')) {
return collection();
}
@@ -92,7 +92,7 @@ class EntriesExpressionsMethods
*/
public function has(string $id): bool
{
if (! registry()->get('flextype.settings.entries.expressions.entries.has.enabled')) {
if (! registry()->get('flextype.settings.parsers.expressions.expressions.entries.has.enabled')) {
return false;
}
@@ -111,7 +111,7 @@ class EntriesExpressionsMethods
*/
public function move(string $id, string $newID): bool
{
if (! registry()->get('flextype.settings.entries.expressions.entries.move.enabled')) {
if (! registry()->get('flextype.settings.parsers.expressions.expressions.entries.move.enabled')) {
return false;
}
@@ -130,7 +130,7 @@ class EntriesExpressionsMethods
*/
public function update(string $id, array $data): bool
{
if (! registry()->get('flextype.settings.entries.expressions.entries.update.enabled')) {
if (! registry()->get('flextype.settings.parsers.expressions.expressions.entries.update.enabled')) {
return false;
}
@@ -149,7 +149,7 @@ class EntriesExpressionsMethods
*/
public function create(string $id, array $data = []): bool
{
if (! registry()->get('flextype.settings.entries.expressions.entries.create.enabled')) {
if (! registry()->get('flextype.settings.parsers.expressions.expressions.entries.create.enabled')) {
return false;
}
@@ -167,7 +167,7 @@ class EntriesExpressionsMethods
*/
public function delete(string $id): bool
{
if (! registry()->get('flextype.settings.entries.expressions.entries.delete.enabled')) {
if (! registry()->get('flextype.settings.parsers.expressions.expressions.entries.delete.enabled')) {
return false;
}
@@ -186,7 +186,7 @@ class EntriesExpressionsMethods
*/
public function copy(string $id, string $newID): bool
{
if (! registry()->get('flextype.settings.entries.expressions.entries.copy.enabled')) {
if (! registry()->get('flextype.settings.parsers.expressions.expressions.entries.copy.enabled')) {
return false;
}

View File

@@ -14,7 +14,7 @@ declare(strict_types=1);
* Redistributions of files must retain the above copyright notice.
*/
namespace Flextype\Entries\Expressions;
namespace Flextype\Parsers\Expressions;
use Glowy\Macroable\Macroable;
use Symfony\Component\ExpressionLanguage\ExpressionFunction;
@@ -26,7 +26,7 @@ class FetchExpression implements ExpressionFunctionProviderInterface
{
public function getFunctions()
{
return [new ExpressionFunction('fetch', static fn (string $resource, array $options = []) => '(new \Flextype\Entries\Expressions\FetchExpressionsMethods())->fetch($resource, $options);', static fn ($arguments, string $resource, array $options = []) => (new \Flextype\Entries\Expressions\FetchExpressionsMethods())->fetch($resource, $options))];
return [new ExpressionFunction('fetch', static fn (string $resource, array $options = []) => '(new \Flextype\Parsers\Expressions\FetchExpressionsMethods())->fetch($resource, $options);', static fn ($arguments, string $resource, array $options = []) => (new \Flextype\Parsers\Expressions\FetchExpressionsMethods())->fetch($resource, $options))];
}
}

View File

@@ -0,0 +1,70 @@
<?php
declare(strict_types=1);
/**
* Flextype - Hybrid Content Management System with the freedom of a headless CMS
* and with the full functionality of a traditional CMS!
*
* Copyright (c) Sergey Romanenko (https://awilum.github.io)
*
* Licensed under The MIT License.
*
* For full copyright and license information, please see the LICENSE
* Redistributions of files must retain the above copyright notice.
*/
namespace Flextype\Parsers\Expressions;
use Symfony\Component\ExpressionLanguage\ExpressionFunction;
use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;
use Glowy\Macroable\Macroable;
use function Flextype\entries;
use function Glowy\Strings\strings;
class FieldExpression implements ExpressionFunctionProviderInterface
{
public function getFunctions()
{
return [
new ExpressionFunction('field',
static function (string $field) {
$field = strings($field)->stripQuotes()->toString();
$code = "\Flextype\\entries()->registry()->get('methods.fetch.result.$field');";
return $code;
},
static fn ($arguments, string $field) => entries()->registry()->get('methods.fetch.result.' . $field)
),
new ExpressionFunction('fields',
static fn () => "(new \\Flextype\\Parsers\\Expressions\\FieldsExpressionMethods())",
static fn ($arguments) => (new FieldsExpressionMethods())
)
];
}
}
class FieldsExpressionMethods
{
use Macroable;
public function set(string|null $key, $value)
{
entries()->registry()->set('methods.fetch.result.' . $key, $value);
}
public function get($key, $default = null)
{
return entries()->registry()->get('methods.fetch.result.' . $key, $default);
}
public function unset(string|null $key)
{
entries()->registry()->set('methods.fetch.result.' . $key, null);
}
public function delete($key)
{
return entries()->registry()->delete('methods.fetch.result.' . $key);
}
}

View File

@@ -14,7 +14,7 @@ declare(strict_types=1);
* Redistributions of files must retain the above copyright notice.
*/
namespace Flextype\Entries\Expressions;
namespace Flextype\Parsers\Expressions;
use Glowy\Macroable\Macroable;
use Symfony\Component\ExpressionLanguage\ExpressionFunction;

View File

@@ -14,7 +14,7 @@ declare(strict_types=1);
* Redistributions of files must retain the above copyright notice.
*/
namespace Flextype\Entries\Expressions;
namespace Flextype\Parsers\Expressions;
use Symfony\Component\ExpressionLanguage\ExpressionFunction;
use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;

View File

@@ -14,7 +14,7 @@ declare(strict_types=1);
* Redistributions of files must retain the above copyright notice.
*/
namespace Flextype\Entries\Expressions;
namespace Flextype\Parsers\Expressions;
use Symfony\Component\ExpressionLanguage\ExpressionFunction;
use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;

View File

@@ -14,7 +14,7 @@ declare(strict_types=1);
* Redistributions of files must retain the above copyright notice.
*/
namespace Flextype\Entries\Expressions;
namespace Flextype\Parsers\Expressions;
use Symfony\Component\ExpressionLanguage\ExpressionFunction;
use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;

View File

@@ -14,7 +14,7 @@ declare(strict_types=1);
* Redistributions of files must retain the above copyright notice.
*/
namespace Flextype\Entries\Expressions;
namespace Flextype\Parsers\Expressions;
use Symfony\Component\ExpressionLanguage\ExpressionFunction;
use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;

View File

@@ -14,7 +14,7 @@ declare(strict_types=1);
* Redistributions of files must retain the above copyright notice.
*/
namespace Flextype\Entries\Expressions;
namespace Flextype\Parsers\Expressions;
use Symfony\Component\ExpressionLanguage\ExpressionFunction;
use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;

View File

@@ -14,7 +14,7 @@ declare(strict_types=1);
* Redistributions of files must retain the above copyright notice.
*/
namespace Flextype\Entries\Expressions;
namespace Flextype\Parsers\Expressions;
use Symfony\Component\ExpressionLanguage\ExpressionFunction;
use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;

View File

@@ -14,7 +14,7 @@ declare(strict_types=1);
* Redistributions of files must retain the above copyright notice.
*/
namespace Flextype\Entries\Expressions;
namespace Flextype\Parsers\Expressions;
use Symfony\Component\ExpressionLanguage\ExpressionFunction;
use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;

View File

@@ -14,7 +14,7 @@ declare(strict_types=1);
* Redistributions of files must retain the above copyright notice.
*/
namespace Flextype\Entries\Expressions;
namespace Flextype\Parsers\Expressions;
use Psr\Http\Message\ServerRequestInterface;
use Symfony\Component\ExpressionLanguage\ExpressionFunction;

View File

@@ -0,0 +1,44 @@
<?php
declare(strict_types=1);
/**
* Flextype - Hybrid Content Management System with the freedom of a headless CMS
* and with the full functionality of a traditional CMS!
*
* Copyright (c) Sergey Romanenko (https://awilum.github.io)
*
* Licensed under The MIT License.
*
* For full copyright and license information, please see the LICENSE
* Redistributions of files must retain the above copyright notice.
*/
namespace Flextype\Parsers\Expressions;
use Symfony\Component\ExpressionLanguage\ExpressionFunction;
use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;
use function Flextype\vars;
use function Glowy\Strings\strings;
class VarExpression implements ExpressionFunctionProviderInterface
{
public function getFunctions()
{
return [
new ExpressionFunction('var',
static function (string $name) {
$name = strings($name)->stripQuotes()->toString();
$code = "\Flextype\\vars()->get('$name');";
return $code;
},
static fn ($arguments, string $name) => vars()->get($name)
),
new ExpressionFunction('vars',
static fn () => "\\Flextype\\vars()",
static fn ($arguments) => vars()
)
];
}
}

View File

@@ -23,7 +23,7 @@ class Parsers
use Macroable;
/**
* Create a Shortcodes instance.
* Get a Shortcodes instance.
*/
public function shortcodes(): Shortcodes
{
@@ -31,7 +31,7 @@ class Parsers
}
/**
* Create a Markdown instance.
* Get a Markdown instance.
*/
public function markdown(): Markdown
{
@@ -39,10 +39,18 @@ class Parsers
}
/**
* Create a Textile instance.
* Get a Textile instance.
*/
public function textile(): Textile
{
return Textile::getInstance();
}
/**
* Get a Expressions instance.
*/
public function expressions(): Expressions
{
return Expressions::getInstance();
}
}

View File

@@ -29,5 +29,5 @@ parsers()->shortcodes()->addHandler('calc', static function (ShortcodeInterface
return '';
}
return expression()->evaluate(parsers()->shortcodes()->parse($s->getBBCode()));
return parsers()->expressions()->eval(parsers()->shortcodes()->parse($s->getBBCode()));
});

View File

@@ -32,10 +32,15 @@ parsers()->shortcodes()->addHandler('eval', static function (ShortcodeInterface
}
if ($s->getContent() !== null) {
return expression()->evaluate(parsers()->shortcodes()->parse($s->getContent()));
return parsers()->expressions()->eval(parsers()->shortcodes()->parse($s->getContent()));
}
if ($s->getBbCode() !== null) {
return expression()->evaluate(parsers()->shortcodes()->parse($s->getBBCode()));
return parsers()->expressions()->eval(parsers()->shortcodes()->parse($s->getBBCode()));
}
});
parsers()->shortcodes()->addHandler('compile', static function (ShortcodeInterface $s) {
return expression()->compile(parsers()->shortcodes()->parse($s->getContent()));
});

View File

@@ -24,10 +24,53 @@ use function Flextype\registry;
// Shortcode: field
// Usage: (field:title)
// (field get:foo default:Foo)
// (field get:foo) Default (/field)
// (field set:foo value:Foo)
// (field set:foo) Foo (/field)
// (field unset:foo)
// (field delete:foo)
parsers()->shortcodes()->addHandler('field', static function (ShortcodeInterface $s) {
if (! registry()->get('flextype.settings.parsers.shortcodes.shortcodes.field.enabled')) {
return '';
}
$params = $s->getParameters();
return entries()->registry()->get('methods.fetch.result.' . parsers()->shortcodes()->parse($s->getBBCode()));
// set
if (isset($params['set'])) {
if (isset($params['value'])) {
$value = $params['value'];
} else {
$value = $s->getContent() ?? '';
}
entries()->registry()->set('methods.fetch.result.' . parsers()->shortcodes()->parse($params['set']), parsers()->shortcodes()->parse($value));
return '';
}
// get
if (isset($params['get'])) {
$default = isset($params['default']) ? $params['default'] : $s->getContent() ?? '';
return entries()->registry()->get('methods.fetch.result.' . parsers()->shortcodes()->parse($params['get']), $default);
}
if ($s->getBBCode() !== null) {
return entries()->registry()->get('methods.fetch.result.' . parsers()->shortcodes()->parse($s->getBBCode()));
}
// unset
if (isset($params['unset'])) {
entries()->registry()->set('methods.fetch.result.' . parsers()->shortcodes()->parse($params['unset']), null);
return '';
}
// delete
if (isset($params['delete'])) {
entries()->registry()->delete('methods.fetch.result.' . parsers()->shortcodes()->parse($params['delete']));
return '';
}
return '';
});

View File

@@ -29,5 +29,5 @@ parsers()->shortcodes()->addHandler('if', static function (ShortcodeInterface $s
return '';
}
return expression()->evaluate(parsers()->shortcodes()->parse(($s->getBbCode() ?? ''))) === true ? parsers()->shortcodes()->parse($s->getContent()) : '';
return parsers()->expressions()->eval(parsers()->shortcodes()->parse(($s->getBbCode() ?? ''))) === true ? parsers()->shortcodes()->parse($s->getContent()) : '';
});

View File

@@ -34,7 +34,6 @@ parsers()->shortcodes()->addHandler('php', static function (ShortcodeInterface $
if ($s->getContent() !== null) {
ob_start();
eval($s->getContent());
return ob_get_clean();
}

View File

@@ -29,5 +29,5 @@ parsers()->shortcodes()->addHandler('unless', static function (ShortcodeInterfac
return '';
}
return expression()->evaluate(parsers()->shortcodes()->parse(($s->getBbCode() ?? ''))) === false ? parsers()->shortcodes()->parse($s->getContent()) : '';
return parsers()->expressions()->eval(parsers()->shortcodes()->parse(($s->getBbCode() ?? ''))) === false ? parsers()->shortcodes()->parse($s->getContent()) : '';
});

View File

@@ -21,6 +21,7 @@ use Thunder\Shortcode\Shortcode\ShortcodeInterface;
use function Flextype\entries;
use function Flextype\parsers;
use function Flextype\registry;
use function Flextype\vars;
// Shortcode: var
// Usage: (var:foo)
@@ -31,9 +32,10 @@ parsers()->shortcodes()->addHandler('var', static function (ShortcodeInterface $
if (! registry()->get('flextype.settings.parsers.shortcodes.shortcodes.var.enabled')) {
return '';
}
$params = $s->getParameters();
// set
if (isset($params['set'])) {
if (isset($params['value'])) {
$value = $params['value'];
@@ -41,18 +43,32 @@ parsers()->shortcodes()->addHandler('var', static function (ShortcodeInterface $
$value = $s->getContent() ?? '';
}
entries()->registry()->set('methods.fetch.result.vars.' . parsers()->shortcodes()->parse($params['set']), parsers()->shortcodes()->parse($value));
vars()->set(parsers()->shortcodes()->parse($params['set']), parsers()->shortcodes()->parse($value));
return '';
}
// get
if (isset($params['get'])) {
return entries()->registry()->get('methods.fetch.result.vars.' . parsers()->shortcodes()->parse($params['get']));
$default = isset($params['default']) ? $params['default'] : $s->getContent() ?? '';
return vars()->get(parsers()->shortcodes()->parse($params['get']), $default);
}
if ($s->getBBCode() !== null) {
return entries()->registry()->get('methods.fetch.result.vars.' . parsers()->shortcodes()->parse($s->getBBCode()));
return vars()->get(parsers()->shortcodes()->parse($s->getBBCode()));
}
// unset
if (isset($params['unset'])) {
vars()->set(parsers()->shortcodes()->parse($params['unset']), null);
return '';
}
// delete
if (isset($params['delete'])) {
vars()->delete(parsers()->shortcodes()->parse($params['delete']));
return '';
}
return '';
});

View File

@@ -29,5 +29,5 @@ parsers()->shortcodes()->addHandler('when', static function (ShortcodeInterface
return '';
}
return expression()->evaluate(parsers()->shortcodes()->parse(($s->getBbCode() ?? ''))) === true ? parsers()->shortcodes()->parse($s->getContent()) : '';
return parsers()->expressions()->eval(parsers()->shortcodes()->parse(($s->getBbCode() ?? ''))) === true ? parsers()->shortcodes()->parse($s->getContent()) : '';
});

View File

@@ -26,6 +26,7 @@ use Flextype\Serializers\Serializers;
use Glowy\Csrf\Csrf;
use Glowy\Session\Session;
use Glowy\View\View;
use Glowy\Arrays\Arrays;
use League\Event\Emitter;
use Monolog\Handler\StreamHandler;
use Monolog\Logger;
@@ -39,7 +40,6 @@ use Slim\Middleware\ContentLengthMiddleware;
use Slim\Middleware\OutputBufferingMiddleware;
use Slim\Middleware\RoutingMiddleware;
use Slim\Psr7\Factory\StreamFactory;
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
use Symfony\Component\Yaml\Yaml as SymfonyYaml;
use function array_replace_recursive;
@@ -87,6 +87,9 @@ container()->set('registry', registry());
// Add Actions Service.
container()->set('actions', Actions::getInstance());
// Add Vars Service.
container()->set('vars', Vars::getInstance());
// Init Flextype config (manifest and settings)
$flextypeManifestFilePath = FLEXTYPE_ROOT_DIR . '/src/flextype/flextype.yaml';
$defaultFlextypeSettingsFilePath = FLEXTYPE_ROOT_DIR . '/src/flextype/settings.yaml';
@@ -189,9 +192,6 @@ if (registry()->get('flextype.settings.router.cache.enabled')) {
app()->getRouteCollector()->setCacheFile(FLEXTYPE_PATH_TMP . '/routes/routes.php');
}
// Add Expression Service
container()->set('expression', new ExpressionLanguage());
// Add Session Service
container()->set('session', new Session());

View File

@@ -76,84 +76,11 @@ entries:
directory: 'entries'
cache:
string: ""
vars:
debug: false
expressions:
math:
enabled: true
class: "Flextype\\Entries\\Expressions\\MathExpression"
date:
enabled: true
class: "Flextype\\Entries\\Expressions\\DateExpression"
actions:
enabled: true
class: "Flextype\\Entries\\Expressions\\ActionsExpression"
registry:
enabled: true
class: "Flextype\\Entries\\Expressions\\RegistryExpression"
entries:
enabled: true
class: "Flextype\\Entries\\Expressions\\EntriesExpression"
fetch:
enabled: true
has:
enabled: true
registry:
enabled: true
create:
enabled: false
move:
enabled: false
update:
enabled: false
delete:
enabled: false
fetch:
enabled: true
class: "Flextype\\Entries\\Expressions\\FetchExpression"
filesystem:
enabled: true
class: "Flextype\\Entries\\Expressions\\FilesystemExpression"
i18n:
enabled: true
class: "Flextype\\Entries\\Expressions\\I18nExpression"
serializers:
enabled: true
class: "Flextype\\Entries\\Expressions\\SerializersExpression"
parsers:
enabled: true
class: "Flextype\\Entries\\Expressions\\ParsersExpression"
slugify:
enabled: true
class: "Flextype\\Entries\\Expressions\\SlugifyExpression"
strings:
enabled: true
class: "Flextype\\Entries\\Expressions\\StringsExpression"
collection:
enabled: true
class: "Flextype\\Entries\\Expressions\\CollectionExpression"
csrf:
enabled: true
class: "Flextype\\Entries\\Expressions\\CsrfExpression"
var:
enabled: true
class: "Flextype\\Entries\\Expressions\\VarExpression"
field:
enabled: true
class: "Flextype\\Entries\\Expressions\\FieldExpression"
const:
enabled: true
class: "Flextype\\Entries\\Expressions\\ConstExpression"
url:
enabled: true
class: "Flextype\\Entries\\Expressions\\UrlExpression"
directives:
expressions:
enabled: true
enabled_globally: true
path: "src/flextype/core/Entries/Directives/ExpressionsDirective.php"
opening_tag: "[["
closing_tag: "]]"
shortcodes:
enabled: true
enabled_globally: true
@@ -175,9 +102,6 @@ entries:
path: "src/flextype/core/Entries/Directives/TypesDirective.php"
macros:
debug: false
vars:
enabled: true
path: "src/flextype/core/Entries/Macros/VarsMacros.php"
php:
enabled: false
path: "src/flextype/core/Entries/Macros/PhpMacros.php"
@@ -722,6 +646,85 @@ parsers:
type:
enabled: true
path: "src/flextype/core/Parsers/Shortcodes/TypeShortcode.php"
expressions:
cache:
enabled: true
string: ''
opening_variable_tag: "[["
closing_variable_tag: "]]"
opening_block_tag: "[%"
closing_block_tag: "%]"
opening_comment_tag: "[#"
closing_comment_tag: "#]"
expressions:
math:
enabled: true
class: "Flextype\\Parsers\\Expressions\\MathExpression"
date:
enabled: true
class: "Flextype\\Parsers\\Expressions\\DateExpression"
actions:
enabled: true
class: "Flextype\\Parsers\\Expressions\\ActionsExpression"
registry:
enabled: true
class: "Flextype\\Parsers\\Expressions\\RegistryExpression"
entries:
enabled: true
class: "Flextype\\Parsers\\Expressions\\EntriesExpression"
fetch:
enabled: true
has:
enabled: true
registry:
enabled: true
create:
enabled: false
move:
enabled: false
update:
enabled: false
delete:
enabled: false
fetch:
enabled: true
class: "Flextype\\Parsers\\Expressions\\FetchExpression"
filesystem:
enabled: true
class: "Flextype\\Parsers\\Expressions\\FilesystemExpression"
i18n:
enabled: true
class: "Flextype\\Parsers\\Expressions\\I18nExpression"
serializers:
enabled: true
class: "Flextype\\Parsers\\Expressions\\SerializersExpression"
parsers:
enabled: true
class: "Flextype\\Parsers\\Expressions\\ParsersExpression"
slugify:
enabled: true
class: "Flextype\\Parsers\\Expressions\\SlugifyExpression"
strings:
enabled: true
class: "Flextype\\Parsers\\Expressions\\StringsExpression"
collection:
enabled: true
class: "Flextype\\Parsers\\Expressions\\CollectionExpression"
csrf:
enabled: true
class: "Flextype\\Parsers\\Expressions\\CsrfExpression"
var:
enabled: true
class: "Flextype\\Parsers\\Expressions\\VarExpression"
field:
enabled: true
class: "Flextype\\Parsers\\Expressions\\FieldExpression"
const:
enabled: true
class: "Flextype\\Parsers\\Expressions\\ConstExpression"
url:
enabled: true
class: "Flextype\\Parsers\\Expressions\\UrlExpression"
# CORS
#

View File

@@ -18,13 +18,13 @@ locale: en_US
# Application Base url
#
# Define application base url
# Define application base url (without trailing slash)
base_url: ''
# Application Base Path
#
# Define application base path if application located in subdirectory
base_path: '/'
# Define application base path (without trailing and without starting slash) if application located in subdirectory
base_path: ''
# Valid date format
#
@@ -76,81 +76,11 @@ entries:
directory: 'entries'
cache:
string: ""
vars:
debug: false
expressions:
math:
enabled: true
class: "Flextype\\Entries\\Expressions\\MathExpression"
date:
enabled: true
class: "Flextype\\Entries\\Expressions\\DateExpression"
actions:
enabled: true
class: "Flextype\\Entries\\Expressions\\ActionsExpression"
registry:
enabled: true
class: "Flextype\\Entries\\Expressions\\RegistryExpression"
entries:
enabled: true
class: "Flextype\\Entries\\Expressions\\EntriesExpression"
fetch:
enabled: true
has:
enabled: true
registry:
enabled: true
create:
enabled: false
move:
enabled: false
update:
enabled: false
delete:
enabled: false
fetch:
enabled: true
class: "Flextype\\Entries\\Expressions\\FetchExpression"
filesystem:
enabled: true
class: "Flextype\\Entries\\Expressions\\FilesystemExpression"
i18n:
enabled: true
class: "Flextype\\Entries\\Expressions\\I18nExpression"
serializers:
enabled: true
class: "Flextype\\Entries\\Expressions\\SerializersExpression"
parsers:
enabled: true
class: "Flextype\\Entries\\Expressions\\ParsersExpression"
slugify:
enabled: true
class: "Flextype\\Entries\\Expressions\\SlugifyExpression"
strings:
enabled: true
class: "Flextype\\Entries\\Expressions\\StringsExpression"
collection:
enabled: true
class: "Flextype\\Entries\\Expressions\\CollectionExpression"
csrf:
enabled: true
class: "Flextype\\Entries\\Expressions\\CsrfExpression"
var:
enabled: true
class: "Flextype\\Entries\\Expressions\\VarExpression"
field:
enabled: true
class: "Flextype\\Entries\\Expressions\\FieldExpression"
const:
enabled: true
class: "Flextype\\Entries\\Expressions\\ConstExpression"
directives:
expressions:
enabled: true
enabled_globally: true
path: "src/flextype/core/Entries/Directives/ExpressionsDirective.php"
opening_tag: "[["
closing_tag: "]]"
shortcodes:
enabled: true
enabled_globally: true
@@ -172,9 +102,6 @@ entries:
path: "src/flextype/core/Entries/Directives/TypesDirective.php"
macros:
debug: false
vars:
enabled: true
path: "src/flextype/core/Entries/Macros/VarsMacros.php"
php:
enabled: true
path: "src/flextype/core/Entries/Macros/PhpMacros.php"
@@ -333,17 +260,6 @@ cache:
ssl_enabled: false
ssl_verify: false
default_ttl: 900
cookie:
aware_of_untrustable_data: false
limited_memory_by_object: 4096
default_ttl: 900
couchbase:
host: '127.0.0.1'
port: 8091
username: ''
password: ''
bucket_name: default
default_ttl: 900
couchdb:
database: 'flextype'
path: '/'
@@ -356,25 +272,20 @@ cache:
timeout: 10
default_ttl: 900
devnull: {}
devfalse: {}
devtrue: {}
phparray:
path: '/data'
security_key: 'auto'
htaccess: true
secure_file_manipulation: false
default_ttl: 900
files:
path: '/data'
security_key: 'auto'
htaccess: true
secure_file_manipulation: false
cache_file_extension: txt
default_ttl: 900
leveldb:
path: '/data'
security_key: 'auto'
htaccess: true
default_ttl: 900
memcache:
host: '127.0.0.1'
@@ -421,15 +332,9 @@ cache:
database: 0
opt_prefix: ''
default_ttl: 900
riak:
host: '127.0.0.1'
port: 8098
prefix: 'riak'
default_ttl: 900
sqlite:
path: '/data'
security_key: auto
htaccess: true
default_ttl: 900
ssdb:
host: 127.0.0.1
@@ -674,12 +579,12 @@ parsers:
path: "src/flextype/core/Parsers/Shortcodes/EntriesShortcode.php"
fetch:
enabled: true
php:
enabled: true
path: "src/flextype/core/Parsers/Shortcodes/PhpShortcode.php"
date:
enabled: true
path: "src/flextype/core/Parsers/Shortcodes/DateShortcode.php"
php:
enabled: true
path: "src/flextype/core/Parsers/Shortcodes/PhpShortcode.php"
raw:
enabled: true
path: "src/flextype/core/Parsers/Shortcodes/RawShortcode.php"
@@ -741,6 +646,85 @@ parsers:
type:
enabled: true
path: "src/flextype/core/Parsers/Shortcodes/TypeShortcode.php"
expressions:
cache:
enabled: true
string: ''
opening_variable_tag: "[["
closing_variable_tag: "]]"
opening_block_tag: "[%"
closing_block_tag: "%]"
opening_comment_tag: "[#"
closing_comment_tag: "#]"
expressions:
math:
enabled: true
class: "Flextype\\Parsers\\Expressions\\MathExpression"
date:
enabled: true
class: "Flextype\\Parsers\\Expressions\\DateExpression"
actions:
enabled: true
class: "Flextype\\Parsers\\Expressions\\ActionsExpression"
registry:
enabled: true
class: "Flextype\\Parsers\\Expressions\\RegistryExpression"
entries:
enabled: true
class: "Flextype\\Parsers\\Expressions\\EntriesExpression"
fetch:
enabled: true
has:
enabled: true
registry:
enabled: true
create:
enabled: false
move:
enabled: false
update:
enabled: false
delete:
enabled: false
fetch:
enabled: true
class: "Flextype\\Parsers\\Expressions\\FetchExpression"
filesystem:
enabled: true
class: "Flextype\\Parsers\\Expressions\\FilesystemExpression"
i18n:
enabled: true
class: "Flextype\\Parsers\\Expressions\\I18nExpression"
serializers:
enabled: true
class: "Flextype\\Parsers\\Expressions\\SerializersExpression"
parsers:
enabled: true
class: "Flextype\\Parsers\\Expressions\\ParsersExpression"
slugify:
enabled: true
class: "Flextype\\Parsers\\Expressions\\SlugifyExpression"
strings:
enabled: true
class: "Flextype\\Parsers\\Expressions\\StringsExpression"
collection:
enabled: true
class: "Flextype\\Parsers\\Expressions\\CollectionExpression"
csrf:
enabled: true
class: "Flextype\\Parsers\\Expressions\\CsrfExpression"
field:
enabled: true
class: "Flextype\\Parsers\\Expressions\\FieldExpression"
var:
enabled: true
class: "Flextype\\Parsers\\Expressions\\VarExpression"
const:
enabled: true
class: "Flextype\\Parsers\\Expressions\\ConstExpression"
url:
enabled: true
class: "Flextype\\Parsers\\Expressions\\UrlExpression"
# CORS
#

View File

@@ -1,18 +0,0 @@
<?php
use Flextype\Component\Filesystem\Filesystem;
use function Glowy\Filesystem\filesystem;
use function Flextype\entries;
beforeEach(function() {
filesystem()->directory(FLEXTYPE_PATH_PROJECT . '/entries')->create();
});
afterEach(function (): void {
filesystem()->directory(FLEXTYPE_PATH_PROJECT . '/entries')->delete();
});
test('field expression', function () {
entries()->create('field', ['test' => '[[ field("id") ]]']);
expect(entries()->fetch('field')['test'])->toBe('field');
});

View File

@@ -1,37 +0,0 @@
<?php
use Flextype\Component\Filesystem\Filesystem;
use function Glowy\Filesystem\filesystem;
use function Flextype\entries;
beforeEach(function() {
filesystem()->directory(FLEXTYPE_PATH_PROJECT . '/entries')->create();
});
afterEach(function (): void {
filesystem()->directory(FLEXTYPE_PATH_PROJECT . '/entries')->delete();
});
test('var + field expression', function () {
entries()->create('var', [
'title' => 'Foo',
'vars' => [
'foo' => 'Foo'
],
'test1' => '[[ var("foo") ]]',
'test2' => "[[ get('vars.foo', 'Foo') ]]",
'test3' => '[[ vars.foo ]]',
'test4' => '[[ set("bar", "Bar") ]][[ bar ]]',
'test5' => '[[ unset("bar") ]]',
'test6' => '[[ delete("bar") ]]',
'test7' => '[[ title ]] [[ get("title") ]]',
]);
expect(entries()->fetch('var')['test1'])->toBe('Foo');
expect(entries()->fetch('var')['test2'])->toBe('Foo');
expect(entries()->fetch('var')['test3'])->toBe('Foo');
expect(entries()->fetch('var')['test4'])->toBe('Bar');
expect(entries()->fetch('var')['test5'])->toBe('');
expect(entries()->fetch('var')['test6'])->toBe('');
expect(entries()->fetch('var')['test7'])->toBe('Foo Foo');
});

View File

@@ -33,9 +33,9 @@ test('entries expression', function () {
'test' => '(type:bool) [[ entries().delete("foo") ]]',
]);
registry()->set('flextype.settings.entries.expressions.entries.delete.enabled', true);
registry()->set('flextype.settings.parsers.expressions.expressions.entries.delete.enabled', true);
expect(entries()->fetch('delete')['test'])->toBeTrue();
registry()->set('flextype.settings.entries.expressions.entries.delete.enabled', false);
registry()->set('flextype.settings.parsers.expressions.expressions.entries.delete.enabled', false);
// copy
entries()->create('copy-foo');
@@ -43,9 +43,9 @@ test('entries expression', function () {
'test' => '(type:bool) [[ entries().copy("copy-foo", "copy-foo-2") ]]',
]);
registry()->set('flextype.settings.entries.expressions.entries.copy.enabled', true);
registry()->set('flextype.settings.parsers.expressions.expressions.entries.copy.enabled', true);
expect(entries()->fetch('copy')['test'])->toBeTrue();
registry()->set('flextype.settings.entries.expressions.entries.copy.enabled', false);
registry()->set('flextype.settings.parsers.expressions.expressions.entries.copy.enabled', false);
// move
entries()->create('move-foo');
@@ -53,9 +53,9 @@ test('entries expression', function () {
'test' => '(type:bool) [[ entries().move("move-foo", "move-foo-2") ]]',
]);
registry()->set('flextype.settings.entries.expressions.entries.move.enabled', true);
registry()->set('flextype.settings.parsers.expressions.expressions.entries.move.enabled', true);
expect(entries()->fetch('move')['test'])->toBeTrue();
registry()->set('flextype.settings.entries.expressions.entries.move.enabled', false);
registry()->set('flextype.settings.parsers.expressions.expressions.entries.move.enabled', false);
// update
entries()->create('update-foo');
@@ -63,8 +63,8 @@ test('entries expression', function () {
'test' => '(type:bool) [[ entries().update("update-foo", {"title": "Foo"}) ]]',
]);
registry()->set('flextype.settings.entries.expressions.entries.update.enabled', true);
registry()->set('flextype.settings.parsers.expressions.expressions.entries.update.enabled', true);
expect(entries()->fetch('update')['test'])->toBeTrue();
expect(entries()->fetch('update-foo')['title'])->toBe('Foo');
registry()->set('flextype.settings.entries.expressions.entries.update.enabled', false);
registry()->set('flextype.settings.parsers.expressions.expressions.entries.update.enabled', false);
});

View File

@@ -0,0 +1,49 @@
<?php
use Flextype\Component\Filesystem\Filesystem;
use function Glowy\Filesystem\filesystem;
use function Flextype\entries;
beforeEach(function() {
filesystem()->directory(FLEXTYPE_PATH_PROJECT . '/entries')->create();
});
afterEach(function (): void {
filesystem()->directory(FLEXTYPE_PATH_PROJECT . '/entries')->delete();
});
test('field expression', function () {
entries()->create('field', [
'title' => 'Title',
'_' => [
'foo' => 'Foo',
'level2' => [
'value' => 'Bar',
]
],
// Get
'test-get-1' => '[[ field("title") ]]',
'test-get-2' => '[[ title ]]',
'test-get-3' => '[[ _.foo ]]',
'test-get-4' => "[[ fields().get('_.foo') ]]",
'test-get-5' => "[[ fields().get('_.bar', 'Default') ]]",
// Set add Get
'test-set-1' => '[% fields().set("qwerty", "Qwerty") %]',
'test-set-2' => '[[ fields().get("qwerty") ]] [[qwerty ]] [[ qwerty]] [[qwerty]] [[ qwerty ]]',
// Delete
'test-delete-1' => '[% fields().delete("qwerty") %]',
]);
expect(entries()->fetch('field')['test-get-1'])->toBe('Title');
expect(entries()->fetch('field')['test-get-2'])->toBe('Title');
expect(entries()->fetch('field')['test-get-3'])->toBe('Foo');
expect(entries()->fetch('field')['test-get-4'])->toBe('Foo');
expect(entries()->fetch('field')['test-get-5'])->toBe('Default');
expect(entries()->fetch('field')['test-set-1'])->toBe('');
expect(entries()->fetch('field')['test-set-2'])->toBe('Qwerty Qwerty Qwerty Qwerty Qwerty');
expect(entries()->fetch('field')['test-delete-1'])->toBe('');
});

View File

@@ -31,9 +31,10 @@ test('entries shortcode', function () {
$this->assertTrue(entries()->create('blog-3', ['title' => 'Blog', 'category-cat' => "(entries fetch id:'categories/cat' field:'title2' default:'Foo' /)"]));
expect(entries()->fetch('blog-3')['category-cat'])->toBe('Foo');
$this->assertTrue(entries()->create('shop', ['vars' => ['id' => 'shop', 'options' => 'collection=true'], 'title' => 'Shop', 'products' => "@type[array] (entries fetch id:'(var:id)' options:'(var:options)' /)"]));
$this->assertTrue(entries()->create('shop', ['_vars' => ['id' => 'shop', 'options' => 'collection=true'], 'title' => 'Shop', 'products' => "@type[array] (entries fetch id:'(field:_vars.id)' options:'(field:_vars.options)' /)"]));
$this->assertTrue(entries()->create('shop/product-1', ['title' => 'Product 1']));
expect(count(entries()->fetch('shop')['products']))->toBe(1);
$this->assertTrue(entries()->create('shop/product-2', ['title' => 'Product 2']));
expect(count(entries()->fetch('shop')['products']))->toBe(2);
});
test('entries shortcode disabled', function () {

View File

@@ -15,8 +15,40 @@ afterEach(function () {
});
test('field shortcode', function () {
expect(entries()->create('foo', ['title' => '(field:id)']))->toBeTrue();
expect(entries()->fetch('foo')['title'])->toBe('foo');
expect(entries()->create('foo', [
'title' => 'Title',
// get
'test-get-1' => '(field:title)',
'test-get-2' => '(field get:title)',
'test-get-3' => '(field get:foo default:Foo)',
'test-get-4' => '(field get:foo)Foo(/field)',
// set
'test-set-1' => '(field set:bar1 value:Bar1)(field:bar1)',
'test-set-2' => '(field set:bar2)Bar2(/field)(field:bar2)',
'test-set-3' => '(field set:level1.level2.level3)Multilevel(/field)(field:level1.level2.level3)',
'test-set-4' => '(field set:_.foo)Foo(/field)(field:_.foo)',
// unset
'test-unset-1' => '(field unset:bar1)(field:bar1)',
// delete
'test-delete-1' => '(field delete:bar1)(field:bar1)',
]))->toBeTrue();
$foo = entries()->fetch('foo');
expect($foo['test-get-1'])->toBe('Title');
expect($foo['test-get-2'])->toBe('Title');
expect($foo['test-get-3'])->toBe('Foo');
expect($foo['test-get-4'])->toBe('Foo');
expect($foo['test-set-1'])->toBe('Bar1');
expect($foo['test-set-2'])->toBe('Bar2');
expect($foo['test-set-3'])->toBe('Multilevel');
expect($foo['test-set-4'])->toBe('Foo');
expect($foo['test-unset-1'])->toBe('');
expect($foo['test-delete-1'])->toBe('');
});
test('field shortcode disabled', function () {