‪TYPO3CMS  ‪main
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 
63  public function ‪__construct(EventDispatcherInterface ‪$eventDispatcher)
64  {
65  $this->eventDispatcher = ‪$eventDispatcher;
66  }
67 
74  public function ‪findOneByUid($fileUid)
75  {
76  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
77  ->getQueryBuilderForTable($this->table);
78 
79  $row = $queryBuilder
80  ->select(...$this->fields)
81  ->from($this->table)
82  ->where(
83  $queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($fileUid, ‪Connection::PARAM_INT))
84  )
85  ->executeQuery()
86  ->fetchAssociative();
87 
88  return is_array($row) ? $row : false;
89  }
90 
100  public function ‪findOneByStorageUidAndIdentifierHash($storageUid, $identifierHash)
101  {
102  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
103  ->getQueryBuilderForTable($this->table);
104 
105  $row = $queryBuilder
106  ->select(...$this->fields)
107  ->from($this->table)
108  ->where(
109  $queryBuilder->expr()->eq('storage', $queryBuilder->createNamedParameter($storageUid, ‪Connection::PARAM_INT)),
110  $queryBuilder->expr()->eq('identifier_hash', $queryBuilder->createNamedParameter($identifierHash))
111  )
112  ->executeQuery()
113  ->fetchAssociative();
114 
115  return is_array($row) ? $row : false;
116  }
117 
125  public function ‪findOneByStorageAndIdentifier(ResourceStorage $storage, ‪$identifier)
126  {
127  $identifierHash = $storage->hashFileIdentifier(‪$identifier);
128  return $this->‪findOneByStorageUidAndIdentifierHash($storage->getUid(), $identifierHash);
129  }
130 
137  public function ‪findOneByFileObject(FileInterface $fileObject)
138  {
139  return $this->‪findOneByStorageAndIdentifier($fileObject->getStorage(), $fileObject->getIdentifier());
140  }
141 
149  public function ‪findByContentHash($hash)
150  {
151  if (!preg_match('/^[0-9a-f]{40}$/i', $hash)) {
152  return [];
153  }
154 
155  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
156  ->getQueryBuilderForTable($this->table);
157 
158  $resultRows = $queryBuilder
159  ->select(...$this->fields)
160  ->from($this->table)
161  ->where(
162  $queryBuilder->expr()->eq('sha1', $queryBuilder->createNamedParameter($hash))
163  )
164  ->executeQuery()
165  ->fetchAllAssociative();
166 
167  return $resultRows;
168  }
169 
175  public function ‪findByFolder(Folder $folder)
176  {
177  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
178  ->getQueryBuilderForTable($this->table);
179 
180  $result = $queryBuilder
181  ->select(...$this->fields)
182  ->from($this->table)
183  ->where(
184  $queryBuilder->expr()->eq(
185  'folder_hash',
186  $queryBuilder->createNamedParameter($folder->getHashedIdentifier())
187  ),
188  $queryBuilder->expr()->eq(
189  'storage',
190  $queryBuilder->createNamedParameter($folder->getStorage()->getUid(), ‪Connection::PARAM_INT)
191  )
192  )
193  ->executeQuery();
194 
195  $resultRows = [];
196  while ($row = $result->fetchAssociative()) {
197  $resultRows[$row['identifier']] = $row;
198  }
199 
200  return $resultRows;
201  }
202 
211  public function ‪findByFolders(array $folders, $includeMissing = true, $fileName = null)
212  {
213  $storageUids = [];
214  $folderIdentifiers = [];
215 
216  foreach ($folders as $folder) {
217  if (!$folder instanceof Folder) {
218  continue;
219  }
220 
221  $storageUids[] = (int)$folder->getStorage()->getUid();
222  $folderIdentifiers[] = $folder->getHashedIdentifier();
223  }
224 
225  $storageUids = array_unique($storageUids);
226  $folderIdentifiers = array_unique($folderIdentifiers);
227 
228  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($this->table);
229 
230  $queryBuilder
231  ->select(...$this->fields)
232  ->from($this->table)
233  ->where(
234  $queryBuilder->expr()->in(
235  'folder_hash',
236  $queryBuilder->createNamedParameter($folderIdentifiers, Connection::PARAM_STR_ARRAY)
237  ),
238  $queryBuilder->expr()->in(
239  'storage',
240  $queryBuilder->createNamedParameter($storageUids, Connection::PARAM_INT_ARRAY)
241  )
242  );
243 
244  if (isset($fileName)) {
245  $nameParts = str_getcsv($fileName, ' ');
246  foreach ($nameParts as $part) {
247  $part = trim($part);
248  if ($part !== '') {
249  $queryBuilder->andWhere(
250  $queryBuilder->expr()->like(
251  'name',
252  $queryBuilder->createNamedParameter(
253  '%' . $queryBuilder->escapeLikeWildcards($part) . '%'
254  )
255  )
256  );
257  }
258  }
259  }
260 
261  if (!$includeMissing) {
262  $queryBuilder->andWhere($queryBuilder->expr()->eq('missing', $queryBuilder->createNamedParameter(0, ‪Connection::PARAM_INT)));
263  }
264 
265  $result = $queryBuilder->executeQuery();
266 
267  $fileRecords = [];
268  while ($fileRecord = $result->fetchAssociative()) {
269  $fileRecords[$fileRecord['identifier']] = $fileRecord;
270  }
271 
272  return $fileRecords;
273  }
274 
278  public function ‪add(File $file)
279  {
280  if ($this->‪hasIndexRecord($file)) {
281  $this->‪update($file);
282  if ($file->_getPropertyRaw('uid') === null) {
283  $file->updateProperties($this->‪findOneByFileObject($file));
284  }
285  } else {
286  $file->updateProperties(['uid' => $this->‪insertRecord($file->getProperties())]);
287  }
288  }
289 
295  public function ‪addRaw(array $data)
296  {
297  $data['uid'] = $this->‪insertRecord($data);
298  return $data;
299  }
300 
307  protected function ‪insertRecord(array $data)
308  {
309  $data = array_intersect_key($data, array_flip($this->fields));
310  $data['tstamp'] = time();
311  $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($this->table);
312  $connection->insert(
313  $this->table,
314  $data
315  );
316  $data['uid'] = (int)$connection->lastInsertId($this->table);
317  $this->‪updateRefIndex($data['uid']);
318  $this->eventDispatcher->dispatch(new AfterFileAddedToIndexEvent($data['uid'], $data));
319  return $data['uid'];
320  }
321 
327  public function ‪hasIndexRecord(File $file)
328  {
329  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($this->table);
330 
331  if ((int)$file->_getPropertyRaw('uid') > 0) {
332  $constraints = [
333  $queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($file->getUid(), ‪Connection::PARAM_INT)),
334  ];
335  } else {
336  $constraints = [
337  $queryBuilder->expr()->eq(
338  'storage',
339  $queryBuilder->createNamedParameter($file->getStorage()->getUid(), ‪Connection::PARAM_INT)
340  ),
341  $queryBuilder->expr()->eq(
342  'identifier',
343  $queryBuilder->createNamedParameter($file->_getPropertyRaw('identifier'))
344  ),
345  ];
346  }
347 
348  $count = $queryBuilder
349  ->count('uid')
350  ->from($this->table)
351  ->where(...$constraints)
352  ->executeQuery()
353  ->fetchOne();
354 
355  return (bool)$count;
356  }
357 
361  public function ‪update(File $file)
362  {
363  $updatedProperties = array_intersect($this->fields, $file->getUpdatedProperties());
364  $updateRow = [];
365  foreach ($updatedProperties as $key) {
366  $updateRow[$key] = $file->getProperty($key);
367  }
368  if (!empty($updateRow)) {
369  if ((int)$file->_getPropertyRaw('uid') > 0) {
370  $constraints = ['uid' => (int)$file->getUid()];
371  } else {
372  $constraints = [
373  'storage' => (int)$file->getStorage()->getUid(),
374  'identifier' => $file->_getPropertyRaw('identifier'),
375  ];
376  }
377 
378  $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($this->table);
379  $updateRow['tstamp'] = time();
380 
381  $connection->update(
382  $this->table,
383  $updateRow,
384  $constraints
385  );
386 
387  $this->‪updateRefIndex($file->getUid());
388  $this->eventDispatcher->dispatch(new AfterFileUpdatedInIndexEvent($file, array_intersect_key($file->getProperties(), array_flip($this->fields)), $updateRow));
389  }
390  }
391 
398  public function ‪findInStorageWithIndexOutstanding(ResourceStorage $storage, $limit = -1)
399  {
400  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($this->table);
401 
402  if ((int)$limit > 0) {
403  $queryBuilder->setMaxResults((int)$limit);
404  }
405 
406  $rows = $queryBuilder
407  ->select(...$this->fields)
408  ->from($this->table)
409  ->where(
410  $queryBuilder->expr()->gt('tstamp', $queryBuilder->quoteIdentifier('last_indexed')),
411  $queryBuilder->expr()->eq('storage', $queryBuilder->createNamedParameter($storage->getUid(), ‪Connection::PARAM_INT))
412  )
413  ->orderBy('tstamp', 'ASC')
414  ->executeQuery()
415  ->fetchAllAssociative();
416 
417  return $rows;
418  }
419 
426  public function ‪findInStorageAndNotInUidList(ResourceStorage $storage, array $uidList)
427  {
428  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($this->table);
429 
430  $queryBuilder
431  ->select(...$this->fields)
432  ->from($this->table)
433  ->where(
434  $queryBuilder->expr()->eq(
435  'storage',
436  $queryBuilder->createNamedParameter($storage->getUid(), ‪Connection::PARAM_INT)
437  )
438  );
439 
440  if (!empty($uidList)) {
441  $queryBuilder->andWhere(
442  $queryBuilder->expr()->notIn(
443  'uid',
444  array_map('intval', $uidList)
445  )
446  );
447  }
448 
449  $rows = $queryBuilder->executeQuery()->fetchAllAssociative();
450 
451  return $rows;
452  }
453 
459  public function ‪updateIndexingTime($fileUid)
460  {
461  $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($this->table);
462  $connection->update(
463  $this->table,
464  [
465  'last_indexed' => time(),
466  ],
467  [
468  'uid' => (int)$fileUid,
469  ]
470  );
471  }
472 
478  public function ‪markFileAsMissing($fileUid)
479  {
480  $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($this->table);
481  $connection->update(
482  $this->table,
483  [
484  'missing' => 1,
485  ],
486  [
487  'uid' => (int)$fileUid,
488  ]
489  );
490  $this->eventDispatcher->dispatch(new AfterFileMarkedAsMissingEvent((int)$fileUid));
491  }
492 
498  public function remove($fileUid)
499  {
500  $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($this->table);
501  $connection->delete(
502  $this->table,
503  [
504  'uid' => (int)$fileUid,
505  ]
506  );
507  $this->‪updateRefIndex($fileUid);
508  $this->eventDispatcher->dispatch(new AfterFileRemovedFromIndexEvent((int)$fileUid));
509  }
510 
516  public function ‪updateRefIndex($id)
517  {
518  $refIndexObj = GeneralUtility::makeInstance(ReferenceIndex::class);
519  $refIndexObj->updateRefIndexTable($this->table, $id);
520  }
521 }
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\findInStorageAndNotInUidList
‪array findInStorageAndNotInUidList(ResourceStorage $storage, array $uidList)
Definition: FileIndexRepository.php:423
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\findOneByFileObject
‪array bool findOneByFileObject(FileInterface $fileObject)
Definition: FileIndexRepository.php:134
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository
Definition: FileIndexRepository.php:42
‪TYPO3\CMS\Core\Database\Connection\PARAM_INT
‪const PARAM_INT
Definition: Connection.php:47
‪TYPO3\CMS\Core\Resource\ResourceStorage\getUid
‪int getUid()
Definition: ResourceStorage.php:328
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\addRaw
‪array addRaw(array $data)
Definition: FileIndexRepository.php:292
‪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:208
‪TYPO3\CMS\Core\Database\ReferenceIndex
Definition: ReferenceIndex.php:43
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\hasIndexRecord
‪bool hasIndexRecord(File $file)
Definition: FileIndexRepository.php:324
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\findByFolder
‪array null findByFolder(Folder $folder)
Definition: FileIndexRepository.php:172
‪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:198
‪TYPO3\CMS\Core\Resource\ResourceInterface\getStorage
‪ResourceStorage getStorage()
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\update
‪update(File $file)
Definition: FileIndexRepository.php:358
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\add
‪add(File $file)
Definition: FileIndexRepository.php:275
‪TYPO3\CMS\Core\Resource\Folder\getStorage
‪ResourceStorage getStorage()
Definition: Folder.php:148
‪TYPO3\CMS\Core\Resource\ResourceStorage\hashFileIdentifier
‪string hashFileIdentifier($file)
Definition: ResourceStorage.php:1309
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\updateIndexingTime
‪updateIndexingTime($fileUid)
Definition: FileIndexRepository.php:456
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\findByContentHash
‪mixed findByContentHash($hash)
Definition: FileIndexRepository.php:146
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\findInStorageWithIndexOutstanding
‪array findInStorageWithIndexOutstanding(ResourceStorage $storage, $limit=-1)
Definition: FileIndexRepository.php:395
‪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\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:60
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\insertRecord
‪int insertRecord(array $data)
Definition: FileIndexRepository.php:304
‪TYPO3\CMS\Core\Resource\AbstractFile\getUid
‪int getUid()
Definition: AbstractFile.php:203
‪TYPO3\CMS\Core\Resource\File\getProperties
‪getProperties()
Definition: File.php:86
‪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:36
‪TYPO3\CMS\Core\Resource\ResourceStorage
Definition: ResourceStorage.php:127
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\findOneByUid
‪array false findOneByUid($fileUid)
Definition: FileIndexRepository.php:71
‪TYPO3\CMS\Core\SingletonInterface
Definition: SingletonInterface.php:23
‪TYPO3\CMS\Core\Resource\File\getProperty
‪mixed getProperty($key)
Definition: File.php:61
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\markFileAsMissing
‪markFileAsMissing($fileUid)
Definition: FileIndexRepository.php:475
‪TYPO3\CMS\Core\Resource\File\updateProperties
‪updateProperties(array $properties)
Definition: File.php:159
‪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:51
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:51
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\findOneByStorageUidAndIdentifierHash
‪array false findOneByStorageUidAndIdentifierHash($storageUid, $identifierHash)
Definition: FileIndexRepository.php:97
‪TYPO3\CMS\Core\Resource\Folder\getHashedIdentifier
‪string getHashedIdentifier()
Definition: Folder.php:169
‪TYPO3\CMS\Webhooks\Message\$identifier
‪identifier readonly string $identifier
Definition: FileAddedMessage.php:37
‪TYPO3\CMS\Core\Resource\File\_getPropertyRaw
‪mixed _getPropertyRaw($key)
Definition: File.php:321
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\findOneByStorageAndIdentifier
‪array bool findOneByStorageAndIdentifier(ResourceStorage $storage, $identifier)
Definition: FileIndexRepository.php:122
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\updateRefIndex
‪updateRefIndex($id)
Definition: FileIndexRepository.php:513
‪TYPO3\CMS\Core\Resource\AbstractFile\getStorage
‪ResourceStorage getStorage()
Definition: AbstractFile.php:395