[TASK] Cleanup and deprecate TYPO3_DB occurrences
[Packages/TYPO3.CMS.git] / typo3 / sysext / install / Classes / Controller / Action / Tool / TestSetup.php
1 <?php
2 namespace TYPO3\CMS\Install\Controller\Action\Tool;
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\Imaging\GraphicalFunctions;
18 use TYPO3\CMS\Core\Utility\GeneralUtility;
19 use TYPO3\CMS\Core\Utility\StringUtility;
20 use TYPO3\CMS\Install\Controller\Action;
21
22 /**
23 * Test various system setup settings
24 */
25 class TestSetup extends Action\AbstractAction
26 {
27 /**
28 * @var string Absolute path to image folder
29 */
30 protected $imageBasePath = '';
31
32 /**
33 * Executes the tool
34 *
35 * @return string Rendered content
36 */
37 protected function executeAction()
38 {
39 $this->imageBasePath = \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath('install') . 'Resources/Public/Images/';
40
41 $actionMessages = [];
42 if (isset($this->postValues['set']['testMail'])) {
43 $actionMessages[] = $this->sendTestMail();
44 $this->view->assign('postAction', 'testMail');
45 }
46
47 if (isset($this->postValues['set']['testTrueTypeFont'])) {
48 $this->view->assign('trueTypeFontTested', true);
49 $actionMessages[] = $this->createTrueTypeFontTestImage();
50 }
51
52 if (isset($this->postValues['set']['testConvertImageFormatsToJpg'])) {
53 $this->view->assign('convertImageFormatsToJpgTested', true);
54 if ($this->isImageMagickEnabledAndConfigured()) {
55 $actionMessages[] = $this->convertImageFormatsToJpg();
56 } else {
57 $actionMessages[] = $this->imageMagickDisabledMessage();
58 }
59 }
60
61 if (isset($this->postValues['set']['testWriteGifAndPng'])) {
62 $this->view->assign('writeGifAndPngTested', true);
63 if ($this->isImageMagickEnabledAndConfigured()) {
64 $actionMessages[] = $this->writeGifAndPng();
65 } else {
66 $actionMessages[] = $this->imageMagickDisabledMessage();
67 }
68 }
69
70 if (isset($this->postValues['set']['testScalingImages'])) {
71 $this->view->assign('scalingImagesTested', true);
72 if ($this->isImageMagickEnabledAndConfigured()) {
73 $actionMessages[] = $this->scaleImages();
74 } else {
75 $actionMessages[] = $this->imageMagickDisabledMessage();
76 }
77 }
78
79 if (isset($this->postValues['set']['testCombiningImages'])) {
80 $this->view->assign('combiningImagesTested', true);
81 if ($this->isImageMagickEnabledAndConfigured()) {
82 $actionMessages[] = $this->combineImages();
83 } else {
84 $actionMessages[] = $this->imageMagickDisabledMessage();
85 }
86 }
87
88 if (isset($this->postValues['set']['testGdlib'])) {
89 $this->view->assign('gdlibTested', true);
90 $actionMessages[] = $this->gdlib();
91 }
92
93 $this->view->assign('actionMessages', $actionMessages);
94 $this->view->assign('senderEmailAddress', $this->getSenderEmailAddress());
95 $this->view->assign('imageConfiguration', $this->getImageConfiguration());
96
97 return $this->view->render();
98 }
99
100 /**
101 * Send a test mail to specified email address
102 *
103 * @return \TYPO3\CMS\Install\Status\StatusInterface
104 */
105 protected function sendTestMail()
106 {
107 if (
108 !isset($this->postValues['values']['testEmailRecipient'])
109 || !GeneralUtility::validEmail($this->postValues['values']['testEmailRecipient'])
110 ) {
111 /** @var $message \TYPO3\CMS\Install\Status\StatusInterface */
112 $message = GeneralUtility::makeInstance(\TYPO3\CMS\Install\Status\ErrorStatus::class);
113 $message->setTitle('Mail not sent');
114 $message->setMessage('Given address is not a valid email address.');
115 } else {
116 $recipient = $this->postValues['values']['testEmailRecipient'];
117 /** @var $mailMessage \TYPO3\CMS\Core\Mail\MailMessage */
118 $mailMessage = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Mail\MailMessage::class);
119 $mailMessage
120 ->addTo($recipient)
121 ->addFrom($this->getSenderEmailAddress(), $this->getSenderEmailName())
122 ->setSubject($this->getEmailSubject())
123 ->setBody('<html><body>html test content</body></html>', 'text/html')
124 ->addPart('TEST CONTENT')
125 ->send();
126 $message = GeneralUtility::makeInstance(\TYPO3\CMS\Install\Status\OkStatus::class);
127 $message->setTitle('Test mail sent');
128 $message->setMessage('Recipient: ' . $recipient);
129 }
130 return $message;
131 }
132
133 /**
134 * Get sender address from configuration
135 * ['TYPO3_CONF_VARS']['MAIL']['defaultMailFromAddress']
136 * If this setting is empty fall back to 'no-reply@example.com'
137 *
138 * @return string Returns an email address
139 */
140 protected function getSenderEmailAddress()
141 {
142 return !empty($GLOBALS['TYPO3_CONF_VARS']['MAIL']['defaultMailFromAddress'])
143 ? $GLOBALS['TYPO3_CONF_VARS']['MAIL']['defaultMailFromAddress']
144 : 'no-reply@example.com';
145 }
146
147 /**
148 * Gets sender name from configuration
149 * ['TYPO3_CONF_VARS']['MAIL']['defaultMailFromName']
150 * If this setting is empty, it falls back to a default string.
151 *
152 * @return string
153 */
154 protected function getSenderEmailName()
155 {
156 return !empty($GLOBALS['TYPO3_CONF_VARS']['MAIL']['defaultMailFromName'])
157 ? $GLOBALS['TYPO3_CONF_VARS']['MAIL']['defaultMailFromName']
158 : 'TYPO3 CMS install tool';
159 }
160
161 /**
162 * Gets email subject from configuration
163 * ['TYPO3_CONF_VARS']['SYS']['sitename']
164 * If this setting is empty, it falls back to a default string.
165 *
166 * @return string
167 */
168 protected function getEmailSubject()
169 {
170 $name = !empty($GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'])
171 ? ' from site "' . $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'] . '"'
172 : '';
173 return 'Test TYPO3 CMS mail delivery' . $name;
174 }
175
176 /**
177 * Create true type font test image
178 *
179 * @return \TYPO3\CMS\Install\Status\StatusInterface
180 */
181 protected function createTrueTypeFontTestImage()
182 {
183 $parseTimeStart = GeneralUtility::milliseconds();
184
185 $image = @imagecreate(200, 50);
186 imagecolorallocate($image, 255, 255, 55);
187 $textColor = imagecolorallocate($image, 233, 14, 91);
188 @imagettftext(
189 $image,
190 GeneralUtility::freetypeDpiComp(20),
191 0,
192 10,
193 20,
194 $textColor,
195 \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath('install') . 'Resources/Private/Font/vera.ttf',
196 'Testing true type'
197 );
198 $outputFile = PATH_site . 'typo3temp/assets/images/installTool-' . StringUtility::getUniqueId('createTrueTypeFontTestImage') . '.gif';
199 imagegif($image, $outputFile);
200
201 /** @var \TYPO3\CMS\Install\Status\StatusInterface $message */
202 $message = GeneralUtility::makeInstance(\TYPO3\CMS\Install\Status\InfoStatus::class);
203 $message->setTitle('True type font');
204 $message->setMessage(
205 'If the two images below do not look the same, please check your FreeType 2 module.'
206 );
207
208 $testResults = [];
209 $testResults['ttf'] = [];
210 $testResults['ttf']['message'] = $message;
211 $testResults['ttf']['title'] = '';
212 $testResults['ttf']['outputFile'] = $outputFile;
213 $testResults['ttf']['referenceFile'] = $this->imageBasePath . 'TestReference/Font.gif';
214
215 $this->view->assign('testResults', $testResults);
216 return $this->imageTestDoneMessage(GeneralUtility::milliseconds() - $parseTimeStart);
217 }
218
219 /**
220 * Create jpg from various image formats using IM / GM
221 *
222 * @return \TYPO3\CMS\Install\Status\StatusInterface
223 */
224 protected function convertImageFormatsToJpg()
225 {
226 $imageProcessor = $this->initializeImageProcessor();
227 $parseTimeStart = GeneralUtility::milliseconds();
228
229 $inputFormatsToTest = ['jpg', 'gif', 'png', 'tif', 'pdf', 'ai'];
230
231 $testResults = [];
232 foreach ($inputFormatsToTest as $formatToTest) {
233 $result = [];
234 if (!GeneralUtility::inList($GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'], $formatToTest)) {
235 /** @var \TYPO3\CMS\Install\Status\StatusInterface $message */
236 $message = GeneralUtility::makeInstance(\TYPO3\CMS\Install\Status\WarningStatus::class);
237 $message->setTitle('Skipped test');
238 $message->setMessage('Handling format ' . $formatToTest . ' must be enabled in TYPO3_CONF_VARS[\'GFX\'][\'imagefile_ext\']');
239 $result['error'] = $message;
240 } else {
241 $imageProcessor->IM_commands = [];
242 $inputFile = $this->imageBasePath . 'TestInput/Test.' . $formatToTest;
243 $imageProcessor->imageMagickConvert_forceFileNameBody = StringUtility::getUniqueId('read') . '-' . $formatToTest;
244 $imResult = $imageProcessor->imageMagickConvert($inputFile, 'jpg', '300', '', '', '', [], true);
245 $result['title'] = 'Read ' . $formatToTest;
246 if ($imResult !== null) {
247 $result['outputFile'] = $imResult[3];
248 $result['referenceFile'] = $this->imageBasePath . 'TestReference/Read-' . $formatToTest . '.jpg';
249 $result['command'] = $imageProcessor->IM_commands;
250 } else {
251 $result['error'] = $this->imageGenerationFailedMessage();
252 }
253 }
254 $testResults[] = $result;
255 }
256
257 $this->view->assign('testResults', $testResults);
258 return $this->imageTestDoneMessage(GeneralUtility::milliseconds() - $parseTimeStart);
259 }
260
261 /**
262 * Write gif and png test
263 *
264 * @return \TYPO3\CMS\Install\Status\StatusInterface
265 */
266 protected function writeGifAndPng()
267 {
268 $imageProcessor = $this->initializeImageProcessor();
269 $parseTimeStart = GeneralUtility::milliseconds();
270
271 $testResults = [
272 'gif' => [],
273 'png' => [],
274 ];
275
276 // Gif
277 $inputFile = $this->imageBasePath . 'TestInput/Test.gif';
278 $imageProcessor->imageMagickConvert_forceFileNameBody = StringUtility::getUniqueId('write-gif');
279 $imResult = $imageProcessor->imageMagickConvert($inputFile, 'gif', '300', '', '', '', [], true);
280 if ($imResult !== null && is_file($imResult[3])) {
281 if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['gif_compress']) {
282 clearstatcache();
283 $previousSize = GeneralUtility::formatSize(filesize($imResult[3]));
284 $methodUsed = GraphicalFunctions::gifCompress($imResult[3], '');
285 clearstatcache();
286 $compressedSize = GeneralUtility::formatSize(filesize($imResult[3]));
287 /** @var \TYPO3\CMS\Install\Status\StatusInterface $message */
288 $message = GeneralUtility::makeInstance(\TYPO3\CMS\Install\Status\InfoStatus::class);
289 $message->setTitle('Compressed gif');
290 $message->setMessage(
291 'Method used by compress: ' . $methodUsed . LF
292 . ' Previous filesize: ' . $previousSize . '. Current filesize:' . $compressedSize
293 );
294 } else {
295 /** @var \TYPO3\CMS\Install\Status\StatusInterface $message */
296 $message = GeneralUtility::makeInstance(\TYPO3\CMS\Install\Status\InfoStatus::class);
297 $message->setTitle('Gif compression not enabled by [GFX][gif_compress]');
298 }
299 $testResults['gif']['message'] = $message;
300 $testResults['gif']['title'] = 'Write gif';
301 $testResults['gif']['outputFile'] = $imResult[3];
302 $testResults['gif']['referenceFile'] = $this->imageBasePath . 'TestReference/Write-gif.gif';
303 $testResults['gif']['command'] = $imageProcessor->IM_commands;
304 } else {
305 $testResults['gif']['error'] = $this->imageGenerationFailedMessage();
306 }
307
308 // Png
309 $inputFile = $this->imageBasePath . 'TestInput/Test.png';
310 $imageProcessor->IM_commands = [];
311 $imageProcessor->imageMagickConvert_forceFileNameBody = StringUtility::getUniqueId('write-png');
312 $imResult = $imageProcessor->imageMagickConvert($inputFile, 'png', '300', '', '', '', [], true);
313 if ($imResult !== null) {
314 $testResults['png']['title'] = 'Write png';
315 $testResults['png']['outputFile'] = $imResult[3];
316 $testResults['png']['referenceFile'] = $this->imageBasePath . 'TestReference/Write-png.png';
317 $testResults['png']['command'] = $imageProcessor->IM_commands;
318 } else {
319 $testResults['png']['error'] = $this->imageGenerationFailedMessage();
320 }
321
322 $this->view->assign('testResults', $testResults);
323 return $this->imageTestDoneMessage(GeneralUtility::milliseconds() - $parseTimeStart);
324 }
325
326 /**
327 * Write gif and png test
328 *
329 * @return \TYPO3\CMS\Install\Status\StatusInterface
330 */
331 protected function scaleImages()
332 {
333 $imageProcessor = $this->initializeImageProcessor();
334 $parseTimeStart = GeneralUtility::milliseconds();
335
336 $testResults = [
337 'gif-to-gif' => [],
338 'png-to-png' => [],
339 'gif-to-jpg' => [],
340 ];
341
342 $imageProcessor->IM_commands = [];
343 $inputFile = $this->imageBasePath . 'TestInput/Transparent.gif';
344 $imageProcessor->imageMagickConvert_forceFileNameBody = StringUtility::getUniqueId('scale-gif');
345 $imResult = $imageProcessor->imageMagickConvert($inputFile, 'gif', '300', '', '', '', [], true);
346 if ($imResult !== null) {
347 $testResults['gif-to-gif']['title'] = 'gif to gif';
348 $testResults['gif-to-gif']['outputFile'] = $imResult[3];
349 $testResults['gif-to-gif']['referenceFile'] = $this->imageBasePath . 'TestReference/Scale-gif.gif';
350 $testResults['gif-to-gif']['command'] = $imageProcessor->IM_commands;
351 } else {
352 $testResults['gif-to-gif']['error'] = $this->imageGenerationFailedMessage();
353 }
354
355 $imageProcessor->IM_commands = [];
356 $inputFile = $this->imageBasePath . 'TestInput/Transparent.png';
357 $imageProcessor->imageMagickConvert_forceFileNameBody = StringUtility::getUniqueId('scale-png');
358 $imResult = $imageProcessor->imageMagickConvert($inputFile, 'png', '300', '', '', '', [], true);
359 if ($imResult !== null) {
360 $testResults['png-to-png']['title'] = 'png to png';
361 $testResults['png-to-png']['outputFile'] = $imResult[3];
362 $testResults['png-to-png']['referenceFile'] = $this->imageBasePath . 'TestReference/Scale-png.png';
363 $testResults['png-to-png']['command'] = $imageProcessor->IM_commands;
364 } else {
365 $testResults['png-to-png']['error'] = $this->imageGenerationFailedMessage();
366 }
367
368 $imageProcessor->IM_commands = [];
369 $inputFile = $this->imageBasePath . 'TestInput/Transparent.gif';
370 $imageProcessor->imageMagickConvert_forceFileNameBody = StringUtility::getUniqueId('scale-jpg');
371 $imResult = $imageProcessor->imageMagickConvert($inputFile, 'jpg', '300', '', '-opaque white -background white -flatten', '', [], true);
372 if ($imResult !== null) {
373 $testResults['gif-to-jpg']['title'] = 'gif to jpg';
374 $testResults['gif-to-jpg']['outputFile'] = $imResult[3];
375 $testResults['gif-to-jpg']['referenceFile'] = $this->imageBasePath . 'TestReference/Scale-jpg.jpg';
376 $testResults['gif-to-jpg']['command'] = $imageProcessor->IM_commands;
377 } else {
378 $testResults['gif-to-jpg']['error'] = $this->imageGenerationFailedMessage();
379 }
380
381 $this->view->assign('testResults', $testResults);
382 return $this->imageTestDoneMessage(GeneralUtility::milliseconds() - $parseTimeStart);
383 }
384
385 /**
386 * Combine multiple images into one test
387 *
388 * @return \TYPO3\CMS\Install\Status\StatusInterface
389 */
390 protected function combineImages()
391 {
392 $imageProcessor = $this->initializeImageProcessor();
393 $parseTimeStart = GeneralUtility::milliseconds();
394
395 $testResults = [
396 'combine1' => [],
397 'combine2' => [],
398 ];
399
400 $inputFile = $this->imageBasePath . 'TestInput/BackgroundOrange.gif';
401 $overlayFile = $this->imageBasePath . 'TestInput/Test.jpg';
402 $maskFile = $this->imageBasePath . 'TestInput/MaskBlackWhite.gif';
403 $resultFile = $imageProcessor->tempPath . $imageProcessor->filenamePrefix
404 . StringUtility::getUniqueId($imageProcessor->alternativeOutputKey . 'combine1') . '.jpg';
405 $imageProcessor->combineExec($inputFile, $overlayFile, $maskFile, $resultFile);
406 $result = $imageProcessor->getImageDimensions($resultFile);
407 if ($result) {
408 $testResults['combine1']['title'] = 'Combine using a GIF mask with only black and white';
409 $testResults['combine1']['outputFile'] = $result[3];
410 $testResults['combine1']['referenceFile'] = $this->imageBasePath . 'TestReference/Combine-1.jpg';
411 $testResults['combine1']['command'] = $imageProcessor->IM_commands;
412 } else {
413 $testResults['combine1']['error'] = $this->imageGenerationFailedMessage();
414 }
415
416 $imageProcessor->IM_commands = [];
417 $inputFile = $this->imageBasePath . 'TestInput/BackgroundCombine.jpg';
418 $overlayFile = $this->imageBasePath . 'TestInput/Test.jpg';
419 $maskFile = $this->imageBasePath . 'TestInput/MaskCombine.jpg';
420 $resultFile = $imageProcessor->tempPath . $imageProcessor->filenamePrefix
421 . StringUtility::getUniqueId($imageProcessor->alternativeOutputKey . 'combine2') . '.jpg';
422 $imageProcessor->combineExec($inputFile, $overlayFile, $maskFile, $resultFile);
423 $result = $imageProcessor->getImageDimensions($resultFile);
424 if ($result) {
425 $testResults['combine2']['title'] = 'Combine using a JPG mask with graylevels';
426 $testResults['combine2']['outputFile'] = $result[3];
427 $testResults['combine2']['referenceFile'] = $this->imageBasePath . 'TestReference/Combine-2.jpg';
428 $testResults['combine2']['command'] = $imageProcessor->IM_commands;
429 } else {
430 $testResults['combine2']['error'] = $this->imageGenerationFailedMessage();
431 }
432
433 $this->view->assign('testResults', $testResults);
434 return $this->imageTestDoneMessage(GeneralUtility::milliseconds() - $parseTimeStart);
435 }
436
437 /**
438 * Test gdlib functions
439 *
440 * @return \TYPO3\CMS\Install\Status\StatusInterface
441 */
442 protected function gdlib()
443 {
444 $imageProcessor = $this->initializeImageProcessor();
445 $parseTimeStart = GeneralUtility::milliseconds();
446 $gifOrPng = $imageProcessor->gifExtension;
447 $testResults = [];
448
449 // GD with simple box
450 $imageProcessor->IM_commands = [];
451 $image = imagecreatetruecolor(300, 225);
452 $backgroundColor = imagecolorallocate($image, 0, 0, 0);
453 imagefilledrectangle($image, 0, 0, 300, 225, $backgroundColor);
454 $workArea = [0, 0, 300, 225];
455 $conf = [
456 'dimensions' => '10,50,280,50',
457 'color' => 'olive',
458 ];
459 $imageProcessor->makeBox($image, $conf, $workArea);
460 $outputFile = $imageProcessor->tempPath . $imageProcessor->filenamePrefix . StringUtility::getUniqueId('gdSimple') . '.' . $gifOrPng;
461 $imageProcessor->ImageWrite($image, $outputFile);
462 $result = $imageProcessor->getImageDimensions($outputFile);
463 $testResults['simple'] = [];
464 $testResults['simple']['title'] = 'Create simple image';
465 $testResults['simple']['outputFile'] = $result[3];
466 $testResults['simple']['referenceFile'] = $this->imageBasePath . 'TestReference/Gdlib-simple.' . $gifOrPng;
467 $testResults['simple']['command'] = $imageProcessor->IM_commands;
468
469 // GD from image with box
470 $imageProcessor->IM_commands = [];
471 $inputFile = $this->imageBasePath . 'TestInput/Test.' . $gifOrPng;
472 $image = $imageProcessor->imageCreateFromFile($inputFile);
473
474 $workArea = [0, 0, 400, 300];
475 $conf = [
476 'dimensions' => '10,50,380,50',
477 'color' => 'olive',
478 ];
479 $imageProcessor->makeBox($image, $conf, $workArea);
480 $outputFile = $imageProcessor->tempPath . $imageProcessor->filenamePrefix . StringUtility::getUniqueId('gdBox') . '.' . $gifOrPng;
481 $imageProcessor->ImageWrite($image, $outputFile);
482 $result = $imageProcessor->getImageDimensions($outputFile);
483 $testResults['box'] = [];
484 $testResults['box']['title'] = 'Create image from file';
485 $testResults['box']['outputFile'] = $result[3];
486 $testResults['box']['referenceFile'] = $this->imageBasePath . 'TestReference/Gdlib-box.' . $gifOrPng;
487 $testResults['box']['command'] = $imageProcessor->IM_commands;
488
489 // GD with text
490 $imageProcessor->IM_commands = [];
491 $image = imagecreatetruecolor(300, 225);
492 $backgroundColor = imagecolorallocate($image, 128, 128, 150);
493 imagefilledrectangle($image, 0, 0, 300, 225, $backgroundColor);
494 $workArea = [0, 0, 300, 225];
495 $conf = [
496 'iterations' => 1,
497 'angle' => 0,
498 'antiAlias' => 1,
499 'text' => 'HELLO WORLD',
500 'fontColor' => '#003366',
501 'fontSize' => 30,
502 'fontFile' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath('install') . 'Resources/Private/Font/vera.ttf',
503 'offset' => '30,80',
504 ];
505 $conf['BBOX'] = $imageProcessor->calcBBox($conf);
506 $imageProcessor->makeText($image, $conf, $workArea);
507 $outputFile = $imageProcessor->tempPath . $imageProcessor->filenamePrefix . StringUtility::getUniqueId('gdText') . '.' . $gifOrPng;
508 $imageProcessor->ImageWrite($image, $outputFile);
509 $result = $imageProcessor->getImageDimensions($outputFile);
510 $testResults['text'] = [];
511 $testResults['text']['title'] = 'Render text with TrueType font';
512 $testResults['text']['outputFile'] = $result[3];
513 $testResults['text']['referenceFile'] = $this->imageBasePath . 'TestReference/Gdlib-text.' . $gifOrPng;
514 $testResults['text']['command'] = $imageProcessor->IM_commands;
515
516 // GD with text, niceText
517 $testResults['niceText'] = [];
518 if ($this->isImageMagickEnabledAndConfigured()) {
519 // Warning: Re-uses $conf from above!
520 $conf['offset'] = '30,120';
521 $conf['niceText'] = 1;
522 $imageProcessor->makeText($image, $conf, $workArea);
523 $outputFile = $imageProcessor->tempPath . $imageProcessor->filenamePrefix . StringUtility::getUniqueId('gdNiceText') . '.' . $gifOrPng;
524 $imageProcessor->ImageWrite($image, $outputFile);
525 $result = $imageProcessor->getImageDimensions($outputFile);
526 $testResults['niceText']['title'] = 'Render text with TrueType font using \'niceText\' option';
527 $testResults['niceText']['outputFile'] = $result[3];
528 $testResults['niceText']['referenceFile'] = $this->imageBasePath . 'TestReference/Gdlib-niceText.' . $gifOrPng;
529 $testResults['niceText']['command'] = $imageProcessor->IM_commands;
530 /** @var \TYPO3\CMS\Install\Status\StatusInterface $message */
531 $message = GeneralUtility::makeInstance(\TYPO3\CMS\Install\Status\InfoStatus::class);
532 $message->setTitle('Note on \'niceText\'');
533 $message->setMessage(
534 '\'niceText\' is a concept that tries to improve the antialiasing of the rendered type by'
535 . ' actually rendering the textstring in double size on a black/white mask, downscaling the mask'
536 . ' and masking the text onto the image through this mask. This involves'
537 . ' ImageMagick \'combine\'/\'composite\' and \'convert\'.'
538 );
539 $testResults['niceText']['message'] = $message;
540 } else {
541 $result['niceText']['error'] = $this->imageGenerationFailedMessage();
542 }
543
544 // GD with text, niceText, shadow
545 $testResults['shadow'] = [];
546 if ($this->isImageMagickEnabledAndConfigured()) {
547 // Warning: Re-uses $conf from above!
548 $conf['offset'] = '30,160';
549 $conf['niceText'] = 1;
550 $conf['shadow.'] = [
551 'offset' => '2,2',
552 'blur' => $imageProcessor->V5_EFFECTS ? '20' : '90',
553 'opacity' => '50',
554 'color' => 'black'
555 ];
556 // Warning: Re-uses $image from above!
557 $imageProcessor->makeShadow($image, $conf['shadow.'], $workArea, $conf);
558 $imageProcessor->makeText($image, $conf, $workArea);
559 $outputFile = $imageProcessor->tempPath . $imageProcessor->filenamePrefix . StringUtility::getUniqueId('GDwithText-niceText-shadow') . '.' . $gifOrPng;
560 $imageProcessor->ImageWrite($image, $outputFile);
561 $result = $imageProcessor->getImageDimensions($outputFile);
562 $testResults['shadow']['title'] = 'Render \'niceText\' with a shadow under';
563 $testResults['shadow']['outputFile'] = $result[3];
564 $testResults['shadow']['referenceFile'] = $this->imageBasePath . 'TestReference/Gdlib-shadow.' . $gifOrPng;
565 $testResults['shadow']['command'] = $imageProcessor->IM_commands;
566 /** @var \TYPO3\CMS\Install\Status\StatusInterface $message */
567 $message = GeneralUtility::makeInstance(\TYPO3\CMS\Install\Status\InfoStatus::class);
568 $message->setTitle('Note on \'shadow\'');
569 $message->setMessage(
570 'This test makes sense only if the above test had a correct output. But if so, you may not see'
571 . ' a soft dropshadow from the third text string as you should. In that case you are most likely'
572 . ' using ImageMagick 5 and should set the flag TYPO3_CONF_VARS[GFX][processor_effects].'
573 );
574 $testResults['shadow']['message'] = $message;
575 } else {
576 $result['shadow']['error'] = $this->imageGenerationFailedMessage();
577 }
578
579 $this->view->assign('testResults', $testResults);
580 return $this->imageTestDoneMessage(GeneralUtility::milliseconds() - $parseTimeStart);
581 }
582
583 /**
584 * Create a 'image test was done' message
585 *
586 * @param int $parseTime Parse time
587 * @return \TYPO3\CMS\Install\Status\StatusInterface
588 */
589 protected function imageTestDoneMessage($parseTime = 0)
590 {
591 /** @var \TYPO3\CMS\Install\Status\StatusInterface $message */
592 $message = GeneralUtility::makeInstance(\TYPO3\CMS\Install\Status\OkStatus::class);
593 $message->setTitle('Executed image tests');
594 $message->setMessage('Parse time: ' . $parseTime . ' ms');
595 return $message;
596 }
597
598 /**
599 * Create a 'imageMagick disabled' message
600 *
601 * @return \TYPO3\CMS\Install\Status\StatusInterface
602 */
603 protected function imageMagickDisabledMessage()
604 {
605 /** @var \TYPO3\CMS\Install\Status\StatusInterface $message */
606 $message = GeneralUtility::makeInstance(\TYPO3\CMS\Install\Status\ErrorStatus::class);
607 $message->setTitle('Tests not executed');
608 $message->setMessage('ImageMagick / GraphicsMagick handling is disabled or not configured correctly.');
609 return $message;
610 }
611
612 /**
613 * Create a 'image generation failed' message
614 *
615 * @return \TYPO3\CMS\Install\Status\StatusInterface
616 */
617 protected function imageGenerationFailedMessage()
618 {
619 /** @var \TYPO3\CMS\Install\Status\StatusInterface $message */
620 $message = GeneralUtility::makeInstance(\TYPO3\CMS\Install\Status\ErrorStatus::class);
621 $message->setTitle('Image generation failed');
622 $message->setMessage(
623 'ImageMagick / GraphicsMagick handling is enabled, but the execute'
624 . ' command returned an error. Please check your settings, especially'
625 . ' [\'GFX\'][\'processor_path\'] and [\'GFX\'][\'processor_path_lzw\'] and ensure Ghostscript is installed on your server.'
626 );
627 return $message;
628 }
629
630 /**
631 * Gather image configuration overview
632 *
633 * @return array Result array
634 */
635 protected function getImageConfiguration()
636 {
637 $result = [];
638 $result['processor'] = $GLOBALS['TYPO3_CONF_VARS']['GFX']['processor'] === 'GraphicsMagick' ? 'GraphicsMagick' : 'ImageMagick';
639 $result['processorEnabled'] = $GLOBALS['TYPO3_CONF_VARS']['GFX']['processor_enabled'];
640 $result['processorPath'] = $GLOBALS['TYPO3_CONF_VARS']['GFX']['processor_path'];
641 $result['processorVersion'] = $this->determineImageMagickVersion();
642 $result['processorEffects'] = $GLOBALS['TYPO3_CONF_VARS']['GFX']['processor_effects'];
643 $result['gdlibEnabled'] = $GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib'];
644 $result['gdlibPng'] = $GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib_png'];
645 $result['fileFormats'] = $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'];
646 return $result;
647 }
648
649 /**
650 * Initialize image processor
651 *
652 * @return GraphicalFunctions Initialized image processor
653 */
654 protected function initializeImageProcessor()
655 {
656 /** @var GraphicalFunctions $imageProcessor */
657 $imageProcessor = GeneralUtility::makeInstance(GraphicalFunctions::class);
658 $imageProcessor->init();
659 $imageProcessor->tempPath = PATH_site . 'typo3temp/';
660 $imageProcessor->dontCheckForExistingTempFile = 1;
661 $imageProcessor->filenamePrefix = 'installTool-';
662 $imageProcessor->dontCompress = 1;
663 $imageProcessor->alternativeOutputKey = 'typo3InstallTest';
664 $imageProcessor->noFramePrepended = $GLOBALS['TYPO3_CONF_VARS']['GFX']['processor_allowFrameSelection'];
665 return $imageProcessor;
666 }
667
668 /**
669 * Find out if ImageMagick or GraphicsMagick is enabled and set up
670 *
671 * @return bool TRUE if enabled and path is set
672 */
673 protected function isImageMagickEnabledAndConfigured()
674 {
675 $enabled = $GLOBALS['TYPO3_CONF_VARS']['GFX']['processor_enabled'];
676 $path = $GLOBALS['TYPO3_CONF_VARS']['GFX']['processor_path'];
677 return $enabled && $path;
678 }
679
680 /**
681 * Determine ImageMagick / GraphicsMagick version
682 *
683 * @return string Version
684 */
685 protected function determineImageMagickVersion()
686 {
687 $command = \TYPO3\CMS\Core\Utility\CommandUtility::imageMagickCommand('identify', '-version');
688 \TYPO3\CMS\Core\Utility\CommandUtility::exec($command, $result);
689 $string = $result[0];
690 list(, $version) = explode('Magick', $string);
691 list($version) = explode(' ', trim($version));
692 return trim($version);
693 }
694 }