TYPO3 CMS  TYPO3_6-2
IndexerService.php
Go to the documentation of this file.
1 <?php
3 
19 
28 
32  protected $repository;
33 
37  public function __construct() {
38 
39  }
40 
47  protected function getRepository() {
48  if ($this->repository === NULL) {
49  $this->repository = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Resource\\FileRepository');
50  }
51  return $this->repository;
52  }
53 
57  protected function getFileIndexRepository() {
58  return GeneralUtility::makeInstance('TYPO3\CMS\Core\Resource\Index\FileIndexRepository');
59  }
60 
61 
67  public function getFactory() {
68  return GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Resource\\ResourceFactory');
69  }
70 
79  public function indexFile(File $fileObject, $updateObject = TRUE) {
80  $fileObject->setIndexingInProgess(TRUE);
81  // Get the file information of this object
82  $fileInfo = $this->gatherFileInformation($fileObject);
83  // Signal slot BEFORE the file was indexed
84  $this->emitPreFileIndexSignal($fileObject, $fileInfo);
85 
86  // If the file is already indexed, then the file information will
87  // be updated on the existing record
88  if ($fileObject->isIndexed()) {
89  $fileInfo['missing'] = 0;
90  $fileObject->updateProperties($fileInfo);
91  $this->getFileIndexRepository()->update($fileObject);
92  } else {
93  // Check if a file has been moved outside of FAL -- we have some
94  // orphaned index record in this case we could update
95  $resultRows = $this->getFileIndexRepository()->findByContentHash($fileInfo['sha1']);
96  $otherFiles = array();
97  foreach ($resultRows as $row) {
98  $otherFiles[] = $this->getFactory()->getFileObject($row['uid'], $row);
99  }
100 
101  $movedFile = FALSE;
103  foreach ($otherFiles as $otherFile) {
104  if (!$otherFile->exists()) {
105  // @todo: create a log entry
106  $movedFile = TRUE;
107  $fileInfo['missing'] = 0;
108  $otherFile->updateProperties($fileInfo);
109  $this->getFileIndexRepository()->update($otherFile);
110  $fileInfo['uid'] = $otherFile->getUid();
111  $fileObject = $otherFile;
112  // Skip the rest of the files here as we might have more files that are missing, but we can only
113  // have one entry. The optimal solution would be to merge these records then, but this requires
114  // some more advanced logic that we currently have not implemented.
115  break;
116  }
117  }
118  // File was not moved, so it is a new index record
119  if ($movedFile === FALSE) {
120  // Crdate and tstamp should not be present when updating
121  // the file object, as they only relate to the index record
122  $additionalInfo = array(
123  'crdate' => $GLOBALS['EXEC_TIME'],
124  'tstamp' => $GLOBALS['EXEC_TIME']
125  );
126  if (isset($GLOBALS['BE_USER']->user['uid'])) {
127  $additionalInfo['cruser_id'] = (int)$GLOBALS['BE_USER']->user['uid'];
128  }
129  $indexRecord = array_merge($fileInfo, $additionalInfo);
130 
131  $fileObject->updateProperties($indexRecord);
132  $this->getFileIndexRepository()->add($fileObject);
133  }
134  }
135  // Check for an error during the execution and throw an exception
136  $error = $GLOBALS['TYPO3_DB']->sql_error();
137  if ($error) {
138  throw new \RuntimeException('Error during file indexing: "' . $error . '"', 1314455642);
139  }
140  if ($fileInfo['type'] == $fileObject::FILETYPE_IMAGE) {
141  $rawFileLocation = $fileObject->getForLocalProcessing(FALSE);
142  $metaData = array();
143  $imageSize = getimagesize($rawFileLocation);
144  if ($imageSize === FALSE) {
145  $metaData['width'] = 0;
146  $metaData['height'] = 0;
147  } else {
148  list($metaData['width'], $metaData['height']) = $imageSize;
149  }
150  $this->getMetaDataRepository()->update($fileObject->getUid(), $metaData);
151  }
152  // Signal slot AFTER the file was indexed
153  $this->emitPostFileIndexSignal($fileObject, $fileInfo);
154  $fileObject->setIndexingInProgess(FALSE);
155  if ($updateObject) {
156  return $fileObject;
157  } else {
158  return $fileInfo;
159  }
160  }
161 
169  public function indexFiles(array $fileObjects) {
170  // emit signal
171  $this->emitPreMultipleFilesIndexSignal($fileObjects);
172  foreach ($fileObjects as $fileObject) {
173  $this->indexFile($fileObject);
174  }
175  // emit signal
176  $this->emitPostMultipleFilesIndexSignal($fileObjects);
177  }
178 
186  public function indexFilesInFolder(\TYPO3\CMS\Core\Resource\Folder $folder) {
187  $numberOfIndexedFiles = 0;
188  $fileIdentifiers = array();
189 
190  // Index all files in this folder
191  $fileObjects = $folder->getFiles();
192 
193  // emit signal
194  $this->emitPreMultipleFilesIndexSignal($fileObjects);
195  foreach ($fileObjects as $fileObject) {
196  $this->indexFile($fileObject);
197  $fileIdentifiers[] = $fileObject->getIdentifier();
198  $numberOfIndexedFiles++;
199  }
200 
201  // check for deleted files (file not found during indexing are marked as missing)
202  $fileIndexRecords = $this->getFileIndexRepository()->findByFolder($folder);
203  foreach ($fileIndexRecords as $file) {
204  if (!in_array($file['identifier'], $fileIdentifiers)) {
206  $fileObject = $this->getRepository()->findByIdentifier($file['uid']);
207  $fileObject->setMissing(TRUE);
208  $this->getFileIndexRepository()->update($fileObject);
209  }
210  }
211 
212  // emit signal
213  $this->emitPostMultipleFilesIndexSignal($fileObjects);
214 
215  // cleanup to prevent to much memory use on big folders
216  unset($fileObjects);
217  unset($fileIdentifiers);
218 
219  // Call this function recursively for each subfolder
220  $subFolders = $folder->getSubfolders();
221  foreach ($subFolders as $subFolder) {
222  $numberOfIndexedFiles += $this->indexFilesInFolder($subFolder);
223  }
224  return $numberOfIndexedFiles;
225  }
226 
236  protected function gatherFileInformation(File $file) {
237  $fileInfo = new \ArrayObject(array());
238  $gatherDefaultInformation = new \stdClass();
239  $gatherDefaultInformation->getDefaultFileInfo = 1;
240  // signal before the files are modified
241  $this->emitPreGatherFileInformationSignal($file, $fileInfo, $gatherDefaultInformation);
242  // the check helps you to disable the regular file fetching,
243  // so a signal could actually remotely access the service
244  if ($gatherDefaultInformation->getDefaultFileInfo) {
245  $storage = $file->getStorage();
246  // TODO: See if we can't just return info, as it contains most of the
247  // stuff we put together in array form again later here.
248  $info = $storage->getFileInfo($file);
249  $defaultFileInfo = array(
250  'creation_date' => $info['ctime'],
251  'modification_date' => $info['mtime'],
252  'size' => $info['size'],
253  'identifier' => $file->getIdentifier(),
254  'identifier_hash' => $storage->hashFileIdentifier($file->getIdentifier()),
255  'folder_hash' => $storage->hashFileIdentifier($storage->getFolderIdentifierFromFileIdentifier($file->getIdentifier())),
256  'storage' => $storage->getUid(),
257  'name' => $file->getName(),
258  'sha1' => $storage->hashFile($file, 'sha1'),
259  'type' => $file->getType(),
260  'mime_type' => $file->getMimeType(),
261  'extension' => $file->getExtension()
262  );
263  $fileInfo = array_merge($defaultFileInfo, $fileInfo->getArrayCopy());
264  $fileInfo = new \ArrayObject($fileInfo);
265  }
266  // signal after the file information is fetched
267  $this->emitPostGatherFileInformationSignal($file, $fileInfo, $gatherDefaultInformation);
268  return $fileInfo->getArrayCopy();
269  }
270 
280  protected function emitPreGatherFileInformationSignal(File $fileObject, $fileInfo, $gatherDefaultInformation) {
281  $this->getSignalSlotDispatcher()->dispatch('TYPO3\\CMS\\Core\\Resource\\Service\\IndexerService', 'preGatherFileInformation', array($fileObject, $fileInfo, $gatherDefaultInformation));
282  }
283 
292  protected function emitPostGatherFileInformationSignal(File $fileObject, $fileInfo, $hasGatheredDefaultInformation) {
293  $this->getSignalSlotDispatcher()->dispatch('TYPO3\\CMS\\Core\\Resource\\Service\\IndexerService', 'postGatherFileInformation', array($fileObject, $fileInfo, $hasGatheredDefaultInformation));
294  }
295 
302  protected function emitPreMultipleFilesIndexSignal(array $fileObjectsToIndex) {
303  $this->getSignalSlotDispatcher()->dispatch('TYPO3\\CMS\\Core\\Resource\\Service\\IndexerService', 'preMultipleFileIndex', array($fileObjectsToIndex));
304  }
305 
312  protected function emitPostMultipleFilesIndexSignal(array $fileObjectsToIndex) {
313  $this->getSignalSlotDispatcher()->dispatch('TYPO3\\CMS\\Core\\Resource\\Service\\IndexerService', 'postMultipleFileIndex', array($fileObjectsToIndex));
314  }
315 
323  protected function emitPreFileIndexSignal(File $fileObject, $fileInfo) {
324  $this->getSignalSlotDispatcher()->dispatch('TYPO3\\CMS\\Core\\Resource\\Service\\IndexerService', 'preFileIndex', array($fileObject, $fileInfo));
325  }
326 
334  protected function emitPostFileIndexSignal(File $fileObject, $fileInfo) {
335  $this->getSignalSlotDispatcher()->dispatch('TYPO3\\CMS\\Core\\Resource\\Service\\IndexerService', 'postFileIndex', array($fileObject, $fileInfo));
336  }
337 
343  protected function getSignalSlotDispatcher() {
344  return $this->getObjectManager()->get('TYPO3\\CMS\\Extbase\\SignalSlot\\Dispatcher');
345  }
346 
352  protected function getObjectManager() {
353  return \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager');
354  }
355 
359  protected function getMetaDataRepository() {
360  return GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Resource\\Index\\MetaDataRepository');
361  }
362 
363 }
emitPostFileIndexSignal(File $fileObject, $fileInfo)
emitPreFileIndexSignal(File $fileObject, $fileInfo)
emitPreGatherFileInformationSignal(File $fileObject, $fileInfo, $gatherDefaultInformation)
updateProperties(array $properties)
Definition: File.php:210
emitPreMultipleFilesIndexSignal(array $fileObjectsToIndex)
emitPostGatherFileInformationSignal(File $fileObject, $fileInfo, $hasGatheredDefaultInformation)
emitPostMultipleFilesIndexSignal(array $fileObjectsToIndex)
if(!defined('TYPO3_MODE')) $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_userauth.php']['logoff_pre_processing'][]
setIndexingInProgess($indexingState)
Definition: File.php:408