[TASK] Doctrine: migrate ext:recycler/CleanerTask 33/47733/4
authorMichael Oehlhof <typo3@oehlhof.de>
Sat, 16 Apr 2016 22:12:11 +0000 (00:12 +0200)
committerChristian Kuhn <lolli@schwarzbu.ch>
Mon, 18 Apr 2016 17:57:25 +0000 (19:57 +0200)
Resolves: #75717
Releases: master
Change-Id: I210f838568c47469eb9926b7b4b6774578a28732
Reviewed-on: https://review.typo3.org/47733
Reviewed-by: Morton Jonuschat <m.jonuschat@mojocode.de>
Tested-by: Morton Jonuschat <m.jonuschat@mojocode.de>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
typo3/sysext/recycler/Classes/Task/CleanerTask.php
typo3/sysext/recycler/Tests/Unit/Task/CleanerTaskTest.php

index e9ed21c..a16d9ee 100644 (file)
@@ -13,13 +13,15 @@ namespace TYPO3\CMS\Recycler\Task;
  *
  * The TYPO3 project - inspiring people to share!
  */
+use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Scheduler\Task\AbstractTask;
 
 /**
  * A task that should be run regularly that deletes deleted
  * datasets from the DB.
  */
-class CleanerTask extends \TYPO3\CMS\Scheduler\Task\AbstractTask
+class CleanerTask extends AbstractTask
 {
     /**
      * @var int The time period, after which the rows are deleted
@@ -32,11 +34,6 @@ class CleanerTask extends \TYPO3\CMS\Scheduler\Task\AbstractTask
     protected $tcaTables = array();
 
     /**
-     * @var \TYPO3\CMS\Core\Database\DatabaseConnection
-     */
-    protected $databaseConnection = null;
-
-    /**
      * The main method of the task. Iterates through
      * the tables and calls the cleaning function
      *
@@ -63,21 +60,35 @@ class CleanerTask extends \TYPO3\CMS\Scheduler\Task\AbstractTask
      */
     protected function cleanTable($tableName)
     {
-        $queryParts = array();
         if (isset($GLOBALS['TCA'][$tableName]['ctrl']['delete'])) {
-            $queryParts[] = $GLOBALS['TCA'][$tableName]['ctrl']['delete'] . ' = 1';
+            $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($tableName);
+
+            $constraints = [
+                $queryBuilder->expr()->eq($GLOBALS['TCA'][$tableName]['ctrl']['delete'], 1),
+            ];
+
             if ($GLOBALS['TCA'][$tableName]['ctrl']['tstamp']) {
                 $dateBefore = $this->getPeriodAsTimestamp();
-                $queryParts[] = $GLOBALS['TCA'][$tableName]['ctrl']['tstamp'] . ' < ' . $dateBefore;
+                $constraints[] = $queryBuilder->expr()->lt($GLOBALS['TCA'][$tableName]['ctrl']['tstamp'], $dateBefore);
             }
-            $where = implode(' AND ', $queryParts);
 
-            $this->checkFileResourceFieldsBeforeDeletion($tableName, $where);
+            $this->checkFileResourceFieldsBeforeDeletion($tableName, $constraints);
 
-            $this->getDatabaseConnection()->exec_DELETEquery($tableName, $where);
+            $queryBuilder
+                ->getQueryContext()
+                ->setIgnoreEnableFields(true)
+                ->setIncludeDeleted(true);
+
+            try {
+                $queryBuilder->delete($tableName)
+                    ->where($queryBuilder->expr()->andX(...$constraints))
+                    ->execute();
+            } catch (\Doctrine\DBAL\DBALException $e) {
+                return false;
+            }
         }
 
-        return $this->getDatabaseConnection()->sql_error() === '';
+        return true;
     }
 
     /**
@@ -153,25 +164,17 @@ class CleanerTask extends \TYPO3\CMS\Scheduler\Task\AbstractTask
     }
 
     /**
-     * @param \TYPO3\CMS\Core\Database\DatabaseConnection
-     */
-    public function setDatabaseConnection($databaseConnection)
-    {
-        $this->databaseConnection = $databaseConnection;
-    }
-
-    /**
      * Checks if the table has fields for uploaded files and removes those files.
      *
      * @param string $table
-     * @param string $where
+     * @param array $constraints
      * @return void
      */
-    protected function checkFileResourceFieldsBeforeDeletion($table, $where)
+    protected function checkFileResourceFieldsBeforeDeletion($table, array $constraints)
     {
         $fieldList = $this->getFileResourceFields($table);
         if (!empty($fieldList)) {
-            $this->deleteFilesForTable($table, $where, $fieldList);
+            $this->deleteFilesForTable($table, $constraints, $fieldList);
         }
     }
 
@@ -179,18 +182,25 @@ class CleanerTask extends \TYPO3\CMS\Scheduler\Task\AbstractTask
      * Removes all files from the given field list in the table.
      *
      * @param string $table
-     * @param string $where
+     * @param array $constraints
      * @param array $fieldList
      * @return void
      */
-    protected function deleteFilesForTable($table, $where, array $fieldList)
+    protected function deleteFilesForTable($table, array $constraints, array $fieldList)
     {
-        $rows = $this->getDatabaseConnection()->exec_SELECTgetRows(
-            implode(',', $fieldList),
-            $table,
-            $where
-        );
-        foreach ($rows as $row) {
+        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($table);
+        $queryBuilder
+            ->getQueryContext()
+            ->setIgnoreEnableFields(true)
+            ->setIncludeDeleted(true);
+
+        $result = $queryBuilder
+            ->select(...$fieldList)
+            ->from($table)
+            ->where(...$constraints)
+            ->execute();
+
+        while ($row = $result->fetch()) {
             foreach ($fieldList as $fieldName) {
                 $uploadDir = PATH_site . $GLOBALS['TCA'][$table]['columns'][$fieldName]['config']['uploadfolder'] . '/';
                 $fileList = GeneralUtility::trimExplode(',', $row[$fieldName]);
@@ -224,17 +234,6 @@ class CleanerTask extends \TYPO3\CMS\Scheduler\Task\AbstractTask
     }
 
     /**
-     * @return \TYPO3\CMS\Core\Database\DatabaseConnection
-     */
-    protected function getDatabaseConnection()
-    {
-        if ($this->databaseConnection === null) {
-            $this->databaseConnection = $GLOBALS['TYPO3_DB'];
-        }
-        return $this->databaseConnection;
-    }
-
-    /**
      * @return \TYPO3\CMS\Lang\LanguageService
      */
     protected function getLanguageService()
index 896b92a..4cb11dc 100644 (file)
@@ -14,7 +14,14 @@ namespace TYPO3\CMS\Recycler\Tests\Unit\Task;
  * The TYPO3 project - inspiring people to share!
  */
 
-use TYPO3\CMS\Core\Database\DatabaseConnection;
+use Prophecy\Argument;
+use Prophecy\Prophecy\ObjectProphecy;
+use TYPO3\CMS\Core\Database\Connection;
+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\Tests\Unit\Database\Mocks\MockPlatform;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Recycler\Task\CleanerTask;
 
 /**
@@ -67,26 +74,29 @@ class CleanerTaskTest extends \TYPO3\CMS\Core\Tests\UnitTestCase
 
         /** @var \PHPUnit_Framework_MockObject_MockObject|CleanerTask $subject */
         $subject = $this->getMock(CleanerTask::class, array('getPeriodAsTimestamp'), array(), '', false);
-
-        $tables = array('pages');
-        $subject->setTcaTables($tables);
-
-        $period = 14;
-        $subject->setPeriod($period);
-        $periodAsTimestamp = strtotime('-' . $period . ' days');
-        $subject->expects($this->once())->method('getPeriodAsTimestamp')->willReturn($periodAsTimestamp);
-
-        $dbMock = $this->getMock(DatabaseConnection::class);
-        $dbMock->expects($this->once())
-            ->method('exec_DELETEquery')
-            ->with($this->equalTo('pages'), $this->equalTo('deleted = 1 AND tstamp < ' . $periodAsTimestamp));
-
-        $dbMock->expects($this->once())
-            ->method('sql_error')
-            ->will($this->returnValue(''));
-
-        $subject->setDatabaseConnection($dbMock);
-
+        $subject->setTcaTables(['pages']);
+        $subject->expects($this->once())->method('getPeriodAsTimestamp')->willReturn(400);
+
+        /** @var Connection|ObjectProphecy $connection */
+        $connection = $this->prophesize(Connection::class);
+        $connection->getDatabasePlatform()->willReturn(new MockPlatform());
+        $connection->getExpressionBuilder()->willReturn(new ExpressionBuilder($connection->reveal()));
+        $connection->quoteIdentifier(Argument::cetera())->willReturnArgument(0);
+
+        $queryBuilder = GeneralUtility::makeInstance(
+            QueryBuilder::class,
+            $connection->reveal(),
+            null,
+            new \Doctrine\DBAL\Query\QueryBuilder($connection->reveal())
+        );
+
+        $connectionPool = $this->prophesize(ConnectionPool::class);
+        $connectionPool->getQueryBuilderForTable('pages')->willReturn($queryBuilder);
+        GeneralUtility::addInstance(ConnectionPool::class, $connectionPool->reveal());
+
+        $connection->executeUpdate('DELETE FROM pages WHERE (deleted = 1) AND (tstamp < 400)', Argument::cetera())
+            ->shouldBeCalled()
+            ->willReturn(1);
         $this->assertTrue($subject->execute());
     }
 
@@ -98,18 +108,28 @@ class CleanerTaskTest extends \TYPO3\CMS\Core\Tests\UnitTestCase
         $GLOBALS['TCA']['pages']['ctrl']['delete'] = 'deleted';
         $GLOBALS['TCA']['pages']['ctrl']['tstamp'] = 'tstamp';
 
-        $tables = array('pages');
-        $this->subject->setTcaTables($tables);
+        $this->subject->setTcaTables(['pages']);
 
-        $period = 14;
-        $this->subject->setPeriod($period);
+        /** @var Connection|ObjectProphecy $connection */
+        $connection = $this->prophesize(Connection::class);
+        $connection->getDatabasePlatform()->willReturn(new MockPlatform());
+        $connection->getExpressionBuilder()->willReturn(new ExpressionBuilder($connection->reveal()));
+        $connection->quoteIdentifier(Argument::cetera())->willReturnArgument(0);
+
+        $queryBuilder = GeneralUtility::makeInstance(
+            QueryBuilder::class,
+            $connection->reveal(),
+            null,
+            new \Doctrine\DBAL\Query\QueryBuilder($connection->reveal())
+        );
 
-        $dbMock = $this->getMock(DatabaseConnection::class);
-        $dbMock->expects($this->once())
-            ->method('sql_error')
-            ->willReturn(1049);
+        $connectionPool = $this->prophesize(ConnectionPool::class);
+        $connectionPool->getQueryBuilderForTable('pages')->willReturn($queryBuilder);
+        GeneralUtility::addInstance(ConnectionPool::class, $connectionPool->reveal());
 
-        $this->subject->setDatabaseConnection($dbMock);
+        $connection->executeUpdate(Argument::cetera())
+            ->shouldBeCalled()
+            ->willThrow(new \Doctrine\DBAL\DBALException());
 
         $this->assertFalse($this->subject->execute());
     }