TYPO3 CMS  TYPO3_6-2
ProcessedFileChecksumUpdate.php
Go to the documentation of this file.
1 <?php
3 
4 /*
5  * This file is part of the TYPO3 CMS project.
6  *
7  * It is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU General Public License, either version 2
9  * of the License, or any later version.
10  *
11  * For the full copyright and license information, please read the
12  * LICENSE.txt file that was distributed with this source code.
13  *
14  * The TYPO3 project - inspiring people to share!
15  */
16 
20 
25 
29  protected $title = '[Optional] Update sys_file_processedfile records to match new checksum calculation.';
30 
37  public function checkForUpdate(&$description) {
38  if ($this->isWizardDone()) {
39  return FALSE;
40  }
41 
42  $join = 'sys_file_processedfile LEFT JOIN sys_registry ON entry_key = sys_file_processedfile.uid AND entry_namespace = \'ProcessedFileChecksumUpdate\'';
43  $count = $this->getDatabaseConnection()->exec_SELECTcountRows('*', $join, '(entry_key IS NULL AND sys_file_processedfile.identifier <> \'\') OR sys_file_processedfile.width IS NULL');
44  if (!$count) {
45  return FALSE;
46  }
47 
48  $description = 'The checksum calculation for processed files (image thumbnails) has been changed with TYPO3 CMS 7.3 and 6.2.13.
49 This means that your processed files need to be updated, if you update from versions <strong>below TYPO3 CMS 7.3 or 6.2.13</strong>.<br />
50 This can either happen on demand, when the processed file is first needed, or by executing this wizard, which updates all processed images at once.<br />
51 <strong>Important:</strong> If you have lots of processed files, you should prefer using this wizard, otherwise this might cause a lot of work for your server.';
52 
53  return TRUE;
54  }
55 
63  public function performUpdate(array &$databaseQueries, &$customMessages) {
64  $db = $this->getDatabaseConnection();
65 
66  // remove all invalid records which hold NULL values
67  $db->exec_DELETEquery('sys_file_processedfile', 'width IS NULL or height IS NULL');
68 
69  $factory = GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Resource\\ResourceFactory');
70 
71  $join = 'sys_file_processedfile LEFT JOIN sys_registry ON entry_key = sys_file_processedfile.uid AND entry_namespace = \'ProcessedFileChecksumUpdate\'';
72  $res = $db->exec_SELECTquery('sys_file_processedfile.*', $join, 'entry_key IS NULL AND sys_file_processedfile.identifier <> \'\'');
73  while ($processedFileRow = $db->sql_fetch_assoc($res)) {
74  $storage = $factory->getStorageObject($processedFileRow['storage']);
75  if (!$storage) {
76  // invalid storage, delete record, we can't take care of the associated file
77  $db->exec_DELETEquery('sys_file_processedfile', 'uid=' . $processedFileRow['uid']);
78  continue;
79  }
80 
81  if ($storage->getDriverType() !== 'Local') {
82  // non-local storage, we can't treat this, skip the record and mark it done
83  $db->exec_INSERTquery('sys_registry', array('entry_namespace' => 'ProcessedFileChecksumUpdate', 'entry_key' => $processedFileRow['uid']));
84  continue;
85  }
86 
87  $configuration = $storage->getConfiguration();
88  if ($configuration['pathType'] === 'relative') {
89  $absoluteBasePath = PATH_site . $configuration['basePath'];
90  } else {
91  $absoluteBasePath = $configuration['basePath'];
92  }
93  $filePath = rtrim($absoluteBasePath, '/') . '/' . ltrim($processedFileRow['identifier'], '/');
94 
95  try {
96  $originalFile = $factory->getFileObject($processedFileRow['original']);
97  } catch (\Exception $e) {
98  // no original file there anymore, delete local file
99  @unlink($filePath);
100  $db->exec_DELETEquery('sys_file_processedfile', 'uid=' . $processedFileRow['uid']);
101  continue;
102  }
103 
104  $processedFileObject = new ProcessedFile($originalFile, '', array(), $processedFileRow);
105 
106  // calculate new checksum and name
107  $newChecksum = $processedFileObject->calculateChecksum();
108 
109  // if the checksum already matches, there is nothing to do
110  if ($newChecksum !== $processedFileRow['checksum']) {
111  $newName = str_replace($processedFileRow['checksum'], $newChecksum, $processedFileRow['name']);
112  $newIdentifier = str_replace($processedFileRow['checksum'], $newChecksum, $processedFileRow['identifier']);
113  $newFilePath = str_replace($processedFileRow['checksum'], $newChecksum, $filePath);
114 
115  // rename file
116  if (@rename($filePath, $newFilePath)) {
117  // save result back into database
118  $fields = array(
119  'tstamp' => time(),
120  'identifier' => $newIdentifier,
121  'name' => $newName,
122  'checksum' => $newChecksum
123  );
124  $db->exec_UPDATEquery('sys_file_processedfile', 'uid=' . $processedFileRow['uid'], $fields);
125  }
126  // if the rename of the file failed, keep the record, but do not bother with it again
127  }
128 
129  // remember we finished this record
130  $db->exec_INSERTquery('sys_registry', array('entry_namespace' => 'ProcessedFileChecksumUpdate', 'entry_key' => $processedFileRow['uid']));
131  }
132 
133  $db->exec_DELETEquery('sys_registry', 'entry_namespace = \'ProcessedFileChecksumUpdate\'');
134  $this->markWizardAsDone();
135  return TRUE;
136  }
137 
138 }
performUpdate(array &$databaseQueries, &$customMessages)