diff --git a/typo3/sysext/core/Classes/Utility/File/ExtendedFileUtility.php b/typo3/sysext/core/Classes/Utility/File/ExtendedFileUtility.php index 7341db66db9a12460b0112ac704cf5435ef74ff6..5fc2d79ee1cabcae6aa49b6c7729a21eabb13186 100644 --- a/typo3/sysext/core/Classes/Utility/File/ExtendedFileUtility.php +++ b/typo3/sysext/core/Classes/Utility/File/ExtendedFileUtility.php @@ -15,6 +15,8 @@ namespace TYPO3\CMS\Core\Utility\File; */ use TYPO3\CMS\Backend\Utility\BackendUtility; +use TYPO3\CMS\Core\Database\ConnectionPool; +use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction; use TYPO3\CMS\Core\Messaging\FlashMessage; use TYPO3\CMS\Core\Messaging\FlashMessageService; use TYPO3\CMS\Core\Resource\DuplicationBehavior; @@ -392,20 +394,22 @@ class ExtendedFileUtility extends BasicFileUtility return false; } - // @todo implement the recycler feature which has been removed from the original implementation // checks to delete the file if ($fileObject instanceof File) { // check if the file still has references // Exclude sys_file_metadata records as these are no use references - $databaseConnection = $this->getDatabaseConnection(); - $table = 'sys_refindex'; - $refIndexRecords = $databaseConnection->exec_SELECTgetRows( - '*', - $table, - 'deleted=0 AND ref_table=' . $databaseConnection->fullQuoteStr('sys_file', $table) - . ' AND ref_uid=' . (int)$fileObject->getUid() - . ' AND tablename != ' . $databaseConnection->fullQuoteStr('sys_file_metadata', $table) - ); + $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_refindex'); + $queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class)); + $refIndexRecords = $queryBuilder + ->select('tablename', 'recuid', 'ref_uid') + ->from('sys_refindex') + ->where( + $queryBuilder->expr()->eq('ref_table', $queryBuilder->createNamedParameter('sys_file')), + $queryBuilder->expr()->eq('ref_uid', (int)$fileObject->getUid()), + $queryBuilder->expr()->neq('tablename', $queryBuilder->createNamedParameter('sys_file_metadata')) + ) + ->execute() + ->fetchAll(); $deleteFile = true; if (!empty($refIndexRecords)) { $shortcutContent = array(); @@ -532,11 +536,17 @@ class ExtendedFileUtility extends BasicFileUtility foreach ($files as $file) { $fileUids[] = $file->getUid(); } - $numberOfReferences = $this->getDatabaseConnection()->exec_SELECTcountRows( - '*', - 'sys_refindex', - 'deleted=0 AND ref_table="sys_file" AND ref_uid IN (' . implode(',', $fileUids) . ') AND tablename<>"sys_file_metadata"' - ); + + $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_refindex'); + $queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class)); + $numberOfReferences = $queryBuilder + ->count('uid') + ->from('sys_refindex') + ->where( + $queryBuilder->expr()->eq('ref_table', $queryBuilder->createNamedParameter('sys_file')), + $queryBuilder->expr()->in('ref_uid', $fileUids), + $queryBuilder->expr()->neq('tablename', $queryBuilder->createNamedParameter('sys_file_metadata')) + )->execute()->fetchColumn(0); $hasReferences = $numberOfReferences > 0; if ($hasReferences) { @@ -563,11 +573,17 @@ class ExtendedFileUtility extends BasicFileUtility */ protected function transformFileReferenceToRecordReference(array $referenceRecord) { - $fileReference = $this->getDatabaseConnection()->exec_SELECTgetSingleRow( - '*', - 'sys_file_reference', - 'uid=' . (int)$referenceRecord['recuid'] - ); + $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_refindex'); + $queryBuilder->getRestrictions()->removeAll(); + $fileReference = $queryBuilder + ->select('recuid', 'uid_foreign', 'tablenames', 'fieldname', 'sorting_foreign') + ->from('sys_file_reference') + ->where( + $queryBuilder->expr()->eq('uid', (int)$referenceRecord['recuid']) + ) + ->execute() + ->fetch(); + return array( 'recuid' => $fileReference['uid_foreign'], 'tablename' => $fileReference['tablenames'], @@ -1179,16 +1195,6 @@ class ExtendedFileUtility extends BasicFileUtility return GeneralUtility::makeInstance(\TYPO3\CMS\Core\Resource\Index\Indexer::class, $storage); } - /** - * Get database connection - * - * @return \TYPO3\CMS\Core\Database\DatabaseConnection - */ - protected function getDatabaseConnection() - { - return $GLOBALS['TYPO3_DB']; - } - /** * @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication */ diff --git a/typo3/sysext/core/Tests/Unit/Utility/File/ExtendedFileUtilityTest.php b/typo3/sysext/core/Tests/Unit/Utility/File/ExtendedFileUtilityTest.php index 31ca233653db5592289fcb6fa2395d099595778a..efe5f690352d32f5b1700a0b555f1c66aee17f08 100644 --- a/typo3/sysext/core/Tests/Unit/Utility/File/ExtendedFileUtilityTest.php +++ b/typo3/sysext/core/Tests/Unit/Utility/File/ExtendedFileUtilityTest.php @@ -13,8 +13,15 @@ namespace TYPO3\CMS\Core\Tests\Unit\Utility\File; * * The TYPO3 project - inspiring people to share! */ +use Doctrine\DBAL\Driver\Statement; +use Prophecy\Argument; +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\DefaultRestrictionContainer; use TYPO3\CMS\Core\Resource\File; use TYPO3\CMS\Core\Resource\Folder; +use TYPO3\CMS\Core\Utility\GeneralUtility; /** * Testcase for class \TYPO3\CMS\Core\Utility\File\ExtendedFileUtility @@ -57,9 +64,25 @@ class ExtendedFileUtilityTest extends \TYPO3\CMS\Core\Tests\UnitTestCase $subject = $this->getMockBuilder(\TYPO3\CMS\Core\Utility\File\ExtendedFileUtility::class) ->setMethods(array('addFlashMessage')) ->getMock(); - $GLOBALS['TYPO3_DB']->expects($this->once()) - ->method('exec_SELECTcountRows')->with('*', 'sys_refindex', 'deleted=0 AND ref_table="sys_file" AND ref_uid IN (' . $fileUid . ') AND tablename<>"sys_file_metadata"') - ->will($this->returnValue(1)); + + // prophetizing the DB query + $expressionBuilderProphet = $this->prophesize(ExpressionBuilder::class); + $expressionBuilderProphet->eq(Argument::cetera())->willReturn('1 = 1'); + $expressionBuilderProphet->neq(Argument::cetera())->willReturn('1 != 1'); + $expressionBuilderProphet->in(Argument::cetera())->willReturn('uid IN (1)'); + $databaseStatementProphet = $this->prophesize(Statement::class); + $databaseStatementProphet->fetchColumn(Argument::cetera())->willReturn(1); + $queryBuilderProphet = $this->prophesize(QueryBuilder::class); + $queryBuilderProphet->getRestrictions()->willReturn(GeneralUtility::makeInstance(DefaultRestrictionContainer::class)); + $queryBuilderProphet->count(Argument::cetera())->willReturn($queryBuilderProphet); + $queryBuilderProphet->from(Argument::cetera())->willReturn($queryBuilderProphet); + $queryBuilderProphet->where(Argument::cetera())->willReturn($queryBuilderProphet); + $queryBuilderProphet->createNamedParameter(Argument::cetera())->willReturnArgument(0); + $queryBuilderProphet->execute()->willReturn($databaseStatementProphet); + $queryBuilderProphet->expr()->willReturn($expressionBuilderProphet->reveal()); + $connectionPoolProphet = $this->prophesize(ConnectionPool::class); + $connectionPoolProphet->getQueryBuilderForTable(Argument::cetera())->willReturn($queryBuilderProphet->reveal()); + GeneralUtility::addInstance(ConnectionPool::class, $connectionPoolProphet->reveal()); $GLOBALS['LANG']->expects($this->at(0))->method('sL') ->with('LLL:EXT:lang/locallang_core.xlf:message.description.folderNotDeletedHasFilesWithReferences')