[TASK] Move access right parameters from BE to SYS configuration
[Packages/TYPO3.CMS.git] / typo3 / sysext / reports / Classes / Report / Status / ConfigurationStatus.php
1 <?php
2 namespace TYPO3\CMS\Reports\Report\Status;
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
17 use TYPO3\CMS\Core\Utility\GeneralUtility;
18
19 /**
20 * Performs some checks about the install tool protection status
21 */
22 class ConfigurationStatus implements \TYPO3\CMS\Reports\StatusProviderInterface
23 {
24 /**
25 * 10MB
26 *
27 * @var int
28 */
29 protected $deprecationLogFileSizeWarningThreshold = 10485760;
30
31 /**
32 * 100MB
33 *
34 * @var int
35 */
36 protected $deprecationLogFileSizeErrorThreshold = 104857600;
37
38 /**
39 * Backpath to the typo3 main directory
40 *
41 * @var string
42 */
43 protected $backPath = '../';
44
45 /**
46 * Determines the Install Tool's status, mainly concerning its protection.
47 *
48 * @return array List of statuses
49 */
50 public function getStatus()
51 {
52 $this->executeAdminCommand();
53 $statuses = array(
54 'emptyReferenceIndex' => $this->getReferenceIndexStatus(),
55 'deprecationLog' => $this->getDeprecationLogStatus()
56 );
57 if ($this->isMemcachedUsed()) {
58 $statuses['memcachedConnection'] = $this->getMemcachedConnectionStatus();
59 }
60 if (TYPO3_OS !== 'WIN') {
61 $statuses['createdFilesWorldWritable'] = $this->getCreatedFilesWorldWritableStatus();
62 $statuses['createdDirectoriesWorldWritable'] = $this->getCreatedDirectoriesWorldWritableStatus();
63 }
64 return $statuses;
65 }
66
67 /**
68 * Checks if sys_refindex is empty.
69 *
70 * @return \TYPO3\CMS\Reports\Status An object representing whether the reference index is empty or not
71 */
72 protected function getReferenceIndexStatus()
73 {
74 $value = $GLOBALS['LANG']->getLL('status_ok');
75 $message = '';
76 $severity = \TYPO3\CMS\Reports\Status::OK;
77 $count = $GLOBALS['TYPO3_DB']->exec_SELECTcountRows('*', 'sys_refindex');
78 $registry = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Registry::class);
79 $lastRefIndexUpdate = $registry->get('core', 'sys_refindex_lastUpdate');
80 if (!$count && $lastRefIndexUpdate) {
81 $value = $GLOBALS['LANG']->getLL('status_empty');
82 $severity = \TYPO3\CMS\Reports\Status::WARNING;
83 $url = \TYPO3\CMS\Backend\Utility\BackendUtility::getModuleUrl('system_dbint') . '&id=0&SET[function]=refindex';
84 $message = sprintf($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:warning.backend_reference_index'), '<a href="' . htmlspecialchars($url) . '">', '</a>', \TYPO3\CMS\Backend\Utility\BackendUtility::dateTime($lastRefIndexUpdate));
85 }
86 return GeneralUtility::makeInstance(\TYPO3\CMS\Reports\Status::class, $GLOBALS['LANG']->getLL('status_referenceIndex'), $value, $message, $severity);
87 }
88
89 /**
90 * Checks whether memcached is configured, if that's the case we assume it's also used.
91 *
92 * @return bool TRUE if memcached is used, FALSE otherwise.
93 */
94 protected function isMemcachedUsed()
95 {
96 $memcachedUsed = false;
97 $memcachedServers = $this->getConfiguredMemcachedServers();
98 if (!empty($memcachedServers)) {
99 $memcachedUsed = true;
100 }
101 return $memcachedUsed;
102 }
103
104 /**
105 * Gets the configured memcached server connections.
106 *
107 * @return array An array of configured memcached server connections.
108 */
109 protected function getConfiguredMemcachedServers()
110 {
111 $memcachedServers = array();
112 if (is_array($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations'])) {
113 foreach ($GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations'] as $table => $conf) {
114 if (is_array($conf)) {
115 foreach ($conf as $key => $value) {
116 if (!is_array($value) && $value === \TYPO3\CMS\Core\Cache\Backend\MemcachedBackend::class) {
117 $memcachedServers = $GLOBALS['TYPO3_CONF_VARS']['SYS']['caching']['cacheConfigurations'][$table]['options']['servers'];
118 break;
119 }
120 }
121 }
122 }
123 }
124 return $memcachedServers;
125 }
126
127 /**
128 * Checks whether TYPO3 can connect to the configured memcached servers.
129 *
130 * @return \TYPO3\CMS\Reports\Status An object representing whether TYPO3 can connect to the configured memcached servers
131 */
132 protected function getMemcachedConnectionStatus()
133 {
134 $value = $GLOBALS['LANG']->getLL('status_ok');
135 $message = '';
136 $severity = \TYPO3\CMS\Reports\Status::OK;
137 $failedConnections = array();
138 $defaultMemcachedPort = ini_get('memcache.default_port');
139 $memcachedServers = $this->getConfiguredMemcachedServers();
140 if (function_exists('memcache_connect') && is_array($memcachedServers)) {
141 foreach ($memcachedServers as $testServer) {
142 $configuredServer = $testServer;
143 if (substr($testServer, 0, 7) == 'unix://') {
144 $host = $testServer;
145 $port = 0;
146 } else {
147 if (substr($testServer, 0, 6) === 'tcp://') {
148 $testServer = substr($testServer, 6);
149 }
150 if (strstr($testServer, ':') !== false) {
151 list($host, $port) = explode(':', $testServer, 2);
152 } else {
153 $host = $testServer;
154 $port = $defaultMemcachedPort;
155 }
156 }
157 $memcachedConnection = @memcache_connect($host, $port);
158 if ($memcachedConnection != null) {
159 memcache_close($memcachedConnection);
160 } else {
161 $failedConnections[] = $configuredServer;
162 }
163 }
164 }
165 if (!empty($failedConnections)) {
166 $value = $GLOBALS['LANG']->getLL('status_connectionFailed');
167 $severity = \TYPO3\CMS\Reports\Status::WARNING;
168 $message = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:warning.memcache_not_usable') . '<br /><br />' . '<ul><li>' . implode('</li><li>', $failedConnections) . '</li></ul>';
169 }
170 return GeneralUtility::makeInstance(\TYPO3\CMS\Reports\Status::class, $GLOBALS['LANG']->getLL('status_memcachedConfiguration'), $value, $message, $severity);
171 }
172
173 /**
174 * Provides status information on the deprecation log, whether it's enabled
175 * and if so whether certain limits in file size are reached.
176 *
177 * @return \TYPO3\CMS\Reports\Status The deprecation log status.
178 */
179 protected function getDeprecationLogStatus()
180 {
181 $title = $GLOBALS['LANG']->getLL('status_configuration_DeprecationLog');
182 $value = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xlf:disabled');
183 $message = '';
184 $severity = \TYPO3\CMS\Reports\Status::OK;
185 if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['enableDeprecationLog']) {
186 $value = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xlf:enabled');
187 $message = '<p>' . $GLOBALS['LANG']->getLL('status_configuration_DeprecationLogEnabled') . '</p>';
188 $severity = \TYPO3\CMS\Reports\Status::NOTICE;
189 $logFile = GeneralUtility::getDeprecationLogFileName();
190 $logFileSize = 0;
191 if (@file_exists($logFile)) {
192 $logFileSize = filesize($logFile);
193 $message .= '<p>' . sprintf($GLOBALS['LANG']->getLL('status_configuration_DeprecationLogFile'), $this->getDeprecationLogFileLink()) . '</p>';
194 $removeDeprecationLogFileUrl = GeneralUtility::getIndpEnv('TYPO3_REQUEST_URL') . '&amp;adminCmd=removeDeprecationLogFile';
195 $message .= '<p>' . sprintf($GLOBALS['LANG']->getLL('status_configuration_DeprecationLogSize'), GeneralUtility::formatSize($logFileSize)) . ' <a href="' . $removeDeprecationLogFileUrl . '">' . $GLOBALS['LANG']->getLL('status_configuration_DeprecationLogDeleteLink') . '</a></p>';
196 }
197 if ($logFileSize > $this->deprecationLogFileSizeWarningThreshold) {
198 $severity = \TYPO3\CMS\Reports\Status::WARNING;
199 }
200 if ($logFileSize > $this->deprecationLogFileSizeErrorThreshold) {
201 $severity = \TYPO3\CMS\Reports\Status::ERROR;
202 }
203 }
204 return GeneralUtility::makeInstance(\TYPO3\CMS\Reports\Status::class, $title, $value, $message, $severity);
205 }
206
207 /**
208 * Warning, if fileCreateMask has write bit for 'others' set.
209 *
210 * @return \TYPO3\CMS\Reports\Status The writable status for 'others'
211 */
212 protected function getCreatedFilesWorldWritableStatus()
213 {
214 $value = $GLOBALS['LANG']->getLL('status_ok');
215 $message = '';
216 $severity = \TYPO3\CMS\Reports\Status::OK;
217 if ((int)$GLOBALS['TYPO3_CONF_VARS']['SYS']['fileCreateMask'] % 10 & 2) {
218 $value = $GLOBALS['TYPO3_CONF_VARS']['SYS']['fileCreateMask'];
219 $severity = \TYPO3\CMS\Reports\Status::WARNING;
220 $message = $GLOBALS['LANG']->getLL('status_CreatedFilePermissions.writable');
221 }
222 return GeneralUtility::makeInstance(\TYPO3\CMS\Reports\Status::class, $GLOBALS['LANG']->getLL('status_CreatedFilePermissions'), $value, $message, $severity);
223 }
224
225 /**
226 * Warning, if folderCreateMask has write bit for 'others' set.
227 *
228 * @return \TYPO3\CMS\Reports\Status The writable status for 'others'
229 */
230 protected function getCreatedDirectoriesWorldWritableStatus()
231 {
232 $value = $GLOBALS['LANG']->getLL('status_ok');
233 $message = '';
234 $severity = \TYPO3\CMS\Reports\Status::OK;
235 if ((int)$GLOBALS['TYPO3_CONF_VARS']['SYS']['folderCreateMask'] % 10 & 2) {
236 $value = $GLOBALS['TYPO3_CONF_VARS']['SYS']['folderCreateMask'];
237 $severity = \TYPO3\CMS\Reports\Status::WARNING;
238 $message = $GLOBALS['LANG']->getLL('status_CreatedDirectoryPermissions.writable');
239 }
240 return GeneralUtility::makeInstance(\TYPO3\CMS\Reports\Status::class, $GLOBALS['LANG']->getLL('status_CreatedDirectoryPermissions'), $value, $message, $severity);
241 }
242
243 /**
244 * Creates a link to the deprecation log file with the absolute path as the
245 * link text.
246 *
247 * @return string Link to the deprecation log file
248 */
249 protected function getDeprecationLogFileLink()
250 {
251 $logFile = GeneralUtility::getDeprecationLogFileName();
252 $relativePath = GeneralUtility::resolveBackPath($this->backPath . \TYPO3\CMS\Core\Utility\PathUtility::stripPathSitePrefix($logFile));
253 $link = '<a href="' . $relativePath . '">' . $logFile . '</a>';
254 return $link;
255 }
256
257 /**
258 * Executes admin commands.
259 *
260 * Currently implemented commands are:
261 * - Remove deprecation log file
262 *
263 * @return void
264 */
265 protected function executeAdminCommand()
266 {
267 $command = GeneralUtility::_GET('adminCmd');
268 switch ($command) {
269 case 'removeDeprecationLogFile':
270 self::removeDeprecationLogFile();
271 break;
272 default:
273 // intentionally left blank
274 }
275 }
276
277 /**
278 * Remove deprecation log file.
279 *
280 * @return void
281 */
282 protected static function removeDeprecationLogFile()
283 {
284 if (@unlink(GeneralUtility::getDeprecationLogFileName())) {
285 $message = $GLOBALS['LANG']->getLL('status_configuration_DeprecationLogDeletedSuccessful');
286 $severity = \TYPO3\CMS\Core\Messaging\FlashMessage::OK;
287 } else {
288 $message = $GLOBALS['LANG']->getLL('status_configuration_DeprecationLogDeletionFailed');
289 $severity = \TYPO3\CMS\Core\Messaging\FlashMessage::ERROR;
290 }
291 $flashMessage = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Messaging\FlashMessage::class, $message, '', $severity, true);
292 /** @var $flashMessageService \TYPO3\CMS\Core\Messaging\FlashMessageService */
293 $flashMessageService = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Messaging\FlashMessageService::class);
294 /** @var $defaultFlashMessageQueue \TYPO3\CMS\Core\Messaging\FlashMessageQueue */
295 $defaultFlashMessageQueue = $flashMessageService->getMessageQueueByIdentifier();
296 $defaultFlashMessageQueue->enqueue($flashMessage);
297 }
298 }