From 8a16e93cb825553f3a6fcf18b9d64c13ce2354d0 Mon Sep 17 00:00:00 2001
From: Nikita Hovratov <nikita.h@live.de>
Date: Mon, 31 Jul 2023 17:38:10 +0200
Subject: [PATCH] [BUGFIX] Stabilize AbstractDomainObject _isDirty check
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Accessing static properties as non-static has always
triggered a notice in PHP. However, since PHP 8.0
accessing undefined properties (which always comes with
the former notice) is now a warning. This will be
caught by the error handler in debug mode.

To fix this, the more robust _getProperty method is
backported from #100120 and used in the _isDirty method.

Resolves: #101488
Related: #100120
Releases: 11.5
Change-Id: I5f9ccb411f02f0dcc164d0d14917ecd631dc1178
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/80280
Reviewed-by: Oliver Klee <typo3-coding@oliverklee.de>
Tested-by: core-ci <typo3@b13.com>
Tested-by: Oliver Klee <typo3-coding@oliverklee.de>
Tested-by: Stefan Bürk <stefan@buerk.tech>
Reviewed-by: Stefan Bürk <stefan@buerk.tech>
---
 .../Classes/DomainObject/AbstractDomainObject.php        | 6 ++++--
 .../extbase/Tests/Functional/Persistence/IsDirtyTest.php | 9 +++++++++
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/typo3/sysext/extbase/Classes/DomainObject/AbstractDomainObject.php b/typo3/sysext/extbase/Classes/DomainObject/AbstractDomainObject.php
index 1f0ad9f33634..9c391c366123 100644
--- a/typo3/sysext/extbase/Classes/DomainObject/AbstractDomainObject.php
+++ b/typo3/sysext/extbase/Classes/DomainObject/AbstractDomainObject.php
@@ -128,7 +128,9 @@ abstract class AbstractDomainObject implements DomainObjectInterface, ObjectMoni
      */
     public function _getProperty(string $propertyName)
     {
-        return $this->{$propertyName};
+        return $this->_hasProperty($propertyName) && isset($this->{$propertyName})
+            ? $this->{$propertyName}
+            : null;
     }
 
     /**
@@ -262,7 +264,7 @@ abstract class AbstractDomainObject implements DomainObjectInterface, ObjectMoni
                 }
             }
         } else {
-            if ($this->isPropertyDirty($this->_getCleanProperty($propertyName), $this->{$propertyName}) === true) {
+            if ($this->isPropertyDirty($this->_getCleanProperty($propertyName), $this->_getProperty($propertyName)) === true) {
                 return true;
             }
         }
diff --git a/typo3/sysext/extbase/Tests/Functional/Persistence/IsDirtyTest.php b/typo3/sysext/extbase/Tests/Functional/Persistence/IsDirtyTest.php
index 15b90eefa68e..1fcea447f898 100644
--- a/typo3/sysext/extbase/Tests/Functional/Persistence/IsDirtyTest.php
+++ b/typo3/sysext/extbase/Tests/Functional/Persistence/IsDirtyTest.php
@@ -133,4 +133,13 @@ class IsDirtyTest extends FunctionalTestCase
         $updatedBlogOne = $this->blogRepository->findByUid(3);
         self::assertSame($updatedBlogOne->getAdministrator()->getUid(), $blogTwo->getAdministrator()->getUid());
     }
+
+    /**
+     * @test
+     */
+    public function undefinedPropertyIsAlwaysClean(): void
+    {
+        $blogOne = $this->blogRepository->findByUid(1);
+        self::assertFalse($blogOne->_isDirty('undefinedProperty'));
+    }
 }
-- 
GitLab