[TASK] Get rid of ObjectManager in install tool
[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 = array();
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 = array();
209 $testResults['ttf'] = array();
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 $this->setUpDatabaseConnectionMock();
227 $imageProcessor = $this->initializeImageProcessor();
228 $parseTimeStart = GeneralUtility::milliseconds();
229
230 $inputFormatsToTest = array('jpg', 'gif', 'png', 'tif', 'bmp', 'pcx', 'tga', 'pdf', 'ai');
231
232 $testResults = array();
233 foreach ($inputFormatsToTest as $formatToTest) {
234 $result = array();
235 if (!GeneralUtility::inList($GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'], $formatToTest)) {
236 /** @var \TYPO3\CMS\Install\Status\StatusInterface $message */
237 $message = GeneralUtility::makeInstance(\TYPO3\CMS\Install\Status\WarningStatus::class);
238 $message->setTitle('Skipped test');
239 $message->setMessage('Handling format ' . $formatToTest . ' must be enabled in TYPO3_CONF_VARS[\'GFX\'][\'imagefile_ext\']');
240 $result['error'] = $message;
241 } else {
242 $imageProcessor->IM_commands = array();
243 $inputFile = $this->imageBasePath . 'TestInput/Test.' . $formatToTest;
244 $imageProcessor->imageMagickConvert_forceFileNameBody = StringUtility::getUniqueId('read') . '-' . $formatToTest;
245 $imResult = $imageProcessor->imageMagickConvert($inputFile, 'jpg', '170', '', '', '', array(), true);
246 $result['title'] = 'Read ' . $formatToTest;
247 if ($imResult !== null) {
248 $result['outputFile'] = $imResult[3];
249 $result['referenceFile'] = $this->imageBasePath . 'TestReference/Read-' . $formatToTest . '.jpg';
250 $result['command'] = $imageProcessor->IM_commands;
251 } else {
252 $result['error'] = $this->imageGenerationFailedMessage();
253 }
254 }
255 $testResults[] = $result;
256 }
257
258 $this->view->assign('testResults', $testResults);
259 return $this->imageTestDoneMessage(GeneralUtility::milliseconds() - $parseTimeStart);
260 }
261
262 /**
263 * Write gif and png test
264 *
265 * @return \TYPO3\CMS\Install\Status\StatusInterface
266 */
267 protected function writeGifAndPng()
268 {
269 $this->setUpDatabaseConnectionMock();
270 $imageProcessor = $this->initializeImageProcessor();
271 $parseTimeStart = GeneralUtility::milliseconds();
272
273 $testResults = array(
274 'gif' => array(),
275 'png' => array(),
276 );
277
278 // Gif
279 $inputFile = $this->imageBasePath . 'TestInput/Test.gif';
280 $imageProcessor->imageMagickConvert_forceFileNameBody = StringUtility::getUniqueId('write-gif');
281 $imResult = $imageProcessor->imageMagickConvert($inputFile, 'gif', '', '', '', '', array(), true);
282 if ($imResult !== null && is_file($imResult[3])) {
283 if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['gif_compress']) {
284 clearstatcache();
285 $previousSize = GeneralUtility::formatSize(filesize($imResult[3]));
286 $methodUsed = GraphicalFunctions::gifCompress($imResult[3], '');
287 clearstatcache();
288 $compressedSize = GeneralUtility::formatSize(filesize($imResult[3]));
289 /** @var \TYPO3\CMS\Install\Status\StatusInterface $message */
290 $message = GeneralUtility::makeInstance(\TYPO3\CMS\Install\Status\InfoStatus::class);
291 $message->setTitle('Compressed gif');
292 $message->setMessage(
293 'Method used by compress: ' . $methodUsed . LF
294 . ' Previous filesize: ' . $previousSize . '. Current filesize:' . $compressedSize
295 );
296 } else {
297 /** @var \TYPO3\CMS\Install\Status\StatusInterface $message */
298 $message = GeneralUtility::makeInstance(\TYPO3\CMS\Install\Status\InfoStatus::class);
299 $message->setTitle('Gif compression not enabled by [GFX][gif_compress]');
300 }
301 $testResults['gif']['message'] = $message;
302 $testResults['gif']['title'] = 'Write gif';
303 $testResults['gif']['outputFile'] = $imResult[3];
304 $testResults['gif']['referenceFile'] = $this->imageBasePath . 'TestReference/Write-gif.gif';
305 $testResults['gif']['command'] = $imageProcessor->IM_commands;
306 } else {
307 $testResults['gif']['error'] = $this->imageGenerationFailedMessage();
308 }
309
310 // Png
311 $inputFile = $this->imageBasePath . 'TestInput/Test.png';
312 $imageProcessor->IM_commands = array();
313 $imageProcessor->imageMagickConvert_forceFileNameBody = StringUtility::getUniqueId('write-png');
314 $imResult = $imageProcessor->imageMagickConvert($inputFile, 'png', '', '', '', '', array(), true);
315 if ($imResult !== null) {
316 $testResults['png']['title'] = 'Write png';
317 $testResults['png']['outputFile'] = $imResult[3];
318 $testResults['png']['referenceFile'] = $this->imageBasePath . 'TestReference/Write-png.png';
319 $testResults['png']['command'] = $imageProcessor->IM_commands;
320 } else {
321 $testResults['png']['error'] = $this->imageGenerationFailedMessage();
322 }
323
324 $this->view->assign('testResults', $testResults);
325 return $this->imageTestDoneMessage(GeneralUtility::milliseconds() - $parseTimeStart);
326 }
327
328 /**
329 * Write gif and png test
330 *
331 * @return \TYPO3\CMS\Install\Status\StatusInterface
332 */
333 protected function scaleImages()
334 {
335 $this->setUpDatabaseConnectionMock();
336 $imageProcessor = $this->initializeImageProcessor();
337 $parseTimeStart = GeneralUtility::milliseconds();
338
339 $testResults = array(
340 'gif-to-gif' => array(),
341 'png-to-png' => array(),
342 'gif-to-jpg' => array(),
343 );
344
345 $imageProcessor->IM_commands = array();
346 $inputFile = $this->imageBasePath . 'TestInput/Transparent.gif';
347 $imageProcessor->imageMagickConvert_forceFileNameBody = StringUtility::getUniqueId('scale-gif');
348 $imResult = $imageProcessor->imageMagickConvert($inputFile, 'gif', '150', '', '', '', array(), true);
349 if ($imResult !== null) {
350 $testResults['gif-to-gif']['title'] = 'gif to gif';
351 $testResults['gif-to-gif']['outputFile'] = $imResult[3];
352 $testResults['gif-to-gif']['referenceFile'] = $this->imageBasePath . 'TestReference/Scale-gif.gif';
353 $testResults['gif-to-gif']['command'] = $imageProcessor->IM_commands;
354 } else {
355 $testResults['gif-to-gif']['error'] = $this->imageGenerationFailedMessage();
356 }
357
358 $imageProcessor->IM_commands = array();
359 $inputFile = $this->imageBasePath . 'TestInput/Transparent.png';
360 $imageProcessor->imageMagickConvert_forceFileNameBody = StringUtility::getUniqueId('scale-png');
361 $imResult = $imageProcessor->imageMagickConvert($inputFile, 'png', '150', '', '', '', array(), true);
362 if ($imResult !== null) {
363 $testResults['png-to-png']['title'] = 'png to png';
364 $testResults['png-to-png']['outputFile'] = $imResult[3];
365 $testResults['png-to-png']['referenceFile'] = $this->imageBasePath . 'TestReference/Scale-png.png';
366 $testResults['png-to-png']['command'] = $imageProcessor->IM_commands;
367 } else {
368 $testResults['png-to-png']['error'] = $this->imageGenerationFailedMessage();
369 }
370
371 $imageProcessor->IM_commands = array();
372 $inputFile = $this->imageBasePath . 'TestInput/Transparent.gif';
373 $imageProcessor->imageMagickConvert_forceFileNameBody = StringUtility::getUniqueId('scale-jpg');
374 $imResult = $imageProcessor->imageMagickConvert($inputFile, 'jpg', '150', '', '-opaque white -background white -flatten', '', array(), true);
375 if ($imResult !== null) {
376 $testResults['gif-to-jpg']['title'] = 'gif to jpg';
377 $testResults['gif-to-jpg']['outputFile'] = $imResult[3];
378 $testResults['gif-to-jpg']['referenceFile'] = $this->imageBasePath . 'TestReference/Scale-jpg.jpg';
379 $testResults['gif-to-jpg']['command'] = $imageProcessor->IM_commands;
380 } else {
381 $testResults['gif-to-jpg']['error'] = $this->imageGenerationFailedMessage();
382 }
383
384 $this->view->assign('testResults', $testResults);
385 return $this->imageTestDoneMessage(GeneralUtility::milliseconds() - $parseTimeStart);
386 }
387
388 /**
389 * Combine multiple images into one test
390 *
391 * @return \TYPO3\CMS\Install\Status\StatusInterface
392 */
393 protected function combineImages()
394 {
395 $this->setUpDatabaseConnectionMock();
396 $imageProcessor = $this->initializeImageProcessor();
397 $parseTimeStart = GeneralUtility::milliseconds();
398
399 $testResults = array(
400 'combine1' => array(),
401 'combine2' => array(),
402 );
403
404 $inputFile = $this->imageBasePath . 'TestInput/BackgroundGreen.gif';
405 $overlayFile = $this->imageBasePath . 'TestInput/Test.jpg';
406 $maskFile = $this->imageBasePath . 'TestInput/MaskBlackWhite.gif';
407 $resultFile = $imageProcessor->tempPath . $imageProcessor->filenamePrefix
408 . StringUtility::getUniqueId($imageProcessor->alternativeOutputKey . 'combine1') . '.jpg';
409 $imageProcessor->combineExec($inputFile, $overlayFile, $maskFile, $resultFile);
410 $result = $imageProcessor->getImageDimensions($resultFile);
411 if ($result) {
412 $testResults['combine1']['title'] = 'Combine using a GIF mask with only black and white';
413 $testResults['combine1']['outputFile'] = $result[3];
414 $testResults['combine1']['referenceFile'] = $this->imageBasePath . 'TestReference/Combine-1.jpg';
415 $testResults['combine1']['command'] = $imageProcessor->IM_commands;
416 } else {
417 $testResults['combine1']['error'] = $this->imageGenerationFailedMessage();
418 }
419
420 $imageProcessor->IM_commands = array();
421 $inputFile = $this->imageBasePath . 'TestInput/BackgroundCombine.jpg';
422 $overlayFile = $this->imageBasePath . 'TestInput/Test.jpg';
423 $maskFile = $this->imageBasePath . 'TestInput/MaskCombine.jpg';
424 $resultFile = $imageProcessor->tempPath . $imageProcessor->filenamePrefix
425 . StringUtility::getUniqueId($imageProcessor->alternativeOutputKey . 'combine2') . '.jpg';
426 $imageProcessor->combineExec($inputFile, $overlayFile, $maskFile, $resultFile);
427 $result = $imageProcessor->getImageDimensions($resultFile);
428 if ($result) {
429 $testResults['combine2']['title'] = 'Combine using a JPG mask with graylevels';
430 $testResults['combine2']['outputFile'] = $result[3];
431 $testResults['combine2']['referenceFile'] = $this->imageBasePath . 'TestReference/Combine-2.jpg';
432 $testResults['combine2']['command'] = $imageProcessor->IM_commands;
433 } else {
434 $testResults['combine2']['error'] = $this->imageGenerationFailedMessage();
435 }
436
437 $this->view->assign('testResults', $testResults);
438 return $this->imageTestDoneMessage(GeneralUtility::milliseconds() - $parseTimeStart);
439 }
440
441 /**
442 * Test gdlib functions
443 *
444 * @return \TYPO3\CMS\Install\Status\StatusInterface
445 */
446 protected function gdlib()
447 {
448 $this->setUpDatabaseConnectionMock();
449 $imageProcessor = $this->initializeImageProcessor();
450 $parseTimeStart = GeneralUtility::milliseconds();
451 $gifOrPng = $imageProcessor->gifExtension;
452 $testResults = array();
453
454 // GD with simple box
455 $imageProcessor->IM_commands = array();
456 $image = imagecreatetruecolor(170, 136);
457 $backgroundColor = imagecolorallocate($image, 0, 0, 0);
458 imagefilledrectangle($image, 0, 0, 170, 136, $backgroundColor);
459 $workArea = array(0, 0, 170, 136);
460 $conf = array(
461 'dimensions' => '10,50,150,36',
462 'color' => 'olive',
463 );
464 $imageProcessor->makeBox($image, $conf, $workArea);
465 $outputFile = $imageProcessor->tempPath . $imageProcessor->filenamePrefix . StringUtility::getUniqueId('gdSimple') . '.' . $gifOrPng;
466 $imageProcessor->ImageWrite($image, $outputFile);
467 $result = $imageProcessor->getImageDimensions($outputFile);
468 $testResults['simple'] = array();
469 $testResults['simple']['title'] = 'Create simple image';
470 $testResults['simple']['outputFile'] = $result[3];
471 $testResults['simple']['referenceFile'] = $this->imageBasePath . 'TestReference/Gdlib-simple.' . $gifOrPng;
472
473 // GD from image with box
474 $imageProcessor->IM_commands = array();
475 $inputFile = $this->imageBasePath . 'TestInput/Test.' . $gifOrPng;
476 $image = $imageProcessor->imageCreateFromFile($inputFile);
477 $workArea = array(0, 0, 170, 136);
478 $conf = array(
479 'dimensions' => '10,50,150,36',
480 'color' => 'olive',
481 );
482 $imageProcessor->makeBox($image, $conf, $workArea);
483 $outputFile = $imageProcessor->tempPath . $imageProcessor->filenamePrefix . StringUtility::getUniqueId('gdBox') . '.' . $gifOrPng;
484 $imageProcessor->ImageWrite($image, $outputFile);
485 $result = $imageProcessor->getImageDimensions($outputFile);
486 $testResults['box'] = array();
487 $testResults['box']['title'] = 'Create image from file';
488 $testResults['box']['outputFile'] = $result[3];
489 $testResults['box']['referenceFile'] = $this->imageBasePath . 'TestReference/Gdlib-box.' . $gifOrPng;
490
491 // GD with text
492 $imageProcessor->IM_commands = array();
493 $image = imagecreatetruecolor(170, 136);
494 $backgroundColor = imagecolorallocate($image, 128, 128, 150);
495 imagefilledrectangle($image, 0, 0, 170, 136, $backgroundColor);
496 $workArea = array(0, 0, 170, 136);
497 $conf = array(
498 'iterations' => 1,
499 'angle' => 0,
500 'antiAlias' => 1,
501 'text' => 'HELLO WORLD',
502 'fontColor' => '#003366',
503 'fontSize' => 18,
504 'fontFile' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath('install') . 'Resources/Private/Font/vera.ttf',
505 'offset' => '17,40',
506 );
507 $conf['BBOX'] = $imageProcessor->calcBBox($conf);
508 $imageProcessor->makeText($image, $conf, $workArea);
509 $outputFile = $imageProcessor->tempPath . $imageProcessor->filenamePrefix . StringUtility::getUniqueId('gdText') . '.' . $gifOrPng;
510 $imageProcessor->ImageWrite($image, $outputFile);
511 $result = $imageProcessor->getImageDimensions($outputFile);
512 $testResults['text'] = array();
513 $testResults['text']['title'] = 'Render text with TrueType font';
514 $testResults['text']['outputFile'] = $result[3];
515 $testResults['text']['referenceFile'] = $this->imageBasePath . 'TestReference/Gdlib-text.' . $gifOrPng;
516
517 // GD with text, niceText
518 $testResults['niceText'] = array();
519 if ($this->isImageMagickEnabledAndConfigured()) {
520 // Warning: Re-uses $conf from above!
521 $conf['offset'] = '17,65';
522 $conf['niceText'] = 1;
523 $imageProcessor->makeText($image, $conf, $workArea);
524 $outputFile = $imageProcessor->tempPath . $imageProcessor->filenamePrefix . StringUtility::getUniqueId('gdNiceText') . '.' . $gifOrPng;
525 $imageProcessor->ImageWrite($image, $outputFile);
526 $result = $imageProcessor->getImageDimensions($outputFile);
527 $testResults['niceText']['title'] = 'Render text with TrueType font using \'niceText\' option';
528 $testResults['niceText']['outputFile'] = $result[3];
529 $testResults['niceText']['referenceFile'] = $this->imageBasePath . 'TestReference/Gdlib-niceText.' . $gifOrPng;
530 $testResults['niceText']['command'] = $imageProcessor->IM_commands;
531 /** @var \TYPO3\CMS\Install\Status\StatusInterface $message */
532 $message = GeneralUtility::makeInstance(\TYPO3\CMS\Install\Status\InfoStatus::class);
533 $message->setTitle('Note on \'niceText\'');
534 $message->setMessage(
535 '\'niceText\' is a concept that tries to improve the antialiasing of the rendered type by'
536 . ' actually rendering the textstring in double size on a black/white mask, downscaling the mask'
537 . ' and masking the text onto the image through this mask. This involves'
538 . ' ImageMagick \'combine\'/\'composite\' and \'convert\'.'
539 );
540 $testResults['niceText']['message'] = $message;
541 } else {
542 $result['niceText']['error'] = $this->imageGenerationFailedMessage();
543 }
544
545 // GD with text, niceText, shadow
546 $testResults['shadow'] = array();
547 if ($this->isImageMagickEnabledAndConfigured()) {
548 // Warning: Re-uses $conf from above!
549 $conf['offset'] = '17,90';
550 $conf['niceText'] = 1;
551 $conf['shadow.'] = array(
552 'offset' => '2,2',
553 'blur' => $imageProcessor->V5_EFFECTS ? '20' : '90',
554 'opacity' => '50',
555 'color' => 'black'
556 );
557 // Warning: Re-uses $image from above!
558 $imageProcessor->makeShadow($image, $conf['shadow.'], $workArea, $conf);
559 $imageProcessor->makeText($image, $conf, $workArea);
560 $outputFile = $imageProcessor->tempPath . $imageProcessor->filenamePrefix . StringUtility::getUniqueId('GDwithText-niceText-shadow') . '.' . $gifOrPng;
561 $imageProcessor->ImageWrite($image, $outputFile);
562 $result = $imageProcessor->getImageDimensions($outputFile);
563 $testResults['shadow']['title'] = 'Render \'niceText\' with a shadow under';
564 $testResults['shadow']['outputFile'] = $result[3];
565 $testResults['shadow']['referenceFile'] = $this->imageBasePath . 'TestReference/Gdlib-shadow.' . $gifOrPng;
566 $testResults['shadow']['command'] = $imageProcessor->IM_commands;
567 /** @var \TYPO3\CMS\Install\Status\StatusInterface $message */
568 $message = GeneralUtility::makeInstance(\TYPO3\CMS\Install\Status\InfoStatus::class);
569 $message->setTitle('Note on \'shadow\'');
570 $message->setMessage(
571 'This test makes sense only if the above test had a correct output. But if so, you may not see'
572 . ' a soft dropshadow from the third text string as you should. In that case you are most likely'
573 . ' using ImageMagick 5 and should set the flag TYPO3_CONF_VARS[GFX][processor_effects].'
574 );
575 $testResults['shadow']['message'] = $message;
576 } else {
577 $result['shadow']['error'] = $this->imageGenerationFailedMessage();
578 }
579
580 $this->view->assign('testResults', $testResults);
581 return $this->imageTestDoneMessage(GeneralUtility::milliseconds() - $parseTimeStart);
582 }
583
584 /**
585 * Create a 'image test was done' message
586 *
587 * @param int $parseTime Parse time
588 * @return \TYPO3\CMS\Install\Status\StatusInterface
589 */
590 protected function imageTestDoneMessage($parseTime = 0)
591 {
592 /** @var \TYPO3\CMS\Install\Status\StatusInterface $message */
593 $message = GeneralUtility::makeInstance(\TYPO3\CMS\Install\Status\OkStatus::class);
594 $message->setTitle('Executed image tests');
595 $message->setMessage('Parse time: ' . $parseTime . ' ms');
596 return $message;
597 }
598
599 /**
600 * Create a 'imageMagick disabled' message
601 *
602 * @return \TYPO3\CMS\Install\Status\StatusInterface
603 */
604 protected function imageMagickDisabledMessage()
605 {
606 /** @var \TYPO3\CMS\Install\Status\StatusInterface $message */
607 $message = GeneralUtility::makeInstance(\TYPO3\CMS\Install\Status\ErrorStatus::class);
608 $message->setTitle('Tests not executed');
609 $message->setMessage('ImageMagick / GraphicsMagick handling is disabled or not configured correctly.');
610 return $message;
611 }
612
613 /**
614 * Create a 'image generation failed' message
615 *
616 * @return \TYPO3\CMS\Install\Status\StatusInterface
617 */
618 protected function imageGenerationFailedMessage()
619 {
620 /** @var \TYPO3\CMS\Install\Status\StatusInterface $message */
621 $message = GeneralUtility::makeInstance(\TYPO3\CMS\Install\Status\ErrorStatus::class);
622 $message->setTitle('Image generation failed');
623 $message->setMessage(
624 'ImageMagick / GraphicsMagick handling is enabled, but the execute'
625 . ' command returned an error. Please check your settings, especially'
626 . ' [\'GFX\'][\'processor_path\'] and [\'GFX\'][\'processor_path_lzw\'] and ensure Ghostscript is installed on your server.'
627 );
628 return $message;
629 }
630
631 /**
632 * Gather image configuration overview
633 *
634 * @return array Result array
635 */
636 protected function getImageConfiguration()
637 {
638 $result = array();
639 $result['processor'] = $GLOBALS['TYPO3_CONF_VARS']['GFX']['processor'] === 'GraphicsMagick' ? 'GraphicsMagick' : 'ImageMagick';
640 $result['processorEnabled'] = $GLOBALS['TYPO3_CONF_VARS']['GFX']['processor_enabled'];
641 $result['processorPath'] = $GLOBALS['TYPO3_CONF_VARS']['GFX']['processor_path'];
642 $result['processorVersion'] = $this->determineImageMagickVersion();
643 $result['processorEffects'] = $GLOBALS['TYPO3_CONF_VARS']['GFX']['processor_effects'];
644 $result['gdlibEnabled'] = $GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib'];
645 $result['gdlibPng'] = $GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib_png'];
646 $result['fileFormats'] = $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'];
647 return $result;
648 }
649
650 /**
651 * Initialize image processor
652 *
653 * @return GraphicalFunctions Initialized image processor
654 */
655 protected function initializeImageProcessor()
656 {
657 /** @var GraphicalFunctions $imageProcessor */
658 $imageProcessor = GeneralUtility::makeInstance(GraphicalFunctions::class);
659 $imageProcessor->init();
660 $imageProcessor->tempPath = PATH_site . 'typo3temp/';
661 $imageProcessor->dontCheckForExistingTempFile = 1;
662 $imageProcessor->filenamePrefix = 'installTool-';
663 $imageProcessor->dontCompress = 1;
664 $imageProcessor->alternativeOutputKey = 'typo3InstallTest';
665 $imageProcessor->noFramePrepended = $GLOBALS['TYPO3_CONF_VARS']['GFX']['processor_allowFrameSelection'];
666 return $imageProcessor;
667 }
668
669 /**
670 * Find out if ImageMagick or GraphicsMagick is enabled and set up
671 *
672 * @return bool TRUE if enabled and path is set
673 */
674 protected function isImageMagickEnabledAndConfigured()
675 {
676 $enabled = $GLOBALS['TYPO3_CONF_VARS']['GFX']['processor_enabled'];
677 $path = $GLOBALS['TYPO3_CONF_VARS']['GFX']['processor_path'];
678 return $enabled && $path;
679 }
680
681 /**
682 * Determine ImageMagick / GraphicsMagick version
683 *
684 * @return string Version
685 */
686 protected function determineImageMagickVersion()
687 {
688 $command = \TYPO3\CMS\Core\Utility\CommandUtility::imageMagickCommand('identify', '-version');
689 \TYPO3\CMS\Core\Utility\CommandUtility::exec($command, $result);
690 $string = $result[0];
691 list(, $version) = explode('Magick', $string);
692 list($version) = explode(' ', trim($version));
693 return trim($version);
694 }
695
696 /**
697 * Instantiate a dummy instance for $GLOBALS['TYPO3_DB'] to
698 * prevent real database calls
699 *
700 * @return void
701 */
702 protected function setUpDatabaseConnectionMock()
703 {
704 $database = GeneralUtility::makeInstance(\TYPO3\CMS\Install\Database\DatabaseConnectionMock::class);
705 $GLOBALS['TYPO3_DB'] = $database;
706 }
707 }