[BUGFIX] Adapt IndexerService to new table structures 26/24726/5
authorSteffen Ritter <info@rs-websystems.de>
Mon, 14 Oct 2013 10:40:41 +0000 (12:40 +0200)
committerSteffen Ritter <info@rs-websystems.de>
Mon, 14 Oct 2013 13:31:51 +0000 (15:31 +0200)
When introducing sys_file_metadata and rearranging FAL
to do so some parts of the IndexerService have been
forgotten.
The IndexerService is now adapted to not do SQL itself
anymore and to push the imagesizes to the metadata table.

Resolves: #52765
Releases: 6.2
Change-Id: I692bbf26e99639d9174ce02603f19955a16cc12e
Reviewed-on: https://review.typo3.org/24726
Reviewed-by: Xavier Perseguers
Tested-by: Xavier Perseguers
Reviewed-by: Steffen Ritter
Tested-by: Steffen Ritter
typo3/sysext/core/Classes/Resource/File.php
typo3/sysext/core/Classes/Resource/Index/FileIndexRepository.php
typo3/sysext/core/Classes/Resource/Index/MetaDataRepository.php
typo3/sysext/core/Classes/Resource/Service/IndexerService.php
typo3/sysext/core/Classes/Utility/File/ExtendedFileUtility.php
typo3/sysext/core/Tests/Unit/Resource/Service/IndexerServiceTest.php

index 77b7632..d6e2f77 100644 (file)
@@ -425,4 +425,21 @@ class File extends AbstractFile {
                }
                return $this->indexerService;
        }
+
+       /**
+        * @param boolean $indexingState
+        * @internal Only for usage in Indexer
+        */
+       public function setIndexingInProgess($indexingState) {
+               $this->indexingInProgress = (boolean)$indexingState;
+       }
+
+       /**
+        * @param $key
+        * @internal Only for use in Repositories and indexer
+        * @return mixed
+        */
+       public function _getPropertyRaw($key) {
+               return parent::getProperty($key);
+       }
 }
index b820541..7963407 100644 (file)
@@ -160,6 +160,9 @@ class FileIndexRepository implements SingletonInterface {
        public function add(File $file) {
                if ($this->hasIndexRecord($file)) {
                        $this->update($file);
+                       if ($file->_getPropertyRaw('uid') === NULL) {
+                               $file->updateProperties($this->findOneByFileObject($file));
+                       }
                } else {
                        $data = array_intersect_key($file->getProperties(), array_flip($this->fields));
                        $this->getDatabase()->exec_INSERTquery($this->table, $data);
@@ -174,17 +177,7 @@ class FileIndexRepository implements SingletonInterface {
         * @return bool
         */
        public function hasIndexRecord(File $file) {
-               if (intval($file->getUid()) > 0) {
-                       $where = 'uid=' . intval($file->getUid());
-
-               } else {
-                       $where = sprintf(
-                               'storage=%u AND identifier=%s',
-                               intval($file->getStorage()->getUid()),
-                               $this->getDatabase()->fullQuoteStr($file->getIdentifier(), $this->table)
-                       );
-               }
-               return $this->getDatabase()->exec_SELECTcountRows('uid', $this->table, $where) === 1;
+               return $this->getDatabase()->exec_SELECTcountRows('uid', $this->table, $this->getWhereClauseForFile($file)) === 1;
        }
 
        /**
@@ -200,7 +193,27 @@ class FileIndexRepository implements SingletonInterface {
                }
                if (count($updateRow) > 0) {
                        $updateRow['tstamp'] = time();
-                       $this->getDatabase()->exec_UPDATEquery($this->table, 'uid=' . intval($file->getUid()), $updateRow);
+                       $this->getDatabase()->exec_UPDATEquery($this->table, $this->getWhereClauseForFile($file), $updateRow);
+               }
+       }
+
+       /**
+        * Returns a where clause to find a file in database
+        *
+        * @param File $file
+        *
+        * @return string
+        */
+       protected function getWhereClauseForFile(File $file) {
+               if (intval($file->_getPropertyRaw('uid')) > 0) {
+                       $where = 'uid=' . intval($file->getUid());
+               } else {
+                       $where = sprintf(
+                               'storage=%u AND identifier=%s',
+                               intval($file->getStorage()->getUid()),
+                               $this->getDatabase()->fullQuoteStr($file->_getPropertyRaw('identifier'), $this->table)
+                       );
                }
+               return $where;
        }
 }
\ No newline at end of file
index 2604430..bf9c24f 100644 (file)
@@ -113,4 +113,23 @@ class MetaDataRepository implements SingletonInterface {
 
                return $record;
        }
+
+       /**
+        * Updates the metadata record in the database
+        *
+        * @internal
+        * @param int $fileUid the file uid to update
+        * @param array $data Data to update
+        */
+       public function update($fileUid, array $data) {
+               $updateRow = array_intersect_key($data, $this->getDatabase()->admin_get_fields($this->tableName));
+               if (array_key_exists('uid', $data)) {
+                       unset($data['uid']);
+               }
+               $row = $this->findByFileUid($fileUid);
+               if (count($updateRow) > 0) {
+                       $updateRow['tstamp'] = time();
+                       $this->getDatabase()->exec_UPDATEquery($this->tableName, 'uid = ' . intval($row['uid']), $updateRow);
+               }
+       }
 }
\ No newline at end of file
index 5c00073..41361df 100644 (file)
@@ -89,21 +89,18 @@ class IndexerService implements \TYPO3\CMS\Core\SingletonInterface {
         * @throws \RuntimeException
         */
        public function indexFile(File $fileObject, $updateObject = TRUE) {
+               $fileObject->setIndexingInProgess(TRUE);
                // Get the file information of this object
                $fileInfo = $this->gatherFileInformation($fileObject);
                // Signal slot BEFORE the file was indexed
                $this->emitPreFileIndexSignal($fileObject, $fileInfo);
-               // @todo: this should be done via services in the future
-               // @todo: this should take remote services into account
-               if ($fileInfo['type'] == $fileObject::FILETYPE_IMAGE && !$fileInfo['width']) {
-                       $rawFileLocation = $fileObject->getForLocalProcessing(FALSE);
-                       list($fileInfo['width'], $fileInfo['height']) = getimagesize($rawFileLocation);
-               }
+
                // If the file is already indexed, then the file information will
                // be updated on the existing record
                if ($fileObject->isIndexed()) {
                        $fileInfo['missing'] = 0;
-                       $GLOBALS['TYPO3_DB']->exec_UPDATEquery('sys_file', sprintf('uid = %d', $fileObject->getUid()), $fileInfo);
+                       $fileObject->updateProperties($fileInfo);
+                       $this->getFileIndexRepository()->update($fileObject);
                } else {
                        // Check if a file has been moved outside of FAL -- we have some
                        // orphaned index record in this case we could update
@@ -143,8 +140,8 @@ class IndexerService implements \TYPO3\CMS\Core\SingletonInterface {
                                }
                                $indexRecord = array_merge($fileInfo, $additionalInfo);
 
-                               $GLOBALS['TYPO3_DB']->exec_INSERTquery('sys_file', $indexRecord);
-                               $fileInfo['uid'] = $GLOBALS['TYPO3_DB']->sql_insert_id();
+                               $fileObject->updateProperties($indexRecord);
+                               $this->getFileIndexRepository()->add($fileObject);
                        }
                }
                // Check for an error during the execution and throw an exception
@@ -152,10 +149,16 @@ class IndexerService implements \TYPO3\CMS\Core\SingletonInterface {
                if ($error) {
                        throw new \RuntimeException('Error during file indexing: "' . $error . '"', 1314455642);
                }
+               if ($fileInfo['type'] == $fileObject::FILETYPE_IMAGE) {
+                       $rawFileLocation = $fileObject->getForLocalProcessing(FALSE);
+                       $metaData = array();
+                       list($metaData['width'], $metaData['height']) = getimagesize($rawFileLocation);
+                       $this->getMetaDataRepository()->update($fileObject->getUid(), $metaData);
+               }
                // Signal slot AFTER the file was indexed
                $this->emitPostFileIndexSignal($fileObject, $fileInfo);
+               $fileObject->setIndexingInProgess(FALSE);
                if ($updateObject) {
-                       $fileObject->updateProperties($fileInfo);
                        return $fileObject;
                } else {
                        return $fileInfo;
@@ -353,4 +356,11 @@ class IndexerService implements \TYPO3\CMS\Core\SingletonInterface {
                return \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager');
        }
 
+       /**
+        * @return \TYPO3\CMS\Core\Resource\Index\MetaDataRepository
+        */
+       protected function getMetaDataRepository() {
+               return GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Resource\\Index\\MetaDataRepository');
+       }
+
 }
index 3f2a094..6d2c437 100644 (file)
@@ -924,7 +924,7 @@ class ExtendedFileUtility extends \TYPO3\CMS\Core\Utility\File\BasicFileUtility
                                }
                                /** @var $fileObject File */
                                $fileObject = $targetFolderObject->addUploadedFile($fileInfo, $conflictMode);
-                               $this->getIndexerService()->indexFile($fileObject, FALSE);
+                               $fileObject = $this->getIndexerService()->indexFile($fileObject);
                                $resultObjects[] = $fileObject;
                                $this->writelog(1, 0, 1, 'Uploading file "%s" to "%s"', array($fileInfo['name'], $targetFolderObject->getIdentifier()));
                        } catch (\TYPO3\CMS\Core\Resource\Exception\UploadException $e) {
index fef6c85..af58d9c 100644 (file)
@@ -39,7 +39,7 @@ class IndexerServiceTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
         */
        public function indexFileUpdatesFileProperties() {
                /** @var $fixture \TYPO3\CMS\Core\Resource\Service\IndexerService|\PHPUnit_Framework_MockObject_MockObject */
-               $fixture = $this->getMock('TYPO3\\CMS\\Core\\Resource\\Service\\IndexerService', array('gatherFileInformation', 'getRepository'));
+               $fixture = $this->getMock('TYPO3\\CMS\\Core\\Resource\\Service\\IndexerService', array('gatherFileInformation', 'getFileIndexRepository'));
 
                $fileInfo = array(
                        'mount' => 1,
@@ -51,15 +51,12 @@ class IndexerServiceTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
 
                $fixture->expects($this->any())->method('gatherFileInformation')->will($this->returnValue($fileInfo));
 
-               $repositoryMock = $this->getMock('TYPO3\\CMS\\Core\\Resource\\FileRepository', array('findBySha1Hash'));
-               $repositoryMock->expects($this->any())->method('findBySha1Hash')->will($this->returnValue(array()));
-               $fixture->expects($this->any())->method('getRepository')->will($this->returnValue($repositoryMock));
-
-               $GLOBALS['TYPO3_DB'] = $this->getMock('TYPO3\\CMS\\Core\\Database\\DatabaseConnection', array(), array(), '', FALSE);
-               $GLOBALS['TYPO3_DB']->expects($this->atLeastOnce())->method('sql_insert_id')->will($this->returnValue($fileInfo['uid']));
+               $repositoryMock = $this->getMock('TYPO3\\CMS\\Core\\Resource\\Index\\FileIndexRepository');
+               $repositoryMock->expects($this->any())->method('findByContentHash')->will($this->returnValue(array()));
+               $fixture->expects($this->any())->method('getFileIndexRepository')->will($this->returnValue($repositoryMock));
 
                $mockedFile = $this->getMock('TYPO3\\CMS\\Core\\Resource\\File', array(), array(), '', FALSE);
-               $mockedFile->expects($this->once())->method('updateProperties')->with($this->equalTo($fileInfo));
+               $mockedFile->expects($this->once())->method('updateProperties');
 
                $fixture->indexFile($mockedFile);
        }
@@ -70,13 +67,14 @@ class IndexerServiceTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
        public function indexFileSetsCreationdateAndTimestampPropertiesOfRecordToCurrentExecutionTime() {
                $fileInfo = array();
                /** @var $fixture \TYPO3\CMS\Core\Resource\Service\IndexerService|\PHPUnit_Framework_MockObject_MockObject */
-               $fixture = $this->getMock('TYPO3\\CMS\\Core\\Resource\\Service\\IndexerService', array('gatherFileInformation', 'getRepository'));
+               $fixture = $this->getMock('TYPO3\\CMS\\Core\\Resource\\Service\\IndexerService', array('gatherFileInformation', 'getFileIndexRepository'));
 
                $fixture->expects($this->any())->method('gatherFileInformation')->will($this->returnValue($fileInfo));
 
-               $repositoryMock = $this->getMock('TYPO3\\CMS\\Core\\Resource\\FileRepository', array('findBySha1Hash'));
-               $repositoryMock->expects($this->any())->method('findBySha1Hash')->will($this->returnValue(array()));
-               $fixture->expects($this->any())->method('getRepository')->will($this->returnValue($repositoryMock));
+               $repositoryMock = $this->getMock('TYPO3\\CMS\\Core\\Resource\\Index\\FileIndexRepository');
+               $repositoryMock->expects($this->any())->method('findByContentHash')->will($this->returnValue(array()));
+               $repositoryMock->expects($this->once())->method('add');
+               $fixture->expects($this->any())->method('getFileIndexRepository')->will($this->returnValue($repositoryMock));
 
                $GLOBALS['TYPO3_DB'] = $this->getMock('TYPO3\\CMS\\Core\\Database\\DatabaseConnection', array(), array(), '', FALSE);
 
@@ -86,8 +84,6 @@ class IndexerServiceTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
                        $this->contains($GLOBALS['EXEC_TIME'])
                );
 
-               $GLOBALS['TYPO3_DB']->expects($this->once())->method('exec_INSERTquery')->with($this->anything(), $arrayConstraint);
-
                $mockedFile = $this->getMock('TYPO3\\CMS\\Core\\Resource\\File', array(), array(), '', FALSE);
 
                $fixture->indexFile($mockedFile);