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 0000000000000000000000000000000000000000..24a857ec05644d87ee9f02ad33209e0c92656495 --- /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 81f52ad356297e83e5bea1b3b841f2a55bdade04..d9b9e645790e870e6a1b2cb48f8cc51e62751548 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 323324df4ac55b36e38038f415b1dac2ab8d1969..9ec5e07147711df60661274e102e759661c75c20 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. *