From 1350e2b8b35159f44e3930c3ae0a59a1f35839a2 Mon Sep 17 00:00:00 2001
From: Oliver Bartsch <bo@cedev.de>
Date: Thu, 21 Mar 2024 18:04:40 +0100
Subject: [PATCH] [BUGFIX] Respect cross classes when removing restrictions
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

When removeByType is used to remove restrictions
from the container, it is now ensured that also
cross classes are properly respected.

Resolves: #103456
Releases: main, 12.4
Change-Id: I4841fe1cba7388358771cf01ee220afa4482349a
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/83562
Tested-by: Stefan Bürk <stefan@buerk.tech>
Reviewed-by: Oliver Bartsch <bo@cedev.de>
Tested-by: Oliver Bartsch <bo@cedev.de>
Tested-by: core-ci <typo3@b13.com>
Tested-by: Benni Mack <benni@typo3.org>
Reviewed-by: Benni Mack <benni@typo3.org>
Reviewed-by: Stefan Bürk <stefan@buerk.tech>
---
 .../Restriction/AbstractRestrictionContainer.php  | 15 ++++++++++++++-
 .../AbstractRestrictionContainerTest.php          | 15 +++++++++++++++
 2 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/typo3/sysext/core/Classes/Database/Query/Restriction/AbstractRestrictionContainer.php b/typo3/sysext/core/Classes/Database/Query/Restriction/AbstractRestrictionContainer.php
index ee5e58b392de..18b2dee69197 100644
--- a/typo3/sysext/core/Classes/Database/Query/Restriction/AbstractRestrictionContainer.php
+++ b/typo3/sysext/core/Classes/Database/Query/Restriction/AbstractRestrictionContainer.php
@@ -69,7 +69,20 @@ abstract class AbstractRestrictionContainer implements QueryRestrictionContainer
      */
     public function removeByType(string $restrictionType): QueryRestrictionContainerInterface
     {
-        unset($this->restrictions[$restrictionType], $this->enforcedRestrictions[$restrictionType]);
+        foreach ($this->restrictions as $type => $instance) {
+            if ($instance instanceof $restrictionType) {
+                unset($this->restrictions[$type]);
+                break;
+            }
+        }
+
+        foreach ($this->enforcedRestrictions as $type => $instance) {
+            if ($instance instanceof $restrictionType) {
+                unset($this->enforcedRestrictions[$type]);
+                break;
+            }
+        }
+
         return $this;
     }
 
diff --git a/typo3/sysext/core/Tests/Unit/Database/Query/Restriction/AbstractRestrictionContainerTest.php b/typo3/sysext/core/Tests/Unit/Database/Query/Restriction/AbstractRestrictionContainerTest.php
index e2bf7c4a4c2c..e15016e6b043 100644
--- a/typo3/sysext/core/Tests/Unit/Database/Query/Restriction/AbstractRestrictionContainerTest.php
+++ b/typo3/sysext/core/Tests/Unit/Database/Query/Restriction/AbstractRestrictionContainerTest.php
@@ -19,6 +19,7 @@ namespace TYPO3\CMS\Core\Tests\Unit\Database\Query\Restriction;
 
 use PHPUnit\Framework\Attributes\Test;
 use TYPO3\CMS\Core\Database\Query\Expression\CompositeExpression;
+use TYPO3\CMS\Core\Database\Query\Restriction\HiddenRestriction;
 use TYPO3\CMS\Core\Tests\Unit\Database\Mocks\InstantiatableAbstractRestrictionContainer;
 use TYPO3\CMS\Core\Tests\Unit\Database\Mocks\MockEnforceableQueryRestriction;
 use TYPO3\CMS\Core\Tests\Unit\Database\Mocks\MockQueryRestriction;
@@ -56,6 +57,20 @@ final class AbstractRestrictionContainerTest extends AbstractRestrictionTestCase
         self::assertSame('', (string)$expression);
     }
 
+    #[Test]
+    public function crossClassWillBeRemovedWhenRemovedByType(): void
+    {
+        $restriction = new class () extends HiddenRestriction {};
+
+        $subject = new InstantiatableAbstractRestrictionContainer();
+        $subject->add($restriction);
+        $subject->removeByType(HiddenRestriction::class);
+
+        $GLOBALS['TCA']['aTable']['ctrl']['enablecolumns']['disabled'] = 'hidden';
+        $expression = $subject->buildExpression(['aTable' => 'aTable'], $this->expressionBuilder);
+        self::assertSame('', (string)$expression);
+    }
+
     #[Test]
     public function enforceableRestrictionsWillBeRemovedWhenRemovedByTypeAndRemovedAllIsAdditionallyCalled(): void
     {
-- 
GitLab