• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Yoast / Yoast-SEO-for-TYPO3 / 24723291290

21 Apr 2026 12:50PM UTC coverage: 10.457% (+9.2%) from 1.275%
24723291290

push

github

web-flow
Merge pull request #632 from Yoast/feature/yoast-v12

[FEATURE] Version 12.0.0, added v14 support, removed v11 support including php8.0 and php8.1, rewrote backend javascript functionality to typescript and webcomponents

40 of 806 new or added lines in 69 files covered. (4.96%)

40 existing lines in 23 files now uncovered.

284 of 2716 relevant lines covered (10.46%)

0.29 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/Classes/Service/SnippetPreview/SnippetPreviewRequestDataGenerator.php
1
<?php
2

3
/**
4
 * This file is part of the "yoast_seo" extension for TYPO3 CMS.
5
 *
6
 * For the full copyright and license information, please read the
7
 * LICENSE.txt file that was distributed with this source code.
8
 */
9

10
declare(strict_types=1);
11

12
namespace YoastSeoForTypo3\YoastSeo\Service\SnippetPreview;
13

14
use TYPO3\CMS\Backend\Utility\BackendUtility;
15
use TYPO3\CMS\Core\Domain\Repository\PageRepository;
16
use TYPO3\CMS\Core\Utility\GeneralUtility;
17
use TYPO3\CMS\Frontend\Page\CacheHashCalculator;
18
use YoastSeoForTypo3\YoastSeo\Constants\TableNames;
19
use YoastSeoForTypo3\YoastSeo\Dto\RequestData;
20
use YoastSeoForTypo3\YoastSeo\Service\UrlService;
21

22
class SnippetPreviewRequestDataGenerator
23
{
24
    public function __construct(
25
        protected CacheHashCalculator $cacheHashCalculator,
26
        protected UrlService $urlService
NEW
27
    ) {}
×
28

29
    /**
30
     * @param array<string, mixed> $data
31
     */
32
    public function getRequestData(array $data): RequestData
33
    {
NEW
34
        $currentPageId = (int)$data['effectivePid'];
×
NEW
35
        $recordId = (int)$data['vanillaUid'];
×
NEW
36
        $tableName = $data['tableName'];
×
37

NEW
38
        $record = $this->getRecordArray($tableName, $recordId);
×
NEW
39
        $previewConfiguration = $this->getPreviewConfiguration($currentPageId, $tableName);
×
40

NEW
41
        $previewPageId = $this->getPreviewPageId($currentPageId, $previewConfiguration);
×
NEW
42
        $languageId = $this->resolveLanguageId($tableName, $record);
×
43

NEW
44
        $recordId = $this->resolveRecordIdForLanguageHandling(
×
NEW
45
            $tableName,
×
NEW
46
            $record,
×
NEW
47
            $previewConfiguration,
×
NEW
48
            $recordId,
×
NEW
49
            $previewPageId
×
NEW
50
        );
×
51

NEW
52
        $linkParameters = $this->buildLinkParameters($record, $recordId, $previewConfiguration);
×
53

NEW
54
        if (!empty($previewConfiguration['useCacheHash'])) {
×
NEW
55
            $this->addCacheHash($linkParameters, $previewPageId);
×
56
        }
57

NEW
58
        $additionalParams = GeneralUtility::implodeArrayForUrl('', $linkParameters, '', false, true);
×
59

NEW
60
        return new RequestData($previewPageId, $languageId, $additionalParams);
×
61
    }
62

63
    /**
64
     * @param array<string, mixed> $record
65
     */
66
    protected function resolveLanguageId(string $tableName, array $record): int
67
    {
NEW
68
        $languageField = $GLOBALS['TCA'][$tableName]['ctrl']['languageField'] ?? '';
×
NEW
69
        if ($languageField === '' || empty($record[$languageField])) {
×
NEW
70
            return 0;
×
71
        }
72

NEW
73
        return $record[$languageField] > -1 ? (int)$record[$languageField] : 0;
×
74
    }
75

76
    /**
77
     * @param array<string, mixed> $record
78
     * @param array<string, mixed> $config
79
     */
80
    protected function resolveRecordIdForLanguageHandling(
81
        string $tableName,
82
        array $record,
83
        array $config,
84
        int $recordId,
85
        int &$previewPageId
86
    ): int {
NEW
87
        $languageField = $GLOBALS['TCA'][$tableName]['ctrl']['languageField'] ?? '';
×
NEW
88
        if (!$languageField || empty($record[$languageField])) {
×
NEW
89
            return $recordId;
×
90
        }
91

NEW
92
        $pointerField = $GLOBALS['TCA'][$tableName]['ctrl']['transOrigPointerField'] ?? '';
×
NEW
93
        if (!$pointerField || empty($record[$pointerField])) {
×
NEW
94
            return $recordId;
×
95
        }
96

97
        // Use parent record if configured
98
        if (
NEW
99
            isset($config['useDefaultLanguageRecord']) &&
×
NEW
100
            !$config['useDefaultLanguageRecord']
×
101
        ) {
NEW
102
            $recordId = (int)$record[$pointerField];
×
103
        }
104

105
        // Special case for pages
NEW
106
        if ($tableName === TableNames::PAGES) {
×
NEW
107
            $previewPageId = (int)$record[$pointerField];
×
108
        }
109

NEW
110
        return $recordId;
×
111
    }
112

113
    /**
114
     * @param array<string, mixed> $record
115
     * @param array<string, mixed> $config
116
     * @return array<int|string, mixed>
117
     */
118
    protected function buildLinkParameters(array $record, int $recordId, array $config): array
119
    {
NEW
120
        $params = [];
×
121

NEW
122
        if (!empty($config['fieldToParameterMap.'])) {
×
NEW
123
            foreach ($config['fieldToParameterMap.'] as $field => $parameterName) {
×
NEW
124
                $value = $field === 'uid' ? $recordId : ($record[$field] ?? '');
×
NEW
125
                $params[$parameterName] = $value;
×
126
            }
127
        }
128

NEW
129
        if (!empty($config['additionalGetParameters.'])) {
×
NEW
130
            $additional = [];
×
NEW
131
            $this->parseAdditionalGetParameters($additional, $config['additionalGetParameters.']);
×
NEW
132
            $params = array_replace($params, $additional);
×
133
        }
134

NEW
135
        return $params;
×
136
    }
137

138
    /**
139
     * @param array<int|string, mixed> $params
140
     */
141
    protected function addCacheHash(array &$params, int $previewPageId): void
142
    {
NEW
143
        $queryString = GeneralUtility::implodeArrayForUrl(
×
NEW
144
            '',
×
NEW
145
            array_merge($params, ['id' => $previewPageId])
×
NEW
146
        );
×
147

NEW
148
        $cacheHashParams = $this->cacheHashCalculator->getRelevantParameters($queryString);
×
NEW
149
        $params['cHash'] = $this->cacheHashCalculator->calculateCacheHash($cacheHashParams);
×
150
    }
151

152
    /**
153
     * @param array<string, mixed> $previewConfiguration
154
     */
155
    protected function getPreviewPageId(int $currentPageId, array $previewConfiguration): int
156
    {
NEW
157
        $configured = (int)($previewConfiguration['previewPageId'] ?? 0);
×
NEW
158
        if ($configured > 0) {
×
NEW
159
            return $configured;
×
160
        }
161

NEW
162
        $rootLine = BackendUtility::BEgetRootLine($currentPageId);
×
NEW
163
        $currentPage = reset($rootLine);
×
164

NEW
165
        if ((int)$currentPage['doktype'] <= PageRepository::DOKTYPE_SPACER) {
×
NEW
166
            return $currentPageId;
×
167
        }
168

NEW
169
        foreach ($rootLine as $page) {
×
NEW
170
            if (!empty($page['is_siteroot'])) {
×
NEW
171
                return (int)$page['uid'];
×
172
            }
173
        }
174

NEW
175
        return $currentPageId;
×
176
    }
177

178
    /**
179
     * @return array<string, mixed>
180
     */
181
    protected function getRecordArray(string $tableName, int $recordId): array
182
    {
NEW
183
        return BackendUtility::getRecord($tableName, $recordId) ?? [];
×
184
    }
185

186
    /**
187
     * @return array<string, mixed>
188
     */
189
    protected function getPreviewConfiguration(int $currentPageId, string $tableName): array
190
    {
NEW
191
        $pageTsConfig = BackendUtility::getPagesTSconfig($currentPageId);
×
NEW
192
        return $pageTsConfig['TCEMAIN.']['preview.'][$tableName . '.'] ?? [];
×
193
    }
194

195
    /**
196
     * Migrates a set of (possibly nested) GET parameters in TypoScript syntax to a
197
     * plain array
198
     *
199
     * This basically removes the trailing dots of sub-array keys in TypoScript.
200
     * The result can be used to create a query string with
201
     * GeneralUtility::implodeArrayForUrl().
202
     *
203
     * @param array<string, mixed> $parameters Should be an empty array by default
204
     * @param array<string, mixed> $typoScript The TypoScript configuration
205
     */
206
    protected function parseAdditionalGetParameters(
207
        array &$parameters,
208
        array $typoScript
209
    ): void {
NEW
210
        foreach ($typoScript as $key => $value) {
×
NEW
211
            if (is_array($value)) {
×
NEW
212
                $key = rtrim($key, '.');
×
NEW
213
                $parameters[$key] = [];
×
NEW
214
                $this->parseAdditionalGetParameters($parameters[$key], $value);
×
215
            } else {
NEW
216
                $parameters[$key] = $value;
×
217
            }
218
        }
219
    }
220
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc