f5a3de29732cc2b42af8f57a11c04dc05240431d
[Packages/TYPO3.CMS.git] / typo3 / sysext / install / Classes / SystemEnvironment / Check.php
1 <?php
2 namespace TYPO3\CMS\Install\SystemEnvironment;
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\Install\Status;
18
19 /**
20 * Check system environment status
21 *
22 * This class is a hardcoded requirement check of the underlying
23 * server and PHP system.
24 *
25 * The class *must not* check for any TYPO3 specific things like
26 * specific configuration values or directories. It should not fail
27 * if there is no TYPO3 at all.
28 *
29 * The only core code used is the class loader
30 *
31 * This class is instantiated as the *very first* class during
32 * installation. It is meant to be *standalone* und must not have
33 * any requirements, except the status classes. It must be possible
34 * to run this script separated from the rest of the core, without
35 * dependencies.
36 *
37 * This means especially:
38 * * No hooks or anything like that
39 * * No usage of *any* TYPO3 code like GeneralUtility
40 * * No require of anything but the status classes
41 * * No localization
42 *
43 * The status messages and title *must not* include HTML, use plain
44 * text only. The return values of this class are not bound to HTML
45 * and can be used in different scopes (eg. as json array).
46 *
47 * @author Christian Kuhn <lolli@schwarzbu.ch>
48 */
49 class Check {
50
51 /**
52 * @var array List of required PHP extensions
53 */
54 protected $requiredPhpExtensions = array(
55 'fileinfo',
56 'filter',
57 'gd',
58 'hash',
59 'json',
60 'mysqli',
61 'openssl',
62 'pcre',
63 'session',
64 'soap',
65 'SPL',
66 'standard',
67 'xml',
68 'zip',
69 'zlib',
70 );
71
72 /**
73 * Get all status information as array with status objects
74 *
75 * @return array<\TYPO3\CMS\Install\Status\StatusInterface>
76 */
77 public function getStatus() {
78 $statusArray = array();
79 $statusArray[] = $this->checkCurrentDirectoryIsInIncludePath();
80 $statusArray[] = $this->checkFileUploadEnabled();
81 $statusArray[] = $this->checkMaximumFileUploadSize();
82 $statusArray[] = $this->checkPostUploadSizeIsHigherOrEqualMaximumFileUploadSize();
83 $statusArray[] = $this->checkMemorySettings();
84 $statusArray[] = $this->checkPhpVersion();
85 $statusArray[] = $this->checkMaxExecutionTime();
86 $statusArray[] = $this->checkDisableFunctions();
87 $statusArray[] = $this->checkDownloadsPossible();
88 $statusArray[] = $this->checkSafeMode();
89 $statusArray[] = $this->checkDocRoot();
90 $statusArray[] = $this->checkOpenBaseDir();
91 $statusArray[] = $this->checkXdebugMaxNestingLevel();
92 $statusArray[] = $this->checkOpenSslInstalled();
93 $statusArray[] = $this->checkSuhosinLoaded();
94 $statusArray[] = $this->checkSuhosinRequestMaxVars();
95 $statusArray[] = $this->checkSuhosinPostMaxVars();
96 $statusArray[] = $this->checkSuhosinGetMaxValueLength();
97 $statusArray[] = $this->checkSuhosinExecutorIncludeWhitelistContainsPhar();
98 $statusArray[] = $this->checkSuhosinExecutorIncludeWhitelistContainsVfs();
99 $statusArray[] = $this->checkSomePhpOpcodeCacheIsLoaded();
100 $statusArray[] = $this->checkReflectionDocComment();
101 $statusArray[] = $this->checkSystemLocale();
102 $statusArray[] = $this->checkLocaleWithUTF8filesystem();
103 $statusArray[] = $this->checkWindowsApacheThreadStackSize();
104 foreach ($this->requiredPhpExtensions as $extension) {
105 $statusArray[] = $this->checkRequiredPhpExtension($extension);
106 }
107 $statusArray[] = $this->checkGdLibTrueColorSupport();
108 $statusArray[] = $this->checkGdLibGifSupport();
109 $statusArray[] = $this->checkGdLibJpgSupport();
110 $statusArray[] = $this->checkGdLibPngSupport();
111 $statusArray[] = $this->checkGdLibFreeTypeSupport();
112 $statusArray[] = $this->checkPhpMagicQuotes();
113 $statusArray[] = $this->checkRegisterGlobals();
114 $statusArray[] = $this->checkLibXmlBug();
115 $statusArray[] = $this->isTrueTypeFontDpiStandard();
116 return $statusArray;
117 }
118
119 /**
120 * Checks if current directory (.) is in PHP include path
121 *
122 * @return Status\StatusInterface
123 */
124 protected function checkCurrentDirectoryIsInIncludePath() {
125 $includePath = ini_get('include_path');
126 $delimiter = $this->isWindowsOs() ? ';' : ':';
127 $pathArray = $this->trimExplode($delimiter, $includePath);
128 if (!in_array('.', $pathArray)) {
129 $status = new Status\WarningStatus();
130 $status->setTitle('Current directory (./) is not within PHP include path');
131 $status->setMessage(
132 'include_path = ' . implode(' ', $pathArray) . LF .
133 'Normally the current path \'.\' is included in the' .
134 ' include_path of PHP. Although TYPO3 does not rely on this,' .
135 ' it is an unusual setting that may introduce problems for' .
136 ' some extensions.'
137 );
138 } else {
139 $status = new Status\OkStatus();
140 $status->setTitle('Current directory (./) is within PHP include path.');
141 }
142 return $status;
143 }
144
145 /**
146 * Check if file uploads are enabled in PHP
147 *
148 * @return Status\StatusInterface
149 */
150 protected function checkFileUploadEnabled() {
151 if (!ini_get('file_uploads')) {
152 $status = new Status\ErrorStatus();
153 $status->setTitle('File uploads not allowed in PHP');
154 $status->setMessage(
155 'file_uploads=' . ini_get('file_uploads') . LF .
156 'TYPO3 uses the ability to upload files from the browser in various cases.' .
157 ' If this flag is disabled in PHP, you won\'t be able to upload files.' .
158 ' But it doesn\'t end here, because not only are files not accepted by' .
159 ' the server - ALL content in the forms are discarded and therefore' .
160 ' nothing at all will be editable if you don\'t set this flag!' .
161 ' However if you cannot enable fileupload for some reason in PHP, alternatively' .
162 ' change the default form encoding value with \\$TYPO3_CONF_VARS[SYS][form_enctype].'
163 );
164 } else {
165 $status = new Status\OkStatus();
166 $status->setTitle('File uploads allowed in PHP');
167 }
168 return $status;
169 }
170
171 /**
172 * Check maximum file upload size against default value of 10MB
173 *
174 * @return Status\StatusInterface
175 */
176 protected function checkMaximumFileUploadSize() {
177 $maximumUploadFilesize = $this->getBytesFromSizeMeasurement(ini_get('upload_max_filesize'));
178 $configuredMaximumUploadFilesize = 1024 * $GLOBALS['TYPO3_CONF_VARS']['BE']['maxFileSize'];
179 if ($maximumUploadFilesize < $configuredMaximumUploadFilesize) {
180 $status = new Status\ErrorStatus();
181 $status->setTitle('PHP Maximum upload filesize too small');
182 $status->setMessage(
183 'PHP upload_max_filesize = ' . (int)ini_get('upload_max_filesize') . ' MB' . LF .
184 'TYPO3_CONF_VARS[BE][maxFileSize] = ' . (int)($configuredMaximumUploadFilesize / 1024 / 1024) . ' MB' . LF . LF .
185 'Currently PHP determines the limits for uploaded file\'s sizes and not TYPO3.' .
186 ' It is recommended that the value of upload_max_filesize is at least equal to the value' .
187 ' of TYPO3_CONF_VARS[BE][maxFileSize].'
188 );
189 } else {
190 $status = new Status\OkStatus();
191 $status->setTitle('PHP Maximum file upload size is higher than or equal to [BE][maxFileSize]');
192 }
193 return $status;
194 }
195
196 /**
197 * Check maximum post upload size correlates with maximum file upload
198 *
199 * @return Status\StatusInterface
200 */
201 protected function checkPostUploadSizeIsHigherOrEqualMaximumFileUploadSize() {
202 $maximumUploadFilesize = $this->getBytesFromSizeMeasurement(ini_get('upload_max_filesize'));
203 $maximumPostSize = $this->getBytesFromSizeMeasurement(ini_get('post_max_size'));
204 if ($maximumPostSize < $maximumUploadFilesize) {
205 $status = new Status\ErrorStatus();
206 $status->setTitle('Maximum size for POST requests is smaller than maximum upload filesize in PHP');
207 $status->setMessage(
208 'upload_max_filesize=' . ini_get('upload_max_filesize') . LF .
209 'post_max_size=' . ini_get('post_max_size') . LF .
210 'You have defined a maximum size for file uploads in PHP which' .
211 ' exceeds the allowed size for POST requests. Therefore the' .
212 ' file uploads can also not be larger than ' . ini_get('post_max_size') . '.'
213 );
214 } else {
215 $status = new Status\OkStatus();
216 $status->setTitle('Maximum post upload size correlates with maximum upload file size in PHP');
217 }
218 return $status;
219 }
220
221 /**
222 * Check memory settings
223 *
224 * @return Status\StatusInterface
225 */
226 protected function checkMemorySettings() {
227 $minimumMemoryLimit = 32;
228 $recommendedMemoryLimit = 64;
229 $memoryLimit = $this->getBytesFromSizeMeasurement(ini_get('memory_limit'));
230 if ($memoryLimit <= 0) {
231 $status = new Status\WarningStatus();
232 $status->setTitle('Unlimited memory limit for PHP');
233 $status->setMessage(
234 'PHP is configured not to limit memory usage at all. This is a risk' .
235 ' and should be avoided in production setup. In general it\'s best practice to limit this.' .
236 ' To be safe, set a limit in PHP, but with a minimum of ' . $recommendedMemoryLimit . 'MB:' . LF .
237 'memory_limit=' . $recommendedMemoryLimit . 'M'
238 );
239 } elseif ($memoryLimit < 1024 * 1024 * $minimumMemoryLimit) {
240 $status = new Status\ErrorStatus();
241 $status->setTitle('PHP Memory limit below ' . $minimumMemoryLimit . 'MB');
242 $status->setMessage(
243 'memory_limit=' . ini_get('memory_limit') . LF .
244 'Your system is configured to enforce a memory limit for PHP scripts lower than ' .
245 $minimumMemoryLimit . 'MB. It is required to raise the limit.' .
246 ' We recommend a minimum PHP memory limit of ' . $recommendedMemoryLimit . 'MB:' . LF .
247 'memory_limit=' . $recommendedMemoryLimit . 'M'
248 );
249 } elseif ($memoryLimit < 1024 * 1024 * $recommendedMemoryLimit) {
250 $status = new Status\WarningStatus();
251 $status->setTitle('PHP Memory limit below ' . $recommendedMemoryLimit . 'MB');
252 $status->setMessage(
253 'memory_limit=' . ini_get('memory_limit') . LF .
254 'Your system is configured to enforce a memory limit for PHP scripts lower than ' .
255 $recommendedMemoryLimit . 'MB.' .
256 ' A slim TYPO3 instance without many extensions will probably work, but you should monitor your' .
257 ' system for "allowed memory size of X bytes exhausted" messages, especially if using the backend.' .
258 ' To be on the safe side,' . ' we recommend a minimum PHP memory limit of ' .
259 $recommendedMemoryLimit . 'MB:' . LF .
260 'memory_limit=' . $recommendedMemoryLimit . 'M'
261 );
262 } else {
263 $status = new Status\OkStatus();
264 $status->setTitle('PHP Memory limit is equal to or more than ' . $recommendedMemoryLimit . 'MB');
265 }
266 return $status;
267 }
268
269 /**
270 * Check minimum PHP version
271 *
272 * @return Status\StatusInterface
273 */
274 protected function checkPhpVersion() {
275 $minimumPhpVersion = '5.3.7';
276 $currentPhpVersion = phpversion();
277 if (version_compare($currentPhpVersion, $minimumPhpVersion) < 0) {
278 $status = new Status\ErrorStatus();
279 $status->setTitle('PHP version too low');
280 $status->setMessage(
281 'Your PHP version ' . $currentPhpVersion . ' is too old. TYPO3 CMS does not run' .
282 ' with this version. Update to at least PHP ' . $minimumPhpVersion
283 );
284 } else {
285 $status = new Status\OkStatus();
286 $status->setTitle('PHP version is fine');
287 }
288 return $status;
289 }
290
291 /**
292 * Check maximum execution time
293 *
294 * @return Status\StatusInterface
295 */
296 protected function checkMaxExecutionTime() {
297 $minimumMaximumExecutionTime = 30;
298 $recommendedMaximumExecutionTime = 240;
299 $currentMaximumExecutionTime = ini_get('max_execution_time');
300 if ($currentMaximumExecutionTime == 0) {
301 if (PHP_SAPI === 'cli') {
302 $status = new Status\OkStatus();
303 $status->setTitle('Infinite PHP script execution time');
304 $status->setMessage(
305 'Maximum PHP script execution time is always set to infinite (0) in cli mode.' .
306 ' The setting used for web requests cannot be checked from command line.'
307 );
308 } else {
309 $status = new Status\WarningStatus();
310 $status->setTitle('Infinite PHP script execution time');
311 $status->setMessage(
312 'max_execution_time=' . $currentMaximumExecutionTime . LF .
313 'While TYPO3 is fine with this, you risk a denial-of-service for your system if for whatever' .
314 ' reason some script hangs in an infinite loop. You are usually on the safe side ' .
315 ' if it is reduced to ' . $recommendedMaximumExecutionTime . ' seconds:' . LF .
316 'max_execution_time=' . $recommendedMaximumExecutionTime
317 );
318 }
319 } elseif ($currentMaximumExecutionTime < $minimumMaximumExecutionTime) {
320 $status = new Status\ErrorStatus();
321 $status->setTitle('Low PHP script execution time');
322 $status->setMessage(
323 'max_execution_time=' . $currentMaximumExecutionTime . LF .
324 'Your max_execution_time is too low. Some expensive operations in TYPO3 can take longer than that.' .
325 ' It is recommended to raise the limit to ' . $recommendedMaximumExecutionTime . ' seconds:' . LF .
326 'max_execution_time=' . $recommendedMaximumExecutionTime
327 );
328 } elseif ($currentMaximumExecutionTime < $recommendedMaximumExecutionTime) {
329 $status = new Status\WarningStatus();
330 $status->setTitle('Low PHP script execution time');
331 $status->setMessage(
332 'max_execution_time=' . $currentMaximumExecutionTime . LF .
333 'Your max_execution_time is low. While TYPO3 often runs without problems' .
334 ' with ' . $minimumMaximumExecutionTime . ' seconds,' .
335 ' it may still happen that script execution is stopped before finishing' .
336 ' calculations. You should monitor the system for messages in this area' .
337 ' and maybe raise the limit to ' . $recommendedMaximumExecutionTime . ' seconds:' . LF .
338 'max_execution_time=' . $recommendedMaximumExecutionTime
339 );
340 } else {
341 $status = new Status\OkStatus();
342 $status->setTitle('Maximum PHP script execution time is equal to or more than '
343 . $recommendedMaximumExecutionTime);
344 }
345 return $status;
346 }
347
348 /**
349 * Check for disabled functions
350 *
351 * @return Status\StatusInterface
352 */
353 protected function checkDisableFunctions() {
354 $disabledFunctions = trim(ini_get('disable_functions'));
355
356 // Filter "disable_functions"
357 $disabledFunctionsArray = $this->trimExplode(',', $disabledFunctions);
358
359 // Array with strings to find
360 $findStrings = array(
361 // Disabled by default on Ubuntu OS but this is okay since the Core does not use them
362 'pcntl_',
363 );
364 foreach ($disabledFunctionsArray as $key => $disabledFunction) {
365 foreach ($findStrings as $findString) {
366 if (strpos($disabledFunction, $findString) !== FALSE) {
367 unset($disabledFunctionsArray[$key]);
368 }
369 }
370 }
371
372 if (strlen($disabledFunctions) > 0 && count($disabledFunctionsArray) > 0) {
373 $status = new Status\ErrorStatus();
374 $status->setTitle('Some PHP functions disabled');
375 $status->setMessage(
376 'disable_functions=' . implode(' ', explode(',', $disabledFunctions)) . LF .
377 'These function(s) are disabled. TYPO3 uses some of those, so there might be trouble.' .
378 ' TYPO3 is designed to use the default set of PHP functions plus some common extensions.' .
379 ' Possibly these functions are disabled' .
380 ' due to security considerations and most likely the list would include a function like' .
381 ' exec() which is used by TYPO3 at various places. Depending on which exact functions' .
382 ' are disabled, some parts of the system may just break without further notice.'
383 );
384 } elseif (strlen($disabledFunctions) > 0 && count($disabledFunctionsArray) === 0) {
385 $status = new Status\NoticeStatus();
386 $status->setTitle('Some PHP functions currently disabled but OK');
387 $status->setMessage(
388 'disable_functions=' . implode(' ', explode(',', $disabledFunctions)) . LF .
389 'These function(s) are disabled. TYPO3 uses currently none of those, so you are good to go.'
390 );
391 } else {
392 $status = new Status\OkStatus();
393 $status->setTitle('No disabled PHP functions');
394 }
395 return $status;
396 }
397
398 /**
399 * Check if it is possible to download external data (e.g. TER)
400 * Either allow_url_fopen must be enabled or curl must be used
401 *
402 * @return Status\OkStatus|Status\WarningStatus
403 */
404 protected function checkDownloadsPossible() {
405 $allowUrlFopen = (bool)ini_get('allow_url_fopen');
406 $curlEnabled = !empty($GLOBALS['TYPO3_CONF_VARS']['SYS']['curlUse']);
407 if ($allowUrlFopen || $curlEnabled) {
408 $status = new Status\OkStatus();
409 $status->setTitle('Fetching external URLs is allowed');
410 } else {
411 $status = new Status\WarningStatus();
412 $status->setTitle('Fetching external URLs is not allowed');
413 $status->setMessage(
414 'Either enable PHP runtime setting "allow_url_fopen"' . LF . 'or enable curl by setting [SYS][curlUse] accordingly.'
415 );
416 }
417 return $status;
418 }
419
420 /**
421 * Check if safe mode is enabled
422 *
423 * @return Status\StatusInterface
424 */
425 protected function checkSafeMode() {
426 $safeModeEnabled = FALSE;
427 if (version_compare(phpversion(), '5.4', '<')) {
428 $safeModeEnabled = filter_var(
429 ini_get('safe_mode'),
430 FILTER_VALIDATE_BOOLEAN,
431 array(FILTER_REQUIRE_SCALAR, FILTER_NULL_ON_FAILURE)
432 );
433 }
434 if ($safeModeEnabled) {
435 $status = new Status\ErrorStatus();
436 $status->setTitle('PHP safe mode on');
437 $status->setMessage(
438 'PHP safe_mode enabled. This is unsupported by TYPO3 CMS, it must be turned off:' . LF .
439 'safe_mode=Off'
440 );
441 } else {
442 $status = new Status\OkStatus();
443 $status->setTitle('PHP safe mode off');
444 }
445 return $status;
446 }
447
448 /**
449 * Check for doc_root ini setting
450 *
451 * @return Status\StatusInterface
452 */
453 protected function checkDocRoot() {
454 $docRootSetting = trim(ini_get('doc_root'));
455 if (strlen($docRootSetting) > 0) {
456 $status = new Status\NoticeStatus();
457 $status->setTitle('doc_root is set');
458 $status->setMessage(
459 'doc_root=' . $docRootSetting . LF .
460 'PHP cannot execute scripts' .
461 ' outside this directory. This setting is seldom used and must correlate' .
462 ' with your actual document root. You might be in trouble if your' .
463 ' TYPO3 CMS core code is linked to some different location.' .
464 ' If that is a problem, the setting must be changed.'
465 );
466 } else {
467 $status = new Status\OkStatus();
468 $status->setTitle('PHP doc_root is not set');
469 }
470 return $status;
471 }
472
473 /**
474 * Check open_basedir
475 *
476 * @return Status\StatusInterface
477 */
478 protected function checkOpenBaseDir() {
479 $openBaseDirSetting = trim(ini_get('open_basedir'));
480 if (strlen($openBaseDirSetting) > 0) {
481 $status = new Status\NoticeStatus();
482 $status->setTitle('PHP open_basedir is set');
483 $status->setMessage(
484 'open_basedir = ' . ini_get('open_basedir') . LF .
485 'This restricts TYPO3 to open and include files only in this' .
486 ' path. Please make sure that this does not prevent TYPO3 from running,' .
487 ' if for example your TYPO3 CMS core is linked to a different directory' .
488 ' not included in this path.'
489 );
490 } else {
491 $status = new Status\OkStatus();
492 $status->setTitle('PHP open_basedir is off');
493 }
494 return $status;
495 }
496
497 /**
498 * If xdebug is loaded, the default max_nesting_level of 100 must be raised
499 *
500 * @return Status\StatusInterface
501 */
502 protected function checkXdebugMaxNestingLevel() {
503 if (extension_loaded('xdebug')) {
504 $recommendedMaxNestingLevel = 400;
505 $currentMaxNestingLevel = ini_get('xdebug.max_nesting_level');
506 if ($currentMaxNestingLevel < $recommendedMaxNestingLevel) {
507 $status = new Status\ErrorStatus();
508 $status->setTitle('PHP xdebug.max_nesting_level too low');
509 $status->setMessage(
510 'xdebug.max_nesting_level=' . $currentMaxNestingLevel . LF .
511 'This setting controls the maximum number of nested function calls to protect against' .
512 ' infinite recursion. The current value is too low for TYPO3 CMS and must' .
513 ' be either raised or xdebug unloaded. A value of ' . $recommendedMaxNestingLevel .
514 ' is recommended. Warning: Expect fatal PHP errors in central parts of the CMS' .
515 ' if the value is not raised significantly to:' . LF .
516 'xdebug.max_nesting_level=' . $recommendedMaxNestingLevel
517 );
518 } else {
519 $status = new Status\OkStatus();
520 $status->setTitle('PHP xdebug.max_nesting_level ok');
521 }
522 } else {
523 $status = new Status\OkStatus();
524 $status->setTitle('PHP xdebug extension not loaded');
525 }
526 return $status;
527 }
528
529 /**
530 * Check accessibility and functionality of OpenSSL
531 *
532 * @return Status\StatusInterface
533 */
534 protected function checkOpenSslInstalled() {
535 if (extension_loaded('openssl')) {
536 $testKey = @openssl_pkey_new();
537 if (is_resource($testKey)) {
538 openssl_free_key($testKey);
539 $status = new Status\OkStatus();
540 $status->setTitle('PHP OpenSSL extension installed properly');
541 } else {
542 $status = new Status\ErrorStatus();
543 $status->setTitle('PHP OpenSSL extension not working');
544 $status->setMessage(
545 'Something went wrong while trying to create a new private key for testing.' .
546 ' Please check the integration of the PHP OpenSSL extension and if it is installed correctly.'
547 );
548 }
549 } else {
550 $status = new Status\ErrorStatus();
551 $status->setTitle('PHP OpenSSL extension not loaded');
552 $status->setMessage(
553 'OpenSSL is a PHP extension to encrypt/decrypt data between requests.' .
554 ' TYPO3 CMS requires it to be able to encrypt stored passwords to improve the security in the' .
555 ' database layer.'
556 );
557 }
558
559 return $status;
560 }
561
562 /**
563 * Check enabled suhosin
564 *
565 * @return Status\StatusInterface
566 */
567 protected function checkSuhosinLoaded() {
568 if ($this->isSuhosinLoaded()) {
569 $status = new Status\OkStatus();
570 $status->setTitle('PHP suhosin extension loaded');
571 } else {
572 $status = new Status\NoticeStatus();
573 $status->setTitle('PHP suhosin extension not loaded');
574 $status->setMessage(
575 'suhosin is an extension to harden the PHP environment. In general, it is' .
576 ' good to have it from a security point of view. While TYPO3 CMS works' .
577 ' fine with suhosin, it has some requirements different from the default settings' .
578 ' to be set if enabled.'
579 );
580 }
581 return $status;
582 }
583
584 /**
585 * Check suhosin.request.max_vars
586 *
587 * @return Status\StatusInterface
588 */
589 protected function checkSuhosinRequestMaxVars() {
590 $recommendedRequestMaxVars = 400;
591 if ($this->isSuhosinLoaded()) {
592 $currentRequestMaxVars = ini_get('suhosin.request.max_vars');
593 if ($currentRequestMaxVars < $recommendedRequestMaxVars) {
594 $status = new Status\ErrorStatus();
595 $status->setTitle('PHP suhosin.request.max_vars too low');
596 $status->setMessage(
597 'suhosin.request.max_vars=' . $currentRequestMaxVars . LF .
598 'This setting can lead to lost information if submitting forms with lots of data in TYPO3 CMS' .
599 ' (as the install tool does). It is highly recommended to raise this' .
600 ' to at least ' . $recommendedRequestMaxVars . ':' . LF .
601 'suhosin.request.max_vars=' . $recommendedRequestMaxVars
602 );
603 } else {
604 $status = new Status\OkStatus();
605 $status->setTitle('PHP suhosin.request.max_vars ok');
606 }
607 } else {
608 $status = new Status\InfoStatus();
609 $status->setTitle('Suhosin not loaded');
610 $status->setMessage(
611 'If enabling suhosin, suhosin.request.max_vars' .
612 ' should be set to at least ' . $recommendedRequestMaxVars . ':' . LF .
613 'suhosin.request.max_vars=' . $recommendedRequestMaxVars
614 );
615 }
616 return $status;
617 }
618
619 /**
620 * Check suhosin.post.max_vars
621 *
622 * @return Status\StatusInterface
623 */
624 protected function checkSuhosinPostMaxVars() {
625 $recommendedPostMaxVars = 400;
626 if ($this->isSuhosinLoaded()) {
627 $currentPostMaxVars = ini_get('suhosin.post.max_vars');
628 if ($currentPostMaxVars < $recommendedPostMaxVars) {
629 $status = new Status\ErrorStatus();
630 $status->setTitle('PHP suhosin.post.max_vars too low');
631 $status->setMessage(
632 'suhosin.post.max_vars=' . $currentPostMaxVars . LF .
633 'This setting can lead to lost information if submitting forms with lots of data in TYPO3 CMS' .
634 ' (as the install tool does). It is highly recommended to raise this' .
635 ' to at least ' . $recommendedPostMaxVars . ':' . LF .
636 'suhosin.post.max_vars=' . $recommendedPostMaxVars
637 );
638 } else {
639 $status = new Status\OkStatus();
640 $status->setTitle('PHP suhosin.post.max_vars ok');
641 }
642 } else {
643 $status = new Status\InfoStatus();
644 $status->setTitle('Suhosin not loaded');
645 $status->setMessage(
646 'If enabling suhosin, suhosin.post.max_vars' .
647 ' should be set to at least ' . $recommendedPostMaxVars . ':' . LF .
648 'suhosin.post.max_vars=' . $recommendedPostMaxVars
649 );
650 }
651 return $status;
652 }
653
654 /**
655 * Check suhosin.get.max_value_length
656 *
657 * @return Status\StatusInterface
658 */
659 protected function checkSuhosinGetMaxValueLength() {
660 $recommendedGetMaxValueLength = 2000;
661 if ($this->isSuhosinLoaded()) {
662 $currentGetMaxValueLength = ini_get('suhosin.get.max_value_length');
663 if ($currentGetMaxValueLength < $recommendedGetMaxValueLength) {
664 $status = new Status\ErrorStatus();
665 $status->setTitle('PHP suhosin.get.max_value_length too low');
666 $status->setMessage(
667 'suhosin.get.max_value_length=' . $currentGetMaxValueLength . LF .
668 'This setting can lead to lost information if submitting forms with lots of data in TYPO3 CMS' .
669 ' (as the install tool does). It is highly recommended to raise this' .
670 ' to at least ' . $recommendedGetMaxValueLength . ':' . LF .
671 'suhosin.get.max_value_length=' . $recommendedGetMaxValueLength
672 );
673 } else {
674 $status = new Status\OkStatus();
675 $status->setTitle('PHP suhosin.get.max_value_length ok');
676 }
677 } else {
678 $status = new Status\InfoStatus();
679 $status->setTitle('Suhosin not loaded');
680 $status->setMessage(
681 'If enabling suhosin, suhosin.get.max_value_length' .
682 ' should be set to at least ' . $recommendedGetMaxValueLength . ':' . LF .
683 'suhosin.get.max_value_length=' . $recommendedGetMaxValueLength
684 );
685 }
686 return $status;
687 }
688
689 /**
690 * Check suhosin.executor.include.whitelist contains phar
691 *
692 * @return Status\StatusInterface
693 */
694 protected function checkSuhosinExecutorIncludeWhiteListContainsPhar() {
695 if ($this->isSuhosinLoaded()) {
696 $currentWhiteListArray = $this->trimExplode(' ', ini_get('suhosin.executor.include.whitelist'));
697 if (!in_array('phar', $currentWhiteListArray)) {
698 $status = new Status\NoticeStatus();
699 $status->setTitle('PHP suhosin.executor.include.whitelist does not contain phar');
700 $status->setMessage(
701 'suhosin.executor.include.whitelist= ' . implode(' ', $currentWhiteListArray) . LF .
702 '"phar" is currently not a hard requirement of TYPO3 CMS but is nice to have and a possible' .
703 ' requirement in future versions. A useful setting is:' . LF .
704 'suhosin.executor.include.whitelist=phar vfs'
705 );
706 } else {
707 $status = new Status\OkStatus();
708 $status->setTitle('PHP suhosin.executor.include.whitelist contains phar');
709 }
710 } else {
711 $status = new Status\InfoStatus();
712 $status->setTitle('Suhosin not loaded');
713 $status->setMessage(
714 'If enabling suhosin, a useful setting is:' . LF .
715 'suhosin.executor.include.whitelist=phar vfs'
716 );
717 }
718 return $status;
719 }
720
721 /**
722 * Check suhosin.executor.include.whitelist contains vfs
723 *
724 * @return Status\StatusInterface
725 */
726 protected function checkSuhosinExecutorIncludeWhiteListContainsVfs() {
727 if ($this->isSuhosinLoaded()) {
728 $currentWhiteListArray = $this->trimExplode(' ', ini_get('suhosin.executor.include.whitelist'));
729 if (!in_array('vfs', $currentWhiteListArray)) {
730 $status = new Status\WarningStatus();
731 $status->setTitle('PHP suhosin.executor.include.whitelist does not contain vfs');
732 $status->setMessage(
733 'suhosin.executor.include.whitelist= ' . implode(' ', $currentWhiteListArray) . LF .
734 '"vfs" is currently not a hard requirement of TYPO3 CMS but tons of unit tests rely on it.' .
735 ' Furthermore, vfs will likely be a base for an additional compatibility layer in the future.' .
736 ' A useful setting is:' . LF .
737 'suhosin.executor.include.whitelist=phar vfs'
738 );
739 } else {
740 $status = new Status\OkStatus();
741 $status->setTitle('PHP suhosin.executor.include.whitelist contains vfs');
742 }
743 } else {
744 $status = new Status\InfoStatus();
745 $status->setTitle('Suhosin not loaded');
746 $status->setMessage(
747 'If enabling suhosin, a useful setting is:' . LF .
748 'suhosin.executor.include.whitelist=phar vfs'
749 );
750 }
751 return $status;
752 }
753
754 /**
755 * Check if some opcode cache is loaded
756 *
757 * @return Status\StatusInterface
758 */
759 protected function checkSomePhpOpcodeCacheIsLoaded() {
760 // Link to our wiki page, so we can update opcode cache issue information independent of TYPO3 CMS releases.
761 $wikiLink = 'For more information take a look in our wiki ' . TYPO3_URL_WIKI_OPCODECACHE . '.';
762 $opcodeCaches = \TYPO3\CMS\Core\Utility\OpcodeCacheUtility::getAllActive();
763 if (count($opcodeCaches) === 0) {
764 // Set status to notice. It needs to be notice so email won't be triggered.
765 $status = new Status\NoticeStatus();
766 $status->setTitle('No PHP opcode cache loaded');
767 $status->setMessage(
768 'PHP opcode caches hold a compiled version of executed PHP scripts in' .
769 ' memory and do not require to recompile a script each time it is accessed.' .
770 ' This can be a massive performance improvement and can reduce the load on a' .
771 ' server in general. A parse time reduction by factor three for fully cached' .
772 ' pages can be achieved easily if using an opcode cache.' .
773 LF . $wikiLink
774 );
775 } else {
776 $status = new Status\OkStatus();
777 $message = '';
778
779 foreach ($opcodeCaches as $opcodeCache => $properties) {
780 $message .= 'Name: ' . $opcodeCache . ' Version: ' . $properties['version'];
781 $message .= LF;
782
783 if ($properties['error']) {
784 // Set status to error if not already set
785 if ($status->getSeverity() !== 'error') {
786 $status = new Status\ErrorStatus();
787 }
788 $message .= ' This opcode cache is marked as malfunctioning by the TYPO3 CMS Team.';
789 } elseif ($properties['canInvalidate']) {
790 $message .= ' This opcode cache should work correctly and has good performance.';
791 } else {
792 // Set status to notice if not already error set. It needs to be notice so email won't be triggered.
793 if ($status->getSeverity() !== 'error' || $status->getSeverity() !== 'warning') {
794 $status = new Status\NoticeStatus();
795 }
796 $message .= ' This opcode cache may work correctly but has medium performance.';
797 }
798 $message .= LF;
799 }
800
801 $message .= $wikiLink;
802
803 // Set title of status depending on serverity
804 switch ($status->getSeverity()) {
805 case 'error':
806 $status->setTitle('A possibly malfunctioning PHP opcode cache is loaded');
807 break;
808 case 'warning':
809 $status->setTitle('A PHP opcode cache is loaded which may cause problems');
810 break;
811 case 'ok':
812 default:
813 $status->setTitle('A PHP opcode cache is loaded');
814 break;
815 }
816 $status->setMessage($message);
817 }
818 return $status;
819 }
820
821 /**
822 * Check doc comments can be fetched by reflection
823 *
824 * @return Status\StatusInterface
825 */
826 protected function checkReflectionDocComment() {
827 $testReflection = new \ReflectionMethod(get_class($this), __FUNCTION__);
828 if ($testReflection->getDocComment() === FALSE) {
829 $status = new Status\AlertStatus();
830 $status->setTitle('PHP Doc comment reflection broken');
831 $status->setMessage(
832 'TYPO3 CMS core extensions like extbase and fluid heavily rely on method'
833 . ' comment parsing to fetch annotations and add magic belonging to them.'
834 . ' This does not work in the current environment and so we cannot install'
835 . ' TYPO3 CMS.' . LF
836 . ' Here are some possibilities: ' . LF
837 . '* In Zend OPcache you can disable saving/loading comments. If you are using'
838 . ' Zend OPcache (included since PHP 5.5) then check your php.ini settings for'
839 . ' opcache.save_comments and opcache.load_comments and enable them.' . LF
840 . '* In Zend Optimizer+ you can disable saving comments. If you are using'
841 . ' Zend Optimizer+ then check your php.ini settings for'
842 . ' zend_optimizerplus.save_comments and enable it.' . LF
843 . '* The PHP extension eaccelerator is known to break this if'
844 . ' it is compiled without --with-eaccelerator-doc-comment-inclusion flag.'
845 . ' This compile flag must be specified, otherwise TYPO3 CMS will not work.' . LF
846 . 'For more information take a look in our wiki ' . TYPO3_URL_WIKI_OPCODECACHE . '.'
847 );
848 } else {
849 $status = new Status\OkStatus();
850 $status->setTitle('PHP Doc comment reflection works');
851 }
852 return $status;
853 }
854
855 /**
856 * Check if systemLocale setting is correct (locale exists in the OS)
857 *
858 * @return Status\StatusInterface
859 */
860 protected function checkSystemLocale() {
861
862 $currentLocale = setlocale(LC_CTYPE, 0);
863
864 // On Windows an empty locale value uses the regional settings from the Control Panel
865 if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['systemLocale'] === '' && TYPO3_OS !== 'WIN') {
866 $status = new Status\InfoStatus();
867 $status->setTitle('Empty systemLocale setting');
868 $status->setMessage(
869 '$GLOBALS[TYPO3_CONF_VARS][SYS][systemLocale] is not set. This is fine as long as no UTF-8' .
870 ' file system is used.'
871 );
872 } elseif (setlocale(LC_CTYPE, $GLOBALS['TYPO3_CONF_VARS']['SYS']['systemLocale']) === FALSE) {
873 $status = new Status\ErrorStatus();
874 $status->setTitle('Incorrect systemLocale setting');
875 $status->setMessage(
876 'Current value of the $GLOBALS[TYPO3_CONF_VARS][SYS][systemLocale] is incorrect. A locale with' .
877 ' this name doesn\'t exist in the operating system.'
878 );
879 setlocale(LC_CTYPE, $currentLocale);
880 } else {
881 $status = new Status\OkStatus();
882 $status->setTitle('System locale is correct');
883 }
884
885 return $status;
886 }
887
888 /**
889 * Checks whether we can use file names with UTF-8 characters.
890 * Configured system locale must support UTF-8 when UTF8filesystem is set
891 *
892 * @return Status\StatusInterface
893 */
894 protected function checkLocaleWithUTF8filesystem() {
895
896 if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['UTF8filesystem']) {
897
898 // On Windows an empty local value uses the regional settings from the Control Panel
899 if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['systemLocale'] === '' && TYPO3_OS !== 'WIN') {
900 $status = new Status\ErrorStatus();
901 $status->setTitle('System locale not set on UTF-8 file system');
902 $status->setMessage(
903 '$GLOBALS[TYPO3_CONF_VARS][SYS][UTF8filesystem] is set, but $GLOBALS[TYPO3_CONF_VARS][SYS][systemLocale]' .
904 ' is empty. Make sure a valid locale which supports UTF-8 is set.'
905 );
906 } else {
907 $testString = 'ÖöĄĆŻĘĆćążąęó.jpg';
908 $currentLocale = setlocale(LC_CTYPE, 0);
909 $quote = TYPO3_OS === 'WIN' ? '"' : '\'';
910
911 setlocale(LC_CTYPE, $GLOBALS['TYPO3_CONF_VARS']['SYS']['systemLocale']);
912
913 if (escapeshellarg($testString) === $quote . $testString . $quote) {
914 $status = new Status\OkStatus();
915 $status->setTitle('File names with UTF-8 characters can be used.');
916 } else {
917 $status = new Status\ErrorStatus();
918 $status->setTitle('System locale setting doesn\'t support UTF-8 file names.');
919 $status->setMessage(
920 'Please check your $GLOBALS[TYPO3_CONF_VARS][SYS][systemLocale] setting.'
921 );
922 }
923
924 setlocale(LC_CTYPE, $currentLocale);
925 }
926
927
928 } else {
929 $status = new Status\OkStatus();
930 $status->setTitle('Skipping test, as UTF8filesystem is not enabled.');
931 }
932
933 return $status;
934 }
935
936 /**
937 * Checks thread stack size if on windows with apache
938 *
939 * @return Status\StatusInterface
940 */
941 protected function checkWindowsApacheThreadStackSize() {
942 if (
943 $this->isWindowsOs()
944 && substr($_SERVER['SERVER_SOFTWARE'], 0, 6) === 'Apache'
945 ) {
946 $status = new Status\WarningStatus();
947 $status->setTitle('Windows apache thread stack size');
948 $status->setMessage(
949 'This current value cannot be checked by the system, so please ignore this warning if it' .
950 ' is already taken care of: Fluid uses complex regular expressions which require a lot' .
951 ' of stack space during the first processing.' .
952 ' On Windows the default stack size for Apache is a lot smaller than on UNIX.' .
953 ' You can increase the size to 8MB (default on UNIX) by adding the following configuration' .
954 ' to httpd.conf and restarting Apache afterwards:' . LF .
955 '<IfModule mpm_winnt_module>' . LF .
956 'ThreadStackSize 8388608' . LF .
957 '</IfModule>'
958 );
959 } else {
960 $status = new Status\OkStatus();
961 $status->setTitle('Apache ThreadStackSize is not an issue on UNIX systems');
962 }
963 return $status;
964 }
965
966 /**
967 * Check if a specific required PHP extension is loaded
968 *
969 * @param string $extension
970 * @return Status\StatusInterface
971 */
972 protected function checkRequiredPhpExtension($extension) {
973 if (!extension_loaded($extension)) {
974 $status = new Status\ErrorStatus();
975 $status->setTitle('PHP extension ' . $extension . ' not loaded');
976 $status->setMessage(
977 'TYPO3 CMS uses PHP extension ' . $extension . ' but it is not loaded' .
978 ' in your environment. Change your environment to provide this extension.'
979 );
980 } else {
981 $status = new Status\OkStatus();
982 $status->setTitle('PHP extension ' . $extension . ' loaded');
983 }
984 return $status;
985 }
986
987 /**
988 * Check imagecreatetruecolor to verify gdlib works as expected
989 *
990 * @return Status\StatusInterface
991 */
992 protected function checkGdLibTrueColorSupport() {
993 if (function_exists('imagecreatetruecolor')) {
994 $imageResource = @imagecreatetruecolor(50, 100);
995 if (is_resource($imageResource)) {
996 imagedestroy($imageResource);
997 $status = new Status\OkStatus();
998 $status->setTitle('PHP GD library true color works');
999 } else {
1000 $status = new Status\ErrorStatus();
1001 $status->setTitle('PHP GD library true color support broken');
1002 $status->setMessage(
1003 'GD is loaded, but calling imagecreatetruecolor() fails.' .
1004 ' This must be fixed, TYPO3 CMS won\'t work well otherwise.'
1005 );
1006 }
1007 } else {
1008 $status = new Status\ErrorStatus();
1009 $status->setTitle('PHP GD library true color support missing');
1010 $status->setMessage(
1011 'Gdlib is essential for TYPO3 CMS to work properly.'
1012 );
1013 }
1014 return $status;
1015 }
1016
1017 /**
1018 * Check gif support of GD library
1019 *
1020 * @return Status\StatusInterface
1021 */
1022 protected function checkGdLibGifSupport() {
1023 if (
1024 function_exists('imagecreatefromgif')
1025 && function_exists('imagegif')
1026 && (imagetypes() & IMG_GIF)
1027 ) {
1028 $imageResource = @imagecreatefromgif(__DIR__ . '/../../Resources/Public/Images/TestInput/Test.gif');
1029 if (is_resource($imageResource)) {
1030 imagedestroy($imageResource);
1031 $status = new Status\OkStatus();
1032 $status->setTitle('PHP GD library has gif support');
1033 } else {
1034 $status = new Status\ErrorStatus();
1035 $status->setTitle('PHP GD library gif support broken');
1036 $status->setMessage(
1037 'GD is loaded, but calling imagecreatefromgif() fails.' .
1038 ' This must be fixed, TYPO3 CMS won\'t work well otherwise.'
1039 );
1040 }
1041 } else {
1042 $status = new Status\ErrorStatus();
1043 $status->setTitle('PHP GD library gif support missing');
1044 $status->setMessage(
1045 'GD must be compiled with gif support. This is essential for' .
1046 ' TYPO3 CMS to work properly.'
1047 );
1048 }
1049 return $status;
1050 }
1051
1052 /**
1053 * Check jgp support of GD library
1054 *
1055 * @return Status\StatusInterface
1056 */
1057 protected function checkGdLibJpgSupport() {
1058 if (
1059 function_exists('imagecreatefromjpeg')
1060 && function_exists('imagejpeg')
1061 && (imagetypes() & IMG_JPG)
1062 ) {
1063 $status = new Status\OkStatus();
1064 $status->setTitle('PHP GD library has jpg support');
1065 } else {
1066 $status = new Status\ErrorStatus();
1067 $status->setTitle('PHP GD library jpg support missing');
1068 $status->setMessage(
1069 'GD must be compiled with jpg support. This is essential for' .
1070 ' TYPO3 CMS to work properly.'
1071 );
1072 }
1073 return $status;
1074 }
1075
1076 /**
1077 * Check png support of GD library
1078 *
1079 * @return Status\StatusInterface
1080 */
1081 protected function checkGdLibPngSupport() {
1082 if (
1083 function_exists('imagecreatefrompng')
1084 && function_exists('imagepng')
1085 && (imagetypes() & IMG_PNG)
1086 ) {
1087 $imageResource = @imagecreatefrompng(__DIR__ . '/../../Resources/Public/Images/TestInput/Test.png');
1088 if (is_resource($imageResource)) {
1089 imagedestroy($imageResource);
1090 $status = new Status\OkStatus();
1091 $status->setTitle('PHP GD library has png support');
1092 } else {
1093 $status = new Status\ErrorStatus();
1094 $status->setTitle('PHP GD library png support broken');
1095 $status->setMessage(
1096 'GD is compiled with png support, but calling imagecreatefrompng() fails.' .
1097 ' Check your environment and fix it, png in GD lib is important' .
1098 ' for TYPO3 CMS to work properly.'
1099 );
1100 }
1101 } else {
1102 $status = new Status\ErrorStatus();
1103 $status->setTitle('PHP GD library png support missing');
1104 $status->setMessage(
1105 'GD must be compiled with png support. This is essential for' .
1106 ' TYPO3 CMS to work properly'
1107 );
1108 }
1109 return $status;
1110 }
1111
1112 /**
1113 * Check gdlib supports freetype
1114 *
1115 * @return Status\StatusInterface
1116 */
1117 protected function checkGdLibFreeTypeSupport() {
1118 if (function_exists('imagettftext')) {
1119 $status = new Status\OkStatus();
1120 $status->setTitle('PHP GD library has freetype font support');
1121 $status->setMessage(
1122 'There is a difference between the font size setting which the GD' .
1123 ' library should be supplied with. If installation is completed' .
1124 ' a test in the install tool helps to find out the value you need.'
1125 );
1126 } else {
1127 $status = new Status\ErrorStatus();
1128 $status->setTitle('PHP GD library freetype support missing');
1129 $status->setMessage(
1130 'Some core functionality and extension rely on the GD' .
1131 ' to render fonts on images. This support is missing' .
1132 ' in your environment. Install it.'
1133 );
1134 }
1135 return $status;
1136 }
1137
1138 /**
1139 * Create true type font test image
1140 *
1141 * @return Status\StatusInterface
1142 */
1143 protected function isTrueTypeFontDpiStandard() {
1144 if (function_exists('imageftbbox')) {
1145 // 20 Pixels at 96 DPI - the DefaultConfiguration
1146 $fontSize = (20 / 96 * 72);
1147 $textDimensions = @imageftbbox(
1148 $fontSize,
1149 0,
1150 __DIR__ . '/../../Resources/Private/Font/vera.ttf',
1151 'Testing true type support'
1152 );
1153 $fontBoxWidth = $textDimensions[2] - $textDimensions[0];
1154 if ($fontBoxWidth < 300 && $fontBoxWidth > 200) {
1155 $status = new Status\OkStatus();
1156 $status->setTitle('FreeType True Type Font DPI');
1157 $status->setMessage('Fonts are rendered by FreeType library. ' .
1158 'We need to ensure that the final dimensions are as expected. ' .
1159 'This server renderes fonts based on 96 DPI correctly'
1160 );
1161 } else {
1162 $status = new Status\NoticeStatus();
1163 $status->setTitle('FreeType True Type Font DPI');
1164 $status->setMessage('Fonts are rendered by FreeType library. ' .
1165 'This server does not render fonts as expected. ' .
1166 'Please configure FreeType or TYPO3_CONF_VARS[GFX][TTFdpi]'
1167 );
1168 }
1169 } else {
1170 $status = new Status\ErrorStatus();
1171 $status->setTitle('PHP GD library freetype2 support missing');
1172 $status->setMessage(
1173 'The core relies on GD library compiled into PHP with freetype2' .
1174 ' support. This is missing on your system. Please install it.'
1175 );
1176 }
1177
1178 return $status;
1179 }
1180
1181 /**
1182 * Check php magic quotes
1183 *
1184 * @return Status\StatusInterface
1185 */
1186 protected function checkPhpMagicQuotes() {
1187 $magicQuotesGpc = get_magic_quotes_gpc();
1188 if ($magicQuotesGpc) {
1189 $status = new Status\WarningStatus();
1190 $status->setTitle('PHP magic quotes on');
1191 $status->setMessage(
1192 'magic_quotes_gpc=' . $magicQuotesGpc . LF .
1193 'Setting magic_quotes_gpc is deprecated since PHP 5.3.' .
1194 ' You are advised to disable it until it is completely removed:' . LF .
1195 'magic_quotes_gpc=Off'
1196 );
1197 } else {
1198 $status = new Status\OkStatus();
1199 $status->setTitle('PHP magic quotes off');
1200 }
1201 return $status;
1202 }
1203
1204 /**
1205 * Check register globals
1206 *
1207 * @return Status\StatusInterface
1208 */
1209 protected function checkRegisterGlobals() {
1210 $registerGlobalsEnabled = filter_var(
1211 ini_get('register_globals'),
1212 FILTER_VALIDATE_BOOLEAN,
1213 array(FILTER_REQUIRE_SCALAR, FILTER_NULL_ON_FAILURE)
1214 );
1215 if ($registerGlobalsEnabled === TRUE) {
1216 $status = new Status\ErrorStatus();
1217 $status->setTitle('PHP register globals on');
1218 $status->setMessage(
1219 'register_globals=' . ini_get('register_globals') . LF .
1220 'TYPO3 requires PHP setting "register_globals" set to off.' .
1221 ' This ancient PHP setting is a big security problem and should' .
1222 ' never be enabled:' . LF .
1223 'register_globals=Off'
1224 );
1225 } else {
1226 $status = new Status\OkStatus();
1227 $status->setTitle('PHP register globals off');
1228 }
1229 return $status;
1230 }
1231
1232 /**
1233 * Check for bug in libxml
1234 *
1235 * @return Status\StatusInterface
1236 */
1237 protected function checkLibXmlBug() {
1238 $sampleArray = array('Test>><<Data');
1239
1240 $xmlContent = '<numIndex index="0">Test&gt;&gt;&lt;&lt;Data</numIndex>' . LF;
1241
1242 $xml = \TYPO3\CMS\Core\Utility\GeneralUtility::array2xml($sampleArray, '', -1);
1243
1244 if ($xmlContent !== $xml) {
1245 $status = new Status\ErrorStatus();
1246 $status->setTitle('PHP libxml bug present');
1247 $status->setMessage(
1248 'Some hosts have problems saving ">><<" in a flexform.' .
1249 ' To fix this, enable [BE][flexformForceCDATA] in' .
1250 ' All Configuration.'
1251 );
1252 } else {
1253 $status = new Status\OkStatus();
1254 $status->setTitle('PHP libxml bug not present');
1255 }
1256 return $status;
1257 }
1258
1259 /**
1260 * Helper methods
1261 */
1262
1263 /**
1264 * Validate a given IP address.
1265 *
1266 * @param string $ip IP address to be tested
1267 * @return boolean
1268 */
1269 protected function isValidIp($ip) {
1270 return filter_var($ip, FILTER_VALIDATE_IP) !== FALSE;
1271 }
1272
1273 /**
1274 * Test if this instance runs on windows OS
1275 *
1276 * @return boolean TRUE if operating system is windows
1277 */
1278 protected function isWindowsOs() {
1279 $windowsOs = FALSE;
1280 if (!stristr(PHP_OS, 'darwin') && stristr(PHP_OS, 'win')) {
1281 $windowsOs = TRUE;
1282 }
1283 return $windowsOs;
1284 }
1285
1286 /**
1287 * Helper method to find out if suhosin extension is loaded
1288 *
1289 * @return boolean TRUE if suhosin PHP extension is loaded
1290 */
1291 protected function isSuhosinLoaded() {
1292 $suhosinLoaded = FALSE;
1293 if (extension_loaded('suhosin')) {
1294 $suhosinLoaded = TRUE;
1295 }
1296 return $suhosinLoaded;
1297 }
1298
1299 /**
1300 * Helper method to explode a string by delimeter and throw away empty values.
1301 * Removes empty values from result array.
1302 *
1303 * @param string $delimiter Delimiter string to explode with
1304 * @param string $string The string to explode
1305 * @return array Exploded values
1306 */
1307 protected function trimExplode($delimiter, $string) {
1308 $explodedValues = explode($delimiter, $string);
1309 $resultWithPossibleEmptyValues = array_map('trim', $explodedValues);
1310 $result = array();
1311 foreach ($resultWithPossibleEmptyValues as $value) {
1312 if ($value !== '') {
1313 $result[] = $value;
1314 }
1315 }
1316 return $result;
1317 }
1318
1319 /**
1320 * Helper method to get the bytes value from a measurement string like "100k".
1321 *
1322 * @param string $measurement The measurement (e.g. "100k")
1323 * @return integer The bytes value (e.g. 102400)
1324 */
1325 protected function getBytesFromSizeMeasurement($measurement) {
1326 $bytes = doubleval($measurement);
1327 if (stripos($measurement, 'G')) {
1328 $bytes *= 1024 * 1024 * 1024;
1329 } elseif (stripos($measurement, 'M')) {
1330 $bytes *= 1024 * 1024;
1331 } elseif (stripos($measurement, 'K')) {
1332 $bytes *= 1024;
1333 }
1334 return $bytes;
1335 }
1336 }