• 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

13.73
/Classes/Service/LocaleService.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;
13

14
use TYPO3\CMS\Core\Localization\Locales;
15
use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
16
use TYPO3\CMS\Core\Utility\GeneralUtility;
17
use YoastSeoForTypo3\YoastSeo\Traits\BackendUserTrait;
18
use YoastSeoForTypo3\YoastSeo\Traits\LanguageServiceTrait;
19

20
class LocaleService
21
{
22
    use BackendUserTrait;
23
    use LanguageServiceTrait;
24

25
    protected const APP_TRANSLATION_FILE_PATTERN = 'EXT:yoast_seo/Resources/Private/Language/wordpress-seo-%s.json';
26

27
    public function __construct(
28
        protected Locales $locales,
29
        protected SiteService $siteService
30
    ) {}
6✔
31

32
    /**
33
     * @return array<string, array<string, string>>
34
     */
35
    public function getTranslations(): array
36
    {
37
        $interfaceLocale = $this->getInterfaceLocale();
×
38

39
        if ($interfaceLocale === null) {
×
40
            // Fall back to English if no suitable locale could be resolved to prevent missing translations
41
            $interfaceLocale = 'en_GB';
×
42
        }
43

44
        $translationFilePath = GeneralUtility::getFileAbsFileName(
×
45
            sprintf(static::APP_TRANSLATION_FILE_PATTERN, $interfaceLocale)
×
46
        );
×
47

48
        if ($translationFilePath === '' || !file_exists($translationFilePath)) {
×
49
            return [];
×
50
        }
51

52
        if ($jsonContents = file_get_contents($translationFilePath)) {
×
53
            return json_decode($jsonContents, true);
×
54
        }
55

56
        return [];
×
57
    }
58

59
    /**
60
     * Try to resolve a supported locale based on the user settings
61
     * take the configured locale dependencies into account
62
     * so if the TYPO3 interface is tailored for a specific dialect
63
     * the local of a parent language might be used
64
     *
65
     * @return string|null
66
     */
67
    protected function getInterfaceLocale(): ?string
68
    {
69
        $locale = null;
×
70

71
        $translationConfiguration = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['yoast_seo']['translations'] ?? [
×
72
            'availableLocales' => [],
×
73
            'languageKeyToLocaleMapping' => [],
×
74
        ];
75

76
        $userLanguage = $this->getBackendUser()->user['lang'] ?? '';
×
77
        if (empty($userLanguage) || $userLanguage === 'default') {
×
78
            $userLanguage = 'en';
×
79
        }
80

81
        $languageChain = $this->locales->getLocaleDependencies($userLanguage);
×
82
        array_unshift($languageChain, $userLanguage);
×
83

84
        // try to find a matching locale available for this plugins UI
85
        // take configured locale dependencies into account
NEW
86
        $suitableLocales = array_intersect(
×
NEW
87
            $languageChain,
×
NEW
88
            $translationConfiguration['availableLocales']
×
NEW
89
        );
×
NEW
90
        if (count($suitableLocales) > 0) {
×
NEW
91
            $locale = array_shift($suitableLocales);
×
92
        }
93

94
        // if a locale couldn't be resolved try if an entry of the
95
        // language dependency chain matches legacy mapping
NEW
96
        if ($locale === null) {
×
97
            $suitableLanguageKeys = array_intersect(
×
98
                $languageChain,
×
99
                array_flip(
×
100
                    $translationConfiguration['languageKeyToLocaleMapping']
×
101
                )
×
102
            );
×
103
            if (count($suitableLanguageKeys) > 0) {
×
104
                $locale = $translationConfiguration['languageKeyToLocaleMapping'][array_shift($suitableLanguageKeys)];
×
105
            }
106
        }
107

108
        return $locale;
×
109
    }
110

111
    public function getLocale(int $pageId, int &$languageId): ?string
112
    {
NEW
113
        $site = $this->siteService->getSiteByPageId($pageId);
×
NEW
114
        if ($site === null) {
×
UNCOV
115
            return null;
×
116
        }
117

NEW
118
        if ($languageId === -1) {
×
NEW
119
            $languageId = $site->getDefaultLanguage()->getLanguageId();
×
NEW
120
            return $this->getLanguageCode($site->getDefaultLanguage());
×
121
        }
NEW
122
        return $this->getLanguageCode($site->getLanguageById($languageId));
×
123
    }
124

125
    protected function getLanguageCode(SiteLanguage $siteLanguage): string
126
    {
UNCOV
127
        return $siteLanguage->getLocale()->getLanguageCode();
×
128
    }
129

130
    /**
131
     * @param array<string, mixed> $data
132
     */
133
    public function getLanguageIdFromData(array $data): int
134
    {
135
        if (!isset($data['databaseRow']['sys_language_uid'])) {
4✔
136
            return 0;
2✔
137
        }
138

139
        if (is_array($data['databaseRow']['sys_language_uid']) && count($data['databaseRow']['sys_language_uid']) > 0) {
2✔
140
            return (int)current($data['databaseRow']['sys_language_uid']);
1✔
141
        }
142
        return (int)$data['databaseRow']['sys_language_uid'];
1✔
143
    }
144

145
    /**
146
     * @return array<int, string>
147
     */
148
    public function getSupportedLanguages(): array
149
    {
150
        return $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['yoast_seo']['supportedLanguages'] ?? [];
2✔
151
    }
152
}
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