‪TYPO3CMS  11.5
ProcessedFileRepository.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\Log\LoggerAwareInterface;
19 use Psr\Log\LoggerAwareTrait;
25 
30 class ‪ProcessedFileRepository extends ‪AbstractRepository implements LoggerAwareInterface
31 {
32  use LoggerAwareTrait;
33 
41  protected ‪$objectType = ProcessedFile::class;
42 
49  protected ‪$table = 'sys_file_processedfile';
50 
57  protected ‪$tableColumns = [];
58 
62  public function ‪__construct()
63  {
64  parent::__construct();
65  }
66 
75  public function ‪createNewProcessedFileObject(‪FileInterface $originalFile, $taskType, array $configuration)
76  {
77  return GeneralUtility::makeInstance(
78  $this->objectType,
79  $originalFile,
80  $taskType,
81  $configuration
82  );
83  }
84 
89  protected function ‪createDomainObject(array $databaseRow)
90  {
91  $originalFile = $this->factory->getFileObject((int)$databaseRow['original']);
92  $taskType = $databaseRow['task_type'];
93  // Allow deserialization of Area class, since Area objects get serialized in configuration
94  // TODO: This should be changed to json encode and decode at some point
95  $configuration = unserialize(
96  $databaseRow['configuration'],
97  [
98  'allowed_classes' => [
99  Area::class,
100  ],
101  ]
102  );
103 
104  return GeneralUtility::makeInstance(
105  $this->objectType,
106  $originalFile,
107  $taskType,
108  $configuration,
109  $databaseRow
110  );
111  }
112 
119  public function ‪findByStorageAndIdentifier(‪ResourceStorage $storage, $identifier)
120  {
121  $processedFileObject = null;
122  if ($storage->‪hasFile($identifier)) {
123  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($this->table);
124  $databaseRow = $queryBuilder
125  ->select('*')
126  ->from($this->table)
127  ->where(
128  $queryBuilder->expr()->eq(
129  'storage',
130  $queryBuilder->createNamedParameter($storage->‪getUid(), ‪Connection::PARAM_INT)
131  ),
132  $queryBuilder->expr()->eq(
133  'identifier',
134  $queryBuilder->createNamedParameter($identifier, ‪Connection::PARAM_STR)
135  )
136  )
137  ->executeQuery()
138  ->fetchAssociative();
139 
140  if ($databaseRow) {
141  $processedFileObject = $this->‪createDomainObject($databaseRow);
142  }
143  }
144  return $processedFileObject;
145  }
146 
154  public function ‪countByStorage(‪ResourceStorage $storage): int
155  {
156  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
157  ->getQueryBuilderForTable($this->table);
158  return (int)$queryBuilder
159  ->count('uid')
160  ->from($this->table)
161  ->where(
162  $queryBuilder->expr()->eq(
163  'storage',
164  $queryBuilder->createNamedParameter($storage->‪getUid(), ‪Connection::PARAM_INT)
165  )
166  )
167  ->executeQuery()
168  ->fetchOne();
169  }
170 
176  public function ‪add($processedFile)
177  {
178  if ($processedFile->isPersisted()) {
179  $this->‪update($processedFile);
180  } else {
181  $insertFields = $processedFile->toArray();
182  $insertFields['crdate'] = $insertFields['tstamp'] = time();
183  $insertFields = $this->‪cleanUnavailableColumns($insertFields);
184 
185  $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($this->table);
186 
187  $connection->insert(
188  $this->table,
189  $insertFields,
190  ['configuration' => ‪Connection::PARAM_LOB]
191  );
192 
193  $uid = $connection->lastInsertId($this->table);
194  $processedFile->updateProperties(['uid' => $uid]);
195  }
196  }
197 
203  public function ‪update($processedFile)
204  {
205  if ($processedFile->isPersisted()) {
206  $uid = (int)$processedFile->getUid();
207  $updateFields = $this->‪cleanUnavailableColumns($processedFile->toArray());
208  unset($updateFields['uid']);
209  $updateFields['tstamp'] = time();
210 
211  $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($this->table);
212  $connection->update(
213  $this->table,
214  $updateFields,
215  [
216  'uid' => (int)$uid,
217  ],
218  ['configuration' => ‪Connection::PARAM_LOB]
219  );
220  }
221  }
222 
230  public function ‪findOneByOriginalFileAndTaskTypeAndConfiguration(‪File $file, $taskType, array $configuration)
231  {
232  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($this->table);
233 
234  $databaseRow = $queryBuilder
235  ->select('*')
236  ->from($this->table)
237  ->where(
238  $queryBuilder->expr()->eq(
239  'original',
240  $queryBuilder->createNamedParameter($file->‪getUid(), ‪Connection::PARAM_INT)
241  ),
242  $queryBuilder->expr()->eq('task_type', $queryBuilder->createNamedParameter($taskType, ‪Connection::PARAM_STR)),
243  $queryBuilder->expr()->eq(
244  'configurationsha1',
245  $queryBuilder->createNamedParameter(sha1((new ‪ConfigurationService())->serialize($configuration)), ‪Connection::PARAM_STR)
246  )
247  )
248  ->executeQuery()
249  ->fetchAssociative();
250 
251  if (is_array($databaseRow)) {
252  $processedFile = $this->‪createDomainObject($databaseRow);
253  } else {
254  $processedFile = $this->‪createNewProcessedFileObject($file, $taskType, $configuration);
255  }
256  return $processedFile;
257  }
258 
264  public function ‪findAllByOriginalFile(‪FileInterface $file)
265  {
266  if (!$file instanceof ‪File) {
267  throw new \InvalidArgumentException('Parameter is no File object but got type "'
268  . (is_object($file) ? get_class($file) : gettype($file)) . '"', 1382006142);
269  }
270 
271  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($this->table);
272  $result = $queryBuilder
273  ->select('*')
274  ->from($this->table)
275  ->where(
276  $queryBuilder->expr()->eq(
277  'original',
278  $queryBuilder->createNamedParameter($file->getUid(), ‪Connection::PARAM_INT)
279  )
280  )
281  ->executeQuery();
282 
283  $itemList = [];
284  while ($row = $result->fetchAssociative()) {
285  $itemList[] = $this->‪createDomainObject($row);
286  }
287  return $itemList;
288  }
289 
297  public function ‪removeAll($storageUid = null)
298  {
299  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
300  ->getQueryBuilderForTable($this->table);
301  $where = [
302  $queryBuilder->expr()->neq('identifier', $queryBuilder->createNamedParameter('', ‪Connection::PARAM_STR)),
303  ];
304  if ($storageUid !== null) {
305  $where[] = $queryBuilder->expr()->eq(
306  'storage',
307  $queryBuilder->createNamedParameter($storageUid, ‪Connection::PARAM_INT)
308  );
309  }
310  $result = $queryBuilder
311  ->select('*')
312  ->from($this->table)
313  ->where(...$where)
314  ->executeQuery();
315 
316  $errorCount = 0;
317 
318  while ($row = $result->fetchAssociative()) {
319  if ($storageUid && (int)$storageUid !== (int)$row['storage']) {
320  continue;
321  }
322  try {
323  $file = $this->‪createDomainObject($row);
324  $file->‪getStorage()->‪setEvaluatePermissions(false);
325  $file->‪delete(true);
326  } catch (\‪Exception $e) {
327  $this->logger->error('Failed to delete file {identifier} in storage uid {storage}.', [
328  'identifier' => $row['identifier'],
329  'storage' => $row['storage'],
330  'exception' => $e,
331  ]);
332  ++$errorCount;
333  }
334  }
335 
336  if ($storageUid === null) {
337  // Truncate entire table if not restricted to specific storage
338  GeneralUtility::makeInstance(ConnectionPool::class)
339  ->getConnectionForTable($this->table)
340  ->truncate($this->table);
341  } else {
342  // else remove db rows of this storage only
343  GeneralUtility::makeInstance(ConnectionPool::class)
344  ->getConnectionForTable($this->table)
345  ->delete($this->table, ['storage' => $storageUid], [‪Connection::PARAM_INT]);
346  }
347 
348  return $errorCount;
349  }
350 
358  protected function ‪cleanUnavailableColumns(array $data)
359  {
360  // As determining the table columns is a costly operation this is done only once during runtime and cached then
361  if (empty($this->tableColumns[$this->table])) {
362  $this->tableColumns[‪$this->table] = GeneralUtility::makeInstance(ConnectionPool::class)
363  ->getConnectionForTable($this->table)
364  ->createSchemaManager()
365  ->listTableColumns($this->table);
366  }
367 
368  return array_intersect_key($data, $this->tableColumns[$this->table]);
369  }
370 }
‪TYPO3\CMS\Core\Resource\ProcessedFileRepository
Definition: ProcessedFileRepository.php:31
‪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\FileInterface
Definition: FileInterface.php:22
‪TYPO3\CMS\Core\Resource\ProcessedFileRepository\createNewProcessedFileObject
‪ProcessedFile createNewProcessedFileObject(FileInterface $originalFile, $taskType, array $configuration)
Definition: ProcessedFileRepository.php:72
‪TYPO3\CMS\Core\Resource\ProcessedFileRepository\update
‪update($processedFile)
Definition: ProcessedFileRepository.php:200
‪TYPO3\CMS\Core\Resource\AbstractRepository
Definition: AbstractRepository.php:32
‪TYPO3\CMS\Core\Imaging\ImageManipulation\Area
Definition: Area.php:23
‪TYPO3\CMS\Core\Resource\ProcessedFileRepository\findAllByOriginalFile
‪ProcessedFile[] findAllByOriginalFile(FileInterface $file)
Definition: ProcessedFileRepository.php:261
‪TYPO3\CMS\Core\Resource\ProcessedFileRepository\$objectType
‪string $objectType
Definition: ProcessedFileRepository.php:40
‪TYPO3\CMS\Core\Resource\ResourceInterface\getStorage
‪ResourceStorage getStorage()
‪TYPO3\CMS\Core\Resource\ProcessedFileRepository\createDomainObject
‪ProcessedFile createDomainObject(array $databaseRow)
Definition: ProcessedFileRepository.php:86
‪TYPO3\CMS\Core\Resource\ProcessedFileRepository\cleanUnavailableColumns
‪array cleanUnavailableColumns(array $data)
Definition: ProcessedFileRepository.php:355
‪TYPO3\CMS\Core\Database\Connection\PARAM_STR
‪const PARAM_STR
Definition: Connection.php:54
‪TYPO3\CMS\Core\Resource\FileInterface\delete
‪bool delete()
‪TYPO3\CMS\Core\Resource\ResourceStorage\hasFile
‪bool hasFile($identifier)
Definition: ResourceStorage.php:1691
‪TYPO3\CMS\Core\Resource\ProcessedFileRepository\add
‪add($processedFile)
Definition: ProcessedFileRepository.php:173
‪TYPO3\CMS\Core\Resource\ResourceStorage\setEvaluatePermissions
‪setEvaluatePermissions($evaluatePermissions)
Definition: ResourceStorage.php:654
‪TYPO3\CMS\Core\Resource\ProcessedFileRepository\$table
‪string $table
Definition: ProcessedFileRepository.php:47
‪TYPO3\CMS\Core\Resource\File
Definition: File.php:24
‪TYPO3\CMS\Core\Resource\ProcessedFileRepository\$tableColumns
‪array $tableColumns
Definition: ProcessedFileRepository.php:54
‪TYPO3\CMS\Core\Resource\ProcessedFileRepository\__construct
‪__construct()
Definition: ProcessedFileRepository.php:59
‪TYPO3\CMS\Core\Resource\AbstractFile\getUid
‪int getUid()
Definition: AbstractFile.php:203
‪TYPO3\CMS\Core\Resource
Definition: generateMimeTypes.php:52
‪TYPO3\CMS\Core\Resource\ProcessedFile
Definition: ProcessedFile.php:45
‪TYPO3\CMS\Core\Resource\AbstractRepository\removeAll
‪removeAll()
Definition: AbstractRepository.php:172
‪TYPO3\CMS\Core\Resource\Exception
Definition: Exception.php:21
‪TYPO3\CMS\Core\Database\Connection
Definition: Connection.php:38
‪TYPO3\CMS\Core\Resource\ResourceStorage
Definition: ResourceStorage.php:125
‪TYPO3\CMS\Core\Resource\Service\ConfigurationService
Definition: ConfigurationService.php:34
‪TYPO3\CMS\Core\Resource\ProcessedFileRepository\removeAll
‪int removeAll($storageUid=null)
Definition: ProcessedFileRepository.php:294
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:46
‪TYPO3\CMS\Core\Resource\ProcessedFileRepository\countByStorage
‪int countByStorage(ResourceStorage $storage)
Definition: ProcessedFileRepository.php:151
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:50
‪TYPO3\CMS\Core\Resource\ProcessedFileRepository\findOneByOriginalFileAndTaskTypeAndConfiguration
‪ProcessedFile findOneByOriginalFileAndTaskTypeAndConfiguration(File $file, $taskType, array $configuration)
Definition: ProcessedFileRepository.php:227
‪TYPO3\CMS\Core\Resource\ProcessedFileRepository\findByStorageAndIdentifier
‪ProcessedFile null findByStorageAndIdentifier(ResourceStorage $storage, $identifier)
Definition: ProcessedFileRepository.php:116
‪TYPO3\CMS\Core\Database\Connection\PARAM_LOB
‪const PARAM_LOB
Definition: Connection.php:59