TYPO3 CMS  TYPO3_6-2
FileIdentifierHashUpdate.php
Go to the documentation of this file.
1 <?php
3 
19 
24 
28  protected $title = 'Add the file identifier hash to existing sys_file records and update the settings for local storages';
29 
33  protected $db;
34 
38  protected $sqlQueries = array();
39 
43  protected $storages;
44 
48  protected $storageRepository;
49 
53  public function __construct() {
54  $this->db = $GLOBALS['TYPO3_DB'];
55  }
56 
60  public function init() {
61  $this->storageRepository = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Resource\\StorageRepository');
62  $this->storages = $this->storageRepository->findAll();
63  // Add default storage for core files
64  $this->storages[] = \TYPO3\CMS\Core\Resource\ResourceFactory::getInstance()->getStorageObject(0);
65  }
66 
73  public function checkForUpdate(&$description) {
74  $description = 'Add file identifier hash to sys_file records, where it is missing. Additionally upgrade storage configurations.';
75  $unhashedFileCount = $this->db->exec_SELECTcountRows(
76  'uid',
77  'sys_file',
78  'identifier_hash = ' . $this->db->fullQuoteStr('', 'sys_file') . ' OR folder_hash = ' . $this->db->fullQuoteStr('', 'sys_file')
79  );
80 
81  $unmigratedStorageCount = $this->db->exec_SELECTcountRows(
82  'uid',
83  'sys_file_storage',
84  'driver = ' . $this->db->fullQuoteStr('Local', 'sys_file_storage') . ' AND configuration NOT LIKE ' . $this->db->fullQuoteStr('%caseSensitive%', 'sys_file_storage')
85  );
86 
87  return $unhashedFileCount > 0 || $unmigratedStorageCount > 0;
88  }
89 
97  public function performUpdate(array &$dbQueries, &$customMessages) {
98  $this->init();
99  foreach ($this->storages as $storage) {
100  $dbQueries = array_merge($dbQueries, $this->updateIdentifierHashesForStorage($storage));
101  }
102 
103  $dbQueries = array_merge($dbQueries, $this->migrateStorages());
104 
105  $this->markWizardAsDone();
106  return TRUE;
107  }
108 
112  protected function migrateStorages() {
113  $dbQueries = array();
114  $unmigratedStorages = $this->db->exec_SELECTgetRows(
115  'uid, configuration',
116  'sys_file_storage',
117  'driver = ' . $this->db->fullQuoteStr('Local', 'sys_file_storage') . ' AND configuration NOT LIKE ' . $this->db->fullQuoteStr('%caseSensitive%', 'sys_file_storage')
118  );
119 
121  $flexObj = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Configuration\\FlexForm\\FlexFormTools');
122 
123 
124  foreach ($unmigratedStorages as $storage) {
125  $flexFormXml = $storage['configuration'];
126  $configurationArray = \TYPO3\CMS\Core\Utility\GeneralUtility::xml2array($flexFormXml);
127 
128  $caseSensitive = $this->testCaseSensitivity(
129  $configurationArray['data']['sDEF']['lDEF']['pathType']['vDEF'] == 'relative' ?
130  PATH_site . $configurationArray['data']['sDEF']['lDEF']['basePath']['vDEF'] :
131  $configurationArray['data']['sDEF']['lDEF']['basePath']['vDEF']
132  );
133  $configurationArray['data']['sDEF']['lDEF']['caseSensitive'] = array('vDEF' => $caseSensitive);
134 
135  $configuration = $flexObj->flexArray2Xml($configurationArray);
136  $dbQueries[] = $query = $this->db->UPDATEquery(
137  'sys_file_storage',
138  'uid=' . $storage['uid'],
139  array(
140  'configuration' => $configuration
141  )
142  );
143  $this->db->sql_query($query);
144  }
145  return $dbQueries;
146  }
147 
154  protected function updateIdentifierHashesForStorage(ResourceStorage $storage) {
155  $queries = array();
156 
158  // if DBAL is not loaded, we're using MySQL and can thus use their
159  // SHA1() function
160  if ($storage->usesCaseSensitiveIdentifiers()) {
161  $updateCall = 'SHA1(identifier)';
162  } else {
163  $updateCall = 'SHA1(LOWER(identifier))';
164  }
165  $queries[] = $query = sprintf(
166  'UPDATE sys_file SET identifier_hash = %s WHERE storage=%d',
167  $updateCall,
168  $storage->getUid()
169  );
170  $this->db->sql_query($query);
171 
172  // folder hashes cannot be done with one call: so do it manually
173  $files = $this->db->exec_SELECTgetRows('uid, storage, identifier', 'sys_file',
174  sprintf('storage=%d AND folder_hash=%s', $storage->getUid(), $this->db->fullQuoteStr('', 'sys_file'))
175  );
176 
177  foreach ($files as $file) {
178  $folderHash = $storage->hashFileIdentifier($storage->getFolderIdentifierFromFileIdentifier($file['identifier']));
179 
180  $queries[] = $query = $this->db->UPDATEquery(
181  'sys_file',
182  'uid=' . $file['uid'],
183  array(
184  'folder_hash' => $folderHash
185  )
186  );
187 
188  $this->db->sql_query($query);
189  }
190  } else {
191  // manually hash the identifiers when using DBAL
192  $files = $this->db->exec_SELECTgetRows('uid, storage, identifier', 'sys_file',
193  sprintf('storage=%d AND identifier_hash=""', $storage->getUid())
194  );
195 
196  foreach ($files as $file) {
197  $hash = $storage->hashFileIdentifier($file['identifier']);
198  $folderHash = $storage->hashFileIdentifier($storage->getFolderIdentifierFromFileIdentifier($file['identifier']));
199 
200  $queries[] = $query = $this->db->UPDATEquery(
201  'sys_file',
202  'uid=' . $file['uid'],
203  array(
204  'identifier_hash' => $hash,
205  'folder_hash' => $folderHash
206  )
207  );
208 
209  $this->db->sql_query($query);
210  }
211  }
212 
213  return $queries;
214  }
215 
216 
223  protected function testCaseSensitivity($absolutePath) {
224  $caseSensitive = TRUE;
225  $path = rtrim($absolutePath, '/') . '/aAbB';
226  $testFileExists = file_exists($path);
227 
228  // create test file
229  if (!$testFileExists) {
230  @touch($path);
231  }
232 
233  // do the actual sensitivity check
234  if (file_exists(strtoupper($path)) && file_exists(strtolower($path))) {
235  $caseSensitive = FALSE;
236  }
237 
238  // clean filesystem
239  if (!$testFileExists) {
240  @unlink($path);
241  }
242 
243  return $caseSensitive;
244  }
245 }
if(!defined('TYPO3_MODE')) $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_userauth.php']['logoff_pre_processing'][]
static xml2array($string, $NSprefix='', $reportDocTag=FALSE)