e28202043ef88c2cc861fc5f635a867c15c8504d
[Packages/TYPO3.CMS.git] / typo3 / sysext / reports / reports / status / class.tx_reports_reports_status_systemstatus.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2009-2011 Ingo Renner <ingo@typo3.org>
6 * All rights reserved
7 *
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 *
17 * This script is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * This copyright notice MUST APPEAR in all copies of the script!
23 ***************************************************************/
24
25
26 /**
27 * Performs several checks about the system's health
28 *
29 * @author Ingo Renner <ingo@typo3.org>
30 * @package TYPO3
31 * @subpackage reports
32 */
33 class tx_reports_reports_status_SystemStatus implements tx_reports_StatusProvider {
34
35 /**
36 * PHP modules which are required. Can be changed by hook in getMissingPhpModules()
37 *
38 * @var array
39 */
40 protected $requiredPhpModules = array(
41 'fileinfo', 'filter', 'gd', 'json', 'mysql', 'pcre', 'session', 'SPL', 'standard', 'openssl', 'xml', 'zlib', 'soap'
42 );
43
44 /**
45 * Determines the Install Tool's status, mainly concerning its protection.
46 *
47 * @return array List of statuses
48 * @see typo3/sysext/reports/interfaces/tx_reports_StatusProvider::getStatus()
49 */
50 public function getStatus() {
51 $this->executeAdminCommand();
52
53 $statuses = array(
54 'Php' => $this->getPhpStatus(),
55 'PhpMemoryLimit' => $this->getPhpMemoryLimitStatus(),
56 'PhpPeakMemory' => $this->getPhpPeakMemoryStatus(),
57 'PhpRegisterGlobals' => $this->getPhpRegisterGlobalsStatus(),
58 'Webserver' => $this->getWebserverStatus(),
59 'PhpModules' => $this->getMissingPhpModules(),
60 );
61
62 return $statuses;
63 }
64
65 /**
66 * Checks the current PHP version against a minimum required version.
67 *
68 * @return tx_reports_reports_status_Status A status of whether a minimum PHP version requirement is met
69 */
70 protected function getPhpStatus() {
71 $message = '';
72 $severity = tx_reports_reports_status_Status::OK;
73
74 if (version_compare(phpversion(), TYPO3_REQUIREMENTS_MINIMUM_PHP) < 0) {
75 $message = $GLOBALS['LANG']->getLL('status_phpTooOld');
76 $severity = tx_reports_reports_status_Status::ERROR;
77 }
78
79 return t3lib_div::makeInstance('tx_reports_reports_status_Status',
80 $GLOBALS['LANG']->getLL('status_phpVersion'),
81 phpversion(),
82 $message,
83 $severity
84 );
85 }
86
87 /**
88 * Checks the current memory limit against a minimum required version.
89 *
90 * @return tx_reports_reports_status_Status A status of whether a minimum memory limit requirement is met
91 */
92 protected function getPhpMemoryLimitStatus() {
93 $memoryLimit = ini_get('memory_limit');
94 $memoryLimitBytes = t3lib_div::getBytesFromSizeMeasurement($memoryLimit);
95 $message = '';
96 $severity = tx_reports_reports_status_Status::OK;
97
98 if ($memoryLimitBytes > 0) {
99 if ($memoryLimitBytes < t3lib_div::getBytesFromSizeMeasurement(TYPO3_REQUIREMENTS_RECOMMENDED_PHP_MEMORY_LIMIT)) {
100 $message = sprintf($GLOBALS['LANG']->getLL('status_phpMemoryRecommendation'), $memoryLimit, TYPO3_REQUIREMENTS_RECOMMENDED_PHP_MEMORY_LIMIT);
101 $severity = tx_reports_reports_status_Status::WARNING;
102 }
103
104 if ($memoryLimitBytes < t3lib_div::getBytesFromSizeMeasurement(TYPO3_REQUIREMENTS_MINIMUM_PHP_MEMORY_LIMIT)) {
105 $message = sprintf($GLOBALS['LANG']->getLL('status_phpMemoryRequirement'), $memoryLimit, TYPO3_REQUIREMENTS_MINIMUM_PHP_MEMORY_LIMIT);
106 $severity = tx_reports_reports_status_Status::ERROR;
107 }
108
109 if ($severity > tx_reports_reports_status_Status::OK) {
110 if ($php_ini_path = get_cfg_var('cfg_file_path')) {
111 $message .= ' ' . sprintf($GLOBALS['LANG']->getLL('status_phpMemoryEditLimit'), $php_ini_path);
112 } else {
113 $message .= ' ' . $GLOBALS['LANG']->getLL('status_phpMemoryContactAdmin');
114 }
115 }
116 }
117
118 return t3lib_div::makeInstance(
119 'tx_reports_reports_status_Status',
120 $GLOBALS['LANG']->getLL('status_phpMemory'),
121 ($memoryLimitBytes > 0 ? $memoryLimit : $GLOBALS['LANG']->getLL('status_phpMemoryUnlimited')),
122 $message,
123 $severity
124 );
125 }
126
127 /**
128 * Executes commands like clearing the memory status flag
129 *
130 * @return void
131 */
132 protected function executeAdminCommand() {
133 $command = t3lib_div::_GET('adminCmd');
134
135 switch ($command) {
136 case 'clear_peak_memory_usage_flag':
137 /** @var $registry t3lib_Registry */
138 $registry = t3lib_div::makeInstance('t3lib_Registry');
139 $registry->remove('core', 'reports-peakMemoryUsage');
140 break;
141 }
142 }
143
144 /**
145 * Checks if there was a request in the past which approached the memory limit
146 *
147 * @return tx_reports_reports_status_Status A status of whether the memory limit was approached by one of the requests
148 */
149 protected function getPhpPeakMemoryStatus() {
150 /** @var $registry t3lib_Registry */
151 $registry = t3lib_div::makeInstance('t3lib_Registry');
152 $peakMemoryUsage = $registry->get('core', 'reports-peakMemoryUsage');
153 $memoryLimit = t3lib_div::getBytesFromSizeMeasurement(ini_get('memory_limit'));
154 $value = $GLOBALS['LANG']->getLL('status_ok');
155
156 $message = '';
157 $severity = tx_reports_reports_status_Status::OK;
158 $bytesUsed = $peakMemoryUsage['used'];
159 $percentageUsed = $memoryLimit ? number_format($bytesUsed / $memoryLimit * 100, 1) . '%' : '?';
160 $dateOfPeak = date($GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'], $peakMemoryUsage['tstamp']);
161 $urlOfPeak = '<a href="' . htmlspecialchars($peakMemoryUsage['url']) . '">' . htmlspecialchars($peakMemoryUsage['url']) . '</a>';
162 $clearFlagUrl = t3lib_div::getIndpEnv('TYPO3_REQUEST_URL') . '&amp;adminCmd=clear_peak_memory_usage_flag';
163
164 if ($peakMemoryUsage['used']) {
165 $message = sprintf(
166 $GLOBALS['LANG']->getLL('status_phpPeakMemoryTooHigh'),
167 t3lib_div::formatSize($peakMemoryUsage['used']),
168 $percentageUsed,
169 t3lib_div::formatSize($memoryLimit),
170 $dateOfPeak,
171 $urlOfPeak
172 );
173 $message .= ' <a href="' . $clearFlagUrl . '">' . $GLOBALS['LANG']->getLL('status_phpPeakMemoryClearFlag') . '</a>.';
174 $severity = tx_reports_reports_status_Status::WARNING;
175 $value = $percentageUsed;
176 }
177
178 return t3lib_div::makeInstance('tx_reports_reports_status_Status',
179 $GLOBALS['LANG']->getLL('status_phpPeakMemory'), $value, $message, $severity
180 );
181 }
182
183 /**
184 * Checks whether register globals is on or off.
185 *
186 * @return tx_reports_reports_status_Status A status of whether register globals is on or off
187 */
188 protected function getPhpRegisterGlobalsStatus() {
189 $value = $GLOBALS['LANG']->getLL('status_disabled');
190 $message = '';
191 $severity = tx_reports_reports_status_Status::OK;
192
193 $registerGlobals = trim(ini_get('register_globals'));
194
195 // Can't reliably check for 'on', therefore checking for the opposite 'off', '', or 0
196 if (!empty($registerGlobals) && strtolower($registerGlobals) != 'off') {
197 $registerGlobalsHighlight = '<em>register_globals</em>';
198 $phpManualLink .= '<a href="http://php.net/configuration.changes">' . $GLOBALS['LANG']->getLL('status_phpRegisterGlobalsHowToChange') . '</a>';
199 $message = sprintf($GLOBALS['LANG']->getLL('status_phpRegisterGlobalsEnabled'), $registerGlobalsHighlight);
200 $message .= ' ' . sprintf($GLOBALS['LANG']->getLL('status_phpRegisterGlobalsSecurity'), $registerGlobalsHighlight);
201 $message .= ' ' . sprintf($GLOBALS['LANG']->getLL('status_phpRegisterGlobalsPHPManual'), $phpManualLink);
202 $severity = tx_reports_reports_status_Status::ERROR;
203 $value = $GLOBALS['LANG']->getLL('status_enabled')
204 . ' (\'' . $registerGlobals . '\')';
205 }
206
207 return t3lib_div::makeInstance('tx_reports_reports_status_Status',
208 $GLOBALS['LANG']->getLL('status_phpRegisterGlobals'), $value, $message, $severity
209 );
210 }
211
212 /**
213 * Reports the webserver TYPO3 is running on.
214 *
215 * @return tx_reports_reports_status_Status The server software as a status
216 */
217 protected function getWebserverStatus() {
218 return t3lib_div::makeInstance('tx_reports_reports_status_Status',
219 $GLOBALS['LANG']->getLL('status_webServer'),
220 $_SERVER['SERVER_SOFTWARE']
221 );
222 }
223
224 /**
225 * Reports whether any of the required PHP modules are missing
226 *
227 * @return tx_reports_reports_status_Status A status of missing PHP modules
228 */
229 protected function getMissingPhpModules() {
230 // Hook to adjust the required PHP modules
231 $modules = $this->requiredPhpModules;
232 if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install/mod/class.tx_install.php']['requiredPhpModules'])) {
233 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install/mod/class.tx_install.php']['requiredPhpModules'] as $classData) {
234 $hookObject = t3lib_div::getUserObj($classData);
235 $modules = $hookObject->setRequiredPhpModules($modules, $this);
236 }
237 }
238 $missingPhpModules = array();
239 foreach ($modules as $module) {
240 if (is_array($module)) {
241 $detectedSubmodules = FALSE;
242 foreach ($module as $submodule) {
243 if (extension_loaded($submodule)) {
244 $detectedSubmodules = TRUE;
245 }
246 }
247 if ($detectedSubmodules === FALSE) {
248 $missingPhpModules[] = sprintf($GLOBALS['LANG']->getLL('status_phpModulesGroup'), '(' . implode(', ', $module) . ')');
249 }
250 } elseif (!extension_loaded($module)) {
251 $missingPhpModules[] = $module;
252 }
253 }
254 if (count($missingPhpModules) > 0) {
255 $value = $GLOBALS['LANG']->getLL('status_phpModulesMissing');
256 $message = sprintf($GLOBALS['LANG']->getLL('status_phpModulesList'), implode(', ', $missingPhpModules));
257 $message .= ' ' . $GLOBALS['LANG']->getLL('status_phpModulesInfo');
258 $severity = tx_reports_reports_status_Status::ERROR;
259 } else {
260 $value = $GLOBALS['LANG']->getLL('status_phpModulesPresent');
261 $message = '';
262 $severity = tx_reports_reports_status_Status::OK;
263 }
264 return t3lib_div::makeInstance('tx_reports_reports_status_Status',
265 $GLOBALS['LANG']->getLL('status_phpModules'), $value, $message, $severity
266 );
267 }
268 }
269 ?>