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