‪TYPO3CMS  10.4
FileIndexRepository.php
Go to the documentation of this file.
1 <?php
2 
3 /*
4  * This file is part of the TYPO3 CMS project.
5  *
6  * It is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU General Public License, either version 2
8  * of the License, or any later version.
9  *
10  * For the full copyright and license information, please read the
11  * LICENSE.txt file that was distributed with this source code.
12  *
13  * The TYPO3 project - inspiring people to share!
14  */
15 
17 
18 use Psr\EventDispatcher\EventDispatcherInterface;
35 
45 {
49  protected ‪$table = 'sys_file';
50 
54  protected ‪$eventDispatcher;
55 
61  protected ‪$fields = [
62  'uid', 'pid', 'missing', 'type', 'storage', 'identifier', 'identifier_hash', 'extension',
63  'mime_type', 'name', 'sha1', 'size', 'creation_date', 'modification_date', 'folder_hash'
64  ];
65 
71  protected function ‪getResourceFactory()
72  {
73  return GeneralUtility::makeInstance(ResourceFactory::class);
74  }
75 
81  public static function ‪getInstance()
82  {
83  return GeneralUtility::makeInstance(self::class);
84  }
85 
86  public function ‪__construct(EventDispatcherInterface ‪$eventDispatcher)
87  {
88  $this->eventDispatcher = ‪$eventDispatcher;
89  }
90 
97  public function ‪findOneByCombinedIdentifier($combinedIdentifier)
98  {
99  [$storageUid, $identifier] = ‪GeneralUtility::trimExplode(':', $combinedIdentifier, false, 2);
100  return $this->‪findOneByStorageUidAndIdentifier((int)$storageUid, $identifier);
101  }
102 
109  public function ‪findOneByUid($fileUid)
110  {
111  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
112  ->getQueryBuilderForTable($this->table);
113 
114  $row = $queryBuilder
115  ->select(...$this->fields)
116  ->from($this->table)
117  ->where(
118  $queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($fileUid, \PDO::PARAM_INT))
119  )
120  ->execute()
121  ->fetch();
122 
123  return is_array($row) ? $row : false;
124  }
125 
135  public function ‪findOneByStorageUidAndIdentifier($storageUid, $identifier)
136  {
137  $identifierHash = $this->‪getResourceFactory()->‪getStorageObject($storageUid)->‪hashFileIdentifier($identifier);
138  return $this->‪findOneByStorageUidAndIdentifierHash($storageUid, $identifierHash);
139  }
140 
150  public function ‪findOneByStorageUidAndIdentifierHash($storageUid, $identifierHash)
151  {
152  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
153  ->getQueryBuilderForTable($this->table);
154 
155  $row = $queryBuilder
156  ->select(...$this->fields)
157  ->from($this->table)
158  ->where(
159  $queryBuilder->expr()->eq('storage', $queryBuilder->createNamedParameter($storageUid, \PDO::PARAM_INT)),
160  $queryBuilder->expr()->eq('identifier_hash', $queryBuilder->createNamedParameter($identifierHash))
161  )
162  ->execute()
163  ->fetch();
164 
165  return is_array($row) ? $row : false;
166  }
167 
176  public function ‪findOneByFileObject(FileInterface $fileObject)
177  {
178  $storageUid = $fileObject->getStorage()->getUid();
179  $identifierHash = $fileObject->getHashedIdentifier();
180  return $this->‪findOneByStorageUidAndIdentifierHash($storageUid, $identifierHash);
181  }
182 
190  public function ‪findByContentHash($hash)
191  {
192  if (!preg_match('/^[0-9a-f]{40}$/i', $hash)) {
193  return [];
194  }
195 
196  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
197  ->getQueryBuilderForTable($this->table);
198 
199  $resultRows = $queryBuilder
200  ->select(...$this->fields)
201  ->from($this->table)
202  ->where(
203  $queryBuilder->expr()->eq('sha1', $queryBuilder->createNamedParameter($hash, \PDO::PARAM_STR))
204  )
205  ->execute()
206  ->fetchAll();
207 
208  return $resultRows;
209  }
210 
217  public function ‪findByFolder(Folder $folder)
218  {
219  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
220  ->getQueryBuilderForTable($this->table);
221 
222  $result = $queryBuilder
223  ->select(...$this->fields)
224  ->from($this->table)
225  ->where(
226  $queryBuilder->expr()->eq(
227  'folder_hash',
228  $queryBuilder->createNamedParameter($folder->getHashedIdentifier(), \PDO::PARAM_STR)
229  ),
230  $queryBuilder->expr()->eq(
231  'storage',
232  $queryBuilder->createNamedParameter($folder->getStorage()->getUid(), \PDO::PARAM_INT)
233  )
234  )
235  ->execute();
236 
237  $resultRows = [];
238  while ($row = $result->fetch()) {
239  $resultRows[$row['identifier']] = $row;
240  }
241 
242  return $resultRows;
243  }
244 
253  public function ‪findByFolders(array $folders, $includeMissing = true, $fileName = null)
254  {
255  $storageUids = [];
256  $folderIdentifiers = [];
257 
258  foreach ($folders as $folder) {
259  if (!$folder instanceof Folder) {
260  continue;
261  }
262 
263  $storageUids[] = (int)$folder->getStorage()->getUid();
264  $folderIdentifiers[] = $folder->getHashedIdentifier();
265  }
266 
267  $storageUids = array_unique($storageUids);
268  $folderIdentifiers = array_unique($folderIdentifiers);
269 
270  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($this->table);
271 
272  $queryBuilder
273  ->select(...$this->fields)
274  ->from($this->table)
275  ->where(
276  $queryBuilder->expr()->in(
277  'folder_hash',
278  $queryBuilder->createNamedParameter($folderIdentifiers, Connection::PARAM_STR_ARRAY)
279  ),
280  $queryBuilder->expr()->in(
281  'storage',
282  $queryBuilder->createNamedParameter($storageUids, Connection::PARAM_INT_ARRAY)
283  )
284  );
285 
286  if (isset($fileName)) {
287  $nameParts = str_getcsv($fileName, ' ');
288  foreach ($nameParts as $part) {
289  $part = trim($part);
290  if ($part !== '') {
291  $queryBuilder->andWhere(
292  $queryBuilder->expr()->like(
293  'name',
294  $queryBuilder->createNamedParameter(
295  '%' . $queryBuilder->escapeLikeWildcards($part) . '%',
296  \PDO::PARAM_STR
297  )
298  )
299  );
300  }
301  }
302  }
303 
304  if (!$includeMissing) {
305  $queryBuilder->andWhere($queryBuilder->expr()->eq('missing', $queryBuilder->createNamedParameter(0, \PDO::PARAM_INT)));
306  }
307 
308  $result = $queryBuilder->execute();
309 
310  $fileRecords = [];
311  while ($fileRecord = $result->fetch()) {
312  $fileRecords[$fileRecord['identifier']] = $fileRecord;
313  }
314 
315  return $fileRecords;
316  }
317 
323  public function ‪add(File $file)
324  {
325  if ($this->‪hasIndexRecord($file)) {
326  $this->‪update($file);
327  if ($file->_getPropertyRaw('uid') === null) {
328  $file->updateProperties($this->‪findOneByFileObject($file));
329  }
330  } else {
331  $file->updateProperties(['uid' => $this->‪insertRecord($file->getProperties())]);
332  }
333  }
334 
341  public function ‪addRaw(array $data)
342  {
343  $data['uid'] = $this->‪insertRecord($data);
344  return $data;
345  }
346 
354  protected function ‪insertRecord(array $data)
355  {
356  $data = array_intersect_key($data, array_flip($this->fields));
357  $data['tstamp'] = time();
358  $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($this->table);
359  $connection->insert(
360  $this->table,
361  $data
362  );
363  $data['uid'] = $connection->lastInsertId($this->table);
364  $this->‪updateRefIndex($data['uid']);
365  $this->eventDispatcher->dispatch(new AfterFileAddedToIndexEvent($data['uid'], $data));
366  return $data['uid'];
367  }
368 
375  public function ‪hasIndexRecord(File $file)
376  {
377  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($this->table);
378 
379  if ((int)$file->_getPropertyRaw('uid') > 0) {
380  $constraints = [
381  $queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($file->getUid(), \PDO::PARAM_INT))
382  ];
383  } else {
384  $constraints = [
385  $queryBuilder->expr()->eq(
386  'storage',
387  $queryBuilder->createNamedParameter($file->getStorage()->getUid(), \PDO::PARAM_INT)
388  ),
389  $queryBuilder->expr()->eq(
390  'identifier',
391  $queryBuilder->createNamedParameter($file->_getPropertyRaw('identifier'), \PDO::PARAM_STR)
392  )
393  ];
394  }
395 
396  $count = $queryBuilder
397  ->count('uid')
398  ->from($this->table)
399  ->where(...$constraints)
400  ->execute()
401  ->fetchColumn(0);
402 
403  return (bool)$count;
404  }
405 
411  public function ‪update(File $file)
412  {
413  $updatedProperties = array_intersect($this->fields, $file->getUpdatedProperties());
414  $updateRow = [];
415  foreach ($updatedProperties as $key) {
416  $updateRow[$key] = $file->getProperty($key);
417  }
418  if (!empty($updateRow)) {
419  if ((int)$file->_getPropertyRaw('uid') > 0) {
420  $constraints = ['uid' => (int)$file->getUid()];
421  } else {
422  $constraints = [
423  'storage' => (int)$file->getStorage()->getUid(),
424  'identifier' => $file->_getPropertyRaw('identifier')
425  ];
426  }
427 
428  $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($this->table);
429  $updateRow['tstamp'] = time();
430 
431  $connection->update(
432  $this->table,
433  $updateRow,
434  $constraints
435  );
436 
437  $this->‪updateRefIndex($file->getUid());
438  $this->eventDispatcher->dispatch(new AfterFileUpdatedInIndexEvent($file, array_intersect_key($file->getProperties(), array_flip($this->fields)), $updateRow));
439  }
440  }
441 
449  public function ‪findInStorageWithIndexOutstanding(ResourceStorage $storage, $limit = -1)
450  {
451  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($this->table);
452 
453  if ((int)$limit > 0) {
454  $queryBuilder->setMaxResults((int)$limit);
455  }
456 
457  $rows = $queryBuilder
458  ->select(...$this->fields)
459  ->from($this->table)
460  ->where(
461  $queryBuilder->expr()->gt('tstamp', $queryBuilder->quoteIdentifier('last_indexed')),
462  $queryBuilder->expr()->eq('storage', $queryBuilder->createNamedParameter($storage->getUid(), \PDO::PARAM_INT))
463  )
464  ->orderBy('tstamp', 'ASC')
465  ->execute()
466  ->fetchAll();
467 
468  return $rows;
469  }
470 
478  public function ‪findInStorageAndNotInUidList(ResourceStorage $storage, array $uidList)
479  {
480  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($this->table);
481 
482  $queryBuilder
483  ->select(...$this->fields)
484  ->from($this->table)
485  ->where(
486  $queryBuilder->expr()->eq(
487  'storage',
488  $queryBuilder->createNamedParameter($storage->getUid(), \PDO::PARAM_INT)
489  )
490  );
491 
492  if (!empty($uidList)) {
493  $queryBuilder->andWhere(
494  $queryBuilder->expr()->notIn(
495  'uid',
496  array_map('intval', $uidList)
497  )
498  );
499  }
500 
501  $rows = $queryBuilder->execute()->fetchAll();
502 
503  return $rows;
504  }
505 
511  public function ‪updateIndexingTime($fileUid)
512  {
513  $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($this->table);
514  $connection->update(
515  $this->table,
516  [
517  'last_indexed' => time()
518  ],
519  [
520  'uid' => (int)$fileUid
521  ]
522  );
523  }
524 
530  public function ‪markFileAsMissing($fileUid)
531  {
532  $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($this->table);
533  $connection->update(
534  $this->table,
535  [
536  'missing' => 1
537  ],
538  [
539  'uid' => (int)$fileUid
540  ]
541  );
542  $this->eventDispatcher->dispatch(new AfterFileMarkedAsMissingEvent((int)$fileUid));
543  }
544 
550  public function remove($fileUid)
551  {
552  $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($this->table);
553  $connection->delete(
554  $this->table,
555  [
556  'uid' => (int)$fileUid
557  ]
558  );
559  $this->‪updateRefIndex($fileUid);
560  $this->eventDispatcher->dispatch(new AfterFileRemovedFromIndexEvent((int)$fileUid));
561  }
562 
568  public function ‪updateRefIndex($id)
569  {
571  $refIndexObj = GeneralUtility::makeInstance(ReferenceIndex::class);
572  $refIndexObj->enableRuntimeCache();
573  $refIndexObj->updateRefIndexTable($this->table, $id);
574  }
575 
583  public function ‪findBySearchWordInMetaData($searchWord)
584  {
585  trigger_error(__METHOD__ . ' is deprecated. Use FileSearchQuery instead', \E_USER_DEPRECATED);
586  $searchDemand = ‪FileSearchDemand::createForSearchTerm($searchWord);
587  $searchQuery = ‪FileSearchQuery::createForSearchDemand($searchDemand);
588  $result = $searchQuery->execute();
589  $fileRecords = [];
590  while ($fileRecord = $result->fetch()) {
591  $fileRecords[$fileRecord['identifier']] = $fileRecord;
592  }
593 
594  return $fileRecords;
595  }
596 }
‪TYPO3\CMS\Core\Resource\Search\FileSearchQuery
Definition: FileSearchQuery.php:37
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\findInStorageAndNotInUidList
‪array findInStorageAndNotInUidList(ResourceStorage $storage, array $uidList)
Definition: FileIndexRepository.php:475
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\findOneByFileObject
‪array bool findOneByFileObject(FileInterface $fileObject)
Definition: FileIndexRepository.php:173
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository
Definition: FileIndexRepository.php:45
‪TYPO3\CMS\Core\Resource\ResourceStorage\getUid
‪int getUid()
Definition: ResourceStorage.php:321
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\addRaw
‪array addRaw(array $data)
Definition: FileIndexRepository.php:338
‪TYPO3\CMS\Core\Resource\FileInterface
Definition: FileInterface.php:22
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\findBySearchWordInMetaData
‪array findBySearchWordInMetaData($searchWord)
Definition: FileIndexRepository.php:580
‪TYPO3\CMS\Core\Resource\Event\AfterFileUpdatedInIndexEvent
Definition: AfterFileUpdatedInIndexEvent.php:27
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\findByFolders
‪array null findByFolders(array $folders, $includeMissing=true, $fileName=null)
Definition: FileIndexRepository.php:250
‪TYPO3\CMS\Core\Database\ReferenceIndex
Definition: ReferenceIndex.php:48
‪TYPO3\CMS\Core\Resource\Search\FileSearchQuery\createForSearchDemand
‪static FileSearchQuery createForSearchDemand(FileSearchDemand $searchDemand, QueryBuilder $queryBuilder=null)
Definition: FileSearchQuery.php:66
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\hasIndexRecord
‪bool hasIndexRecord(File $file)
Definition: FileIndexRepository.php:372
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\findByFolder
‪array null findByFolder(Folder $folder)
Definition: FileIndexRepository.php:214
‪TYPO3\CMS\Core\Resource\Event\AfterFileAddedToIndexEvent
Definition: AfterFileAddedToIndexEvent.php:26
‪TYPO3\CMS\Core\Resource\File\getUpdatedProperties
‪array getUpdatedProperties()
Definition: File.php:221
‪TYPO3\CMS\Core\Resource\ResourceInterface\getStorage
‪ResourceStorage getStorage()
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\getResourceFactory
‪ResourceFactory getResourceFactory()
Definition: FileIndexRepository.php:68
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\findOneByStorageUidAndIdentifier
‪array bool findOneByStorageUidAndIdentifier($storageUid, $identifier)
Definition: FileIndexRepository.php:132
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\update
‪update(File $file)
Definition: FileIndexRepository.php:408
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\add
‪add(File $file)
Definition: FileIndexRepository.php:320
‪TYPO3\CMS\Core\Resource\Folder\getStorage
‪ResourceStorage getStorage()
Definition: Folder.php:149
‪TYPO3\CMS\Core\Resource\ResourceStorage\hashFileIdentifier
‪string hashFileIdentifier($file)
Definition: ResourceStorage.php:1350
‪TYPO3\CMS\Core\Resource\File\getProperties
‪array getProperties()
Definition: File.php:93
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\findOneByCombinedIdentifier
‪array bool findOneByCombinedIdentifier($combinedIdentifier)
Definition: FileIndexRepository.php:94
‪TYPO3\CMS\Core\Resource\Search\FileSearchDemand
Definition: FileSearchDemand.php:26
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\updateIndexingTime
‪updateIndexingTime($fileUid)
Definition: FileIndexRepository.php:508
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\findByContentHash
‪mixed findByContentHash($hash)
Definition: FileIndexRepository.php:187
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\findInStorageWithIndexOutstanding
‪array findInStorageWithIndexOutstanding(ResourceStorage $storage, $limit=-1)
Definition: FileIndexRepository.php:446
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\$eventDispatcher
‪EventDispatcherInterface $eventDispatcher
Definition: FileIndexRepository.php:52
‪TYPO3\CMS\Core\Resource\Folder
Definition: Folder.php:37
‪TYPO3\CMS\Core\Resource\ResourceFactory
Definition: ResourceFactory.php:41
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\getInstance
‪static FileIndexRepository getInstance()
Definition: FileIndexRepository.php:78
‪TYPO3\CMS\Core\Resource\File
Definition: File.php:24
‪TYPO3\CMS\Core\Resource\Event\AfterFileRemovedFromIndexEvent
Definition: AfterFileRemovedFromIndexEvent.php:26
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\__construct
‪__construct(EventDispatcherInterface $eventDispatcher)
Definition: FileIndexRepository.php:83
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\insertRecord
‪int insertRecord(array $data)
Definition: FileIndexRepository.php:351
‪TYPO3\CMS\Core\Resource\AbstractFile\getUid
‪int getUid()
Definition: AbstractFile.php:202
‪TYPO3\CMS\Core\Resource\Index
Definition: ExtractorInterface.php:16
‪TYPO3\CMS\Core\Resource\ResourceInterface\getHashedIdentifier
‪string getHashedIdentifier()
‪TYPO3\CMS\Core\Utility\GeneralUtility\trimExplode
‪static string[] trimExplode($delim, $string, $removeEmptyValues=false, $limit=0)
Definition: GeneralUtility.php:1059
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\$fields
‪array $fields
Definition: FileIndexRepository.php:58
‪TYPO3\CMS\Core\Database\Connection
Definition: Connection.php:36
‪TYPO3\CMS\Core\Resource\ResourceStorage
Definition: ResourceStorage.php:122
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\findOneByUid
‪array false findOneByUid($fileUid)
Definition: FileIndexRepository.php:106
‪TYPO3\CMS\Core\Resource\ResourceFactory\getStorageObject
‪ResourceStorage getStorageObject($uid, array $recordData=[], &$fileIdentifier=null)
Definition: ResourceFactory.php:139
‪TYPO3\CMS\Core\SingletonInterface
Definition: SingletonInterface.php:23
‪TYPO3\CMS\Core\Resource\File\getProperty
‪mixed getProperty($key)
Definition: File.php:65
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\markFileAsMissing
‪markFileAsMissing($fileUid)
Definition: FileIndexRepository.php:527
‪TYPO3\CMS\Core\Resource\File\updateProperties
‪updateProperties(array $properties)
Definition: File.php:182
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\$table
‪string $table
Definition: FileIndexRepository.php:48
‪TYPO3\CMS\Core\Resource\Event\AfterFileMarkedAsMissingEvent
Definition: AfterFileMarkedAsMissingEvent.php:27
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:46
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:46
‪TYPO3\CMS\Core\Resource\Search\FileSearchDemand\createForSearchTerm
‪static createForSearchTerm(string $searchTerm)
Definition: FileSearchDemand.php:70
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\findOneByStorageUidAndIdentifierHash
‪array false findOneByStorageUidAndIdentifierHash($storageUid, $identifierHash)
Definition: FileIndexRepository.php:147
‪TYPO3\CMS\Core\Resource\Folder\getHashedIdentifier
‪string getHashedIdentifier()
Definition: Folder.php:170
‪TYPO3\CMS\Core\Resource\File\_getPropertyRaw
‪mixed _getPropertyRaw($key)
Definition: File.php:346
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\updateRefIndex
‪updateRefIndex($id)
Definition: FileIndexRepository.php:565
‪TYPO3\CMS\Core\Resource\AbstractFile\getStorage
‪ResourceStorage getStorage()
Definition: AbstractFile.php:390