diff --git a/src/ViewHelpers/Expression/CastViewHelper.php b/src/ViewHelpers/Expression/CastViewHelper.php index 45ab8ec77..27acb0e28 100644 --- a/src/ViewHelpers/Expression/CastViewHelper.php +++ b/src/ViewHelpers/Expression/CastViewHelper.php @@ -13,7 +13,7 @@ use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper; /** - * Math Expression ViewHelper, seconds as expression type + * Cast Expression ViewHelper, seconds as expression type */ class CastViewHelper extends AbstractViewHelper implements ExpressionComponentInterface { @@ -31,7 +31,7 @@ public function __construct(iterable $parts = []) protected function initializeArguments() { $this->registerArgument('subject', 'mixed', 'Numeric first value to calculate', true); - $this->registerArgument('as', 'string', 'Type to cast, valid values are: integer, boolean, string, float and array', true); + $this->registerArgument('as', 'string', 'Type to cast, valid values are: integer, boolean, string, float, array and DateTime', true); } public function evaluate(RenderingContextInterface $renderingContext) diff --git a/src/ViewHelpers/Expression/NullcoalescingViewHelper.php b/src/ViewHelpers/Expression/NullcoalescingViewHelper.php new file mode 100644 index 000000000..8dab44291 --- /dev/null +++ b/src/ViewHelpers/Expression/NullcoalescingViewHelper.php @@ -0,0 +1,85 @@ +parts = $parts; + } + + protected function initializeArguments() + { + $this->registerArgument('a', 'mixed', 'Anythong that can have a value or null', true); + $this->registerArgument('b', 'mixed', 'Fallback value', true); + } + + public static function matches(array $parts): bool + { + var_dump('matches'); + return isset($parts[2]) && strpos('??', $parts[1]) !== false; + } + + /** + * @param RenderingContextInterface $renderingContext + * @param string $expression + * @param array $matches + * @return mixed + */ + public function evaluate(RenderingContextInterface $renderingContext) + { + $arguments = $this->getArguments()->setRenderingContext($renderingContext)->getArrayCopy(); + $parts = empty($this->parts) ? [$arguments['a'], $arguments['b']] : $this->parts; + + var_dump($parts); + var_dump($renderingContext->getVariableProvider()->getAll()); + + foreach($parts as $part) { + $value = static::getTemplateVariableOrValueItself($part, $renderingContext); + var_dump($value); + if(!is_null($value)) { + return $value; + } + } + + return null; + } + + + /** + * @param mixed $candidate + * @param RenderingContextInterface $renderingContext + * @return mixed + */ + protected static function getTemplateVariableOrValueItself($candidate, RenderingContextInterface $renderingContext) + { + if(is_null($candidate)) { + return null; + } + if (is_numeric($candidate)) { + return $candidate; + } + + if (mb_strpos($candidate, '\'') === 0) { + return trim($candidate, '\''); + } elseif (mb_strpos($candidate, '"') === 0) { + return trim($candidate, '"'); + } + return $renderingContext->getVariableProvider()->get($candidate); + } +} diff --git a/tests/Unit/Core/Rendering/RenderingContextFixture.php b/tests/Unit/Core/Rendering/RenderingContextFixture.php index 3c6057065..fd4f1cc6a 100644 --- a/tests/Unit/Core/Rendering/RenderingContextFixture.php +++ b/tests/Unit/Core/Rendering/RenderingContextFixture.php @@ -11,6 +11,7 @@ use TYPO3Fluid\Fluid\Core\ErrorHandler\ErrorHandlerInterface; use TYPO3Fluid\Fluid\Core\ErrorHandler\StandardErrorHandler; use TYPO3Fluid\Fluid\Core\Parser\Configuration; +use TYPO3Fluid\Fluid\ViewHelpers\Expression\NullcoalescingViewHelper; use TYPO3Fluid\Fluid\Core\Parser\TemplateParser; use TYPO3Fluid\Fluid\Core\Rendering\FluidRenderer; use TYPO3Fluid\Fluid\Core\Rendering\FluidRendererInterface; @@ -71,6 +72,7 @@ class RenderingContextFixture implements RenderingContextInterface MathViewHelper::class, CastViewHelper::class, IfViewHelper::class, + NullcoalescingViewHelper::class, ]; /** diff --git a/tests/Unit/ViewHelpers/Expression/NullcoalescingViewHelperTest.php b/tests/Unit/ViewHelpers/Expression/NullcoalescingViewHelperTest.php new file mode 100644 index 000000000..3518c8dbe --- /dev/null +++ b/tests/Unit/ViewHelpers/Expression/NullcoalescingViewHelperTest.php @@ -0,0 +1,59 @@ +setVariableProvider(new StandardVariableProvider($variables)); + $result = NullcoalescingViewHelper::evaluateExpression($renderingContext, $expression, []); + $this->assertEquals($expected, $result); + } + + public function getStandardTestValues(): array + { + + $context = new RenderingContextFixture(); + foreach(['a' => 'a', 'b' => 'b', 'c' => 'c'] as $key => $value) { + $context->getVariableProvider()->add($key, $value); + } + + return [ + 'value not null, default integer' => ['a', $context, ['a' => 'a', 'b' => 1]], + 'value null, default to 1' => [1, $context, ['d' => null, 'b' => 1]], + 'value not null, default other value' => ['a', $context, ['a' => 'a', 'b' => 'b']], + 'value null, default to other value' => ['b', $context, ['d' => null, 'b' => 'b']], + 'value not null, default other value with additional fallback object' => ['a', $context, ['a' => 'a', 'b' => 'b', 'c' => 'c']], + 'value null, default other value with additional fallback object' => ['b', $context, ['d' => null, 'b' => 'b', 'c' => 'c']], + 'value null, default other value also null, with additional fallback object' => ['c', $context, ['d' => null, ['e' => null, 'c' => 'c']]], + 'value null, default other value also null, with additional fallback string (single quote)' => ['test', $context, ['d' => null, 'e' => null], [new TextNode('\'test\'')]], + 'value null, default other value also null, with additional fallback string (double quote)' => ['test', $context, ['d' => null, 'e' => null], [new TextNode('"test"')]], + ]; + } +}