From b61e71170ff80a83fcbb6e87a9fcc751fa9ca393 Mon Sep 17 00:00:00 2001 From: Gernot Leitgab <typo3@webentwickler.at> Date: Fri, 2 Sep 2016 20:59:26 +0200 Subject: [PATCH] [BUGFIX] Return null value instead of string 'NULL' 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/43627 Tested-by: TYPO3com <no-reply@typo3.com> Reviewed-by: Benni Mack <benni@typo3.org> Tested-by: Benni Mack <benni@typo3.org> Reviewed-by: Markus Klein <markus.klein@typo3.org> Tested-by: Markus Klein <markus.klein@typo3.org> --- .../Classes/Persistence/Generic/Backend.php | 26 ++++++++++--- .../Classes/Domain/Model/Blog.php | 23 ++++++++++++ .../TCA/tx_blogexample_domain_model_blog.php | 9 +++++ .../Private/Language/locallang_db.xml | 1 + .../Extensions/blog_example/ext_tables.sql | 1 + .../Tests/Functional/Persistence/AddTest.php | 37 +++++++++++++++++++ 6 files changed, 91 insertions(+), 6 deletions(-) diff --git a/typo3/sysext/extbase/Classes/Persistence/Generic/Backend.php b/typo3/sysext/extbase/Classes/Persistence/Generic/Backend.php index 02d0657b5c2a..e78954e00116 100644 --- a/typo3/sysext/extbase/Classes/Persistence/Generic/Backend.php +++ b/typo3/sysext/extbase/Classes/Persistence/Generic/Backend.php @@ -398,14 +398,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)) { @@ -677,7 +674,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); @@ -1123,4 +1120,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; + } } diff --git a/typo3/sysext/extbase/Tests/Functional/Fixtures/Extensions/blog_example/Classes/Domain/Model/Blog.php b/typo3/sysext/extbase/Tests/Functional/Fixtures/Extensions/blog_example/Classes/Domain/Model/Blog.php index 7a96e03ec68d..69c02e93640e 100644 --- a/typo3/sysext/extbase/Tests/Functional/Fixtures/Extensions/blog_example/Classes/Domain/Model/Blog.php +++ b/typo3/sysext/extbase/Tests/Functional/Fixtures/Extensions/blog_example/Classes/Domain/Model/Blog.php @@ -27,6 +27,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 * @@ -72,6 +79,14 @@ class Blog extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity $this->posts = new \TYPO3\CMS\Extbase\Persistence\ObjectStorage(); } + /** + * @return string + */ + public function getSubtitle() + { + return $this->subtitle; + } + /** * Sets this 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; + } } diff --git a/typo3/sysext/extbase/Tests/Functional/Fixtures/Extensions/blog_example/Configuration/TCA/tx_blogexample_domain_model_blog.php b/typo3/sysext/extbase/Tests/Functional/Fixtures/Extensions/blog_example/Configuration/TCA/tx_blogexample_domain_model_blog.php index c0611eae7cd7..716f43ad7bcb 100644 --- a/typo3/sysext/extbase/Tests/Functional/Fixtures/Extensions/blog_example/Configuration/TCA/tx_blogexample_domain_model_blog.php +++ b/typo3/sysext/extbase/Tests/Functional/Fixtures/Extensions/blog_example/Configuration/TCA/tx_blogexample_domain_model_blog.php @@ -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', diff --git a/typo3/sysext/extbase/Tests/Functional/Fixtures/Extensions/blog_example/Resources/Private/Language/locallang_db.xml b/typo3/sysext/extbase/Tests/Functional/Fixtures/Extensions/blog_example/Resources/Private/Language/locallang_db.xml index feeef2e08c96..50a05731ee4e 100644 --- a/typo3/sysext/extbase/Tests/Functional/Fixtures/Extensions/blog_example/Resources/Private/Language/locallang_db.xml +++ b/typo3/sysext/extbase/Tests/Functional/Fixtures/Extensions/blog_example/Resources/Private/Language/locallang_db.xml @@ -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> diff --git a/typo3/sysext/extbase/Tests/Functional/Fixtures/Extensions/blog_example/ext_tables.sql b/typo3/sysext/extbase/Tests/Functional/Fixtures/Extensions/blog_example/ext_tables.sql index e04333ad3141..7794b40693b9 100644 --- a/typo3/sysext/extbase/Tests/Functional/Fixtures/Extensions/blog_example/ext_tables.sql +++ b/typo3/sysext/extbase/Tests/Functional/Fixtures/Extensions/blog_example/ext_tables.sql @@ -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, diff --git a/typo3/sysext/extbase/Tests/Functional/Persistence/AddTest.php b/typo3/sysext/extbase/Tests/Functional/Persistence/AddTest.php index 1c91cc99c83d..eafa12c83532 100644 --- a/typo3/sysext/extbase/Tests/Functional/Persistence/AddTest.php +++ b/typo3/sysext/extbase/Tests/Functional/Persistence/AddTest.php @@ -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']); + } } -- GitLab