‪TYPO3CMS  ‪main
MetaTagGenerator.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 Psr\Http\Message\ServerRequestInterface;
29 
35 readonly class ‪MetaTagGenerator
36 {
37  public function ‪__construct(
39  protected ‪ImageService $imageService
40  ) {}
41 
45  public function ‪generate(array $params)
46  {
48  $request = $params['request'];
49  $pageRecord = $request->getAttribute('frontend.page.information')->getPageRecord();
50  if (!empty($pageRecord['description'])) {
51  $manager = $this->metaTagManagerRegistry->getManagerForProperty('description');
52  $manager->addProperty('description', $pageRecord['description']);
53  }
54 
55  if (!empty($pageRecord['og_title'])) {
56  $manager = $this->metaTagManagerRegistry->getManagerForProperty('og:title');
57  $manager->addProperty('og:title', $pageRecord['og_title']);
58  }
59 
60  if (!empty($pageRecord['og_description'])) {
61  $manager = $this->metaTagManagerRegistry->getManagerForProperty('og:description');
62  $manager->addProperty('og:description', $pageRecord['og_description']);
63  }
64 
65  if (!empty($pageRecord['og_image'])) {
66  $fileCollector = GeneralUtility::makeInstance(FileCollector::class);
67  $fileCollector->addFilesFromRelation('pages', 'og_image', $pageRecord);
68  $manager = $this->metaTagManagerRegistry->getManagerForProperty('og:image');
69 
70  $ogImages = $this->‪generateSocialImages($fileCollector->getFiles());
71  foreach ($ogImages as $ogImage) {
72  $subProperties = [];
73  $subProperties['url'] = $ogImage['url'];
74  $subProperties['width'] = $ogImage['width'];
75  $subProperties['height'] = $ogImage['height'];
76 
77  if (!empty($ogImage['alternative'])) {
78  $subProperties['alt'] = $ogImage['alternative'];
79  }
80 
81  $manager->addProperty(
82  'og:image',
83  $ogImage['url'],
84  $subProperties
85  );
86  }
87  }
88 
89  $manager = $this->metaTagManagerRegistry->getManagerForProperty('twitter:card');
90  $manager->addProperty('twitter:card', $pageRecord['twitter_card'] ?: 'summary');
91 
92  if (!empty($pageRecord['twitter_title'])) {
93  $manager = $this->metaTagManagerRegistry->getManagerForProperty('twitter:title');
94  $manager->addProperty('twitter:title', $pageRecord['twitter_title']);
95  }
96 
97  if (!empty($pageRecord['twitter_description'])) {
98  $manager = $this->metaTagManagerRegistry->getManagerForProperty('twitter:description');
99  $manager->addProperty('twitter:description', $pageRecord['twitter_description']);
100  }
101 
102  if (!empty($pageRecord['twitter_image'])) {
103  $fileCollector = GeneralUtility::makeInstance(FileCollector::class);
104  $fileCollector->addFilesFromRelation('pages', 'twitter_image', $pageRecord);
105  $manager = $this->metaTagManagerRegistry->getManagerForProperty('twitter:image');
106 
107  $twitterImages = $this->‪generateSocialImages($fileCollector->getFiles());
108  foreach ($twitterImages as $twitterImage) {
109  $subProperties = [];
110 
111  if (!empty($twitterImage['alternative'])) {
112  $subProperties['alt'] = $twitterImage['alternative'];
113  }
114 
115  $manager->addProperty(
116  'twitter:image',
117  $twitterImage['url'],
118  $subProperties
119  );
120  }
121  }
122 
123  $noIndex = ($pageRecord['no_index']) ? 'noindex' : 'index';
124  $noFollow = ($pageRecord['no_follow']) ? 'nofollow' : 'follow';
125 
126  if ($noIndex === 'noindex' || $noFollow === 'nofollow') {
127  $manager = $this->metaTagManagerRegistry->getManagerForProperty('robots');
128  $manager->addProperty('robots', implode(',', [$noIndex, $noFollow]));
129  }
130  }
131 
135  protected function ‪generateSocialImages(array $fileReferences): array
136  {
137  $socialImages = [];
138 
139  foreach ($fileReferences as $fileReference) {
140  $arguments = $fileReference->getProperties();
141  $image = $this->‪processSocialImage($fileReference);
142  $socialImages[] = [
143  'url' => $this->imageService->getImageUri($image, true),
144  'width' => floor((float)$image->getProperty('width')),
145  'height' => floor((float)$image->getProperty('height')),
146  'alternative' => $arguments['alternative'],
147  ];
148  }
149 
150  return $socialImages;
151  }
152 
153  protected function ‪processSocialImage(‪FileReference $fileReference): ‪FileInterface
154  {
155  $arguments = $fileReference->‪getProperties();
156  $cropVariantCollection = ‪CropVariantCollection::create((string)($arguments['crop'] ?? ''));
157  $cropVariantName = ($arguments['cropVariant'] ?? false) ?: 'social';
158  $cropArea = $cropVariantCollection->getCropArea($cropVariantName);
159  $crop = $cropArea->makeAbsoluteBasedOnFile($fileReference);
160 
161  $processingConfiguration = [
162  'crop' => $crop,
163  'maxWidth' => 2000,
164  ];
165 
166  // The image needs to be processed if:
167  // - the image width is greater than the defined maximum width, or
168  // - there is a cropping other than the full image (starts at 0,0 and has a width and height of 100%) defined
169  $needsProcessing = $fileReference->‪getProperty('width') > $processingConfiguration['maxWidth']
170  || !$cropArea->isEmpty();
171  if (!$needsProcessing) {
172  return $fileReference->getOriginalFile();
173  }
174 
175  return $fileReference->getOriginalFile()->process(
177  $processingConfiguration
178  );
179  }
180 }
‪TYPO3\CMS\Core\Resource\FileReference\getProperty
‪getProperty(string $key)
Definition: FileReference.php:108
‪TYPO3\CMS\Core\Imaging\ImageManipulation\CropVariantCollection\create
‪static create(string $jsonString, array $tcaConfig=[])
Definition: CropVariantCollection.php:37
‪TYPO3\CMS\Core\Resource\FileInterface
Definition: FileInterface.php:26
‪TYPO3\CMS\Core\Resource\ProcessedFile\CONTEXT_IMAGECROPSCALEMASK
‪const CONTEXT_IMAGECROPSCALEMASK
Definition: ProcessedFile.php:61
‪TYPO3\CMS\Core\MetaTag\MetaTagManagerRegistry
Definition: MetaTagManagerRegistry.php:28
‪TYPO3\CMS\Core\Resource\FileReference
Definition: FileReference.php:37
‪TYPO3\CMS\Seo\MetaTag\MetaTagGenerator
Definition: MetaTagGenerator.php:36
‪TYPO3\CMS\Seo\MetaTag
Definition: MetaTagGenerator.php:18
‪TYPO3\CMS\Frontend\Resource\FileCollector
Definition: FileCollector.php:47
‪TYPO3\CMS\Extbase\Service\ImageService
Definition: ImageService.php:38
‪TYPO3\CMS\Core\Resource\FileReference\getProperties
‪array getProperties()
Definition: FileReference.php:137
‪TYPO3\CMS\Seo\MetaTag\MetaTagGenerator\__construct
‪__construct(protected MetaTagManagerRegistry $metaTagManagerRegistry, protected ImageService $imageService)
Definition: MetaTagGenerator.php:37
‪TYPO3\CMS\Seo\MetaTag\MetaTagGenerator\processSocialImage
‪processSocialImage(FileReference $fileReference)
Definition: MetaTagGenerator.php:153
‪TYPO3\CMS\Seo\MetaTag\MetaTagGenerator\generateSocialImages
‪generateSocialImages(array $fileReferences)
Definition: MetaTagGenerator.php:135
‪TYPO3\CMS\Core\Resource\ProcessedFile
Definition: ProcessedFile.php:47
‪TYPO3\CMS\Core\Imaging\ImageManipulation\CropVariantCollection
Definition: CropVariantCollection.php:23
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Seo\MetaTag\MetaTagGenerator\generate
‪generate(array $params)
Definition: MetaTagGenerator.php:45
‪$metaTagManagerRegistry
‪$metaTagManagerRegistry
Definition: ext_localconf.php:77