From 86c1956772ea7d6811807fcaca6d5bb2da1e5557 Mon Sep 17 00:00:00 2001 From: Daniel Siepmann <daniel.siepmann@typo3.org> Date: Mon, 27 Jan 2020 12:24:02 +0100 Subject: [PATCH] [FEATURE] Support bit-wise and in TypoScript checkIf Allows direct checks whether an expected bit is part of a bit set, e.g. in a stored checkbox or radio of a record. Resolves: #90213 Releases: master Change-Id: I2ff188c74b207376f5f44307f0a8a2e9514ea6d8 Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/63046 Tested-by: Georg Ringer <georg.ringer@gmail.com> Tested-by: TYPO3com <noreply@typo3.com> Tested-by: Stefan Froemken <froemken@gmail.com> Tested-by: Benni Mack <benni@typo3.org> Reviewed-by: Georg Ringer <georg.ringer@gmail.com> Reviewed-by: Stefan Froemken <froemken@gmail.com> Reviewed-by: Benni Mack <benni@typo3.org> --- ...213-SupportBitAndInTypoScriptStdWrapIf.rst | 38 +++++++++++++++++++ .../ContentObject/ContentObjectRenderer.php | 7 ++++ .../ContentObjectRendererTest.php | 34 +++++++++++++++++ 3 files changed, 79 insertions(+) create mode 100644 typo3/sysext/core/Documentation/Changelog/master/Feature-90213-SupportBitAndInTypoScriptStdWrapIf.rst diff --git a/typo3/sysext/core/Documentation/Changelog/master/Feature-90213-SupportBitAndInTypoScriptStdWrapIf.rst b/typo3/sysext/core/Documentation/Changelog/master/Feature-90213-SupportBitAndInTypoScriptStdWrapIf.rst new file mode 100644 index 000000000000..24a857ec0564 --- /dev/null +++ b/typo3/sysext/core/Documentation/Changelog/master/Feature-90213-SupportBitAndInTypoScriptStdWrapIf.rst @@ -0,0 +1,38 @@ +.. include:: ../../Includes.txt + +========================================================== +Feature: #90213 - Support bit and in TypoScript stdWrap_if +========================================================== + +See :issue:`90213` + +Description +=========== + +It is now possible to use :ts:`bitAnd` within TypoScript :ts:`if`. + +TYPO3 uses bits to store radio and checkboxes via TCA. +Without this feature one would need to check whether any possible bit value is in a +list. With this feature a simple comparison whether the expected value is part of the +bit set is possible. + +Example +======= + +An example usage could look like this: + +.. code-block:: ts + + hideDefaultLanguageOfPage = TEXT + hideDefaultLanguageOfPage { + value = 0 + value { + override = 1 + override.if { + bitAnd.field = l18n_cfg + value = 1 + } + } + } + +.. index:: ext:frontend, TypoScript, NotScanned diff --git a/typo3/sysext/frontend/Classes/ContentObject/ContentObjectRenderer.php b/typo3/sysext/frontend/Classes/ContentObject/ContentObjectRenderer.php index 81f52ad35629..d9b9e645790e 100644 --- a/typo3/sysext/frontend/Classes/ContentObject/ContentObjectRenderer.php +++ b/typo3/sysext/frontend/Classes/ContentObject/ContentObjectRenderer.php @@ -52,6 +52,7 @@ use TYPO3\CMS\Core\Service\FlexFormService; use TYPO3\CMS\Core\Service\MarkerBasedTemplateService; use TYPO3\CMS\Core\Site\SiteFinder; use TYPO3\CMS\Core\TimeTracker\TimeTracker; +use TYPO3\CMS\Core\Type\BitSet; use TYPO3\CMS\Core\TypoScript\Parser\TypoScriptParser; use TYPO3\CMS\Core\TypoScript\TypoScriptService; use TYPO3\CMS\Core\Utility\ArrayUtility; @@ -3076,6 +3077,12 @@ class ContentObjectRenderer implements LoggerAwareInterface $flag = false; } } + if (isset($conf['bitAnd']) || isset($conf['bitAnd.'])) { + $number = isset($conf['bitAnd.']) ? trim($this->stdWrap($conf['bitAnd'], $conf['bitAnd.'])) : trim($conf['bitAnd']); + if ((new BitSet($number))->get($value) === false) { + $flag = false; + } + } } if ($conf['negate'] ?? false) { $flag = !$flag; diff --git a/typo3/sysext/frontend/Tests/Unit/ContentObject/ContentObjectRendererTest.php b/typo3/sysext/frontend/Tests/Unit/ContentObject/ContentObjectRendererTest.php index 323324df4ac5..9ec5e0714771 100644 --- a/typo3/sysext/frontend/Tests/Unit/ContentObject/ContentObjectRendererTest.php +++ b/typo3/sysext/frontend/Tests/Unit/ContentObject/ContentObjectRendererTest.php @@ -5898,6 +5898,40 @@ class ContentObjectRendererTest extends UnitTestCase self::assertSame($stop, $subject->_get('stopRendering')[1]); } + /** + * Data provider for checkIf. + * + * @return array [$expect, $conf] + */ + public function checkIfDataProvider(): array + { + return [ + 'true bitAnd the same' => [true, ['bitAnd' => '4', 'value' => '4']], + 'true bitAnd included' => [true, ['bitAnd' => '6', 'value' => '4']], + 'false bitAnd' => [false, ['bitAnd' => '4', 'value' => '3']], + 'negate true bitAnd the same' => [false, ['bitAnd' => '4', 'value' => '4', 'negate' => '1']], + 'negate true bitAnd included' => [false, ['bitAnd' => '6', 'value' => '4', 'negate' => '1']], + 'negate false bitAnd' => [true, ['bitAnd' => '3', 'value' => '4', 'negate' => '1']], + ]; + } + + /** + * Check if checkIf works properly. + * + * @test + * @dataProvider checkIfDataProvider + * @param bool $expect Whether result should be true or false. + * @param array $conf TypoScript configuration to pass into checkIf + */ + public function checkIf(bool $expect, array $conf) + { + $subject = $this->getAccessibleMock( + ContentObjectRenderer::class, + ['stdWrap'] + ); + self::assertSame($expect, $subject->checkIf($conf)); + } + /** * Data provider for stdWrap_ifBlank. * -- GitLab