138e6789acf4fb8d2d406cef56d453bcecb12442
[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 ' As long as this flag is disabled in PHP, you\'ll not 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 ' by the config option TYPO3_CONF_VARS[BE][maxFileSize]).' .
195 ' Your current PHP value is below this, so at this point, PHP determines' .
196 ' the limits for uploaded filesizes and not TYPO3.' .
197 ' It is recommended that the value of upload_max_filesize at least equals 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 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 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 to not 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 of 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 of 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 exhausted messages, especially if using the backend. To be on the safe side,' .
269 ' we recommend a minimum PHP memory limit of ' . $recommendedMemoryLimit . 'MB:' . LF .
270 'memory_limit=' . $recommendedMemoryLimit . 'M'
271 );
272 } else {
273 $status = new Status\OkStatus();
274 $status->setTitle('PHP Memory limit equals to ' . $recommendedMemoryLimit . 'MB or more');
275 }
276 return $status;
277 }
278
279 /**
280 * Check minimum PHP version
281 *
282 * @return Status\StatusInterface
283 */
284 protected function checkPhpVersion() {
285 $minimumPhpVersion = '5.3.7';
286 $currentPhpVersion = phpversion();
287 if (version_compare($currentPhpVersion, $minimumPhpVersion) < 0) {
288 $status = new Status\ErrorStatus();
289 $status->setTitle('PHP version too low');
290 $status->setMessage(
291 'Your PHP version ' . $currentPhpVersion . ' is too old. TYPO3 CMS does not run' .
292 ' with this version. Update to at least PHP ' . $minimumPhpVersion
293 );
294 } else {
295 $status = new Status\OkStatus();
296 $status->setTitle('PHP version is fine');
297 }
298 return $status;
299 }
300
301 /**
302 * Check maximum execution time
303 *
304 * @return Status\StatusInterface
305 */
306 protected function checkMaxExecutionTime() {
307 $minimumMaximumExecutionTime = 30;
308 $recommendedMaximumExecutionTime = 240;
309 $currentMaximumExecutionTime = ini_get('max_execution_time');
310 if ($currentMaximumExecutionTime == 0) {
311 if (PHP_SAPI === 'cli') {
312 $status = new Status\OkStatus();
313 $status->setTitle('Infinite PHP script execution time');
314 $status->setMessage(
315 'Maximum PHP script execution time is always set to infinite (0) in cli mode.' .
316 ' The setting used for web requests can not be checked from command line.'
317 );
318 } else {
319 $status = new Status\WarningStatus();
320 $status->setTitle('Infinite PHP script execution time');
321 $status->setMessage(
322 'max_execution_time=' . $currentMaximumExecutionTime . LF .
323 'While TYPO3 is fine with this, you risk a denial-of-service of your system if for whatever' .
324 ' reason some script hangs in an infinite loop. You are usually on safe side ' .
325 ' if it is reduced to ' . $recommendedMaximumExecutionTime . ' seconds:' . LF .
326 'max_execution_time=' . $recommendedMaximumExecutionTime
327 );
328 }
329 } elseif ($currentMaximumExecutionTime < $minimumMaximumExecutionTime) {
330 $status = new Status\ErrorStatus();
331 $status->setTitle('Low PHP script execution time');
332 $status->setMessage(
333 'max_execution_time=' . $currentMaximumExecutionTime . LF .
334 'Your max_execution_time is too low. Some expensive operation in TYPO3 can take longer than that.' .
335 ' It is recommended to raise the limit to ' . $recommendedMaximumExecutionTime . ' seconds:' . LF .
336 'max_execution_time=' . $recommendedMaximumExecutionTime
337 );
338 } elseif ($currentMaximumExecutionTime < $recommendedMaximumExecutionTime) {
339 $status = new Status\WarningStatus();
340 $status->setTitle('Low PHP script execution time');
341 $status->setMessage(
342 'max_execution_time=' . $currentMaximumExecutionTime . LF .
343 'Your max_execution_time is low. While TYPO3 often runs without problems' .
344 ' with ' . $minimumMaximumExecutionTime . ' seconds,' .
345 ' it still may happen that script execution is stopped before finishing' .
346 ' calculations. You should monitor the system for messages in this area' .
347 ' and maybe raise the limit to ' . $recommendedMaximumExecutionTime . ' seconds:' . LF .
348 'max_execution_time=' . $recommendedMaximumExecutionTime
349 );
350 } else {
351 $status = new Status\OkStatus();
352 $status->setTitle('Maximum PHP script execution time equals ' . $recommendedMaximumExecutionTime . ' or more');
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 used seldom 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 adapted.'
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 default value of 100 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 store passwords encrypted to improve the security on database layer.'
542 );
543 }
544
545 return $status;
546 }
547
548 /**
549 * Check enabled suhosin
550 *
551 * @return Status\StatusInterface
552 */
553 protected function checkSuhosinLoaded() {
554 if ($this->isSuhosinLoaded()) {
555 $status = new Status\OkStatus();
556 $status->setTitle('PHP suhosin extension loaded');
557 } else {
558 $status = new Status\NoticeStatus();
559 $status->setTitle('PHP suhosin extension not loaded');
560 $status->setMessage(
561 'suhosin is an extension to harden the PHP environment. In general, it is' .
562 ' good to have it from a security point of view. While TYPO3 CMS works' .
563 ' fine with suhosin, it has some requirements different from default settings' .
564 ' to be set if enabled.'
565 );
566 }
567 return $status;
568 }
569
570 /**
571 * Check suhosin.request.max_vars
572 *
573 * @return Status\StatusInterface
574 */
575 protected function checkSuhosinRequestMaxVars() {
576 $recommendedRequestMaxVars = 400;
577 if ($this->isSuhosinLoaded()) {
578 $currentRequestMaxVars = ini_get('suhosin.request.max_vars');
579 if ($currentRequestMaxVars < $recommendedRequestMaxVars) {
580 $status = new Status\ErrorStatus();
581 $status->setTitle('PHP suhosin.request.max_vars too low');
582 $status->setMessage(
583 'suhosin.request.max_vars=' . $currentRequestMaxVars . LF .
584 'This setting can lead to lost information if submitting big forms in TYPO3 CMS like' .
585 ' it is done in the install tool. It is heavily recommended to raise this' .
586 ' to at least ' . $recommendedRequestMaxVars . ':' . LF .
587 'suhosin.request.max_vars=' . $recommendedRequestMaxVars
588 );
589 } else {
590 $status = new Status\OkStatus();
591 $status->setTitle('PHP suhosin.request.max_vars ok');
592 }
593 } else {
594 $status = new Status\InfoStatus();
595 $status->setTitle('Suhosin not loaded');
596 $status->setMessage(
597 'If enabling suhosin, suhosin.request.max_vars' .
598 ' should be set to at least ' . $recommendedRequestMaxVars . ':' . LF .
599 'suhosin.request.max_vars=' . $recommendedRequestMaxVars
600 );
601 }
602 return $status;
603 }
604
605 /**
606 * Check suhosin.post.max_vars
607 *
608 * @return Status\StatusInterface
609 */
610 protected function checkSuhosinPostMaxVars() {
611 $recommendedPostMaxVars = 400;
612 if ($this->isSuhosinLoaded()) {
613 $currentPostMaxVars = ini_get('suhosin.post.max_vars');
614 if ($currentPostMaxVars < $recommendedPostMaxVars) {
615 $status = new Status\ErrorStatus();
616 $status->setTitle('PHP suhosin.post.max_vars too low');
617 $status->setMessage(
618 'suhosin.post.max_vars=' . $currentPostMaxVars . LF .
619 'This setting can lead to lost information if submitting big forms in TYPO3 CMS like' .
620 ' it is done in the install tool. It is heavily recommended to raise this' .
621 ' to at least ' . $recommendedPostMaxVars . ':' . LF .
622 'suhosin.post.max_vars=' . $recommendedPostMaxVars
623 );
624 } else {
625 $status = new Status\OkStatus();
626 $status->setTitle('PHP suhosin.post.max_vars ok');
627 }
628 } else {
629 $status = new Status\InfoStatus();
630 $status->setTitle('Suhosin not loaded');
631 $status->setMessage(
632 'If enabling suhosin, suhosin.post.max_vars' .
633 ' should be set to at least ' . $recommendedPostMaxVars . ':' . LF .
634 'suhosin.post.max_vars=' . $recommendedPostMaxVars
635 );
636 }
637 return $status;
638 }
639
640 /**
641 * Check suhosin.get.max_value_length
642 *
643 * @return Status\StatusInterface
644 */
645 protected function checkSuhosinGetMaxValueLength() {
646 $recommendedGetMaxValueLength = 2000;
647 if ($this->isSuhosinLoaded()) {
648 $currentGetMaxValueLength = ini_get('suhosin.get.max_value_length');
649 if ($currentGetMaxValueLength < $recommendedGetMaxValueLength) {
650 $status = new Status\ErrorStatus();
651 $status->setTitle('PHP suhosin.get.max_value_length too low');
652 $status->setMessage(
653 'suhosin.get.max_value_length=' . $currentGetMaxValueLength . LF .
654 'This setting can lead to lost information if submitting big forms in TYPO3 CMS like' .
655 ' it is done in the install tool. It is heavily recommended to raise this' .
656 ' to at least ' . $recommendedGetMaxValueLength . ':' . LF .
657 'suhosin.get.max_value_length=' . $recommendedGetMaxValueLength
658 );
659 } else {
660 $status = new Status\OkStatus();
661 $status->setTitle('PHP suhosin.get.max_value_length ok');
662 }
663 } else {
664 $status = new Status\InfoStatus();
665 $status->setTitle('Suhosin not loaded');
666 $status->setMessage(
667 'If enabling suhosin, suhosin.get.max_value_length' .
668 ' should be set to at least ' . $recommendedGetMaxValueLength . ':' . LF .
669 'suhosin.get.max_value_length=' . $recommendedGetMaxValueLength
670 );
671 }
672 return $status;
673 }
674
675 /**
676 * Check suhosin.executor.include.whitelist contains phar
677 *
678 * @return Status\StatusInterface
679 */
680 protected function checkSuhosinExecutorIncludeWhiteListContainsPhar() {
681 if ($this->isSuhosinLoaded()) {
682 $currentWhiteListArray = $this->trimExplode(' ', ini_get('suhosin.executor.include.whitelist'));
683 if (!in_array('phar', $currentWhiteListArray)) {
684 $status = new Status\NoticeStatus();
685 $status->setTitle('PHP suhosin.executor.include.whitelist does not contain phar');
686 $status->setMessage(
687 'suhosin.executor.include.whitelist= ' . implode(' ', $currentWhiteListArray) . LF .
688 '"phar" is currently not a hard requirement of TYPO3 CMS but is nice to have and a possible' .
689 ' requirement in future versions. A useful setting is:' . LF .
690 'suhosin.executor.include.whitelist=phar vfs'
691 );
692 } else {
693 $status = new Status\OkStatus();
694 $status->setTitle('PHP suhosin.executor.include.whitelist contains phar');
695 }
696 } else {
697 $status = new Status\InfoStatus();
698 $status->setTitle('Suhosin not loaded');
699 $status->setMessage(
700 'If enabling suhosin, a useful setting is:' . LF .
701 'suhosin.executor.include.whitelist=phar vfs'
702 );
703 }
704 return $status;
705 }
706
707 /**
708 * Check suhosin.executor.include.whitelist contains vfs
709 *
710 * @return Status\StatusInterface
711 */
712 protected function checkSuhosinExecutorIncludeWhiteListContainsVfs() {
713 if ($this->isSuhosinLoaded()) {
714 $currentWhiteListArray = $this->trimExplode(' ', ini_get('suhosin.executor.include.whitelist'));
715 if (!in_array('vfs', $currentWhiteListArray)) {
716 $status = new Status\WarningStatus();
717 $status->setTitle('PHP suhosin.executor.include.whitelist does not contain vfs');
718 $status->setMessage(
719 'suhosin.executor.include.whitelist= ' . implode(' ', $currentWhiteListArray) . LF .
720 '"vfs" is currently not a hard requirement of TYPO3 CMS but tons of unit tests rely on it.' .
721 ' Furthermore, vfs is likely a base for an additional compatibility layer in the future.' .
722 ' A useful setting is:' . LF .
723 'suhosin.executor.include.whitelist=phar vfs'
724 );
725 } else {
726 $status = new Status\OkStatus();
727 $status->setTitle('PHP suhosin.executor.include.whitelist contains vfs');
728 }
729 } else {
730 $status = new Status\InfoStatus();
731 $status->setTitle('Suhosin not loaded');
732 $status->setMessage(
733 'If enabling suhosin, a useful setting is:' . LF .
734 'suhosin.executor.include.whitelist=phar vfs'
735 );
736 }
737 return $status;
738 }
739
740 /**
741 * Check if some opcode cache is loaded
742 *
743 * @return Status\StatusInterface
744 */
745 protected function checkSomePhpOpcodeCacheIsLoaded() {
746 if (
747 // Currently APCu identifies itself both as "apcu" and "apc" (for compatibility) although it doesn't provide the APC-opcache functionality
748 extension_loaded('eaccelerator')
749 || extension_loaded('xcache')
750 || (extension_loaded('apc') && !extension_loaded('apcu'))
751 || extension_loaded('Zend Optimizer+')
752 || extension_loaded('Zend OPcache')
753 || extension_loaded('wincache')
754 ) {
755 $status = new Status\OkStatus();
756 $status->setTitle('A PHP opcode cache is loaded');
757 } else {
758 $status = new Status\WarningStatus();
759 $status->setTitle('No PHP opcode cache loaded');
760 $status->setMessage(
761 'PHP opcode caches hold a compiled version of executed PHP scripts in' .
762 ' memory and do not require to recompile any script on each access.' .
763 ' This can be a massive performance improvement and can put load off a' .
764 ' server in general, a parse time reduction by factor three for full cached' .
765 ' pages can be achieved easily if using some opcode cache.' .
766 ' If in doubt choosing one, APC runs well and can be used as data' .
767 ' cache layer in TYPO3 CMS as additional feature.'
768 );
769 }
770 return $status;
771 }
772
773 /**
774 * Check doc comments can be fetched by reflection
775 *
776 * @return Status\StatusInterface
777 */
778 protected function checkReflectionDocComment() {
779 $testReflection = new \ReflectionMethod(get_class($this), __FUNCTION__);
780 if (strlen($testReflection->getDocComment()) === 0) {
781 $status = new Status\ErrorStatus();
782 $status->setTitle('PHP Doc comment reflection broken');
783 $status->setMessage(
784 'TYPO3 CMS core extensions like extbase and fluid heavily rely on method' .
785 ' comment parsing to fetch annotations and add magic according to them.' .
786 ' This does not work in the current environment and will lead to a lot of' .
787 ' broken extensions. The PHP extension eaccelerator is known to break this if' .
788 ' it is compiled without --with-eaccelerator-doc-comment-inclusion flag.' .
789 ' This compile flag must be given, otherwise TYPO3 CMS is no fun.'
790 );
791 } else {
792 $status = new Status\OkStatus();
793 $status->setTitle('PHP Doc comment reflection works');
794 }
795 return $status;
796 }
797
798 /**
799 * Check if systemLocale setting is correct (locale exists in the OS)
800 *
801 * @return Status\StatusInterface
802 */
803 protected function checkSystemLocale() {
804
805 $currentLocale = setlocale(LC_CTYPE, 0);
806
807 // On Windows an empty locale value uses the regional settings from the Control Panel
808 if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['systemLocale'] === '' && TYPO3_OS !== 'WIN') {
809 $status = new Status\InfoStatus();
810 $status->setTitle('Empty systemLocale setting');
811 $status->setMessage(
812 '$GLOBALS[TYPO3_CONF_VARS][SYS][systemLocale] is not set. This is fine as long as no UTF-8 file system is used.'
813 );
814 } elseif (setlocale(LC_CTYPE, $GLOBALS['TYPO3_CONF_VARS']['SYS']['systemLocale']) === FALSE) {
815 $status = new Status\ErrorStatus();
816 $status->setTitle('Incorrect systemLocale setting');
817 $status->setMessage(
818 'Current value of the $GLOBALS[TYPO3_CONF_VARS][SYS][systemLocale] is incorrect. Locale with this name doesn\'t exist in the operating system.'
819 );
820 setlocale(LC_CTYPE, $currentLocale);
821 } else {
822 $status = new Status\OkStatus();
823 $status->setTitle('System locale is correct');
824 }
825
826 return $status;
827 }
828
829 /**
830 * Checks whether we can use file names with UTF-8 characters.
831 * Configured system locale must support UTF-8 when UTF8filesystem is set
832 *
833 * @return Status\StatusInterface
834 */
835 protected function checkLocaleWithUTF8filesystem() {
836
837 if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['UTF8filesystem']) {
838
839 // On Windows an empty local value uses the regional settings from the Control Panel
840 if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['systemLocale'] === '' && TYPO3_OS !== 'WIN') {
841 $status = new Status\ErrorStatus();
842 $status->setTitle('System locale not set on UTF-8 file system');
843 $status->setMessage(
844 '$GLOBALS[TYPO3_CONF_VARS][SYS][UTF8filesystem] is set, but $GLOBALS[TYPO3_CONF_VARS][SYS][systemLocale] is empty. Make sure a valid locale which supports UTF-8 is set.'
845 );
846 } else {
847 $testString = 'ÖöĄĆŻĘĆćążąęó.jpg';
848 $currentLocale = setlocale(LC_CTYPE, 0);
849 $quote = TYPO3_OS === 'WIN' ? '"' : '\'';
850
851 setlocale(LC_CTYPE, $GLOBALS['TYPO3_CONF_VARS']['SYS']['systemLocale']);
852
853 if (escapeshellarg($testString) === $quote . $testString . $quote) {
854 $status = new Status\OkStatus();
855 $status->setTitle('File names with UTF-8 characters can be used.');
856 } else {
857 $status = new Status\ErrorStatus();
858 $status->setTitle('System locale setting doesn\'t support UTF-8 file names.');
859 $status->setMessage(
860 'Please check your $GLOBALS[TYPO3_CONF_VARS][SYS][systemLocale] setting.'
861 );
862 }
863
864 setlocale(LC_CTYPE, $currentLocale);
865 }
866
867
868 } else {
869 $status = new Status\OkStatus();
870 $status->setTitle('Skipping test, as UTF8filesystem is not enabled.');
871 }
872
873 return $status;
874 }
875
876 /**
877 * Checks thread stack size if on windows with apache
878 *
879 * @return Status\StatusInterface
880 */
881 protected function checkWindowsApacheThreadStackSize() {
882 if (
883 $this->isWindowsOs()
884 && substr($_SERVER['SERVER_SOFTWARE'], 0, 6) === 'Apache'
885 ) {
886 $status = new Status\WarningStatus();
887 $status->setTitle('Windows apache thread stack size');
888 $status->setMessage(
889 'This current value can not be checked by the system, so please ignore this warning if it' .
890 ' is already taken care of: Fluid uses complex regular expressions which require a lot' .
891 ' of stack space during the first processing.' .
892 ' On Windows the default stack size for Apache is a lot smaller than on UNIX.' .
893 ' You can increase the size to 8MB (default on UNIX) by adding the following configuration' .
894 ' to httpd.conf and restart Apache afterwards:' . LF .
895 '<IfModule mpm_winnt_module>' . LF .
896 'ThreadStackSize 8388608' . LF .
897 '</IfModule>'
898 );
899 } else {
900 $status = new Status\OkStatus();
901 $status->setTitle('Apache ThreadStackSize is not an issue on UNIX systems');
902 }
903 return $status;
904 }
905
906 /**
907 * Check if a specific required PHP extension is loaded
908 *
909 * @param string $extension
910 * @return Status\StatusInterface
911 */
912 protected function checkRequiredPhpExtension($extension) {
913 if (!extension_loaded($extension)) {
914 $status = new Status\ErrorStatus();
915 $status->setTitle('PHP extension ' . $extension . ' not loaded');
916 $status->setMessage(
917 'TYPO3 CMS uses PHP extension ' . $extension . ' but it is not loaded' .
918 ' in your environment. Change your environment to provide this extension.'
919 );
920 } else {
921 $status = new Status\OkStatus();
922 $status->setTitle('PHP extension ' . $extension . ' loaded');
923 }
924 return $status;
925 }
926
927 /**
928 * Check imagecreatetruecolor to verify gdlib works as expected
929 *
930 * @return Status\StatusInterface
931 */
932 protected function checkGdLibTrueColorSupport() {
933 if (function_exists('imagecreatetruecolor')) {
934 $imageResource = @imagecreatetruecolor(50, 100);
935 if (is_resource($imageResource)) {
936 imagedestroy($imageResource);
937 $status = new Status\OkStatus();
938 $status->setTitle('PHP GD library true color works');
939 } else {
940 $status = new Status\ErrorStatus();
941 $status->setTitle('PHP GD library true color support broken');
942 $status->setMessage(
943 'GD is loaded, but calling imagecreatetruecolor() fails.' .
944 ' This must be fixed, TYPO3 CMS won\'t work well otherwise.'
945 );
946 }
947 } else {
948 $status = new Status\ErrorStatus();
949 $status->setTitle('PHP GD library true color support missing');
950 $status->setMessage(
951 'Gdlib is essential for TYPO3 CMS to work properly.'
952 );
953 }
954 return $status;
955 }
956
957 /**
958 * Check gif support of GD library
959 *
960 * @return Status\StatusInterface
961 */
962 protected function checkGdLibGifSupport() {
963 if (
964 function_exists('imagecreatefromgif')
965 && function_exists('imagegif')
966 && (imagetypes() & IMG_GIF)
967 ) {
968 $imageResource = @imagecreatefromgif(__DIR__ . '/../../Resources/Public/Images/TestInput/Test.gif');
969 if (is_resource($imageResource)) {
970 imagedestroy($imageResource);
971 $status = new Status\OkStatus();
972 $status->setTitle('PHP GD library has gif support');
973 } else {
974 $status = new Status\ErrorStatus();
975 $status->setTitle('PHP GD library gif support broken');
976 $status->setMessage(
977 'GD is loaded, but calling imagecreatefromgif() fails.' .
978 ' This must be fixed, TYPO3 CMS won\'t work well otherwise.'
979 );
980 }
981 } else {
982 $status = new Status\ErrorStatus();
983 $status->setTitle('PHP GD library gif support missing');
984 $status->setMessage(
985 'GD must be compiled with gif support. This is essential for' .
986 ' TYPO3 CMS to work properly.'
987 );
988 }
989 return $status;
990 }
991
992 /**
993 * Check jgp support of GD library
994 *
995 * @return Status\StatusInterface
996 */
997 protected function checkGdLibJpgSupport() {
998 if (
999 function_exists('imagecreatefromjpeg')
1000 && function_exists('imagejpeg')
1001 && (imagetypes() & IMG_JPG)
1002 ) {
1003 $status = new Status\OkStatus();
1004 $status->setTitle('PHP GD library has jpg support');
1005 } else {
1006 $status = new Status\ErrorStatus();
1007 $status->setTitle('PHP GD library jpg support missing');
1008 $status->setMessage(
1009 'GD must be compiled with jpg support. This is essential for' .
1010 ' TYPO3 CMS to work properly.'
1011 );
1012 }
1013 return $status;
1014 }
1015
1016 /**
1017 * Check png support of GD library
1018 *
1019 * @return Status\StatusInterface
1020 */
1021 protected function checkGdLibPngSupport() {
1022 if (
1023 function_exists('imagecreatefrompng')
1024 && function_exists('imagepng')
1025 && (imagetypes() & IMG_PNG)
1026 ) {
1027 $imageResource = @imagecreatefrompng(__DIR__ . '/../../Resources/Public/Images/TestInput/Test.png');
1028 if (is_resource($imageResource)) {
1029 imagedestroy($imageResource);
1030 $status = new Status\OkStatus();
1031 $status->setTitle('PHP GD library has png support');
1032 } else {
1033 $status = new Status\ErrorStatus();
1034 $status->setTitle('PHP GD library png support broken');
1035 $status->setMessage(
1036 'GD is compiled with png support, but calling imagecreatefrompng() fails.' .
1037 ' Check your environment and fix it, png in GD lib is important' .
1038 ' for TYPO3 CMS to work properly.'
1039 );
1040 }
1041 } else {
1042 $status = new Status\ErrorStatus();
1043 $status->setTitle('PHP GD library png support missing');
1044 $status->setMessage(
1045 'GD must be compiled with png support. This is essential for' .
1046 ' TYPO3 CMS to work properly'
1047 );
1048 }
1049 return $status;
1050 }
1051
1052 /**
1053 * Check gdlib supports freetype
1054 *
1055 * @return Status\StatusInterface
1056 */
1057 protected function checkGdLibFreeTypeSupport() {
1058 if (function_exists('imagettftext')) {
1059 $status = new Status\OkStatus();
1060 $status->setTitle('PHP GD library has freetype font support');
1061 $status->setMessage(
1062 'There is a difference between the font size setting the GD' .
1063 ' library should be feeded with. If installation is completed' .
1064 ' a test in the install tool helps to find out the value you need.'
1065 );
1066 } else {
1067 $status = new Status\ErrorStatus();
1068 $status->setTitle('PHP GD library freetype support missing');
1069 $status->setMessage(
1070 'Some core functionality and extension rely on the GD' .
1071 ' to render fonts on images. This support is missing' .
1072 ' in your environment. Install it.'
1073 );
1074 }
1075 return $status;
1076 }
1077
1078 /**
1079 * Create true type font test image
1080 *
1081 * @return Status\StatusInterface
1082 */
1083 protected function isTrueTypeFontDpiStandard() {
1084 if (function_exists('imageftbbox')) {
1085 // 20 Pixels at 96 DPI - the DefaultConfiguration
1086 $fontSize = (20 / 96 * 72);
1087 $textDimensions = @imageftbbox(
1088 $fontSize,
1089 0,
1090 __DIR__ . '/../../Resources/Private/Font/vera.ttf',
1091 'Testing true type support'
1092 );
1093 $fontBoxWidth = $textDimensions[2] - $textDimensions[0];
1094 if ($fontBoxWidth < 300 && $fontBoxWidth > 200) {
1095 $status = new Status\OkStatus();
1096 $status->setTitle('FreeType True Type Font DPI');
1097 $status->setMessage('Fonts are rendered by FreeType library. ' .
1098 'We need to ensure that the final dimensions are as expected. ' .
1099 'This server renderes fonts based on 96 DPI correctly'
1100 );
1101 } else {
1102 $status = new Status\NoticeStatus();
1103 $status->setTitle('FreeType True Type Font DPI');
1104 $status->setMessage('Fonts are rendered by FreeType library. ' .
1105 'This server renders fonts not as expected. ' .
1106 'Please configure FreeType or TYPO3_CONF_VARS[GFX][TTFdpi]'
1107 );
1108 }
1109 } else {
1110 $status = new Status\ErrorStatus();
1111 $status->setTitle('PHP GD library freetype2 support missing');
1112 $status->setMessage(
1113 'The core relies on GD library compiled into PHP with freetype2' .
1114 ' support. This is missing on your system. Please install it.'
1115 );
1116 }
1117
1118 return $status;
1119 }
1120
1121 /**
1122 * Check php magic quotes
1123 *
1124 * @return Status\StatusInterface
1125 */
1126 protected function checkPhpMagicQuotes() {
1127 $magicQuotesGpc = get_magic_quotes_gpc();
1128 if ($magicQuotesGpc) {
1129 $status = new Status\WarningStatus();
1130 $status->setTitle('PHP magic quotes on');
1131 $status->setMessage(
1132 'magic_quotes_gpc=' . $magicQuotesGpc . LF .
1133 'Setting magic_quotes_gpc is deprecated since PHP 5.3.' .
1134 ' You are advised to disable it until it gets completely removed:' . LF .
1135 'magic_quotes_gpc=Off'
1136 );
1137 } else {
1138 $status = new Status\OkStatus();
1139 $status->setTitle('PHP magic quotes off');
1140 }
1141 return $status;
1142 }
1143
1144 /**
1145 * Check register globals
1146 *
1147 * @return Status\StatusInterface
1148 */
1149 protected function checkRegisterGlobals() {
1150 $registerGlobalsEnabled = filter_var(
1151 ini_get('register_globals'),
1152 FILTER_VALIDATE_BOOLEAN,
1153 array(FILTER_REQUIRE_SCALAR, FILTER_NULL_ON_FAILURE)
1154 );
1155 if ($registerGlobalsEnabled === TRUE) {
1156 $status = new Status\ErrorStatus();
1157 $status->setTitle('PHP register globals on');
1158 $status->setMessage(
1159 'register_globals=' . ini_get('register_globals') . LF .
1160 'TYPO3 requires PHP setting "register_globals" set to off.' .
1161 ' This ancient PHP setting is a big security problem and should' .
1162 ' never be enabled:' . LF .
1163 'register_globals=Off'
1164 );
1165 } else {
1166 $status = new Status\OkStatus();
1167 $status->setTitle('PHP register globals off');
1168 }
1169 return $status;
1170 }
1171
1172 /**
1173 * Check for bug in libxml
1174 *
1175 * @return Status\StatusInterface
1176 */
1177 protected function checkLibXmlBug() {
1178 $sampleArray = array('Test>><<Data');
1179
1180 $xmlContent = '<numIndex index="0">Test&gt;&gt;&lt;&lt;Data</numIndex>' . LF;
1181
1182 $xml = \TYPO3\CMS\Core\Utility\GeneralUtility::array2xml($sampleArray, '', -1);
1183
1184 if ($xmlContent !== $xml) {
1185 $status = new Status\ErrorStatus();
1186 $status->setTitle('PHP libxml bug present');
1187 $status->setMessage(
1188 'Some hosts have problems saving ">><<" in a flexform.' .
1189 ' To fix this, enable [BE][flexformForceCDATA] in' .
1190 ' All Configuration.'
1191 );
1192 } else {
1193 $status = new Status\OkStatus();
1194 $status->setTitle('PHP libxml bug not present');
1195 }
1196 return $status;
1197 }
1198
1199 /**
1200 * Helper methods
1201 */
1202
1203 /**
1204 * Validate a given IP address.
1205 *
1206 * @param string $ip IP address to be tested
1207 * @return boolean
1208 */
1209 protected function isValidIp($ip) {
1210 return filter_var($ip, FILTER_VALIDATE_IP) !== FALSE;
1211 }
1212
1213 /**
1214 * Test if this instance runs on windows OS
1215 *
1216 * @return boolean TRUE if operating system is windows
1217 */
1218 protected function isWindowsOs() {
1219 $windowsOs = FALSE;
1220 if (!stristr(PHP_OS, 'darwin') && stristr(PHP_OS, 'win')) {
1221 $windowsOs = TRUE;
1222 }
1223 return $windowsOs;
1224 }
1225
1226 /**
1227 * Helper method to find out if suhosin extension is loaded
1228 *
1229 * @return boolean TRUE if suhosin PHP extension is loaded
1230 */
1231 protected function isSuhosinLoaded() {
1232 $suhosinLoaded = FALSE;
1233 if (extension_loaded('suhosin')) {
1234 $suhosinLoaded = TRUE;
1235 }
1236 return $suhosinLoaded;
1237 }
1238
1239 /**
1240 * Helper method to explode a string by delimeter and throw away empty values.
1241 * Removes empty values from result array.
1242 *
1243 * @param string $delimiter Delimiter string to explode with
1244 * @param string $string The string to explode
1245 * @return array Exploded values
1246 */
1247 protected function trimExplode($delimiter, $string) {
1248 $explodedValues = explode($delimiter, $string);
1249 $resultWithPossibleEmptyValues = array_map('trim', $explodedValues);
1250 $result = array();
1251 foreach ($resultWithPossibleEmptyValues as $value) {
1252 if ($value !== '') {
1253 $result[] = $value;
1254 }
1255 }
1256 return $result;
1257 }
1258
1259 /**
1260 * Helper method to get the bytes value from a measurement string like "100k".
1261 *
1262 * @param string $measurement The measurement (e.g. "100k")
1263 * @return integer The bytes value (e.g. 102400)
1264 */
1265 protected function getBytesFromSizeMeasurement($measurement) {
1266 $bytes = doubleval($measurement);
1267 if (stripos($measurement, 'G')) {
1268 $bytes *= 1024 * 1024 * 1024;
1269 } elseif (stripos($measurement, 'M')) {
1270 $bytes *= 1024 * 1024;
1271 } elseif (stripos($measurement, 'K')) {
1272 $bytes *= 1024;
1273 }
1274 return $bytes;
1275 }
1276 }