[BUGFIX] Fix several typos in php comments
[Packages/TYPO3.CMS.git] / typo3 / sysext / install / Classes / SystemEnvironment / SetupCheck.php
1 <?php
2 namespace TYPO3\CMS\Install\SystemEnvironment;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use TYPO3\CMS\Core\Core\Environment;
18 use TYPO3\CMS\Core\Messaging\FlashMessage;
19 use TYPO3\CMS\Core\Messaging\FlashMessageQueue;
20 use TYPO3\CMS\Core\Service\OpcodeCacheService;
21 use TYPO3\CMS\Core\Utility\GeneralUtility;
22
23 /**
24 * Check TYPO3 setup status
25 *
26 * This class is a hardcoded requirement check for the TYPO3 setup.
27 *
28 * The status messages and title *must not* include HTML, use plain
29 * text only. The return values of this class are not bound to HTML
30 * and can be used in different scopes (eg. as json array).
31 *
32 * @internal This class is only meant to be used within EXT:install and is not part of the TYPO3 Core API.
33 */
34 class SetupCheck implements CheckInterface
35 {
36 /**
37 * @var FlashMessageQueue
38 */
39 protected $messageQueue;
40
41 /**
42 * Get all status information as array with status objects
43 *
44 * @return FlashMessageQueue
45 */
46 public function getStatus(): FlashMessageQueue
47 {
48 $this->messageQueue = new FlashMessageQueue('install');
49
50 $this->checkTrustedHostPattern();
51 $this->checkDownloadsPossible();
52 $this->checkSystemLocale();
53 $this->checkLocaleWithUTF8filesystem();
54 $this->checkSomePhpOpcodeCacheIsLoaded();
55 $this->isTrueTypeFontWorking();
56 $this->checkLibXmlBug();
57
58 return $this->messageQueue;
59 }
60
61 /**
62 * Checks the status of the trusted hosts pattern check
63 */
64 protected function checkTrustedHostPattern()
65 {
66 if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['trustedHostsPattern'] === GeneralUtility::ENV_TRUSTED_HOSTS_PATTERN_ALLOW_ALL) {
67 $this->messageQueue->enqueue(new FlashMessage(
68 'Trusted hosts pattern is configured to allow all header values. Check the pattern defined in Admin'
69 . ' Tools -> Settings -> Configure Installation-Wide Options -> System -> trustedHostsPattern'
70 . ' and adapt it to expected host value(s).',
71 'Trusted hosts pattern is insecure',
72 FlashMessage::WARNING
73 ));
74 } else {
75 if (GeneralUtility::hostHeaderValueMatchesTrustedHostsPattern($_SERVER['HTTP_HOST'])) {
76 $this->messageQueue->enqueue(new FlashMessage(
77 '',
78 'Trusted hosts pattern is configured to allow current host value.'
79 ));
80 } else {
81 $defaultPort = GeneralUtility::getIndpEnv('TYPO3_SSL') ? '443' : '80';
82 $this->messageQueue->enqueue(new FlashMessage(
83 'The trusted hosts pattern will be configured to allow all header values. This is because your $SERVER_NAME:[defaultPort]'
84 . ' is "' . $_SERVER['SERVER_NAME'] . ':' . $defaultPort . '" while your HTTP_HOST:SERVER_PORT is "'
85 . $_SERVER['HTTP_HOST'] . ':' . $_SERVER['SERVER_PORT'] . '". Check the pattern defined in Admin'
86 . ' Tools -> Settings -> Configure Installation-Wide Options -> System -> trustedHostsPattern'
87 . ' and adapt it to expected host value(s).',
88 'Trusted hosts pattern mismatch',
89 FlashMessage::ERROR
90 ));
91 }
92 }
93 }
94
95 /**
96 * Check if it is possible to download external data (e.g. TER)
97 * Either allow_url_fopen must be enabled or curl must be used
98 */
99 protected function checkDownloadsPossible()
100 {
101 $allowUrlFopen = (bool)ini_get('allow_url_fopen');
102 $curlEnabled = function_exists('curl_version');
103 if ($allowUrlFopen || $curlEnabled) {
104 $this->messageQueue->enqueue(new FlashMessage(
105 '',
106 'Fetching external URLs is allowed'
107 ));
108 } else {
109 $this->messageQueue->enqueue(new FlashMessage(
110 'Either enable PHP runtime setting "allow_url_fopen"' . LF . 'or compile curl into your PHP with --with-curl.',
111 'Fetching external URLs is not allowed',
112 FlashMessage::WARNING
113 ));
114 }
115 }
116
117 /**
118 * Check if systemLocale setting is correct (locale exists in the OS)
119 */
120 protected function checkSystemLocale()
121 {
122 $currentLocale = setlocale(LC_CTYPE, 0);
123
124 // On Windows an empty locale value uses the regional settings from the Control Panel
125 if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['systemLocale'] === '' && !Environment::isWindows()) {
126 $this->messageQueue->enqueue(new FlashMessage(
127 '$GLOBALS[TYPO3_CONF_VARS][SYS][systemLocale] is not set. This is fine as long as no UTF-8 file system is used.',
128 'Empty systemLocale setting',
129 FlashMessage::INFO
130 ));
131 } elseif (setlocale(LC_CTYPE, $GLOBALS['TYPO3_CONF_VARS']['SYS']['systemLocale']) === false) {
132 $this->messageQueue->enqueue(new FlashMessage(
133 'Current value of the $GLOBALS[TYPO3_CONF_VARS][SYS][systemLocale] is incorrect. A locale with'
134 . ' this name doesn\'t exist in the operating system.',
135 'Incorrect systemLocale setting',
136 FlashMessage::ERROR
137 ));
138 setlocale(LC_CTYPE, $currentLocale);
139 } else {
140 $this->messageQueue->enqueue(new FlashMessage(
141 '',
142 'System locale is correct'
143 ));
144 }
145 }
146
147 /**
148 * Checks whether we can use file names with UTF-8 characters.
149 * Configured system locale must support UTF-8 when UTF8filesystem is set
150 */
151 protected function checkLocaleWithUTF8filesystem()
152 {
153 if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['UTF8filesystem']) {
154 // On Windows an empty local value uses the regional settings from the Control Panel
155 if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['systemLocale'] === '' && !Environment::isWindows()) {
156 $this->messageQueue->enqueue(new FlashMessage(
157 '$GLOBALS[TYPO3_CONF_VARS][SYS][UTF8filesystem] is set, but $GLOBALS[TYPO3_CONF_VARS][SYS][systemLocale]'
158 . ' is empty. Make sure a valid locale which supports UTF-8 is set.',
159 'System locale not set on UTF-8 file system',
160 FlashMessage::ERROR
161 ));
162 } else {
163 $testString = 'ÖöĄĆŻĘĆćążąęó.jpg';
164 $currentLocale = setlocale(LC_CTYPE, 0);
165 $quote = Environment::isWindows() ? '"' : '\'';
166 setlocale(LC_CTYPE, $GLOBALS['TYPO3_CONF_VARS']['SYS']['systemLocale']);
167 if (escapeshellarg($testString) === $quote . $testString . $quote) {
168 $this->messageQueue->enqueue(new FlashMessage(
169 '',
170 'File names with UTF-8 characters can be used.'
171 ));
172 } else {
173 $this->messageQueue->enqueue(new FlashMessage(
174 'Please check your $GLOBALS[TYPO3_CONF_VARS][SYS][systemLocale] setting.',
175 'System locale setting doesn\'t support UTF-8 file names.',
176 FlashMessage::ERROR
177 ));
178 }
179 setlocale(LC_CTYPE, $currentLocale);
180 }
181 } else {
182 $this->messageQueue->enqueue(new FlashMessage(
183 '',
184 'Skipping test, as UTF8filesystem is not enabled.'
185 ));
186 }
187 }
188
189 /**
190 * Check if some opcode cache is loaded
191 */
192 protected function checkSomePhpOpcodeCacheIsLoaded()
193 {
194 // Link to our wiki page, so we can update opcode cache issue information independent of TYPO3 CMS releases.
195 $wikiLink = 'For more information take a look in our wiki ' . TYPO3_URL_WIKI_OPCODECACHE . '.';
196 $opcodeCaches = GeneralUtility::makeInstance(OpcodeCacheService::class)->getAllActive();
197 if (empty($opcodeCaches)) {
198 // Set status to notice. It needs to be notice so email won't be triggered.
199 $this->messageQueue->enqueue(new FlashMessage(
200 'PHP opcode caches hold a compiled version of executed PHP scripts in'
201 . ' memory and do not require to recompile a script each time it is accessed.'
202 . ' This can be a massive performance improvement and can reduce the load on a'
203 . ' server in general. A parse time reduction by factor three for fully cached'
204 . ' pages can be achieved easily if using an opcode cache.'
205 . LF . $wikiLink,
206 'No PHP opcode cache loaded',
207 FlashMessage::NOTICE
208 ));
209 } else {
210 $status = FlashMessage::OK;
211 $message = '';
212 foreach ($opcodeCaches as $opcodeCache => $properties) {
213 $message .= 'Name: ' . $opcodeCache . ' Version: ' . $properties['version'];
214 $message .= LF;
215 if ($properties['error']) {
216 $status = FlashMessage::ERROR;
217 $message .= ' This opcode cache is marked as malfunctioning by the TYPO3 CMS Team.';
218 } elseif ($properties['canInvalidate']) {
219 $message .= ' This opcode cache should work correctly and has good performance.';
220 } else {
221 // Set status to notice if not already error set. It needs to be notice so email won't be triggered.
222 if ($status !== FlashMessage::ERROR) {
223 $status = FlashMessage::NOTICE;
224 }
225 $message .= ' This opcode cache may work correctly but has medium performance.';
226 }
227 $message .= LF;
228 }
229 $message .= $wikiLink;
230 // Set title of status depending on severity
231 switch ($status) {
232 case FlashMessage::ERROR:
233 $title = 'A possibly malfunctioning PHP opcode cache is loaded';
234 break;
235 case FlashMessage::OK:
236 default:
237 $title = 'A PHP opcode cache is loaded';
238 break;
239 }
240 $this->messageQueue->enqueue(new FlashMessage(
241 $message,
242 $title,
243 $status
244 ));
245 }
246 }
247
248 /**
249 * Create true type font test image
250 */
251 protected function isTrueTypeFontWorking()
252 {
253 if (function_exists('imageftbbox')) {
254 // 20 Pixels at 96 DPI
255 $fontSize = (20 / 96 * 72);
256 $textDimensions = @imageftbbox(
257 $fontSize,
258 0,
259 __DIR__ . '/../../Resources/Private/Font/vera.ttf',
260 'Testing true type support'
261 );
262 $fontBoxWidth = $textDimensions[2] - $textDimensions[0];
263 if ($fontBoxWidth < 300 && $fontBoxWidth > 200) {
264 $this->messageQueue->enqueue(new FlashMessage(
265 'Fonts are rendered by FreeType library. '
266 . 'We need to ensure that the final dimensions are as expected. '
267 . 'This server renderes fonts based on 96 DPI correctly',
268 'FreeType True Type Font DPI'
269 ));
270 } else {
271 $this->messageQueue->enqueue(new FlashMessage(
272 'Fonts are rendered by FreeType library. '
273 . 'This server does not render fonts as expected. '
274 . 'Please check your FreeType 2 module.',
275 'FreeType True Type Font DPI',
276 FlashMessage::NOTICE
277 ));
278 }
279 } else {
280 $this->messageQueue->enqueue(new FlashMessage(
281 'The core relies on GD library compiled into PHP with freetype2'
282 . ' support. This is missing on your system. Please install it.',
283 'PHP GD library freetype2 support missing',
284 FlashMessage::ERROR
285 ));
286 }
287 }
288
289 /**
290 * Check for bug in libxml
291 */
292 protected function checkLibXmlBug()
293 {
294 $sampleArray = ['Test>><<Data'];
295 $xmlContent = '<numIndex index="0">Test&gt;&gt;&lt;&lt;Data</numIndex>' . LF;
296 $xml = GeneralUtility::array2xml($sampleArray, '', -1);
297 if ($xmlContent !== $xml) {
298 $this->messageQueue->enqueue(new FlashMessage(
299 'Some hosts have problems saving ">><<" in a flexform.'
300 . ' To fix this, enable [BE][flexformForceCDATA] in'
301 . ' All Configuration.',
302 'PHP libxml bug present',
303 FlashMessage::ERROR
304 ));
305 } else {
306 $this->messageQueue->enqueue(new FlashMessage(
307 '',
308 'PHP libxml bug not present'
309 ));
310 }
311 }
312 }