2 namespace TYPO3\CMS\Install\Controller\Action\Tool;
18 use TYPO3\CMS\Install\Controller\Action;
39 $this->imageBasePath = \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath(
'install') .
'Resources/Public/Images/';
41 $actionMessages = array();
42 if (isset($this->postValues[
'set'][
'testMail'])) {
43 $actionMessages[] = $this->sendTestMail();
44 $this->view->assign(
'postAction',
'testMail');
47 if (isset($this->postValues[
'set'][
'testTrueTypeFont'])) {
48 $this->view->assign(
'trueTypeFontTested',
true);
49 $actionMessages[] = $this->createTrueTypeFontTestImage();
52 if (isset($this->postValues[
'set'][
'testConvertImageFormatsToJpg'])) {
53 $this->view->assign(
'convertImageFormatsToJpgTested',
true);
55 $actionMessages[] = $this->convertImageFormatsToJpg();
57 $actionMessages[] = $this->imageMagickDisabledMessage();
61 if (isset($this->postValues[
'set'][
'testWriteGifAndPng'])) {
62 $this->view->assign(
'writeGifAndPngTested',
true);
64 $actionMessages[] = $this->writeGifAndPng();
66 $actionMessages[] = $this->imageMagickDisabledMessage();
70 if (isset($this->postValues[
'set'][
'testScalingImages'])) {
71 $this->view->assign(
'scalingImagesTested',
true);
75 $actionMessages[] = $this->imageMagickDisabledMessage();
79 if (isset($this->postValues[
'set'][
'testCombiningImages'])) {
80 $this->view->assign(
'combiningImagesTested',
true);
84 $actionMessages[] = $this->imageMagickDisabledMessage();
88 if (isset($this->postValues[
'set'][
'testGdlib'])) {
89 $this->view->assign(
'gdlibTested',
true);
90 $actionMessages[] = $this->gdlib();
93 $this->view->assign(
'actionMessages', $actionMessages);
97 return $this->view->render();
105 protected function sendTestMail()
108 !isset($this->postValues[
'values'][
'testEmailRecipient'])
112 $message = $this->objectManager->get(\TYPO3\CMS\Install\Status\ErrorStatus::class);
113 $message->setTitle(
'Mail not sent');
114 $message->setMessage(
'Given address is not a valid email address.');
116 $recipient = $this->postValues[
'values'][
'testEmailRecipient'];
118 $mailMessage = $this->objectManager->get(\TYPO3\CMS\Core\Mail\MailMessage::class);
123 ->setBody(
'<html><body>html test content</body></html>',
'text/html')
124 ->addPart(
'TEST CONTENT')
126 $message = $this->objectManager->get(\TYPO3\CMS\Install\Status\OkStatus::class);
127 $message->setTitle(
'Test mail sent');
128 $message->setMessage(
'Recipient: ' . $recipient);
142 return !empty(
$GLOBALS[
'TYPO3_CONF_VARS'][
'MAIL'][
'defaultMailFromAddress'])
143 ?
$GLOBALS[
'TYPO3_CONF_VARS'][
'MAIL'][
'defaultMailFromAddress']
144 :
'no-reply@example.com';
156 return !empty(
$GLOBALS[
'TYPO3_CONF_VARS'][
'MAIL'][
'defaultMailFromName'])
157 ?
$GLOBALS[
'TYPO3_CONF_VARS'][
'MAIL'][
'defaultMailFromName']
158 :
'TYPO3 CMS install tool';
170 $name = !empty(
$GLOBALS[
'TYPO3_CONF_VARS'][
'SYS'][
'sitename'])
171 ?
' from site "' .
$GLOBALS[
'TYPO3_CONF_VARS'][
'SYS'][
'sitename'] .
'"'
173 return 'Test TYPO3 CMS mail delivery' . $name;
181 protected function createTrueTypeFontTestImage()
185 $image = @imagecreate(200, 50);
186 imagecolorallocate($image, 255, 255, 55);
187 $textColor = imagecolorallocate($image, 233, 14, 91);
195 \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath(
'install') .
'Resources/Private/Font/vera.ttf',
199 imagegif($image, $outputFile);
202 $message = $this->objectManager->get(\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.'
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';
215 $this->view->assign(
'testResults', $testResults);
224 protected function convertImageFormatsToJpg()
227 $imageProcessor = $this->initializeImageProcessor();
230 $inputFormatsToTest = array(
'jpg',
'gif',
'png',
'tif',
'bmp',
'pcx',
'tga',
'pdf',
'ai');
232 $testResults = array();
233 foreach ($inputFormatsToTest as $formatToTest) {
237 $message = $this->objectManager->get(\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;
242 $imageProcessor->IM_commands = array();
243 $inputFile = $this->imageBasePath .
'TestInput/Test.' . $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;
252 $result[
'error'] = $this->imageGenerationFailedMessage();
255 $testResults[] = $result;
258 $this->view->assign(
'testResults', $testResults);
267 protected function writeGifAndPng()
270 $imageProcessor = $this->initializeImageProcessor();
273 $testResults = array(
279 $inputFile = $this->imageBasePath .
'TestInput/Test.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']) {
290 $message = $this->objectManager->get(\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
298 $message = $this->objectManager->get(\TYPO3\CMS\Install\Status\InfoStatus::class);
299 $message->setTitle(
'Gif compression not enabled by [GFX][gif_compress]');
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;
307 $testResults[
'gif'][
'error'] = $this->imageGenerationFailedMessage();
311 $inputFile = $this->imageBasePath .
'TestInput/Test.png';
312 $imageProcessor->IM_commands = array();
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;
321 $testResults[
'png'][
'error'] = $this->imageGenerationFailedMessage();
324 $this->view->assign(
'testResults', $testResults);
336 $imageProcessor = $this->initializeImageProcessor();
339 $testResults = array(
340 'gif-to-gif' => array(),
341 'png-to-png' => array(),
342 'gif-to-jpg' => array(),
345 $imageProcessor->IM_commands = array();
346 $inputFile = $this->imageBasePath .
'TestInput/Transparent.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;
355 $testResults[
'gif-to-gif'][
'error'] = $this->imageGenerationFailedMessage();
358 $imageProcessor->IM_commands = array();
359 $inputFile = $this->imageBasePath .
'TestInput/Transparent.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;
368 $testResults[
'png-to-png'][
'error'] = $this->imageGenerationFailedMessage();
371 $imageProcessor->IM_commands = array();
372 $inputFile = $this->imageBasePath .
'TestInput/Transparent.gif';
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;
381 $testResults[
'gif-to-jpg'][
'error'] = $this->imageGenerationFailedMessage();
384 $this->view->assign(
'testResults', $testResults);
396 $imageProcessor = $this->initializeImageProcessor();
399 $testResults = array(
400 'combine1' => array(),
401 'combine2' => array(),
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
409 $imageProcessor->combineExec($inputFile, $overlayFile, $maskFile, $resultFile,
true);
410 $result = $imageProcessor->getImageDimensions($resultFile);
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;
417 $testResults[
'combine1'][
'error'] = $this->imageGenerationFailedMessage();
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
426 $imageProcessor->combineExec($inputFile, $overlayFile, $maskFile, $resultFile,
true);
427 $result = $imageProcessor->getImageDimensions($resultFile);
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;
434 $testResults[
'combine2'][
'error'] = $this->imageGenerationFailedMessage();
437 $this->view->assign(
'testResults', $testResults);
446 protected function gdlib()
449 $imageProcessor = $this->initializeImageProcessor();
451 $gifOrPng = $imageProcessor->gifExtension;
452 $testResults = array();
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);
461 'dimensions' =>
'10,50,150,36',
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;
474 $imageProcessor->IM_commands = array();
475 $inputFile = $this->imageBasePath .
'TestInput/Test.' . $gifOrPng;
476 $image = $imageProcessor->imageCreateFromFile($inputFile);
477 $workArea = array(0, 0, 170, 136);
479 'dimensions' =>
'10,50,150,36',
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;
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);
501 'text' =>
'HELLO WORLD',
502 'fontColor' =>
'#003366',
504 'fontFile' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath(
'install') .
'Resources/Private/Font/vera.ttf',
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;
518 $testResults[
'niceText'] = array();
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;
532 $message = $this->objectManager->get(\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\'.'
540 $testResults[
'niceText'][
'message'] = $message;
542 $result[
'niceText'][
'error'] = $this->imageGenerationFailedMessage();
546 $testResults[
'shadow'] = array();
549 $conf[
'offset'] =
'17,90';
550 $conf[
'niceText'] = 1;
551 $conf[
'shadow.'] = array(
553 'blur' => $imageProcessor->V5_EFFECTS ?
'20' :
'90',
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;
568 $message = $this->objectManager->get(\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][im_v5effects].'
575 $testResults[
'shadow'][
'message'] = $message;
577 $result[
'shadow'][
'error'] = $this->imageGenerationFailedMessage();
580 $this->view->assign(
'testResults', $testResults);
590 protected function imageTestDoneMessage($parseTime = 0)
593 $message = $this->objectManager->get(\TYPO3\CMS\Install\Status\OkStatus::class);
594 $message->setTitle(
'Executed image tests');
595 $message->setMessage(
'Parse time: ' . $parseTime .
' ms');
604 protected function imageMagickDisabledMessage()
607 $message = $this->objectManager->get(\TYPO3\CMS\Install\Status\ErrorStatus::class);
608 $message->setTitle(
'Tests not executed');
609 $message->setMessage(
'ImageMagick / GraphicsMagick handling is disabled or not configured correctly.');
618 protected function imageGenerationFailedMessage()
621 $message = $this->objectManager->get(\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\'][\'im_path\'] and [\'GFX\'][\'im_path_lzw\'] and ensure Ghostscript is installed on your server.'
639 $result[
'imageMagickOrGraphicsMagick'] =
$GLOBALS[
'TYPO3_CONF_VARS'][
'GFX'][
'im_version_5'] ===
'gm' ?
'gm' :
'im';
640 $result[
'imageMagickEnabled'] =
$GLOBALS[
'TYPO3_CONF_VARS'][
'GFX'][
'im'];
641 $result[
'imageMagickPath'] =
$GLOBALS[
'TYPO3_CONF_VARS'][
'GFX'][
'im_path'];
643 $result[
'imageMagick5Effects'] =
$GLOBALS[
'TYPO3_CONF_VARS'][
'GFX'][
'im_v5effects'];
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'];
655 protected function initializeImageProcessor()
658 $imageProcessor = $this->objectManager->get(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'][
'im_noFramePrepended'];
666 return $imageProcessor;
676 $enabled =
$GLOBALS[
'TYPO3_CONF_VARS'][
'GFX'][
'im'];
677 $path =
$GLOBALS[
'TYPO3_CONF_VARS'][
'GFX'][
'im_path'];
678 return $enabled && $path;
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);
704 $database = $this->objectManager->get(\TYPO3\CMS\Install\Database\DatabaseConnectionMock::class);