[TASK] Add FileCollectionRegistry
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Classes / Resource / ResourceFactory.php
1 <?php
2 namespace TYPO3\CMS\Core\Resource;
3
4 /***************************************************************
5 * Copyright notice
6 *
7 * (c) 2011-2013 Andreas Wolf <andreas.wolf@typo3.org>
8 * All rights reserved
9 *
10 * This script is part of the TYPO3 project. The TYPO3 project is
11 * free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * The GNU General Public License can be found at
17 * http://www.gnu.org/copyleft/gpl.html.
18 * A copy is found in the text file GPL.txt and important notices to the license
19 * from the author is found in LICENSE.txt distributed with these scripts.
20 *
21 *
22 * This script is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * This copyright notice MUST APPEAR in all copies of the script!
28 ***************************************************************/
29
30 use TYPO3\CMS\Core\Resource\Index\FileIndexRepository;
31 use TYPO3\CMS\Core\Utility\GeneralUtility;
32 use TYPO3\CMS\Core\Utility\MathUtility;
33 use TYPO3\CMS\Core\Utility\PathUtility;
34
35 // TODO implement constructor-level caching
36 /**
37 * Factory class for FAL objects.
38 *
39 * NOTE: This class is part of the lowlevel FAL API and should not be used from outside the FAL package.
40 *
41 * @author Andreas Wolf <andreas.wolf@typo3.org>
42 */
43 class ResourceFactory implements \TYPO3\CMS\Core\SingletonInterface {
44
45 const SIGNAL_PostProcessStorage = 'postProcessStorage';
46
47 /**
48 * Gets a singleton instance of this class.
49 *
50 * @return ResourceFactory
51 */
52 static public function getInstance() {
53 return GeneralUtility::makeInstance(__CLASS__);
54 }
55
56 /**
57 * @var ResourceStorage[]
58 */
59 protected $storageInstances = array();
60
61 /**
62 * @var Collection\AbstractFileCollection[]
63 */
64 protected $collectionInstances = array();
65
66 /**
67 * @var File[]
68 */
69 protected $fileInstances = array();
70
71 /**
72 * @var FileReference[]
73 */
74 protected $fileReferenceInstances = array();
75
76 /**
77 * A list of the base paths of "local" driver storages. Used to make the detection of base paths easier.
78 *
79 * @var array
80 */
81 protected $localDriverStorageCache = NULL;
82
83 /**
84 * @var \TYPO3\CMS\Extbase\SignalSlot\Dispatcher
85 */
86 protected $signalSlotDispatcher;
87
88 /**
89 * Inject signal slot dispatcher
90 */
91 public function __construct(\TYPO3\CMS\Extbase\SignalSlot\Dispatcher $signalSlotDispatcher = NULL) {
92 $this->signalSlotDispatcher = $signalSlotDispatcher ?: GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\SignalSlot\\Dispatcher');
93 }
94
95 /**
96 * Creates a driver object for a specified storage object.
97 *
98 * @param string $driverIdentificationString The driver class (or identifier) to use.
99 * @param array $driverConfiguration The configuration of the storage
100 * @return Driver\DriverInterface
101 * @throws \InvalidArgumentException
102 */
103 public function getDriverObject($driverIdentificationString, array $driverConfiguration) {
104 /** @var $driverRegistry Driver\DriverRegistry */
105 $driverRegistry = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Resource\\Driver\\DriverRegistry');
106 $driverClass = $driverRegistry->getDriverClass($driverIdentificationString);
107 $driverObject = GeneralUtility::makeInstance($driverClass, $driverConfiguration);
108 return $driverObject;
109 }
110
111
112 /**
113 * Returns the Default Storage
114 *
115 * The Default Storage is considered to be the replacement for the fileadmin/ construct.
116 * It is automatically created with the setting fileadminDir from install tool.
117 * getDefaultStorage->getDefaultFolder() will get you fileadmin/user_upload/ in a standard
118 * TYPO3 installation.
119 *
120 * @return null|ResourceStorage
121 */
122 public function getDefaultStorage() {
123 /** @var $storageRepository StorageRepository */
124 $storageRepository = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Resource\\StorageRepository');
125
126 $allStorages = $storageRepository->findAll();
127 foreach ($allStorages as $storage) {
128 if ($storage->isDefault()) {
129 return $storage;
130 }
131 }
132 return NULL;
133 }
134 /**
135 * Creates an instance of the storage from given UID. The $recordData can
136 * be supplied to increase performance.
137 *
138 * @param integer $uid The uid of the storage to instantiate.
139 * @param array $recordData The record row from database.
140 * @param string $fileIdentifier Identifier for a file. Used for auto-detection of a storage, but only if $uid === 0 (Local default storage) is used
141 *
142 * @throws \InvalidArgumentException
143 * @return ResourceStorage
144 */
145 public function getStorageObject($uid, array $recordData = array(), &$fileIdentifier = NULL) {
146 if (!is_numeric($uid)) {
147 throw new \InvalidArgumentException('uid of Storage has to be numeric.', 1314085991);
148 }
149 $uid = (int)$uid;
150 if ($uid === 0 && $fileIdentifier !== NULL) {
151 $uid = $this->findBestMatchingStorageByLocalPath($fileIdentifier);
152 }
153 if (!$this->storageInstances[$uid]) {
154 $storageConfiguration = NULL;
155 $storageObject = NULL;
156 // If the built-in storage with UID=0 is requested:
157 if ($uid === 0) {
158 $recordData = array(
159 'uid' => 0,
160 'pid' => 0,
161 'name' => 'Fallback Storage',
162 'description' => 'Internal storage, mounting the main TYPO3_site directory.',
163 'driver' => 'Local',
164 'processingfolder' => 'typo3temp/_processed_/',
165 // legacy code
166 'configuration' => '',
167 'is_online' => TRUE,
168 'is_browsable' => TRUE,
169 'is_public' => TRUE,
170 'is_writable' => TRUE,
171 'is_default' => FALSE,
172 );
173 $storageConfiguration = array(
174 'basePath' => '/',
175 'pathType' => 'relative'
176 );
177 } elseif (count($recordData) === 0 || (int)$recordData['uid'] !== $uid) {
178 /** @var $storageRepository StorageRepository */
179 $storageRepository = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Resource\\StorageRepository');
180 /** @var $storage ResourceStorage */
181 $storageObject = $storageRepository->findByUid($uid);
182 }
183 if (!$storageObject instanceof ResourceStorage) {
184 $storageObject = $this->createStorageObject($recordData, $storageConfiguration);
185 }
186 $this->signalSlotDispatcher->dispatch('TYPO3\\CMS\\Core\\Resource\\ResourceFactory', self::SIGNAL_PostProcessStorage, array($this, $storageObject));
187 $this->storageInstances[$uid] = $storageObject;
188 }
189 return $this->storageInstances[$uid];
190 }
191
192 /**
193 * Checks whether a file resides within a real storage in local file system.
194 * If no match is found, uid 0 is returned which is a fallback storage pointing to PATH_site.
195 *
196 * The file identifier is adapted accordingly to match the new storage's base path.
197 *
198 * @param string $localPath
199 *
200 * @return integer
201 */
202 protected function findBestMatchingStorageByLocalPath(&$localPath) {
203 if ($this->localDriverStorageCache === NULL) {
204 $this->initializeLocalStorageCache();
205 }
206
207 $bestMatchStorageUid = 0;
208 $bestMatchLength = 0;
209 foreach ($this->localDriverStorageCache as $storageUid => $basePath) {
210 $matchLength = strlen(PathUtility::getCommonPrefix(array($basePath, $localPath)));
211 $basePathLength = strlen($basePath);
212
213 if ($matchLength >= $basePathLength && $matchLength > $bestMatchLength) {
214 $bestMatchStorageUid = (int)$storageUid;
215 $bestMatchLength = $matchLength;
216 }
217 }
218 if ($bestMatchStorageUid !== 0) {
219 $localPath = substr($localPath, $bestMatchLength);
220 }
221 return $bestMatchStorageUid;
222 }
223
224 /**
225 * Creates an array mapping all uids to the basePath of storages using the "local" driver.
226 *
227 * @return void
228 */
229 protected function initializeLocalStorageCache() {
230 /** @var $storageRepository StorageRepository */
231 $storageRepository = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Resource\\StorageRepository');
232 /** @var $storageObjects ResourceStorage[] */
233 $storageObjects = $storageRepository->findByStorageType('Local');
234
235 $storageCache = array();
236 foreach ($storageObjects as $localStorage) {
237 $configuration = $localStorage->getConfiguration();
238 $storageCache[$localStorage->getUid()] = $configuration['basePath'];
239 }
240 $this->localDriverStorageCache = $storageCache;
241 }
242
243 /**
244 * Converts a flexform data string to a flat array with key value pairs
245 *
246 * @param string $flexFormData
247 * @return array Array with key => value pairs of the field data in the FlexForm
248 */
249 public function convertFlexFormDataToConfigurationArray($flexFormData) {
250 $configuration = array();
251 if ($flexFormData) {
252 $flexFormContents = GeneralUtility::xml2array($flexFormData);
253 if (!empty($flexFormContents['data']['sDEF']['lDEF']) && is_array($flexFormContents['data']['sDEF']['lDEF'])) {
254 foreach ($flexFormContents['data']['sDEF']['lDEF'] as $key => $value) {
255 if (isset($value['vDEF'])) {
256 $configuration[$key] = $value['vDEF'];
257 }
258 }
259 }
260 }
261 return $configuration;
262 }
263
264 /**
265 * Creates an instance of the collection from given UID. The $recordData can be supplied to increase performance.
266 *
267 * @param integer $uid The uid of the collection to instantiate.
268 * @param array $recordData The record row from database.
269 *
270 * @throws \InvalidArgumentException
271 * @return Collection\AbstractFileCollection
272 */
273 public function getCollectionObject($uid, array $recordData = array()) {
274 if (!is_numeric($uid)) {
275 throw new \InvalidArgumentException('uid of collection has to be numeric.', 1314085999);
276 }
277 if (!$this->collectionInstances[$uid]) {
278 // Get mount data if not already supplied as argument to this function
279 if (count($recordData) === 0 || $recordData['uid'] !== $uid) {
280 /** @var $GLOBALS['TYPO3_DB'] \TYPO3\CMS\Core\Database\DatabaseConnection */
281 $recordData = $GLOBALS['TYPO3_DB']->exec_SELECTgetSingleRow('*', 'sys_file_collection', 'uid=' . (int)$uid . ' AND deleted=0');
282 if (!is_array($recordData)) {
283 throw new \InvalidArgumentException('No collection found for given UID.', 1314085992);
284 }
285 }
286 $collectionObject = $this->createCollectionObject($recordData);
287 $this->collectionInstances[$uid] = $collectionObject;
288 }
289 return $this->collectionInstances[$uid];
290 }
291
292 /**
293 * Creates a collection object.
294 *
295 * @param array $collectionData The database row of the sys_file_collection record.
296 * @return Collection\AbstractFileCollection
297 */
298 public function createCollectionObject(array $collectionData) {
299 /** @var $registry Collection\FileCollectionRegistry */
300 $registry = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Resource\\Collection\\FileCollectionRegistry');
301 $class = $registry->getFileCollectionClass($collectionData['type']);
302
303 return $class::create($collectionData);
304 }
305
306 /**
307 * Creates a storage object from a storage database row.
308 *
309 * @param array $storageRecord
310 * @param array $storageConfiguration Storage configuration (if given, this won't be extracted from the FlexForm value but the supplied array used instead)
311 * @return ResourceStorage
312 */
313 public function createStorageObject(array $storageRecord, array $storageConfiguration = NULL) {
314 $className = 'TYPO3\\CMS\\Core\\Resource\\ResourceStorage';
315 if (!$storageConfiguration) {
316 $storageConfiguration = $this->convertFlexFormDataToConfigurationArray($storageRecord['configuration']);
317 }
318 $driverType = $storageRecord['driver'];
319 $driverObject = $this->getDriverObject($driverType, $storageConfiguration);
320 /** @var $storage ResourceStorage */
321 $storage = GeneralUtility::makeInstance($className, $driverObject, $storageRecord);
322 // TODO handle publisher
323 return $storage;
324 }
325
326 /**
327 * Creates a folder to directly access (a part of) a storage.
328 *
329 * @param ResourceStorage $storage The storage the folder belongs to
330 * @param string $identifier The path to the folder. Might also be a simple unique string, depending on the storage driver.
331 * @param string $name The name of the folder (e.g. the folder name)
332 * @return Folder
333 */
334 public function createFolderObject(ResourceStorage $storage, $identifier, $name) {
335 return GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Resource\\Folder', $storage, $identifier, $name);
336 }
337
338 protected function createPublisherFromConfiguration(array $configuration) {
339 $publishingTarget = $this->getStorageObject($configuration['publisherConfiguration']['publishingTarget']);
340 $publisher = GeneralUtility::makeInstance($configuration['publisher'], $publishingTarget, $configuration['publisherConfiguration']);
341 return $publisher;
342 }
343
344 /**
345 * Creates an instance of the file given UID. The $fileData can be supplied
346 * to increase performance.
347 *
348 * @param integer $uid The uid of the file to instantiate.
349 * @param array $fileData The record row from database.
350 *
351 * @throws \InvalidArgumentException
352 * @throws \TYPO3\CMS\Core\Resource\Exception\FileDoesNotExistException
353 * @return File
354 */
355 public function getFileObject($uid, array $fileData = array()) {
356 if (!is_numeric($uid)) {
357 throw new \InvalidArgumentException('uid of file has to be numeric.', 1300096564);
358 }
359 if (!$this->fileInstances[$uid]) {
360 // Fetches data in case $fileData is empty
361 if (empty($fileData)) {
362 $fileData = $this->getFileIndexRepository()->findOneByUid($uid);
363 if ($fileData === FALSE) {
364 throw new \TYPO3\CMS\Core\Resource\Exception\FileDoesNotExistException('No file found for given UID.', 1317178604);
365 }
366 }
367 $this->fileInstances[$uid] = $this->createFileObject($fileData);
368 }
369 return $this->fileInstances[$uid];
370 }
371
372 /**
373 * Gets an file object from an identifier [storage]:[fileId]
374 *
375 * @param string $identifier
376 * @return File
377 */
378 public function getFileObjectFromCombinedIdentifier($identifier) {
379 $parts = GeneralUtility::trimExplode(':', $identifier);
380 if (count($parts) === 2) {
381 $storageUid = $parts[0];
382 $fileIdentifier = $parts[1];
383 } else {
384 // We only got a path: Go into backwards compatibility mode and
385 // use virtual Storage (uid=0)
386 $storageUid = 0;
387 $fileIdentifier = $parts[0];
388 }
389
390 // please note that getStorageObject() might modify $fileIdentifier when
391 // auto-detecting the best-matching storage to use
392 return $this->getFileObjectByStorageAndIdentifier($storageUid, $fileIdentifier);
393 }
394
395 /**
396 * @param int $storageUid
397 * @param string $fileIdentifier
398 *
399 * @return File
400 */
401 public function getFileObjectByStorageAndIdentifier($storageUid, &$fileIdentifier) {
402 $storage = $this->getStorageObject($storageUid, array(), $fileIdentifier);
403 $fileData = $this->getFileIndexRepository()->findOneByStorageUidAndIdentifier($storage->getUid(), $fileIdentifier);
404 if ($fileData === FALSE) {
405 $fileObject = $this->getIndexer($storage)->createIndexEntry($fileIdentifier);
406 } else {
407 $fileObject = $this->getFileObject($fileData['uid'], $fileData);
408 }
409 return $fileObject;
410 }
411
412 /**
413 * Bulk function, can be used for anything to get a file or folder
414 *
415 * 1. It's a UID
416 * 2. It's a combined identifier
417 * 3. It's just a path/filename (coming from the oldstyle/backwards compatibility)
418 *
419 * Files, previously laid on fileadmin/ or something, will be "mapped" to the storage the file is
420 * in now. Files like typo3temp/ or typo3conf/ will be moved to the first writable storage
421 * in its processing folder
422 *
423 * $input could be
424 * - "2:myfolder/myfile.jpg" (combined identifier)
425 * - "23" (file UID)
426 * - "uploads/myfile.png" (backwards-compatibility, storage "0")
427 * - "file:23"
428 *
429 * @param string $input
430 * @return FileInterface|Folder
431 */
432 public function retrieveFileOrFolderObject($input) {
433 // Remove PATH_site because absolute paths under Windows systems contain ':'
434 // This is done in all considered sub functions anyway
435 $input = str_replace(PATH_site, '', $input);
436
437 if (GeneralUtility::isFirstPartOfStr($input, 'file:')) {
438 $input = substr($input, 5);
439 return $this->retrieveFileOrFolderObject($input);
440 } elseif (\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($input)) {
441 return $this->getFileObject($input);
442 } elseif (strpos($input, ':') > 0) {
443 list($prefix, $folderIdentifier) = explode(':', $input);
444 if (\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($prefix)) {
445 // path or folder in a valid storageUID
446 return $this->getObjectFromCombinedIdentifier($input);
447 } elseif ($prefix == 'EXT') {
448 $input = GeneralUtility::getFileAbsFileName($input);
449 if (empty($input)) {
450 return NULL;
451 }
452 $input = PathUtility::getRelativePath(PATH_site, dirname($input)) . basename($input);
453 return $this->getFileObjectFromCombinedIdentifier($input);
454 } else {
455 return NULL;
456 }
457 // this is a backwards-compatible way to access "0-storage" files or folders
458 } elseif (@is_file(PATH_site . $input)) {
459 // only the local file
460 return $this->getFileObjectFromCombinedIdentifier($input);
461 } else {
462 // only the local path
463 return $this->getFolderObjectFromCombinedIdentifier($input);
464 }
465 }
466
467 /**
468 * Gets a folder object from an identifier [storage]:[fileId]
469 *
470 * @TODO check naming, inserted by SteffenR while working on filelist
471 * @param string $identifier
472 * @return Folder
473 */
474 public function getFolderObjectFromCombinedIdentifier($identifier) {
475 $parts = GeneralUtility::trimExplode(':', $identifier);
476 if (count($parts) === 2) {
477 $storageUid = $parts[0];
478 $folderIdentifier = $parts[1];
479 } else {
480 // We only got a path: Go into backwards compatibility mode and
481 // use virtual Storage (uid=0)
482 $storageUid = 0;
483
484 // please note that getStorageObject() might modify $folderIdentifier when
485 // auto-detecting the best-matching storage to use
486 $folderIdentifier = $parts[0];
487 // make sure to not use an absolute path, and remove PATH_site if it is prepended
488 if (GeneralUtility::isFirstPartOfStr($folderIdentifier, PATH_site)) {
489 $folderIdentifier = \TYPO3\CMS\Core\Utility\PathUtility::stripPathSitePrefix($parts[0]);
490 }
491 }
492 return $this->getStorageObject($storageUid, array(), $folderIdentifier)->getFolder($folderIdentifier);
493 }
494
495 /**
496 * Gets a storage object from a combined identifier
497 *
498 * @param string $identifier An identifier of the form [storage uid]:[object identifier]
499 * @return ResourceStorage
500 */
501 public function getStorageObjectFromCombinedIdentifier($identifier) {
502 $parts = GeneralUtility::trimExplode(':', $identifier);
503 $storageUid = count($parts) === 2 ? $parts[0] : NULL;
504 return $this->getStorageObject($storageUid);
505 }
506
507 /**
508 * Gets a file or folder object.
509 *
510 * @param string $identifier
511 *
512 * @throws \TYPO3\CMS\Core\Resource\Exception\ResourceDoesNotExistException
513 * @return FileInterface|Folder
514 */
515 public function getObjectFromCombinedIdentifier($identifier) {
516 list($storageId, $objectIdentifier) = GeneralUtility::trimExplode(':', $identifier);
517 $storage = $this->getStorageObject($storageId);
518 if ($storage->hasFile($objectIdentifier)) {
519 return $storage->getFile($objectIdentifier);
520 } elseif ($storage->hasFolder($objectIdentifier)) {
521 return $storage->getFolder($objectIdentifier);
522 } else {
523 throw new \TYPO3\CMS\Core\Resource\Exception\ResourceDoesNotExistException('Object with identifier "' . $identifier . '" does not exist in storage', 1329647780);
524 }
525 }
526
527 /**
528 * Creates a file object from an array of file data. Requires a database
529 * row to be fetched.
530 *
531 * @param array $fileData
532 * @param ResourceStorage $storage
533 * @return File
534 */
535 public function createFileObject(array $fileData, ResourceStorage $storage = NULL) {
536 /** @var File $fileObject */
537 if (array_key_exists('storage', $fileData) && MathUtility::canBeInterpretedAsInteger($fileData['storage'])) {
538 $storageObject = $this->getStorageObject((int)$fileData['storage']);
539 } elseif ($storage !== NULL) {
540 $storageObject = $storage;
541 $fileData['storage'] = $storage->getUid();
542 } else {
543 throw new \RuntimeException('A file needs to reside in a Storage', 1381570997);
544 }
545 $fileObject = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Resource\\File', $fileData, $storageObject);
546 return $fileObject;
547 }
548
549 /**
550 * Creates an instance of a FileReference object. The $fileReferenceData can
551 * be supplied to increase performance.
552 *
553 * @param integer $uid The uid of the file usage (sys_file_reference) to instantiate.
554 * @param array $fileReferenceData The record row from database.
555 *
556 * @throws \InvalidArgumentException
557 * @return FileReference
558 */
559 public function getFileReferenceObject($uid, array $fileReferenceData = array()) {
560 if (!is_numeric($uid)) {
561 throw new \InvalidArgumentException('uid of fileusage (sys_file_reference) has to be numeric.', 1300086584);
562 }
563 if (!$this->fileReferenceInstances[$uid]) {
564 // Fetches data in case $fileData is empty
565 if (empty($fileReferenceData)) {
566 // fetch the reference record of the current workspace
567 if (TYPO3_MODE === 'BE') {
568 $fileReferenceData = \TYPO3\CMS\Backend\Utility\BackendUtility::getRecordWSOL('sys_file_reference', $uid);
569 } elseif (is_object($GLOBALS['TSFE'])) {
570 $fileReferenceData = $GLOBALS['TSFE']->sys_page->checkRecord('sys_file_reference', $uid);
571 } else {
572 /** @var $GLOBALS['TYPO3_DB'] \TYPO3\CMS\Core\Database\DatabaseConnection */
573 $fileReferenceData = $GLOBALS['TYPO3_DB']->exec_SELECTgetSingleRow('*', 'sys_file_reference', 'uid=' . (int)$uid . ' AND deleted=0');
574 }
575 if (!is_array($fileReferenceData)) {
576 throw new \InvalidArgumentException('No fileusage (sys_file_reference) found for given UID.', 1317178794);
577 }
578 }
579 $this->fileReferenceInstances[$uid] = $this->createFileReferenceObject($fileReferenceData);
580 }
581 return $this->fileReferenceInstances[$uid];
582 }
583
584 /**
585 * Creates a file usage object from an array of fileReference data
586 * from sys_file_reference table.
587 * Requires a database row to be already fetched and present.
588 *
589 * @param array $fileReferenceData
590 * @return FileReference
591 */
592 public function createFileReferenceObject(array $fileReferenceData) {
593 /** @var FileReference $fileReferenceObject */
594 $fileReferenceObject = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Resource\\FileReference', $fileReferenceData);
595 return $fileReferenceObject;
596 }
597
598 /**
599 * Returns an instance of the FileIndexRepository
600 *
601 * @return FileIndexRepository
602 */
603 protected function getFileIndexRepository() {
604 return FileIndexRepository::getInstance();
605 }
606
607 /**
608 * Returns an instance of the Indexer
609 *
610 * @return \TYPO3\CMS\Core\Resource\Index\Indexer
611 */
612 protected function getIndexer(ResourceStorage $storage) {
613 return GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Resource\\Index\\Indexer', $storage);
614 }
615
616 }