TYPO3 CMS  TYPO3_8-7
ImportantActions.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 
24 
29 {
35  protected function executeAction()
36  {
37  $actionMessages = [];
38  if (isset($this->postValues['set']['changeInstallToolPassword'])) {
39  $actionMessages[] = $this->changeInstallToolPassword();
40  }
41  if (isset($this->postValues['set']['createAdministrator'])) {
42  $actionMessages[] = $this->createAdministrator();
43  }
44 
45  // Database analyzer handling
46  if (isset($this->postValues['set']['databaseAnalyzerExecute'])
47  || isset($this->postValues['set']['databaseAnalyzerAnalyze'])
48  ) {
50  }
51  if (isset($this->postValues['set']['databaseAnalyzerExecute'])) {
52  $actionMessages = array_merge($actionMessages, $this->databaseAnalyzerExecute());
53  }
54  if (isset($this->postValues['set']['databaseAnalyzerAnalyze'])) {
55  try {
56  $actionMessages[] = $this->databaseAnalyzerAnalyze();
57  } catch (\TYPO3\CMS\Core\Database\Schema\Exception\StatementException $e) {
58  $message = GeneralUtility::makeInstance(\TYPO3\CMS\Install\Status\ErrorStatus::class);
59  $message->setTitle('Database analysis failed');
60  $message->setMessage($e->getMessage());
61  $actionMessages[] = $message;
62  }
63  }
64 
65  $this->view->assign('actionMessages', $actionMessages);
66 
67  $operatingSystem = TYPO3_OS === 'WIN' ? 'Windows' : 'Unix';
68 
69  $opcodeCacheService = GeneralUtility::makeInstance(OpcodeCacheService::class);
70 
72  $coreUpdateService = GeneralUtility::makeInstance(\TYPO3\CMS\Install\Service\CoreUpdateService::class);
74  $coreVersionService = GeneralUtility::makeInstance(\TYPO3\CMS\Install\Service\CoreVersionService::class);
75  $this->view
76  ->assign('enableCoreUpdate', $coreUpdateService->isCoreUpdateEnabled())
77  ->assign('composerMode', Bootstrap::usesComposerClassLoading())
78  ->assign('isInstalledVersionAReleasedVersion', $coreVersionService->isInstalledVersionAReleasedVersion())
79  ->assign('isSymLinkedCore', is_link(PATH_site . 'typo3_src'))
80  ->assign('operatingSystem', $operatingSystem)
81  ->assign('cgiDetected', GeneralUtility::isRunningOnCgiServerApi())
82  ->assign('extensionCompatibilityTesterProtocolFile', GeneralUtility::getIndpEnv('TYPO3_SITE_URL') . 'typo3temp/assets/ExtensionCompatibilityTester.txt')
83  ->assign('extensionCompatibilityTesterErrorProtocolFile', GeneralUtility::getIndpEnv('TYPO3_SITE_URL') . 'typo3temp/assets/ExtensionCompatibilityTesterErrors.json')
84  ->assign('extensionCompatibilityTesterMessages', $this->getExtensionCompatibilityTesterMessages())
85  ->assign('listOfOpcodeCaches', $opcodeCacheService->getAllActive());
86 
87  $connectionInfos = [];
88  $connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
89  foreach ($connectionPool->getConnectionNames() as $connectionName) {
90  $connection = $connectionPool->getConnectionByName($connectionName);
91  $connectionParameters = $connection->getParams();
92  $connectionInfo = [
93  'connectionName' => $connectionName,
94  'version' => $connection->getServerVersion(),
95  'databaseName' => $connection->getDatabase(),
96  'username' => $connection->getUsername(),
97  'host' => $connection->getHost(),
98  'port' => $connection->getPort(),
99  'socket' => $connectionParameters['unix_socket'] ?? '',
100  'numberOfTables' => count($connection->getSchemaManager()->listTableNames()),
101  'numberOfMappedTables' => 0,
102  ];
103  if (isset($GLOBALS['TYPO3_CONF_VARS']['DB']['TableMapping'])
104  && is_array($GLOBALS['TYPO3_CONF_VARS']['DB']['TableMapping'])
105  ) {
106  // Count number of array keys having $connectionName as value
107  $connectionInfo['numberOfMappedTables'] = count(array_intersect(
108  $GLOBALS['TYPO3_CONF_VARS']['DB']['TableMapping'],
109  [$connectionName]
110  ));
111  }
112  $connectionInfos[] = $connectionInfo;
113  }
114 
115  $this->view->assign('connections', $connectionInfos);
116 
117  return $this->view->render();
118  }
119 
125  protected function changeInstallToolPassword()
126  {
127  $values = $this->postValues['values'];
128  if ($values['newInstallToolPassword'] !== $values['newInstallToolPasswordCheck']) {
130  $message = GeneralUtility::makeInstance(\TYPO3\CMS\Install\Status\ErrorStatus::class);
131  $message->setTitle('Install tool password not changed');
132  $message->setMessage('Given passwords do not match.');
133  } elseif (strlen($values['newInstallToolPassword']) < 8) {
135  $message = GeneralUtility::makeInstance(\TYPO3\CMS\Install\Status\ErrorStatus::class);
136  $message->setTitle('Install tool password not changed');
137  $message->setMessage('Given password must be at least eight characters long.');
138  } else {
140  $configurationManager = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Configuration\ConfigurationManager::class);
141  $configurationManager->setLocalConfigurationValueByPath(
142  'BE/installToolPassword',
143  $this->getHashedPassword($values['newInstallToolPassword'])
144  );
146  $message = GeneralUtility::makeInstance(\TYPO3\CMS\Install\Status\OkStatus::class);
147  $message->setTitle('Install tool password changed');
148  }
149  return $message;
150  }
151 
157  protected function createAdministrator()
158  {
159  $values = $this->postValues['values'];
160  $username = preg_replace('/\\s/i', '', $values['newUserUsername']);
161  $password = $values['newUserPassword'];
162  $passwordCheck = $values['newUserPasswordCheck'];
163 
164  if (strlen($username) < 1) {
166  $message = GeneralUtility::makeInstance(\TYPO3\CMS\Install\Status\ErrorStatus::class);
167  $message->setTitle('Administrator user not created');
168  $message->setMessage('No valid username given.');
169  } elseif ($password !== $passwordCheck) {
171  $message = GeneralUtility::makeInstance(\TYPO3\CMS\Install\Status\ErrorStatus::class);
172  $message->setTitle('Administrator user not created');
173  $message->setMessage('Passwords do not match.');
174  } elseif (strlen($password) < 8) {
176  $message = GeneralUtility::makeInstance(\TYPO3\CMS\Install\Status\ErrorStatus::class);
177  $message->setTitle('Administrator user not created');
178  $message->setMessage('Password must be at least eight characters long.');
179  } else {
180  $connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
181  $userExists = $connectionPool->getConnectionForTable('be_users')
182  ->count(
183  'uid',
184  'be_users',
185  ['username' => $username]
186  );
187 
188  if ($userExists) {
190  $message = GeneralUtility::makeInstance(\TYPO3\CMS\Install\Status\ErrorStatus::class);
191  $message->setTitle('Administrator user not created');
192  $message->setMessage('A user with username "' . $username . '" exists already.');
193  } else {
194  $hashedPassword = $this->getHashedPassword($password);
195  $adminUserFields = [
196  'username' => $username,
197  'password' => $hashedPassword,
198  'admin' => 1,
199  'tstamp' => $GLOBALS['EXEC_TIME'],
200  'crdate' => $GLOBALS['EXEC_TIME']
201  ];
202  $connectionPool->getConnectionForTable('be_users')
203  ->insert('be_users', $adminUserFields);
205  $message = GeneralUtility::makeInstance(\TYPO3\CMS\Install\Status\OkStatus::class);
206  $message->setTitle('Administrator created with username "' . $username . '".');
207  }
208  }
209 
210  return $message;
211  }
212 
218  protected function databaseAnalyzerExecute()
219  {
220  $messages = [];
221 
222  // Early return in case no update was selected
223  if (empty($this->postValues['values'])) {
225  $message = GeneralUtility::makeInstance(\TYPO3\CMS\Install\Status\WarningStatus::class);
226  $message->setTitle('No database changes selected');
227  $messages[] = $message;
228  return $messages;
229  }
230 
231  $sqlReader = GeneralUtility::makeInstance(SqlReader::class);
232  $sqlStatements = $sqlReader->getCreateTableStatementArray($sqlReader->getTablesDefinitionString());
233  $schemaMigrationService = GeneralUtility::makeInstance(SchemaMigrator::class);
234 
235  $statementHashesToPerform = $this->postValues['values'];
236 
237  $results = $schemaMigrationService->migrate($sqlStatements, $statementHashesToPerform);
238 
239  // Create error flash messages if any
240  foreach ($results as $errorMessage) {
241  $message = GeneralUtility::makeInstance(\TYPO3\CMS\Install\Status\ErrorStatus::class);
242  $message->setTitle('Database update failed');
243  $message->setMessage('Error: ' . $errorMessage);
244  $messages[] = $message;
245  }
246 
247  $message = GeneralUtility::makeInstance(\TYPO3\CMS\Install\Status\OkStatus::class);
248  $message->setTitle('Executed database updates');
249  $messages[] = $message;
250 
251  return $messages;
252  }
253 
267  protected function databaseAnalyzerAnalyze()
268  {
269  $databaseAnalyzerSuggestion = [];
270 
271  $sqlReader = GeneralUtility::makeInstance(SqlReader::class);
272  $sqlStatements = $sqlReader->getCreateTableStatementArray($sqlReader->getTablesDefinitionString());
273  $schemaMigrationService = GeneralUtility::makeInstance(SchemaMigrator::class);
274 
275  $addCreateChange = $schemaMigrationService->getUpdateSuggestions($sqlStatements);
276  // Aggregate the per-connection statements into one flat array
277  $addCreateChange = array_merge_recursive(...array_values($addCreateChange));
278 
279  if (!empty($addCreateChange['create_table'])) {
280  $databaseAnalyzerSuggestion['addTable'] = [];
281  foreach ($addCreateChange['create_table'] as $hash => $statement) {
282  $databaseAnalyzerSuggestion['addTable'][$hash] = [
283  'hash' => $hash,
284  'statement' => $statement,
285  ];
286  }
287  }
288  if (!empty($addCreateChange['add'])) {
289  $databaseAnalyzerSuggestion['addField'] = [];
290  foreach ($addCreateChange['add'] as $hash => $statement) {
291  $databaseAnalyzerSuggestion['addField'][$hash] = [
292  'hash' => $hash,
293  'statement' => $statement,
294  ];
295  }
296  }
297  if (!empty($addCreateChange['change'])) {
298  $databaseAnalyzerSuggestion['change'] = [];
299  foreach ($addCreateChange['change'] as $hash => $statement) {
300  $databaseAnalyzerSuggestion['change'][$hash] = [
301  'hash' => $hash,
302  'statement' => $statement,
303  ];
304  if (isset($addCreateChange['change_currentValue'][$hash])) {
305  $databaseAnalyzerSuggestion['change'][$hash]['current'] = $addCreateChange['change_currentValue'][$hash];
306  }
307  }
308  }
309 
310  // Difference from current to expected
311  $dropRename = $schemaMigrationService->getUpdateSuggestions($sqlStatements, true);
312  // Aggregate the per-connection statements into one flat array
313  $dropRename = array_merge_recursive(...array_values($dropRename));
314  if (!empty($dropRename['change_table'])) {
315  $databaseAnalyzerSuggestion['renameTableToUnused'] = [];
316  foreach ($dropRename['change_table'] as $hash => $statement) {
317  $databaseAnalyzerSuggestion['renameTableToUnused'][$hash] = [
318  'hash' => $hash,
319  'statement' => $statement,
320  ];
321  if (!empty($dropRename['tables_count'][$hash])) {
322  $databaseAnalyzerSuggestion['renameTableToUnused'][$hash]['count'] = $dropRename['tables_count'][$hash];
323  }
324  }
325  }
326  if (!empty($dropRename['change'])) {
327  $databaseAnalyzerSuggestion['renameTableFieldToUnused'] = [];
328  foreach ($dropRename['change'] as $hash => $statement) {
329  $databaseAnalyzerSuggestion['renameTableFieldToUnused'][$hash] = [
330  'hash' => $hash,
331  'statement' => $statement,
332  ];
333  }
334  }
335  if (!empty($dropRename['drop'])) {
336  $databaseAnalyzerSuggestion['deleteField'] = [];
337  foreach ($dropRename['drop'] as $hash => $statement) {
338  $databaseAnalyzerSuggestion['deleteField'][$hash] = [
339  'hash' => $hash,
340  'statement' => $statement,
341  ];
342  }
343  }
344  if (!empty($dropRename['drop_table'])) {
345  $databaseAnalyzerSuggestion['deleteTable'] = [];
346  foreach ($dropRename['drop_table'] as $hash => $statement) {
347  $databaseAnalyzerSuggestion['deleteTable'][$hash] = [
348  'hash' => $hash,
349  'statement' => $statement,
350  ];
351  if (!empty($dropRename['tables_count'][$hash])) {
352  $databaseAnalyzerSuggestion['deleteTable'][$hash]['count'] = $dropRename['tables_count'][$hash];
353  }
354  }
355  }
356 
357  $this->view->assign('databaseAnalyzerSuggestion', $databaseAnalyzerSuggestion);
358 
360  $message = GeneralUtility::makeInstance(\TYPO3\CMS\Install\Status\OkStatus::class);
361  $message->setTitle('Analyzed current database');
362 
363  return $message;
364  }
365 }
static makeInstance($className,... $constructorArguments)
if(TYPO3_MODE==='BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']