[TASK] Doctrine: Migrate DatabaseSystemLanguageRows 10/49210/5
authorWouter Wolters <typo3@wouterwolters.nl>
Tue, 26 Jul 2016 14:41:55 +0000 (16:41 +0200)
committerChristian Kuhn <lolli@schwarzbu.ch>
Fri, 29 Jul 2016 10:47:50 +0000 (12:47 +0200)
Resolves: #77260
Releases: master
Change-Id: I035ccb084841966492b8c6fada43aff6c313af5b
Reviewed-on: https://review.typo3.org/49210
Tested-by: Bamboo TYPO3com <info@typo3.com>
Reviewed-by: Mathias Schreiber <mathias.schreiber@wmdb.de>
Tested-by: Mathias Schreiber <mathias.schreiber@wmdb.de>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
typo3/sysext/backend/Classes/Form/FormDataProvider/DatabaseSystemLanguageRows.php
typo3/sysext/backend/Tests/Unit/Form/FormDataProvider/DatabaseSystemLanguageRowsTest.php

index 817023d..29ba560 100644 (file)
@@ -15,7 +15,7 @@ namespace TYPO3\CMS\Backend\Form\FormDataProvider;
  */
 
 use TYPO3\CMS\Backend\Form\FormDataProviderInterface;
-use TYPO3\CMS\Core\Database\DatabaseConnection;
+use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Messaging\FlashMessage;
 use TYPO3\CMS\Core\Messaging\FlashMessageService;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -35,7 +35,6 @@ class DatabaseSystemLanguageRows implements FormDataProviderInterface
      */
     public function addData(array $result)
     {
-        $database = $this->getDatabase();
         $languageService = $this->getLanguageService();
 
         $pageTs = $result['pageTsConfig'];
@@ -69,28 +68,26 @@ class DatabaseSystemLanguageRows implements FormDataProviderInterface
             ],
         ];
 
-        $dbRows = $database->exec_SELECTgetRows(
-            'uid,title,language_isocode,flag',
-            'sys_language',
-            'pid=0'
-        );
+        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
+            ->getQueryBuilderForTable('sys_language');
 
-        if ($dbRows === null) {
-            throw new \UnexpectedValueException(
-                'Database query error ' . $database->sql_error(),
-                1438170741
-            );
-        }
+        $queryBuilder->getRestrictions()->removeAll();
+
+        $queryResult = $queryBuilder
+            ->select('uid', 'title', 'language_isocode', 'flag')
+            ->from('sys_language')
+            ->where($queryBuilder->expr()->eq('pid', 0))
+            ->execute();
 
-        foreach ($dbRows as $dbRow) {
-            $uid = $dbRow['uid'];
+        while ($row = $queryResult->fetch()) {
+            $uid = $row['uid'];
             $languageRows[$uid] = [
                 'uid' => $uid,
-                'title' => $dbRow['title'],
-                'flagIconIdentifier' => 'flags-' . $dbRow['flag'],
+                'title' => $row['title'],
+                'flagIconIdentifier' => 'flags-' . $row['flag'],
             ];
-            if (!empty($dbRow['language_isocode'])) {
-                $languageRows[$uid]['iso'] = $dbRow['language_isocode'];
+            if (!empty($row['language_isocode'])) {
+                $languageRows[$uid]['iso'] = $row['language_isocode'];
             } else {
                 // No iso code could be found. This is currently possible in the system but discouraged.
                 // So, code within FormEngine has to be suited to work with an empty iso code. However,
@@ -102,7 +99,7 @@ class DatabaseSystemLanguageRows implements FormDataProviderInterface
                 // @todo: since the rest of the FormEngine code does not rely on iso code?
                 $message = sprintf(
                     $languageService->sL('LLL:EXT:lang/locallang_core.xlf:error.missingLanguageIsocode'),
-                    $dbRow['title'],
+                    $row['title'],
                     $uid
                 );
                 /** @var FlashMessage $flashMessage */
@@ -126,14 +123,6 @@ class DatabaseSystemLanguageRows implements FormDataProviderInterface
     }
 
     /**
-     * @return DatabaseConnection
-     */
-    protected function getDatabase()
-    {
-        return $GLOBALS['TYPO3_DB'];
-    }
-
-    /**
      * @return LanguageService
      */
     protected function getLanguageService()
index 70959a3..b8e34cc 100644 (file)
@@ -14,10 +14,14 @@ namespace TYPO3\CMS\Backend\Tests\Unit\Form\FormDataProvider;
  * The TYPO3 project - inspiring people to share!
  */
 
+use Doctrine\DBAL\Driver\Statement;
 use Prophecy\Argument;
 use Prophecy\Prophecy\ObjectProphecy;
 use TYPO3\CMS\Backend\Form\FormDataProvider\DatabaseSystemLanguageRows;
-use TYPO3\CMS\Core\Database\DatabaseConnection;
+use TYPO3\CMS\Core\Database\ConnectionPool;
+use TYPO3\CMS\Core\Database\Query\Expression\ExpressionBuilder;
+use TYPO3\CMS\Core\Database\Query\QueryBuilder;
+use TYPO3\CMS\Core\Database\Query\Restriction\QueryRestrictionContainerInterface;
 use TYPO3\CMS\Core\Messaging\FlashMessage;
 use TYPO3\CMS\Core\Messaging\FlashMessageQueue;
 use TYPO3\CMS\Core\Messaging\FlashMessageService;
@@ -34,10 +38,6 @@ class DatabaseSystemLanguageRowsTest extends UnitTestCase
      * @var DatabaseSystemLanguageRows
      */
     protected $subject;
-    /**
-     * @var DatabaseConnection | ObjectProphecy
-     */
-    protected $dbProphecy;
 
     /**
      * @var array A backup of registered singleton instances
@@ -47,8 +47,6 @@ class DatabaseSystemLanguageRowsTest extends UnitTestCase
     protected function setUp()
     {
         $this->singletonInstances = GeneralUtility::getSingletonInstances();
-        $this->dbProphecy = $this->prophesize(DatabaseConnection::class);
-        $GLOBALS['TYPO3_DB'] = $this->dbProphecy->reveal();
         $languageService = $this->prophesize(LanguageService::class);
         $GLOBALS['LANG'] = $languageService->reveal();
         $languageService->sL(Argument::cetera())->willReturnArgument(0);
@@ -65,18 +63,6 @@ class DatabaseSystemLanguageRowsTest extends UnitTestCase
     /**
      * @test
      */
-    public function addDataThrowsExceptionOnDatabaseError()
-    {
-        $this->dbProphecy->exec_SELECTgetRows(Argument::cetera())->willReturn(null);
-        $this->dbProphecy->sql_error(Argument::cetera())->willReturn(null);
-        $this->expectException(\UnexpectedValueException::class);
-        $this->expectExceptionCode(1438170741);
-        $this->subject->addData([]);
-    }
-
-    /**
-     * @test
-     */
     public function addDataSetsDefaultLanguageAndAllEntries()
     {
         $expected = [
@@ -95,7 +81,31 @@ class DatabaseSystemLanguageRowsTest extends UnitTestCase
                 ],
             ],
         ];
-        $this->dbProphecy->exec_SELECTgetRows(Argument::cetera())->willReturn([]);
+
+        // Prophecies and revelations for a lot of the database stack classes
+        $queryBuilderProphecy = $this->prophesize(QueryBuilder::class);
+        $queryBuilderRevelation = $queryBuilderProphecy->reveal();
+        $connectionPoolProphecy = $this->prophesize(ConnectionPool::class);
+        $queryRestrictionContainerProphecy = $this->prophesize(QueryRestrictionContainerInterface::class);
+        $queryRestrictionContainerRevelation = $queryRestrictionContainerProphecy->reveal();
+        $expressionBuilderProphecy = $this->prophesize(ExpressionBuilder::class);
+        $statementProphecy = $this->prophesize(Statement::class);
+
+        // Register connection pool revelation in framework, this is the entry point used by system unter tetst
+        GeneralUtility::addInstance(ConnectionPool::class, $connectionPoolProphecy->reveal());
+
+        // Simulate method call flow on database objects and verify correct query is built
+        $connectionPoolProphecy->getQueryBuilderForTable('sys_language')->shouldBeCalled()->willReturn($queryBuilderRevelation);
+        $queryRestrictionContainerProphecy->removeAll()->shouldBeCalled()->willReturn($queryRestrictionContainerRevelation);
+        $queryBuilderProphecy->getRestrictions()->shouldBeCalled()->willReturn($queryRestrictionContainerRevelation);
+        $queryBuilderProphecy->select('uid', 'title', 'language_isocode', 'flag')->shouldBeCalled()->willReturn($queryBuilderRevelation);
+        $queryBuilderProphecy->from('sys_language')->shouldBeCalled()->willReturn($queryBuilderRevelation);
+        $queryBuilderProphecy->expr()->shouldBeCalled()->willReturn($expressionBuilderProphecy->reveal());
+        $expressionBuilderProphecy->eq('pid', 0)->shouldBeCalled()->willReturn('pid = 0');
+        $queryBuilderProphecy->where('pid = 0')->shouldBeCalled()->willReturn($queryBuilderRevelation);
+        $queryBuilderProphecy->execute()->shouldBeCalled()->willReturn($statementProphecy->reveal());
+        $statementProphecy->fetch()->shouldBeCalledTimes(1)->willReturn(false);
+
         $this->assertSame($expected, $this->subject->addData([]));
     }
 
@@ -113,7 +123,31 @@ class DatabaseSystemLanguageRowsTest extends UnitTestCase
                 ]
             ],
         ];
-        $this->dbProphecy->exec_SELECTgetRows(Argument::cetera())->willReturn([]);
+
+        // Prophecies and revelations for a lot of the database stack classes
+        $queryBuilderProphecy = $this->prophesize(QueryBuilder::class);
+        $queryBuilderRevelation = $queryBuilderProphecy->reveal();
+        $connectionPoolProphecy = $this->prophesize(ConnectionPool::class);
+        $queryRestrictionContainerProphecy = $this->prophesize(QueryRestrictionContainerInterface::class);
+        $queryRestrictionContainerRevelation = $queryRestrictionContainerProphecy->reveal();
+        $expressionBuilderProphecy = $this->prophesize(ExpressionBuilder::class);
+        $statementProphecy = $this->prophesize(Statement::class);
+
+        // Register connection pool revelation in framework, this is the entry point used by system unter tetst
+        GeneralUtility::addInstance(ConnectionPool::class, $connectionPoolProphecy->reveal());
+
+        // Simulate method call flow on database objects and verify correct query is built
+        $connectionPoolProphecy->getQueryBuilderForTable('sys_language')->shouldBeCalled()->willReturn($queryBuilderRevelation);
+        $queryRestrictionContainerProphecy->removeAll()->shouldBeCalled()->willReturn($queryRestrictionContainerRevelation);
+        $queryBuilderProphecy->getRestrictions()->shouldBeCalled()->willReturn($queryRestrictionContainerRevelation);
+        $queryBuilderProphecy->select('uid', 'title', 'language_isocode', 'flag')->shouldBeCalled()->willReturn($queryBuilderRevelation);
+        $queryBuilderProphecy->from('sys_language')->shouldBeCalled()->willReturn($queryBuilderRevelation);
+        $queryBuilderProphecy->expr()->shouldBeCalled()->willReturn($expressionBuilderProphecy->reveal());
+        $expressionBuilderProphecy->eq('pid', 0)->shouldBeCalled()->willReturn('pid = 0');
+        $queryBuilderProphecy->where('pid = 0')->shouldBeCalled()->willReturn($queryBuilderRevelation);
+        $queryBuilderProphecy->execute()->shouldBeCalled()->willReturn($statementProphecy->reveal());
+        $statementProphecy->fetch()->shouldBeCalledTimes(1)->willReturn(false);
+
         $expected = $input;
         $expected['systemLanguageRows'] = [
             -1 => [
@@ -146,7 +180,31 @@ class DatabaseSystemLanguageRowsTest extends UnitTestCase
                 ]
             ],
         ];
-        $this->dbProphecy->exec_SELECTgetRows(Argument::cetera())->willReturn([]);
+
+        // Prophecies and revelations for a lot of the database stack classes
+        $queryBuilderProphecy = $this->prophesize(QueryBuilder::class);
+        $queryBuilderRevelation = $queryBuilderProphecy->reveal();
+        $connectionPoolProphecy = $this->prophesize(ConnectionPool::class);
+        $queryRestrictionContainerProphecy = $this->prophesize(QueryRestrictionContainerInterface::class);
+        $queryRestrictionContainerRevelation = $queryRestrictionContainerProphecy->reveal();
+        $expressionBuilderProphecy = $this->prophesize(ExpressionBuilder::class);
+        $statementProphecy = $this->prophesize(Statement::class);
+
+        // Register connection pool revelation in framework, this is the entry point used by system unter tetst
+        GeneralUtility::addInstance(ConnectionPool::class, $connectionPoolProphecy->reveal());
+
+        // Simulate method call flow on database objects and verify correct query is built
+        $connectionPoolProphecy->getQueryBuilderForTable('sys_language')->shouldBeCalled()->willReturn($queryBuilderRevelation);
+        $queryRestrictionContainerProphecy->removeAll()->shouldBeCalled()->willReturn($queryRestrictionContainerRevelation);
+        $queryBuilderProphecy->getRestrictions()->shouldBeCalled()->willReturn($queryRestrictionContainerRevelation);
+        $queryBuilderProphecy->select('uid', 'title', 'language_isocode', 'flag')->shouldBeCalled()->willReturn($queryBuilderRevelation);
+        $queryBuilderProphecy->from('sys_language')->shouldBeCalled()->willReturn($queryBuilderRevelation);
+        $queryBuilderProphecy->expr()->shouldBeCalled()->willReturn($expressionBuilderProphecy->reveal());
+        $expressionBuilderProphecy->eq('pid', 0)->shouldBeCalled()->willReturn('pid = 0');
+        $queryBuilderProphecy->where('pid = 0')->shouldBeCalled()->willReturn($queryBuilderRevelation);
+        $queryBuilderProphecy->execute()->shouldBeCalled()->willReturn($statementProphecy->reveal());
+        $statementProphecy->fetch()->shouldBeCalledTimes(1)->willReturn(false);
+
         $expected = $input;
         $expected['systemLanguageRows'] = [
             -1 => [
@@ -170,16 +228,39 @@ class DatabaseSystemLanguageRowsTest extends UnitTestCase
      */
     public function addDataResolvesLanguageIsocodeFromDatabaseField()
     {
-        $dbRows = [
-            [
-                'uid' => 3,
-                'title' => 'french',
-                'language_isocode' => 'fr',
-                'static_lang_isocode' => '',
-                'flag' => 'fr',
-            ],
+        $aDatabaseResultRow = [
+            'uid' => 3,
+            'title' => 'french',
+            'language_isocode' => 'fr',
+            'static_lang_isocode' => '',
+            'flag' => 'fr',
         ];
-        $this->dbProphecy->exec_SELECTgetRows('uid,title,language_isocode,flag', 'sys_language', 'pid=0')->willReturn($dbRows);
+
+        // Prophecies and revelations for a lot of the database stack classes
+        $queryBuilderProphecy = $this->prophesize(QueryBuilder::class);
+        $queryBuilderRevelation = $queryBuilderProphecy->reveal();
+        $connectionPoolProphecy = $this->prophesize(ConnectionPool::class);
+        $queryRestrictionContainerProphecy = $this->prophesize(QueryRestrictionContainerInterface::class);
+        $queryRestrictionContainerRevelation = $queryRestrictionContainerProphecy->reveal();
+        $expressionBuilderProphecy = $this->prophesize(ExpressionBuilder::class);
+        $statementProphecy = $this->prophesize(Statement::class);
+
+        // Register connection pool revelation in framework, this is the entry point used by system under test
+        GeneralUtility::addInstance(ConnectionPool::class, $connectionPoolProphecy->reveal());
+
+        // Simulate method call flow on database objects and verify correct query is built
+        $connectionPoolProphecy->getQueryBuilderForTable('sys_language')->shouldBeCalled()->willReturn($queryBuilderRevelation);
+        $queryRestrictionContainerProphecy->removeAll()->shouldBeCalled()->willReturn($queryRestrictionContainerRevelation);
+        $queryBuilderProphecy->getRestrictions()->shouldBeCalled()->willReturn($queryRestrictionContainerRevelation);
+        $queryBuilderProphecy->select('uid', 'title', 'language_isocode', 'flag')->shouldBeCalled()->willReturn($queryBuilderRevelation);
+        $queryBuilderProphecy->from('sys_language')->shouldBeCalled()->willReturn($queryBuilderRevelation);
+        $queryBuilderProphecy->expr()->shouldBeCalled()->willReturn($expressionBuilderProphecy->reveal());
+        $expressionBuilderProphecy->eq('pid', 0)->shouldBeCalled()->willReturn('pid = 0');
+        $queryBuilderProphecy->where('pid = 0')->shouldBeCalled()->willReturn($queryBuilderRevelation);
+        $queryBuilderProphecy->execute()->shouldBeCalled()->willReturn($statementProphecy->reveal());
+
+        $statementProphecy->fetch()->shouldBeCalledTimes(2)->willReturn($aDatabaseResultRow, false);
+
         $expected = [
             'systemLanguageRows' => [
                 -1 => [
@@ -210,16 +291,39 @@ class DatabaseSystemLanguageRowsTest extends UnitTestCase
      */
     public function addDataAddFlashMessageWithMissingIsoCode()
     {
-        $dbRows = [
-            [
-                'uid' => 3,
-                'title' => 'french',
-                'language_isocode' => '',
-                'static_lang_isocode' => '',
-                'flag' => 'fr',
-            ],
+        $aDatabaseResultRow = [
+            'uid' => 3,
+            'title' => 'french',
+            'language_isocode' => '',
+            'static_lang_isocode' => '',
+            'flag' => 'fr',
         ];
-        $this->dbProphecy->exec_SELECTgetRows('uid,title,language_isocode,flag', 'sys_language', 'pid=0')->shouldBeCalled()->willReturn($dbRows);
+
+        // Prophecies and revelations for a lot of the database stack classes
+        $queryBuilderProphecy = $this->prophesize(QueryBuilder::class);
+        $queryBuilderRevelation = $queryBuilderProphecy->reveal();
+        $connectionPoolProphecy = $this->prophesize(ConnectionPool::class);
+        $queryRestrictionContainerProphecy = $this->prophesize(QueryRestrictionContainerInterface::class);
+        $queryRestrictionContainerRevelation = $queryRestrictionContainerProphecy->reveal();
+        $expressionBuilderProphecy = $this->prophesize(ExpressionBuilder::class);
+        $statementProphecy = $this->prophesize(Statement::class);
+
+        // Register connection pool revelation in framework, this is the entry point used by system under test
+        GeneralUtility::addInstance(ConnectionPool::class, $connectionPoolProphecy->reveal());
+
+        // Simulate method call flow on database objects and verify correct query is built
+        $connectionPoolProphecy->getQueryBuilderForTable('sys_language')->shouldBeCalled()->willReturn($queryBuilderRevelation);
+        $queryRestrictionContainerProphecy->removeAll()->shouldBeCalled()->willReturn($queryRestrictionContainerRevelation);
+        $queryBuilderProphecy->getRestrictions()->shouldBeCalled()->willReturn($queryRestrictionContainerRevelation);
+        $queryBuilderProphecy->select('uid', 'title', 'language_isocode', 'flag')->shouldBeCalled()->willReturn($queryBuilderRevelation);
+        $queryBuilderProphecy->from('sys_language')->shouldBeCalled()->willReturn($queryBuilderRevelation);
+        $queryBuilderProphecy->expr()->shouldBeCalled()->willReturn($expressionBuilderProphecy->reveal());
+        $expressionBuilderProphecy->eq('pid', 0)->shouldBeCalled()->willReturn('pid = 0');
+        $queryBuilderProphecy->where('pid = 0')->shouldBeCalled()->willReturn($queryBuilderRevelation);
+        $queryBuilderProphecy->execute()->shouldBeCalled()->willReturn($statementProphecy->reveal());
+
+        $statementProphecy->fetch()->shouldBeCalledTimes(2)->willReturn($aDatabaseResultRow, false);
+
         // Needed for backendUtility::getRecord()
         $GLOBALS['TCA']['static_languages'] = [ 'foo' ];
         $expected = [