TYPO3 CMS  TYPO3_8-7
ConfigurationStatus.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 
28 
33 {
40 
47 
53  public function getStatus()
54  {
55  $this->executeAdminCommand();
56  $statuses = [
57  'emptyReferenceIndex' => $this->getReferenceIndexStatus(),
58  'deprecationLog' => $this->getDeprecationLogStatus()
59  ];
60  if ($this->isMemcachedUsed()) {
61  $statuses['memcachedConnection'] = $this->getMemcachedConnectionStatus();
62  }
63  if (TYPO3_OS !== 'WIN') {
64  $statuses['createdFilesWorldWritable'] = $this->getCreatedFilesWorldWritableStatus();
65  $statuses['createdDirectoriesWorldWritable'] = $this->getCreatedDirectoriesWorldWritableStatus();
66  }
67  if ($this->isMysqlUsed()) {
68  $statuses['mysqlDatabaseUsesUtf8'] = $this->getMysqlDatabaseUtf8Status();
69  }
70  return $statuses;
71  }
72 
78  protected function getReferenceIndexStatus()
79  {
80  $value = $this->getLanguageService()->getLL('status_ok');
81  $message = '';
82  $severity = ReportStatus::OK;
83 
84  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_refindex');
85  $count = $queryBuilder
86  ->count('*')
87  ->from('sys_refindex')
88  ->execute()
89  ->fetchColumn(0);
90 
91  $registry = GeneralUtility::makeInstance(Registry::class);
92  $lastRefIndexUpdate = $registry->get('core', 'sys_refindex_lastUpdate');
93  if (!$count && $lastRefIndexUpdate) {
94  $value = $this->getLanguageService()->getLL('status_empty');
95  $severity = ReportStatus::WARNING;
96  $url = BackendUtility::getModuleUrl('system_dbint') . '&id=0&SET[function]=refindex';
97  $message = sprintf($this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:warning.backend_reference_index'), '<a href="' . htmlspecialchars($url) . '">', '</a>', BackendUtility::datetime($lastRefIndexUpdate));
98  }
99  return GeneralUtility::makeInstance(ReportStatus::class, $this->getLanguageService()->getLL('status_referenceIndex'), $value, $message, $severity);
100  }
101 
107  protected function isMemcachedUsed()
108  {
109  $memcachedUsed = false;
110  $memcachedServers = $this->getConfiguredMemcachedServers();
111  if (!empty($memcachedServers)) {
112  $memcachedUsed = true;
113  }
114  return $memcachedUsed;
115  }
116 
122  protected function getConfiguredMemcachedServers()
123  {
124  $memcachedServers = [];
125  if (is_array($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations'])) {
126  foreach ($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations'] as $table => $conf) {
127  if (is_array($conf)) {
128  foreach ($conf as $key => $value) {
129  if (!is_array($value) && $value === \TYPO3\CMS\Core\Cache\Backend\MemcachedBackend::class) {
130  $memcachedServers = $GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations'][$table]['options']['servers'];
131  break;
132  }
133  }
134  }
135  }
136  }
137  return $memcachedServers;
138  }
139 
145  protected function getMemcachedConnectionStatus()
146  {
147  $value = $this->getLanguageService()->getLL('status_ok');
148  $message = '';
149  $severity = ReportStatus::OK;
150  $failedConnections = [];
151  $defaultMemcachedPort = ini_get('memcache.default_port');
152  $memcachedServers = $this->getConfiguredMemcachedServers();
153  if (function_exists('memcache_connect') && is_array($memcachedServers)) {
154  foreach ($memcachedServers as $testServer) {
155  $configuredServer = $testServer;
156  if (substr($testServer, 0, 7) === 'unix://') {
157  $host = $testServer;
158  $port = 0;
159  } else {
160  if (substr($testServer, 0, 6) === 'tcp://') {
161  $testServer = substr($testServer, 6);
162  }
163  if (strstr($testServer, ':') !== false) {
164  list($host, $port) = explode(':', $testServer, 2);
165  } else {
166  $host = $testServer;
167  $port = $defaultMemcachedPort;
168  }
169  }
170  $memcachedConnection = @memcache_connect($host, $port);
171  if ($memcachedConnection != null) {
172  memcache_close($memcachedConnection);
173  } else {
174  $failedConnections[] = $configuredServer;
175  }
176  }
177  }
178  if (!empty($failedConnections)) {
179  $value = $this->getLanguageService()->getLL('status_connectionFailed');
180  $severity = ReportStatus::WARNING;
181  $message = $this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:warning.memcache_not_usable') . '<br /><br />' . '<ul><li>' . implode('</li><li>', $failedConnections) . '</li></ul>';
182  }
183  return GeneralUtility::makeInstance(ReportStatus::class, $this->getLanguageService()->getLL('status_memcachedConfiguration'), $value, $message, $severity);
184  }
185 
192  protected function getDeprecationLogStatus()
193  {
194  $title = $this->getLanguageService()->getLL('status_configuration_DeprecationLog');
195  $value = $this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_common.xlf:disabled');
196  $message = '';
197  $severity = ReportStatus::OK;
198  if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['enableDeprecationLog']) {
199  $value = $this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_common.xlf:enabled');
200  $message = '<p>' . $this->getLanguageService()->getLL('status_configuration_DeprecationLogEnabled') . '</p>';
201  $severity = ReportStatus::NOTICE;
203  $logFileSize = 0;
204  if (@file_exists($logFile)) {
205  $logFileSize = filesize($logFile);
206  $message .= '<p>' . sprintf($this->getLanguageService()->getLL('status_configuration_DeprecationLogFile'), '<code>' . $this->getDeprecationLogFileLink()) . '</code></p>';
207  $removeDeprecationLogFileUrl = GeneralUtility::getIndpEnv('TYPO3_REQUEST_URL') . '&amp;adminCmd=removeDeprecationLogFile';
208  $message .= '<p>' . sprintf($this->getLanguageService()->getLL('status_configuration_DeprecationLogSize'), GeneralUtility::formatSize($logFileSize)) . ' <a href="' . $removeDeprecationLogFileUrl . '">' . $this->getLanguageService()->getLL('status_configuration_DeprecationLogDeleteLink') . '</a></p>';
209  }
210  if ($logFileSize > $this->deprecationLogFileSizeWarningThreshold) {
211  $severity = ReportStatus::WARNING;
212  }
213  if ($logFileSize > $this->deprecationLogFileSizeErrorThreshold) {
214  $severity = ReportStatus::ERROR;
215  }
216  }
217  return GeneralUtility::makeInstance(ReportStatus::class, $title, $value, $message, $severity);
218  }
219 
226  {
227  $value = $this->getLanguageService()->getLL('status_ok');
228  $message = '';
229  $severity = ReportStatus::OK;
230  if ((int)$GLOBALS['TYPO3_CONF_VARS']['SYS']['fileCreateMask'] % 10 & 2) {
231  $value = $GLOBALS['TYPO3_CONF_VARS']['SYS']['fileCreateMask'];
232  $severity = ReportStatus::WARNING;
233  $message = $this->getLanguageService()->getLL('status_CreatedFilePermissions.writable');
234  }
235  return GeneralUtility::makeInstance(ReportStatus::class, $this->getLanguageService()->getLL('status_CreatedFilePermissions'), $value, $message, $severity);
236  }
237 
244  {
245  $value = $this->getLanguageService()->getLL('status_ok');
246  $message = '';
247  $severity = ReportStatus::OK;
248  if ((int)$GLOBALS['TYPO3_CONF_VARS']['SYS']['folderCreateMask'] % 10 & 2) {
249  $value = $GLOBALS['TYPO3_CONF_VARS']['SYS']['folderCreateMask'];
250  $severity = ReportStatus::WARNING;
251  $message = $this->getLanguageService()->getLL('status_CreatedDirectoryPermissions.writable');
252  }
253  return GeneralUtility::makeInstance(ReportStatus::class, $this->getLanguageService()->getLL('status_CreatedDirectoryPermissions'), $value, $message, $severity);
254  }
255 
262  protected function getDeprecationLogFileLink()
263  {
265  $linkToLogFile = PathUtility::getAbsoluteWebPath($logFile);
266  return '<a href="' . $linkToLogFile . '">' . $logFile . '</a>';
267  }
268 
274  protected function isMysqlUsed()
275  {
276  $connection = GeneralUtility::makeInstance(ConnectionPool::class)
277  ->getConnectionByName(ConnectionPool::DEFAULT_CONNECTION_NAME);
278 
279  return strpos($connection->getServerVersion(), 'MySQL') === 0;
280  }
281 
287  protected function getMysqlDatabaseUtf8Status()
288  {
289  $connection = GeneralUtility::makeInstance(ConnectionPool::class)
290  ->getConnectionByName(ConnectionPool::DEFAULT_CONNECTION_NAME);
292  $queryBuilder = $connection->createQueryBuilder();
293  $defaultDatabaseCharset = (string)$queryBuilder->select('DEFAULT_CHARACTER_SET_NAME')
294  ->from('information_schema.SCHEMATA')
295  ->where(
296  $queryBuilder->expr()->eq(
297  'SCHEMA_NAME',
298  $queryBuilder->createNamedParameter($connection->getDatabase(), \PDO::PARAM_STR)
299  )
300  )
301  ->setMaxResults(1)
302  ->execute()
303  ->fetchColumn();
304 
305  $severity = ReportStatus::OK;
306  $statusValue = $this->getLanguageService()->getLL('status_ok');
307  // also allow utf8mb4
308  if (strpos($defaultDatabaseCharset, 'utf8') !== 0) {
309  // If the default character set is e.g. latin1, BUT all tables in the system are UTF-8,
310  // we assume that TYPO3 has the correct charset for adding tables, and everything is fine
311  $nonUtf8TableCollationsFound = $queryBuilder->select('table_collation')
312  ->from('information_schema.tables')
313  ->where(
314  $queryBuilder->expr()->andX(
315  $queryBuilder->expr()->eq('table_schema', $queryBuilder->quote($connection->getDatabase())),
316  $queryBuilder->expr()->notLike('table_collation', $queryBuilder->quote('utf8%'))
317  )
318  )
319  ->setMaxResults(1)
320  ->execute();
321 
322  if ($nonUtf8TableCollationsFound->rowCount() > 0) {
323  $message = sprintf($this->getLanguageService()
324  ->getLL('status_MysqlDatabaseCharacterSet_Unsupported'), $defaultDatabaseCharset);
325  $severity = ReportStatus::ERROR;
326  $statusValue = $this->getLanguageService()->getLL('status_wrongValue');
327  } else {
328  $message = $this->getLanguageService()->getLL('status_MysqlDatabaseCharacterSet_Info');
329  $severity = ReportStatus::INFO;
330  $statusValue = $this->getLanguageService()->getLL('status_info');
331  }
332  } else {
333  $message = $this->getLanguageService()->getLL('status_MysqlDatabaseCharacterSet_Ok');
334  }
335 
337  ReportStatus::class,
338  $this->getLanguageService()->getLL('status_MysqlDatabaseCharacterSet'),
339  $statusValue,
340  $message,
341  $severity
342  );
343  }
344 
351  protected function executeAdminCommand()
352  {
353  $command = GeneralUtility::_GET('adminCmd');
354  switch ($command) {
355  case 'removeDeprecationLogFile':
356  self::removeDeprecationLogFile();
357  break;
358  default:
359  // intentionally left blank
360  }
361  }
362 
366  protected static function removeDeprecationLogFile()
367  {
369  $message = $GLOBALS['LANG']->getLL('status_configuration_DeprecationLogDeletedSuccessful');
370  $severity = FlashMessage::OK;
371  } else {
372  $message = $GLOBALS['LANG']->getLL('status_configuration_DeprecationLogDeletionFailed');
373  $severity = FlashMessage::ERROR;
374  }
375  $flashMessage = GeneralUtility::makeInstance(FlashMessage::class, $message, '', $severity, true);
377  $flashMessageService = GeneralUtility::makeInstance(FlashMessageService::class);
379  $defaultFlashMessageQueue = $flashMessageService->getMessageQueueByIdentifier();
380  $defaultFlashMessageQueue->enqueue($flashMessage);
381  }
382 
386  protected function getLanguageService()
387  {
388  return $GLOBALS['LANG'];
389  }
390 }
static getAbsoluteWebPath($targetPath)
Definition: PathUtility.php:40
static makeInstance($className,... $constructorArguments)
static formatSize($sizeInBytes, $labels='', $base=0)
if(TYPO3_MODE==='BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']