[BUGFIX] Return null value instead of string 'NULL' 77/54877/2
authorGernot Leitgab <typo3@webentwickler.at>
Fri, 2 Sep 2016 18:59:26 +0000 (20:59 +0200)
committerMarkus Klein <markus.klein@typo3.org>
Wed, 29 Nov 2017 21:34:15 +0000 (22:34 +0100)
Add local getPlainValue method in persistence backend, so a
null value instead of string 'NULL' is written to database.

Resolves: #68994
Related: #57255
Releases: master, 8.7
Change-Id: Idb61caabf5115da4bb818d2ed8bb4faa16f5df2c
Reviewed-on: https://review.typo3.org/54877
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Markus Klein <markus.klein@typo3.org>
Tested-by: Markus Klein <markus.klein@typo3.org>
typo3/sysext/extbase/Classes/Persistence/Generic/Backend.php
typo3/sysext/extbase/Tests/Functional/Fixtures/Extensions/blog_example/Classes/Domain/Model/Blog.php
typo3/sysext/extbase/Tests/Functional/Fixtures/Extensions/blog_example/Configuration/TCA/tx_blogexample_domain_model_blog.php
typo3/sysext/extbase/Tests/Functional/Fixtures/Extensions/blog_example/Resources/Private/Language/locallang_db.xml
typo3/sysext/extbase/Tests/Functional/Fixtures/Extensions/blog_example/ext_tables.sql
typo3/sysext/extbase/Tests/Functional/Persistence/AddTest.php

index 5217ec0..f430a0f 100644 (file)
@@ -397,14 +397,11 @@ class Backend implements \TYPO3\CMS\Extbase\Persistence\Generic\BackendInterface
                     if ($propertyValue->_isNew()) {
                         $this->insertObject($propertyValue, $object, $propertyName);
                     }
-                    // Check explicitly for NULL, as getPlainValue would convert this to 'NULL'
-                    $row[$columnMap->getColumnName()] = $propertyValue !== null
-                        ? $this->dataMapper->getPlainValue($propertyValue)
-                        : null;
+                    $row[$columnMap->getColumnName()] = $this->getPlainValue($propertyValue);
                 }
                 $queue[] = $propertyValue;
             } elseif ($object->_isNew() || $object->_isDirty($propertyName)) {
-                $row[$columnMap->getColumnName()] = $this->dataMapper->getPlainValue($propertyValue, $columnMap);
+                $row[$columnMap->getColumnName()] = $this->getPlainValue($propertyValue, $columnMap);
             }
         }
         if (!empty($row)) {
@@ -676,7 +673,7 @@ class Backend implements \TYPO3\CMS\Extbase\Persistence\Generic\BackendInterface
                     $row[$columnMap->getColumnName()] = 0;
                 }
             } elseif ($propertyValue !== null) {
-                $row[$columnMap->getColumnName()] = $this->dataMapper->getPlainValue($propertyValue, $columnMap);
+                $row[$columnMap->getColumnName()] = $this->getPlainValue($propertyValue, $columnMap);
             }
         }
         $this->addCommonFieldsToRow($object, $row);
@@ -1122,4 +1119,21 @@ class Backend implements \TYPO3\CMS\Extbase\Persistence\Generic\BackendInterface
         $storagePidList = \TYPO3\CMS\Core\Utility\GeneralUtility::intExplode(',', $frameworkConfiguration['persistence']['storagePid']);
         return (int)$storagePidList[0];
     }
+
+    /**
+     * Returns a plain value
+     *
+     * i.e. objects are flattened out if possible.
+     * Checks explicitly for null values as DataMapper's getPlainValue would convert this to 'NULL'
+     *
+     * @param mixed $input The value that will be converted
+     * @param ColumnMap $columnMap Optional column map for retrieving the date storage format
+     * @return int|string|null
+     */
+    protected function getPlainValue($input, ColumnMap $columnMap = null)
+    {
+        return $input !== null
+            ? $this->dataMapper->getPlainValue($input, $columnMap)
+            : null;
+    }
 }
index 7a96e03..69c02e9 100644 (file)
@@ -28,6 +28,13 @@ class Blog extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity
     protected $title = '';
 
     /**
+     * The blog's subtitle
+     *
+     * @var string
+     */
+    protected $subtitle;
+
+    /**
      * A short description of the blog
      *
      * @var string
@@ -73,6 +80,14 @@ class Blog extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity
     }
 
     /**
+     * @return string
+     */
+    public function getSubtitle()
+    {
+        return $this->subtitle;
+    }
+
+    /**
      * Sets this blog's title
      *
      * @param string $title The blog's title
@@ -225,4 +240,12 @@ class Blog extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity
     {
         return $this->administrator;
     }
+
+    /**
+     * @param ?string $subtitle
+     */
+    public function setSubtitle($subtitle)
+    {
+        $this->subtitle = $subtitle;
+    }
 }
index c0611ea..716f43a 100644 (file)
@@ -107,6 +107,15 @@ return [
                 'max' => 256
             ]
         ],
+        'subtitle' => [
+            'label' => 'LLL:EXT:blog_example/Resources/Private/Language/locallang_db.xml:tx_blogexample_domain_model_blog.subtitle',
+            'config' => [
+                'type' => 'input',
+                'size' => 20,
+                'eval' => 'trim',
+                'max' => 256
+            ]
+        ],
         'description' => [
             'exclude' => true,
             'label' => 'LLL:EXT:blog_example/Resources/Private/Language/locallang_db.xml:tx_blogexample_domain_model_blog.description',
index feeef2e..50a0573 100644 (file)
@@ -15,6 +15,7 @@
                        <label index="tx_blogexample_domain_model_post">Post</label>
                        <label index="tx_blogexample_domain_model_post.blog">Related to</label>
                        <label index="tx_blogexample_domain_model_post.title">Title</label>
+                       <label index="tx_blogexample_domain_model_post.subtitle">Title</label>
                        <label index="tx_blogexample_domain_model_post.date">Date</label>
                        <label index="tx_blogexample_domain_model_post.author">Author</label>
                        <label index="tx_blogexample_domain_model_post.content">Content</label>
index e04333a..7794b40 100644 (file)
@@ -6,6 +6,7 @@ CREATE TABLE tx_blogexample_domain_model_blog (
        pid int(11) DEFAULT '0' NOT NULL,
 
        title varchar(255) DEFAULT '' NOT NULL,
+       subtitle varchar(255) DEFAULT '',
        description text NOT NULL,
        logo tinyblob NOT NULL,
        administrator int(11) DEFAULT '0' NOT NULL,
index 1c91cc9..eafa12c 100644 (file)
@@ -146,4 +146,41 @@ class AddTest extends \TYPO3\TestingFramework\Core\Functional\FunctionalTestCase
             ->fetch();
         $this->assertEquals(-1, $newBlogRecord['sys_language_uid']);
     }
+
+    /**
+    * @test
+    */
+    public function addObjectSetsNullAsNullForSimpleTypes()
+    {
+        $newBlogTitle = 'aDi1oogh';
+        $newBlog = $this->objectManager->get(\ExtbaseTeam\BlogExample\Domain\Model\Blog::class);
+        $newBlog->setTitle($newBlogTitle);
+        $newBlog->setSubtitle('subtitle');
+
+        /** @var \ExtbaseTeam\BlogExample\Domain\Repository\BlogRepository $blogRepository */
+        $this->blogRepository->add($newBlog);
+        $this->persistentManager->persistAll();
+
+        // make sure null can be set explicitly
+        $insertedBlog = $this->blogRepository->findByUid(1);
+        $insertedBlog->setSubtitle(null);
+        $this->blogRepository->update($insertedBlog);
+        $this->persistentManager->persistAll();
+
+        $queryBuilder = (new ConnectionPool())->getQueryBuilderForTable('tx_blogexample_domain_model_blog');
+        $queryBuilder->getRestrictions()
+            ->removeAll();
+        $newBlogRecord = $queryBuilder
+            ->select('*')
+            ->from('tx_blogexample_domain_model_blog')
+            ->where(
+                $queryBuilder->expr()->eq(
+                    'subtitle',
+                    $queryBuilder->createNamedParameter($newBlogTitle, \PDO::PARAM_STR)
+                )
+            )
+            ->execute()
+            ->fetch();
+        $this->assertNull($newBlogRecord['subtitle']);
+    }
 }