‪TYPO3CMS  11.5
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;
32 
42 {
46  protected ‪$table = 'sys_file';
47 
51  protected ‪$eventDispatcher;
52 
58  protected ‪$fields = [
59  'uid', 'pid', 'missing', 'type', 'storage', 'identifier', 'identifier_hash', 'extension',
60  'mime_type', 'name', 'sha1', 'size', 'creation_date', 'modification_date', 'folder_hash',
61  ];
62 
69  public static function ‪getInstance()
70  {
71  trigger_error(__CLASS__ . '::getInstance() will be removed in TYPO3 v12.0. Use Dependency Injection or GeneralUtility::makeInstance() if DI is not possible.', E_USER_DEPRECATED);
72  return GeneralUtility::makeInstance(self::class);
73  }
74 
75  public function ‪__construct(EventDispatcherInterface ‪$eventDispatcher)
76  {
77  $this->eventDispatcher = ‪$eventDispatcher;
78  }
79 
86  public function ‪findOneByUid($fileUid)
87  {
88  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
89  ->getQueryBuilderForTable($this->table);
90 
91  $row = $queryBuilder
92  ->select(...$this->fields)
93  ->from($this->table)
94  ->where(
95  $queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($fileUid, ‪Connection::PARAM_INT))
96  )
97  ->executeQuery()
98  ->fetchAssociative();
99 
100  return is_array($row) ? $row : false;
101  }
102 
112  public function ‪findOneByStorageUidAndIdentifierHash($storageUid, $identifierHash)
113  {
114  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
115  ->getQueryBuilderForTable($this->table);
116 
117  $row = $queryBuilder
118  ->select(...$this->fields)
119  ->from($this->table)
120  ->where(
121  $queryBuilder->expr()->eq('storage', $queryBuilder->createNamedParameter($storageUid, ‪Connection::PARAM_INT)),
122  $queryBuilder->expr()->eq('identifier_hash', $queryBuilder->createNamedParameter($identifierHash))
123  )
124  ->executeQuery()
125  ->fetchAssociative();
126 
127  return is_array($row) ? $row : false;
128  }
129 
139  public function ‪findOneByStorageAndIdentifier(ResourceStorage $storage, $identifier)
140  {
141  $identifierHash = $storage->hashFileIdentifier($identifier);
142  return $this->‪findOneByStorageUidAndIdentifierHash($storage->getUid(), $identifierHash);
143  }
144 
153  public function ‪findOneByFileObject(FileInterface $fileObject)
154  {
155  return $this->‪findOneByStorageAndIdentifier($fileObject->getStorage(), $fileObject->getIdentifier());
156  }
157 
165  public function ‪findByContentHash($hash)
166  {
167  if (!preg_match('/^[0-9a-f]{40}$/i', $hash)) {
168  return [];
169  }
170 
171  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
172  ->getQueryBuilderForTable($this->table);
173 
174  $resultRows = $queryBuilder
175  ->select(...$this->fields)
176  ->from($this->table)
177  ->where(
178  $queryBuilder->expr()->eq('sha1', $queryBuilder->createNamedParameter($hash, ‪Connection::PARAM_STR))
179  )
180  ->executeQuery()
181  ->fetchAllAssociative();
182 
183  return $resultRows;
184  }
185 
192  public function ‪findByFolder(Folder $folder)
193  {
194  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
195  ->getQueryBuilderForTable($this->table);
196 
197  $result = $queryBuilder
198  ->select(...$this->fields)
199  ->from($this->table)
200  ->where(
201  $queryBuilder->expr()->eq(
202  'folder_hash',
203  $queryBuilder->createNamedParameter($folder->getHashedIdentifier(), ‪Connection::PARAM_STR)
204  ),
205  $queryBuilder->expr()->eq(
206  'storage',
207  $queryBuilder->createNamedParameter($folder->getStorage()->getUid(), ‪Connection::PARAM_INT)
208  )
209  )
210  ->executeQuery();
211 
212  $resultRows = [];
213  while ($row = $result->fetchAssociative()) {
214  $resultRows[$row['identifier']] = $row;
215  }
216 
217  return $resultRows;
218  }
219 
228  public function ‪findByFolders(array $folders, $includeMissing = true, $fileName = null)
229  {
230  $storageUids = [];
231  $folderIdentifiers = [];
232 
233  foreach ($folders as $folder) {
234  if (!$folder instanceof Folder) {
235  continue;
236  }
237 
238  $storageUids[] = (int)$folder->getStorage()->getUid();
239  $folderIdentifiers[] = $folder->getHashedIdentifier();
240  }
241 
242  $storageUids = array_unique($storageUids);
243  $folderIdentifiers = array_unique($folderIdentifiers);
244 
245  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($this->table);
246 
247  $queryBuilder
248  ->select(...$this->fields)
249  ->from($this->table)
250  ->where(
251  $queryBuilder->expr()->in(
252  'folder_hash',
253  $queryBuilder->createNamedParameter($folderIdentifiers, Connection::PARAM_STR_ARRAY)
254  ),
255  $queryBuilder->expr()->in(
256  'storage',
257  $queryBuilder->createNamedParameter($storageUids, Connection::PARAM_INT_ARRAY)
258  )
259  );
260 
261  if (isset($fileName)) {
262  $nameParts = str_getcsv($fileName, ' ');
263  foreach ($nameParts as $part) {
264  $part = trim($part);
265  if ($part !== '') {
266  $queryBuilder->andWhere(
267  $queryBuilder->expr()->like(
268  'name',
269  $queryBuilder->createNamedParameter(
270  '%' . $queryBuilder->escapeLikeWildcards($part) . '%',
272  )
273  )
274  );
275  }
276  }
277  }
278 
279  if (!$includeMissing) {
280  $queryBuilder->andWhere($queryBuilder->expr()->eq('missing', $queryBuilder->createNamedParameter(0, ‪Connection::PARAM_INT)));
281  }
282 
283  $result = $queryBuilder->executeQuery();
284 
285  $fileRecords = [];
286  while ($fileRecord = $result->fetchAssociative()) {
287  $fileRecords[$fileRecord['identifier']] = $fileRecord;
288  }
289 
290  return $fileRecords;
291  }
292 
298  public function ‪add(File $file)
299  {
300  if ($this->‪hasIndexRecord($file)) {
301  $this->‪update($file);
302  if ($file->_getPropertyRaw('uid') === null) {
303  $file->updateProperties($this->‪findOneByFileObject($file));
304  }
305  } else {
306  $file->updateProperties(['uid' => $this->‪insertRecord($file->getProperties())]);
307  }
308  }
309 
316  public function ‪addRaw(array $data)
317  {
318  $data['uid'] = $this->‪insertRecord($data);
319  return $data;
320  }
321 
329  protected function ‪insertRecord(array $data)
330  {
331  $data = array_intersect_key($data, array_flip($this->fields));
332  $data['tstamp'] = time();
333  $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($this->table);
334  $connection->insert(
335  $this->table,
336  $data
337  );
338  $data['uid'] = (int)$connection->lastInsertId($this->table);
339  $this->‪updateRefIndex($data['uid']);
340  $this->eventDispatcher->dispatch(new AfterFileAddedToIndexEvent($data['uid'], $data));
341  return $data['uid'];
342  }
343 
350  public function ‪hasIndexRecord(File $file)
351  {
352  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($this->table);
353 
354  if ((int)$file->_getPropertyRaw('uid') > 0) {
355  $constraints = [
356  $queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($file->getUid(), ‪Connection::PARAM_INT)),
357  ];
358  } else {
359  $constraints = [
360  $queryBuilder->expr()->eq(
361  'storage',
362  $queryBuilder->createNamedParameter($file->getStorage()->getUid(), ‪Connection::PARAM_INT)
363  ),
364  $queryBuilder->expr()->eq(
365  'identifier',
366  $queryBuilder->createNamedParameter($file->_getPropertyRaw('identifier'), ‪Connection::PARAM_STR)
367  ),
368  ];
369  }
370 
371  $count = $queryBuilder
372  ->count('uid')
373  ->from($this->table)
374  ->where(...$constraints)
375  ->executeQuery()
376  ->fetchOne();
377 
378  return (bool)$count;
379  }
380 
386  public function ‪update(File $file)
387  {
388  $updatedProperties = array_intersect($this->fields, $file->getUpdatedProperties());
389  $updateRow = [];
390  foreach ($updatedProperties as $key) {
391  $updateRow[$key] = $file->getProperty($key);
392  }
393  if (!empty($updateRow)) {
394  if ((int)$file->_getPropertyRaw('uid') > 0) {
395  $constraints = ['uid' => (int)$file->getUid()];
396  } else {
397  $constraints = [
398  'storage' => (int)$file->getStorage()->getUid(),
399  'identifier' => $file->_getPropertyRaw('identifier'),
400  ];
401  }
402 
403  $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($this->table);
404  $updateRow['tstamp'] = time();
405 
406  $connection->update(
407  $this->table,
408  $updateRow,
409  $constraints
410  );
411 
412  $this->‪updateRefIndex($file->getUid());
413  $this->eventDispatcher->dispatch(new AfterFileUpdatedInIndexEvent($file, array_intersect_key($file->getProperties(), array_flip($this->fields)), $updateRow));
414  }
415  }
416 
424  public function ‪findInStorageWithIndexOutstanding(ResourceStorage $storage, $limit = -1)
425  {
426  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($this->table);
427 
428  if ((int)$limit > 0) {
429  $queryBuilder->setMaxResults((int)$limit);
430  }
431 
432  $rows = $queryBuilder
433  ->select(...$this->fields)
434  ->from($this->table)
435  ->where(
436  $queryBuilder->expr()->gt('tstamp', $queryBuilder->quoteIdentifier('last_indexed')),
437  $queryBuilder->expr()->eq('storage', $queryBuilder->createNamedParameter($storage->getUid(), ‪Connection::PARAM_INT))
438  )
439  ->orderBy('tstamp', 'ASC')
440  ->executeQuery()
441  ->fetchAllAssociative();
442 
443  return $rows;
444  }
445 
453  public function ‪findInStorageAndNotInUidList(ResourceStorage $storage, array $uidList)
454  {
455  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($this->table);
456 
457  $queryBuilder
458  ->select(...$this->fields)
459  ->from($this->table)
460  ->where(
461  $queryBuilder->expr()->eq(
462  'storage',
463  $queryBuilder->createNamedParameter($storage->getUid(), ‪Connection::PARAM_INT)
464  )
465  );
466 
467  if (!empty($uidList)) {
468  $queryBuilder->andWhere(
469  $queryBuilder->expr()->notIn(
470  'uid',
471  array_map('intval', $uidList)
472  )
473  );
474  }
475 
476  $rows = $queryBuilder->executeQuery()->fetchAllAssociative();
477 
478  return $rows;
479  }
480 
486  public function ‪updateIndexingTime($fileUid)
487  {
488  $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($this->table);
489  $connection->update(
490  $this->table,
491  [
492  'last_indexed' => time(),
493  ],
494  [
495  'uid' => (int)$fileUid,
496  ]
497  );
498  }
499 
505  public function ‪markFileAsMissing($fileUid)
506  {
507  $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($this->table);
508  $connection->update(
509  $this->table,
510  [
511  'missing' => 1,
512  ],
513  [
514  'uid' => (int)$fileUid,
515  ]
516  );
517  $this->eventDispatcher->dispatch(new AfterFileMarkedAsMissingEvent((int)$fileUid));
518  }
519 
525  public function remove($fileUid)
526  {
527  $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($this->table);
528  $connection->delete(
529  $this->table,
530  [
531  'uid' => (int)$fileUid,
532  ]
533  );
534  $this->‪updateRefIndex($fileUid);
535  $this->eventDispatcher->dispatch(new AfterFileRemovedFromIndexEvent((int)$fileUid));
536  }
537 
543  public function ‪updateRefIndex($id)
544  {
545  $refIndexObj = GeneralUtility::makeInstance(ReferenceIndex::class);
546  $refIndexObj->updateRefIndexTable($this->table, $id);
547  }
548 }
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\findInStorageAndNotInUidList
‪array findInStorageAndNotInUidList(ResourceStorage $storage, array $uidList)
Definition: FileIndexRepository.php:450
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\findOneByFileObject
‪array bool findOneByFileObject(FileInterface $fileObject)
Definition: FileIndexRepository.php:150
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository
Definition: FileIndexRepository.php:42
‪TYPO3\CMS\Core\Database\Connection\PARAM_INT
‪const PARAM_INT
Definition: Connection.php:49
‪TYPO3\CMS\Core\Resource\ResourceStorage\getUid
‪int getUid()
Definition: ResourceStorage.php:330
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\addRaw
‪array addRaw(array $data)
Definition: FileIndexRepository.php:313
‪TYPO3\CMS\Core\Resource\FileInterface
Definition: FileInterface.php:22
‪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:225
‪TYPO3\CMS\Core\Database\ReferenceIndex
Definition: ReferenceIndex.php:42
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\hasIndexRecord
‪bool hasIndexRecord(File $file)
Definition: FileIndexRepository.php:347
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\findByFolder
‪array null findByFolder(Folder $folder)
Definition: FileIndexRepository.php:189
‪TYPO3\CMS\Core\Resource\Event\AfterFileAddedToIndexEvent
Definition: AfterFileAddedToIndexEvent.php:26
‪TYPO3\CMS\Core\Resource\ResourceInterface\getIdentifier
‪string getIdentifier()
‪TYPO3\CMS\Core\Resource\File\getUpdatedProperties
‪array getUpdatedProperties()
Definition: File.php:205
‪TYPO3\CMS\Core\Resource\ResourceInterface\getStorage
‪ResourceStorage getStorage()
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\update
‪update(File $file)
Definition: FileIndexRepository.php:383
‪TYPO3\CMS\Core\Database\Connection\PARAM_STR
‪const PARAM_STR
Definition: Connection.php:54
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\add
‪add(File $file)
Definition: FileIndexRepository.php:295
‪TYPO3\CMS\Core\Resource\Folder\getStorage
‪ResourceStorage getStorage()
Definition: Folder.php:149
‪TYPO3\CMS\Core\Resource\ResourceStorage\hashFileIdentifier
‪string hashFileIdentifier($file)
Definition: ResourceStorage.php:1355
‪TYPO3\CMS\Core\Resource\File\getProperties
‪array getProperties()
Definition: File.php:93
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\updateIndexingTime
‪updateIndexingTime($fileUid)
Definition: FileIndexRepository.php:483
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\findByContentHash
‪mixed findByContentHash($hash)
Definition: FileIndexRepository.php:162
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\findInStorageWithIndexOutstanding
‪array findInStorageWithIndexOutstanding(ResourceStorage $storage, $limit=-1)
Definition: FileIndexRepository.php:421
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\$eventDispatcher
‪EventDispatcherInterface $eventDispatcher
Definition: FileIndexRepository.php:49
‪TYPO3\CMS\Core\Resource\Folder
Definition: Folder.php:37
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\getInstance
‪static FileIndexRepository getInstance()
Definition: FileIndexRepository.php:66
‪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:72
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\insertRecord
‪int insertRecord(array $data)
Definition: FileIndexRepository.php:326
‪TYPO3\CMS\Core\Resource\AbstractFile\getUid
‪int getUid()
Definition: AbstractFile.php:203
‪TYPO3\CMS\Core\Resource\Index
Definition: ExtractorInterface.php:16
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\$fields
‪array $fields
Definition: FileIndexRepository.php:55
‪TYPO3\CMS\Core\Database\Connection
Definition: Connection.php:38
‪TYPO3\CMS\Core\Resource\ResourceStorage
Definition: ResourceStorage.php:125
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\findOneByUid
‪array false findOneByUid($fileUid)
Definition: FileIndexRepository.php:83
‪TYPO3\CMS\Core\SingletonInterface
Definition: SingletonInterface.php:22
‪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:502
‪TYPO3\CMS\Core\Resource\File\updateProperties
‪updateProperties(array $properties)
Definition: File.php:166
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\$table
‪string $table
Definition: FileIndexRepository.php:45
‪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:50
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\findOneByStorageUidAndIdentifierHash
‪array false findOneByStorageUidAndIdentifierHash($storageUid, $identifierHash)
Definition: FileIndexRepository.php:109
‪TYPO3\CMS\Core\Resource\Folder\getHashedIdentifier
‪string getHashedIdentifier()
Definition: Folder.php:170
‪TYPO3\CMS\Core\Resource\File\_getPropertyRaw
‪mixed _getPropertyRaw($key)
Definition: File.php:331
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\findOneByStorageAndIdentifier
‪array bool findOneByStorageAndIdentifier(ResourceStorage $storage, $identifier)
Definition: FileIndexRepository.php:136
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\updateRefIndex
‪updateRefIndex($id)
Definition: FileIndexRepository.php:540
‪TYPO3\CMS\Core\Resource\AbstractFile\getStorage
‪ResourceStorage getStorage()
Definition: AbstractFile.php:395