‪TYPO3CMS  ‪main
MetaDataRepository.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;
30 use TYPO3\CMS\Core\Type\File\ImageInfo;
32 
40 {
44  protected ‪$tableName = 'sys_file_metadata';
45 
51  protected ‪$tableFields = [];
52 
53  public function ‪__construct(
54  protected readonly EventDispatcherInterface $eventDispatcher,
55  ) {}
56 
62  public function ‪findByFile(‪File $file)
63  {
64  ‪$record = $this->‪findByFileUid($file->‪getUid());
65 
66  // It could be possible that the meta information is freshly
67  // created and inserted into the database. If this is the case
68  // we have to take care about correct meta information for width and
69  // height in case of an image.
70  // This logic can be transferred into a custom PSR-14 event listener in the future by just using
71  // the AfterMetaDataCreated event.
72  if (!empty(‪$record['crdate']) && (int)‪$record['crdate'] === ‪$GLOBALS['EXEC_TIME']) {
73  if ($file->‪isType(FileType::IMAGE) && $file->‪getStorage()->getDriverType() === 'Local') {
74  $fileNameAndPath = $file->‪getForLocalProcessing(false);
75 
76  $imageInfo = GeneralUtility::makeInstance(ImageInfo::class, $fileNameAndPath);
77 
78  $additionalMetaInformation = [
79  'width' => $imageInfo->getWidth(),
80  'height' => $imageInfo->getHeight(),
81  ];
82 
83  $this->‪update($file->‪getUid(), $additionalMetaInformation, ‪$record);
84  }
85  ‪$record = $this->‪findByFileUid($file->‪getUid());
86  }
87 
88  return ‪$record;
89  }
90 
98  public function ‪findByFileUid(‪$uid)
99  {
100  ‪$uid = (int)‪$uid;
101  if (‪$uid <= 0) {
102  throw new InvalidUidException('Metadata can only be retrieved for indexed files. UID: "' . ‪$uid . '"', 1381590731);
103  }
104 
105  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($this->tableName);
106 
107  $queryBuilder->getRestrictions()->add(GeneralUtility::makeInstance(RootLevelRestriction::class));
108 
109  ‪$record = $queryBuilder
110  ->select('*')
111  ->from($this->tableName)
112  ->where(
113  $queryBuilder->expr()->eq('file', $queryBuilder->createNamedParameter(‪$uid, ‪Connection::PARAM_INT)),
114  $queryBuilder->expr()->in('sys_language_uid', $queryBuilder->createNamedParameter([0, -1], ‪Connection::PARAM_INT_ARRAY))
115  )
116  ->executeQuery()
117  ->fetchAssociative();
118 
119  if (empty(‪$record)) {
120  return [];
121  }
122 
123  return $this->eventDispatcher->dispatch(new EnrichFileMetaDataEvent(‪$uid, (int)‪$record['uid'], ‪$record))->getRecord();
124  }
125 
132  public function ‪createMetaDataRecord($fileUid, array $additionalFields = [])
133  {
134  $emptyRecord = [
135  'file' => (int)$fileUid,
136  'pid' => 0,
137  'crdate' => ‪$GLOBALS['EXEC_TIME'],
138  'tstamp' => ‪$GLOBALS['EXEC_TIME'],
139  'l10n_diffsource' => '',
140  ];
141  $additionalFields = array_intersect_key($additionalFields, $this->‪getTableFields());
142  $emptyRecord = array_merge($emptyRecord, $additionalFields);
143 
144  $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($this->tableName);
145  $connection->insert(
146  $this->tableName,
147  $emptyRecord,
148  ['l10n_diffsource' => ‪Connection::PARAM_LOB]
149  );
150 
151  ‪$record = $emptyRecord;
152  ‪$record['uid'] = $connection->lastInsertId();
153 
154  return $this->eventDispatcher->dispatch(new AfterFileMetaDataCreatedEvent($fileUid, (int)‪$record['uid'], ‪$record))->getRecord();
155  }
156 
166  public function ‪update($fileUid, array $updateData, ?array $metaDataFromDatabase = null): array
167  {
168  // backwards compatibility layer
169  $metaDataFromDatabase ??= $this->‪findByFileUid($fileUid);
170 
171  $updateRow = array_intersect_key($updateData, $this->‪getTableFields());
172  if ($updateRow === []) {
173  // No valid keys to update - return current database row
174  return $metaDataFromDatabase;
175  }
176  if (array_key_exists('uid', $updateRow)) {
177  unset($updateRow['uid']);
178  }
179  $updateRow = array_diff($updateRow, $metaDataFromDatabase);
180  if ($updateRow === []) {
181  // Nothing to update - return current database row
182  return $metaDataFromDatabase;
183  }
184 
185  $updateRow['tstamp'] = time();
186  $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($this->tableName);
187  $connection->update(
188  $this->tableName,
189  $updateRow,
190  [
191  'uid' => (int)$metaDataFromDatabase['uid'],
192  ]
193  );
194 
195  return $this->eventDispatcher->dispatch(
196  new AfterFileMetaDataUpdatedEvent($fileUid, (int)$metaDataFromDatabase['uid'], array_merge($metaDataFromDatabase, $updateRow))
197  )->getRecord();
198  }
199 
205  public function ‪removeByFileUid($fileUid)
206  {
207  GeneralUtility::makeInstance(ConnectionPool::class)
208  ->getConnectionForTable($this->tableName)
209  ->delete(
210  $this->tableName,
211  [
212  'file' => (int)$fileUid,
213  ]
214  );
215 
216  $this->eventDispatcher->dispatch(new AfterFileMetaDataDeletedEvent((int)$fileUid));
217  }
218 
222  protected function ‪getTableFields(): array
223  {
224  if (empty($this->tableFields)) {
225  $this->tableFields = GeneralUtility::makeInstance(ConnectionPool::class)
226  ->getConnectionForTable($this->tableName)
227  ->createSchemaManager()
228  ->listTableColumns($this->tableName);
229  }
230 
231  return ‪$this->tableFields;
232  }
233 }
‪TYPO3\CMS\Core\Resource\Index\MetaDataRepository
Definition: MetaDataRepository.php:40
‪TYPO3\CMS\Core\Database\Connection\PARAM_INT
‪const PARAM_INT
Definition: Connection.php:52
‪TYPO3\CMS\Core\Resource\AbstractFile\getForLocalProcessing
‪non empty string getForLocalProcessing(bool $writable=true)
Definition: AbstractFile.php:576
‪TYPO3\CMS\Core\Resource\Index\MetaDataRepository\findByFileUid
‪array findByFileUid($uid)
Definition: MetaDataRepository.php:96
‪TYPO3\CMS\Core\Resource\Event\AfterFileMetaDataDeletedEvent
Definition: AfterFileMetaDataDeletedEvent.php:25
‪TYPO3\CMS\Core\Resource\Index\MetaDataRepository\__construct
‪__construct(protected readonly EventDispatcherInterface $eventDispatcher,)
Definition: MetaDataRepository.php:51
‪TYPO3\CMS\Core\Resource\Event\AfterFileMetaDataCreatedEvent
Definition: AfterFileMetaDataCreatedEvent.php:25
‪TYPO3\CMS\Core\Resource\Exception\InvalidUidException
Definition: InvalidUidException.php:23
‪TYPO3\CMS\Core\Resource\Index\MetaDataRepository\findByFile
‪array findByFile(File $file)
Definition: MetaDataRepository.php:60
‪TYPO3\CMS\Core\Resource\Index\MetaDataRepository\getTableFields
‪getTableFields()
Definition: MetaDataRepository.php:220
‪TYPO3\CMS\Core\Resource\Index\MetaDataRepository\removeByFileUid
‪removeByFileUid($fileUid)
Definition: MetaDataRepository.php:203
‪TYPO3\CMS\Core\Resource\AbstractFile\isType
‪isType(FileType $fileType)
Definition: AbstractFile.php:292
‪TYPO3\CMS\Core\Database\Query\Restriction\RootLevelRestriction
Definition: RootLevelRestriction.php:27
‪TYPO3\CMS\Core\Resource\AbstractFile\getStorage
‪int< 0, getSize():int { if( $this->deleted) { throw new \RuntimeException( 'File has been deleted.', 1329821480);} if(empty( $this->properties[ 'size'])) { $fileInfo=$this-> getStorage() -> getFileInfoByIdentifier($this->getIdentifier(), ['size'])
‪TYPO3\CMS\Core\Resource\File
Definition: File.php:26
‪TYPO3\CMS\Webhooks\Message\$record
‪identifier readonly int readonly array $record
Definition: PageModificationMessage.php:36
‪TYPO3\CMS\Core\Resource\Event\EnrichFileMetaDataEvent
Definition: EnrichFileMetaDataEvent.php:26
‪TYPO3\CMS\Core\Resource\Index\MetaDataRepository\$tableName
‪string $tableName
Definition: MetaDataRepository.php:43
‪TYPO3\CMS\Core\Resource\Index
Definition: ExtractorInterface.php:16
‪TYPO3\CMS\Core\Resource\AbstractFile\getUid
‪return MathUtility::canBeInterpretedAsInteger($size) ?(int) $size int getUid()
Definition: AbstractFile.php:195
‪TYPO3\CMS\Core\Database\Connection
Definition: Connection.php:41
‪TYPO3\CMS\Webhooks\Message\$uid
‪identifier readonly int $uid
Definition: PageModificationMessage.php:35
‪TYPO3\CMS\Core\SingletonInterface
Definition: SingletonInterface.php:22
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Core\Resource\Index\MetaDataRepository\$tableFields
‪array $tableFields
Definition: MetaDataRepository.php:49
‪TYPO3\CMS\Core\Resource\FileType
‪FileType
Definition: FileType.php:21
‪TYPO3\CMS\Core\Resource\Event\AfterFileMetaDataUpdatedEvent
Definition: AfterFileMetaDataUpdatedEvent.php:24
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:46
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Core\Database\Connection\PARAM_INT_ARRAY
‪const PARAM_INT_ARRAY
Definition: Connection.php:72
‪TYPO3\CMS\Core\Resource\Index\MetaDataRepository\createMetaDataRecord
‪array createMetaDataRecord($fileUid, array $additionalFields=[])
Definition: MetaDataRepository.php:130
‪TYPO3\CMS\Core\Database\Connection\PARAM_LOB
‪const PARAM_LOB
Definition: Connection.php:62
‪TYPO3\CMS\Core\Resource\Index\MetaDataRepository\update
‪array update($fileUid, array $updateData, ?array $metaDataFromDatabase=null)
Definition: MetaDataRepository.php:164