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