15a6615736d536403050fa49ec8dc3d0b5f8dd55
[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 // PHP modules which are required. Can be changed by hook in getMissingPhpModules()
36 protected $requiredPhpModules = array(
37 'filter', 'gd', 'json', 'mysql', 'pcre', 'session', 'SPL', 'standard', 'openssl', 'xml', 'zlib'
38 );
39
40 /**
41 * Determines the Install Tool's status, mainly concerning its protection.
42 *
43 * @return array List of statuses
44 * @see typo3/sysext/reports/interfaces/tx_reports_StatusProvider::getStatus()
45 */
46 public function getStatus() {
47 $this->executeAdminCommand();
48
49 $statuses = array(
50 'Php' => $this->getPhpStatus(),
51 'PhpMemoryLimit' => $this->getPhpMemoryLimitStatus(),
52 'PhpPeakMemory' => $this->getPhpPeakMemoryStatus(),
53 'PhpRegisterGlobals' => $this->getPhpRegisterGlobalsStatus(),
54 'Webserver' => $this->getWebserverStatus(),
55 'PhpModules' => $this->getMissingPhpModules(),
56 );
57
58 return $statuses;
59 }
60
61
62 /**
63 * Checks the current PHP version against a minimum required version.
64 *
65 * @return tx_reports_reports_status_Status A status of whether a minimum PHP version requirment is met
66 */
67 protected function getPhpStatus() {
68 $message = '';
69 $severity = tx_reports_reports_status_Status::OK;
70
71 if (version_compare(phpversion(), TYPO3_REQUIREMENTS_MINIMUM_PHP) < 0) {
72 $message = $GLOBALS['LANG']->getLL('status_phpTooOld');
73 $severity = tx_reports_reports_status_Status::ERROR;
74 }
75
76 return t3lib_div::makeInstance('tx_reports_reports_status_Status',
77 $GLOBALS['LANG']->getLL('status_phpVersion'),
78 phpversion(),
79 $message,
80 $severity
81 );
82 }
83
84 /**
85 * Checks the current memory limit against a minimum required version.
86 *
87 * @return tx_reports_reports_status_Status A status of whether a minimum memory limit requirment is met
88 */
89 protected function getPhpMemoryLimitStatus() {
90 $memoryLimit = ini_get('memory_limit');
91 $message = '';
92 $severity = tx_reports_reports_status_Status::OK;
93
94 if ($memoryLimit && t3lib_div::getBytesFromSizeMeasurement($memoryLimit) < t3lib_div::getBytesFromSizeMeasurement(TYPO3_REQUIREMENTS_RECOMMENDED_PHP_MEMORY_LIMIT)) {
95 $message = sprintf($GLOBALS['LANG']->getLL('status_phpMemoryRecommendation'), $memoryLimit, TYPO3_REQUIREMENTS_RECOMMENDED_PHP_MEMORY_LIMIT);
96 $severity = tx_reports_reports_status_Status::WARNING;
97 }
98
99 if ($memoryLimit && t3lib_div::getBytesFromSizeMeasurement($memoryLimit) < t3lib_div::getBytesFromSizeMeasurement(TYPO3_REQUIREMENTS_MINIMUM_PHP_MEMORY_LIMIT)) {
100 $message = sprintf($GLOBALS['LANG']->getLL('status_phpMemoryRequirement'), $memoryLimit, TYPO3_REQUIREMENTS_MINIMUM_PHP_MEMORY_LIMIT);
101 $severity = tx_reports_reports_status_Status::ERROR;
102 }
103
104 if ($severity > tx_reports_reports_status_Status::OK) {
105 if ($php_ini_path = get_cfg_var('cfg_file_path')) {
106 $message .= ' ' . sprintf($GLOBALS['LANG']->getLL('status_phpMemoryEditLimit'), $php_ini_path);
107 } else {
108 $message .= ' ' . $GLOBALS['LANG']->getLL('status_phpMemoryContactAdmin');
109 }
110 }
111
112 return t3lib_div::makeInstance('tx_reports_reports_status_Status',
113 $GLOBALS['LANG']->getLL('status_phpMemory'), $memoryLimit, $message, $severity
114 );
115 }
116
117 /**
118 * Executes commands like clearing the memory status flag
119 *
120 * @return void
121 */
122 protected function executeAdminCommand() {
123 $command = t3lib_div::_GET('adminCmd');
124
125 switch ($command) {
126 case 'clear_peak_memory_usage_flag':
127 /** @var $registry t3lib_Registry */
128 $registry = t3lib_div::makeInstance('t3lib_Registry');
129 $registry->remove('core', 'reports-peakMemoryUsage');
130 break;
131 }
132 }
133
134 /**
135 * Checks if there was a request in the past which approached the memory limit
136 *
137 * @return tx_reports_reports_status_Status A status of whether the memory limit was approached by one of the requests
138 */
139 protected function getPhpPeakMemoryStatus() {
140 /** @var $registry t3lib_Registry */
141 $registry = t3lib_div::makeInstance('t3lib_Registry');
142 $peakMemoryUsage = $registry->get('core', 'reports-peakMemoryUsage');
143 $memoryLimit = t3lib_div::getBytesFromSizeMeasurement(ini_get('memory_limit'));
144 $value = $GLOBALS['LANG']->getLL('status_ok');
145
146 $message = '';
147 $severity = tx_reports_reports_status_Status::OK;
148 $bytesUsed = $peakMemoryUsage['used'];
149 $percentageUsed = $memoryLimit ? number_format($bytesUsed / $memoryLimit * 100, 1) . '%' : '?';
150 $dateOfPeak = date($GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'], $peakMemoryUsage['tstamp']);
151 $urlOfPeak = '<a href="' . htmlspecialchars($peakMemoryUsage['url']) . '">' . htmlspecialchars($peakMemoryUsage['url']) . '</a>';
152 $clearFlagUrl = t3lib_div::getIndpEnv('TYPO3_REQUEST_URL') . '&amp;adminCmd=clear_peak_memory_usage_flag';
153
154 if ($peakMemoryUsage['used']) {
155 $message = sprintf(
156 $GLOBALS['LANG']->getLL('status_phpPeakMemoryTooHigh'),
157 t3lib_div::formatSize($peakMemoryUsage['used']),
158 $percentageUsed,
159 t3lib_div::formatSize($memoryLimit),
160 $dateOfPeak,
161 $urlOfPeak
162 );
163 $message .= ' <a href="' . $clearFlagUrl . '">' . $GLOBALS['LANG']->getLL('status_phpPeakMemoryClearFlag') . '</a>.';
164 $severity = tx_reports_reports_status_Status::WARNING;
165 $value = $percentageUsed;
166 }
167
168 return t3lib_div::makeInstance('tx_reports_reports_status_Status',
169 $GLOBALS['LANG']->getLL('status_phpPeakMemory'), $value, $message, $severity
170 );
171 }
172
173 /**
174 * checks whether register globals is on or off.
175 *
176 * @return tx_reports_reports_status_Status A status of whether register globals is on or off
177 */
178 protected function getPhpRegisterGlobalsStatus() {
179 $value = $GLOBALS['LANG']->getLL('status_disabled');
180 $message = '';
181 $severity = tx_reports_reports_status_Status::OK;
182
183 $registerGlobals = trim(ini_get('register_globals'));
184
185 // can't reliably check for 'on', therefore checking for the oposite 'off', '', or 0
186 if (!empty($registerGlobals) && strtolower($registerGlobals) != 'off') {
187 $registerGlobalsHighlight = '<em>register_globals</em>';
188 $phpManualLink .= '<a href="http://php.net/configuration.changes">' . $GLOBALS['LANG']->getLL('status_phpRegisterGlobalsHowToChange') . '</a>';
189 $message = sprintf($GLOBALS['LANG']->getLL('status_phpRegisterGlobalsEnabled'), $registerGlobalsHighlight);
190 $message .= ' ' . sprintf($GLOBALS['LANG']->getLL('status_phpRegisterGlobalsSecurity'), $registerGlobalsHighlight);
191 $message .= ' ' . sprintf($GLOBALS['LANG']->getLL('status_phpRegisterGlobalsPHPManual'), $phpManualLink);
192 $severity = tx_reports_reports_status_Status::ERROR;
193 $value = $GLOBALS['LANG']->getLL('status_enabled')
194 . ' (\'' . $registerGlobals . '\')';
195 }
196
197 return t3lib_div::makeInstance('tx_reports_reports_status_Status',
198 $GLOBALS['LANG']->getLL('status_phpRegisterGlobals'), $value, $message, $severity
199 );
200 }
201
202 /**
203 * Reports the webserver TYPO3 is running on.
204 *
205 * @return tx_reports_reports_status_Status The server software as a status
206 */
207 protected function getWebserverStatus() {
208 return t3lib_div::makeInstance('tx_reports_reports_status_Status',
209 $GLOBALS['LANG']->getLL('status_webServer'),
210 $_SERVER['SERVER_SOFTWARE']
211 );
212 }
213
214 /**
215 * Reports whether any of the required PHP modules are missing
216 *
217 * @return tx_reports_reports_status_Status A status of missing PHP modules
218 */
219 protected function getMissingPhpModules() {
220 // Hook to adjust the required PHP modules
221 $modules = $this->requiredPhpModules;
222 if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install/mod/class.tx_install.php']['requiredPhpModules'])) {
223 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/install/mod/class.tx_install.php']['requiredPhpModules'] as $classData) {
224 $hookObject = t3lib_div::getUserObj($classData);
225 $modules = $hookObject->setRequiredPhpModules($modules, $this);
226 }
227 }
228 $missingPhpModules = array();
229 foreach ($modules as $module) {
230 if (is_array($module)) {
231 $detectedSubmodules = FALSE;
232 foreach ($module as $submodule) {
233 if (extension_loaded($submodule)) {
234 $detectedSubmodules = TRUE;
235 }
236 }
237 if ($detectedSubmodules === FALSE) {
238 $missingPhpModules[] = sprintf($GLOBALS['LANG']->getLL('status_phpModulesGroup'), '(' . implode(', ', $module) . ')');
239 }
240 } elseif (!extension_loaded($module)) {
241 $missingPhpModules[] = $module;
242 }
243 }
244 if (count($missingPhpModules) > 0) {
245 $value = $GLOBALS['LANG']->getLL('status_phpModulesMissing');
246 $message = sprintf($GLOBALS['LANG']->getLL('status_phpModulesList'), implode(', ', $missingPhpModules));
247 $message .= ' ' . $GLOBALS['LANG']->getLL('status_phpModulesInfo');
248 $severity = tx_reports_reports_status_Status::ERROR;
249 } else {
250 $value = $GLOBALS['LANG']->getLL('status_phpModulesPresent');
251 $message = '';
252 $severity = tx_reports_reports_status_Status::OK;
253 }
254 return t3lib_div::makeInstance('tx_reports_reports_status_Status',
255 $GLOBALS['LANG']->getLL('status_phpModules'), $value, $message, $severity
256 );
257 }
258 }
259
260
261 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['ext/reports/reports/status/class.tx_reports_reports_status_systemstatus.php'])) {
262 include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['ext/reports/reports/status/class.tx_reports_reports_status_systemstatus.php']);
263 }
264
265 ?>