‪TYPO3CMS  11.5
MetaTagGeneratorTest.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
20 use org\bovigo\vfs\vfsStream;
21 use org\bovigo\vfs\vfsStreamDirectory;
33 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
34 
35 class ‪MetaTagGeneratorTest extends FunctionalTestCase
36 {
39  private vfsStreamDirectory ‪$temporaryFileSystem;
40  protected ‪$coreExtensionsToLoad = ['seo'];
41 
42  protected function ‪setUp(): void
43  {
44  parent::setUp();
45  // functional tests use GraphicMagick per default, resolve the corresponding path in current OS
46  ‪$GLOBALS['TYPO3_CONF_VARS']['GFX']['processor_path'] = $this->‪determineGraphicMagickBinaryPath();
47  $this->subject = GeneralUtility::makeInstance(MetaTagGenerator::class);
48  $this->defaultStorage = GeneralUtility::makeInstance(StorageRepository::class)->getDefaultStorage();
49  $this->temporaryFileSystem = vfsStream::setup();
50  }
51 
52  public static function ‪socialImageIsProcessedDataProvider(): \Generator
53  {
54  // having a valid `crop` definition, images are only process if there's a necessity
55  yield 'social: 600x600 enforced ratio' => [
56  true,
57  ['width' => 600, 'height' => 600],
58  ['width' => 600, 'height' => 315],
59  ProcessedFile::class,
60  ];
61  yield 'social: 600x315 kept as is' => [
62  true,
63  ['width' => 600, 'height' => 315],
64  ['width' => 600, 'height' => 315],
65  File::class,
66  ];
67  yield 'social: 1200x630 kept as is' => [
68  true,
69  ['width' => 1200, 'height' => 630],
70  ['width' => 1200, 'height' => 630],
71  File::class,
72  ];
73  yield 'social: 2400x1260 limited to maxWidth, kept ratio' => [
74  true,
75  ['width' => 2400, 'height' => 1260],
76  ['width' => 2000, 'height' => 1050],
77  ProcessedFile::class,
78  ];
79  yield 'social: 3000x3000 limited to maxWidth, enforced ratio' => [
80  true,
81  ['width' => 3000, 'height' => 3000],
82  ['width' => 2000, 'height' => 1050],
83  ProcessedFile::class,
84  ];
85  yield 'social: 600x300 enforced ratio (no up-scaling)' => [
86  true,
87  ['width' => 600, 'height' => 3000],
88  ['width' => 600, 'height' => 315],
89  ProcessedFile::class,
90  ];
91  yield 'social: 3000x600 enforced ratio (no up-scaling)' => [
92  true,
93  ['width' => 3000, 'height' => 600],
94  ['width' => 1142, 'height' => 600],
95  ProcessedFile::class,
96  ];
97 
98  // in case `crop` is not defined, no target ratio is defined for these images
99  // (data created prior to https://review.typo3.org/c/Packages/TYPO3.CMS/+/58774/ in v9.5.1 behaves like this)
100  yield 'empty crop: 600x600 kept as is' => [
101  false,
102  ['width' => 600, 'height' => 600],
103  ['width' => 600, 'height' => 600],
104  File::class,
105  ];
106  yield 'empty crop: 600x315 kept as is' => [
107  false,
108  ['width' => 600, 'height' => 315],
109  ['width' => 600, 'height' => 315],
110  File::class,
111  ];
112  yield 'empty crop: 1200x630 kept as is' => [
113  false,
114  ['width' => 1200, 'height' => 630],
115  ['width' => 1200, 'height' => 630],
116  File::class,
117  ];
118  yield 'empty crop: 2400x1260 limited to maxWidth' => [
119  false,
120  ['width' => 2400, 'height' => 1260],
121  ['width' => 2000, 'height' => 1050],
122  ProcessedFile::class,
123  ];
124  yield 'empty crop: 3000x3000 limited to maxWidth' => [
125  false,
126  ['width' => 3000, 'height' => 3000],
127  ['width' => 2000, 'height' => 2000],
128  ProcessedFile::class,
129  ];
130  yield 'empty crop: 600x300 kept as is' => [
131  false,
132  ['width' => 600, 'height' => 3000],
133  ['width' => 600, 'height' => 3000],
134  File::class,
135  ];
136  yield 'empty crop: 3000x600 limited to maxWidth' => [
137  false,
138  ['width' => 3000, 'height' => 600],
139  ['width' => 2000, 'height' => 400],
140  ProcessedFile::class,
141  ];
142  }
143 
150  public function ‪socialImageIsProcessed(bool $hasCrop, array $imageDimension, array $expectedDimension, string $expectedClassName): void
151  {
152  $fileName = sprintf('test_%dx%d.png', $imageDimension['width'], $imageDimension['height']);
153  $folder = $this->defaultStorage->getFolder('/');
154  // drop file if it exists
155  $file = $folder->getFile($fileName);
156  if ($file !== null) {
157  $file->delete();
158  }
159  // create new file, fill it dummy PNG data for given dimension
161  $file = $this->defaultStorage->createFile($fileName, $folder);
162  $file->setContents($this->‪createImagePngContent($imageDimension['width'], $imageDimension['height']));
163  // temporary file reference to an actual existing file
164  $fileReferenceProperties = [
165  'uid_local' => $file->getUid(),
166  'uid_foreign' => 0,
167  'uid' => 0,
168  'crop' => '',
169  ];
170  if ($hasCrop) {
171  $cropVariantCollection = ‪CropVariantCollection::create('', $this->‪resolveCropVariantsConfiguration());
172  $cropVariantCollection = $cropVariantCollection->applyRatioRestrictionToSelectedCropArea($file);
173  $fileReferenceProperties['crop'] = (string)$cropVariantCollection;
174  }
175  $fileReference = GeneralUtility::makeInstance(ResourceFactory::class)
176  ->createFileReferenceObject($fileReferenceProperties);
177  // invoke processing of social image
178  $reflectionSubject = new \ReflectionObject($this->subject);
179  $reflectionMethod = $reflectionSubject->getMethod('processSocialImage');
180  $reflectionMethod->setAccessible(true); // no-op in PHP 8.1
182  $processedSocialImage = $reflectionMethod->invoke($this->subject, $fileReference);
183 
184  self::assertSame($expectedDimension, [
185  'width' => (int)$processedSocialImage->getProperty('width'),
186  'height' => (int)$processedSocialImage->getProperty('height'),
187  ]);
188  self::assertInstanceOf($expectedClassName, $processedSocialImage);
189  }
190 
191  private function ‪createImagePngContent(int $width, int $height): string
192  {
193  $filePath = $this->temporaryFileSystem->url() . '/image.png';
194  $gdImage = imagecreatetruecolor($width, $height);
195  imagepng($gdImage, $filePath);
196  return file_get_contents($filePath);
197  }
198 
199  private function ‪determineGraphicMagickBinaryPath(): string
200  {
201  $values = GeneralUtility::makeInstance(GraphicsMagickPreset::class)->getConfigurationValues();
202  return $values['GFX/processor_path'] ?? ‪$GLOBALS['TYPO3_CONF_VARS']['GFX']['processor_path'];
203  }
204 
208  private function ‪resolveCropVariantsConfiguration(): array
209  {
210  $config = ‪$GLOBALS['TCA']['pages']['columns']['og_image']['config']['overrideChildTca']['columns']['crop']['config'];
211  $cropVariants = [];
212  foreach ($config['cropVariants'] as $id => $cropVariant) {
213  // Filter allowed aspect ratios
214  $cropVariant['allowedAspectRatios'] = array_filter(
215  $cropVariant['allowedAspectRatios'] ?? [],
216  static fn($aspectRatio) => empty($aspectRatio['disabled'])
217  );
218  // Ignore disabled crop variants
219  if (!empty($cropVariant['disabled'])) {
220  continue;
221  }
222  // Enforce a crop area (default is full image)
223  if (empty($cropVariant['cropArea'])) {
224  $cropVariant['cropArea'] = ‪Area::createEmpty()->‪asArray();
225  }
226  $cropVariants[$id] = $cropVariant;
227  }
228  return $cropVariants;
229  }
230 }
‪TYPO3\CMS\Seo\Tests\Functional\MetaTag\MetaTagGeneratorTest
Definition: MetaTagGeneratorTest.php:36
‪TYPO3\CMS\Core\Resource\FileInterface
Definition: FileInterface.php:22
‪TYPO3\CMS\Seo\Tests\Functional\MetaTag\MetaTagGeneratorTest\socialImageIsProcessed
‪socialImageIsProcessed(bool $hasCrop, array $imageDimension, array $expectedDimension, string $expectedClassName)
Definition: MetaTagGeneratorTest.php:150
‪TYPO3\CMS\Core\Imaging\ImageManipulation\Area
Definition: Area.php:23
‪TYPO3\CMS\Seo\Tests\Functional\MetaTag\MetaTagGeneratorTest\$subject
‪MetaTagGenerator $subject
Definition: MetaTagGeneratorTest.php:37
‪TYPO3\CMS\Seo\Tests\Functional\MetaTag
Definition: MetaTagGeneratorTest.php:18
‪TYPO3\CMS\Seo\Tests\Functional\MetaTag\MetaTagGeneratorTest\$temporaryFileSystem
‪vfsStreamDirectory $temporaryFileSystem
Definition: MetaTagGeneratorTest.php:39
‪TYPO3\CMS\Seo\MetaTag\MetaTagGenerator
Definition: MetaTagGenerator.php:35
‪TYPO3\CMS\Seo\Tests\Functional\MetaTag\MetaTagGeneratorTest\setUp
‪setUp()
Definition: MetaTagGeneratorTest.php:42
‪TYPO3\CMS\Seo\Tests\Functional\MetaTag\MetaTagGeneratorTest\$defaultStorage
‪ResourceStorage $defaultStorage
Definition: MetaTagGeneratorTest.php:38
‪TYPO3\CMS\Seo\Tests\Functional\MetaTag\MetaTagGeneratorTest\$coreExtensionsToLoad
‪$coreExtensionsToLoad
Definition: MetaTagGeneratorTest.php:40
‪TYPO3\CMS\Install\Configuration\Image\GraphicsMagickPreset
Definition: GraphicsMagickPreset.php:26
‪TYPO3\CMS\Core\Resource\ResourceFactory
Definition: ResourceFactory.php:41
‪TYPO3\CMS\Core\Resource\StorageRepository
Definition: StorageRepository.php:38
‪TYPO3\CMS\Core\Resource\File
Definition: File.php:24
‪TYPO3\CMS\Seo\Tests\Functional\MetaTag\MetaTagGeneratorTest\socialImageIsProcessedDataProvider
‪static socialImageIsProcessedDataProvider()
Definition: MetaTagGeneratorTest.php:52
‪TYPO3\CMS\Seo\Tests\Functional\MetaTag\MetaTagGeneratorTest\resolveCropVariantsConfiguration
‪resolveCropVariantsConfiguration()
Definition: MetaTagGeneratorTest.php:208
‪TYPO3\CMS\Core\Resource\ProcessedFile
Definition: ProcessedFile.php:45
‪TYPO3\CMS\Core\Resource\ResourceStorage
Definition: ResourceStorage.php:125
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Core\Imaging\ImageManipulation\CropVariantCollection
Definition: CropVariantCollection.php:23
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:50
‪TYPO3\CMS\Core\Imaging\ImageManipulation\Area\asArray
‪array asArray()
Definition: Area.php:119
‪TYPO3\CMS\Seo\Tests\Functional\MetaTag\MetaTagGeneratorTest\createImagePngContent
‪createImagePngContent(int $width, int $height)
Definition: MetaTagGeneratorTest.php:191
‪TYPO3\CMS\Seo\Tests\Functional\MetaTag\MetaTagGeneratorTest\determineGraphicMagickBinaryPath
‪determineGraphicMagickBinaryPath()
Definition: MetaTagGeneratorTest.php:199
‪TYPO3\CMS\Core\Imaging\ImageManipulation\CropVariantCollection\create
‪static CropVariantCollection create(string $jsonString, array $tcaConfig=[])
Definition: CropVariantCollection.php:42
‪TYPO3\CMS\Core\Imaging\ImageManipulation\Area\createEmpty
‪static Area createEmpty()
Definition: Area.php:90