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

Yoast / Yoast-SEO-for-TYPO3 / 21521134747

30 Jan 2026 03:30PM UTC coverage: 0.866% (-0.4%) from 1.275%
21521134747

push

github

RinyVT
[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

0 of 550 new or added lines in 53 files covered. (0.0%)

33 existing lines in 21 files now uncovered.

23 of 2657 relevant lines covered (0.87%)

0.03 hits per line

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

0.0
/Classes/Service/ProminentWordsService.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\Database\Connection;
15
use TYPO3\CMS\Core\Database\ConnectionPool;
16
use TYPO3\CMS\Core\Database\Query\QueryBuilder;
17

18
class ProminentWordsService
19
{
20
    protected const PROMINENT_WORDS_TABLE = 'tx_yoastseo_prominent_word';
21

22
    protected int $uid;
23
    protected int $pid;
24
    protected string $table;
25
    protected int $languageId;
26

27
    public function __construct(
28
        protected ConnectionPool $connectionPool,
29
        protected SiteService $siteService
UNCOV
30
    ) {}
×
31

32
    /**
33
     * @param array<string, int|string> $prominentWords
34
     */
35
    public function saveProminentWords(
36
        int $uid,
37
        ?int $pid,
38
        string $table,
39
        int $languageId,
40
        array $prominentWords
41
    ): void {
42
        $this->uid = $uid;
×
43
        $this->pid = $pid ?? $this->getPidForRecord($uid, $table);
×
44
        $this->table = $table;
×
45
        $this->languageId = $languageId;
×
46

47
        $wordsToDelete = [];
×
48

49
        $oldWords = $this->getOldWords();
×
50
        foreach ($oldWords as $oldWord) {
×
51
            if (!isset($prominentWords[$oldWord['stem']])) {
×
52
                $wordsToDelete[] = $oldWord['uid'];
×
53
                continue;
×
54
            }
55

56
            $this->updateIfWeightHasChanged($oldWord, (int)$prominentWords[$oldWord['stem']]);
×
57
            unset($prominentWords[$oldWord['stem']]);
×
58
        }
59

60
        $this->deleteProminentWords($wordsToDelete);
×
61
        $this->createNewWords($prominentWords);
×
62
    }
63

64
    /**
65
     * @param array{uid: int, weight: int} $oldWord
66
     */
67
    protected function updateIfWeightHasChanged(array $oldWord, int $weight): void
68
    {
69
        if ((int)$oldWord['weight'] === $weight) {
×
70
            return;
×
71
        }
72
        $queryBuilder = $this->getQueryBuilder();
×
73
        $queryBuilder->update(self::PROMINENT_WORDS_TABLE)
×
74
            ->set('weight', $weight)
×
75
            ->where(
×
76
                $queryBuilder->expr()->eq('uid', $oldWord['uid'])
×
77
            )
×
78
            ->setMaxResults(1)
×
79
            ->executeStatement();
×
80
    }
81

82
    /**
83
     * @param int[] $wordsToDelete
84
     */
85
    protected function deleteProminentWords(array $wordsToDelete): void
86
    {
87
        if ($wordsToDelete === []) {
×
88
            return;
×
89
        }
90

91
        $queryBuilder = $this->getQueryBuilder();
×
92
        $queryBuilder->delete(self::PROMINENT_WORDS_TABLE)
×
93
            ->where(
×
94
                $queryBuilder->expr()->in(
×
95
                    'uid',
×
96
                    $queryBuilder->createNamedParameter($wordsToDelete, Connection::PARAM_INT_ARRAY)
×
97
                )
×
98
            )
×
99
            ->executeStatement();
×
100
    }
101

102
    /**
103
     * @param array<string, int|string> $prominentWords
104
     */
105
    protected function createNewWords(array $prominentWords): void
106
    {
107
        $site = $this->getSiteRootPageId();
×
108
        foreach ($prominentWords as $word => $weight) {
×
109
            $data = [
×
110
                'pid' => $this->table === 'pages' ? $this->uid : $this->pid,
×
111
                'sys_language_uid' => $this->languageId,
×
112
                'uid_foreign' => $this->uid,
×
113
                'site' => $site,
×
114
                'tablenames' => $this->table,
×
115
                'stem' => $word,
×
116
                'weight' => (int)$weight,
×
117
            ];
×
118
            $this->connectionPool->getConnectionForTable(self::PROMINENT_WORDS_TABLE)
×
119
                ->insert(self::PROMINENT_WORDS_TABLE, $data);
×
120
        }
121
    }
122

123
    /**
124
     * @return array<array{uid: int, stem: string, weight: int}>
125
     */
126
    protected function getOldWords(): array
127
    {
128
        $queryBuilder = $this->getQueryBuilder();
×
129
        $queryBuilder->select('uid', 'stem', 'weight')
×
130
            ->from(self::PROMINENT_WORDS_TABLE)
×
131
            ->where(
×
132
                $queryBuilder->expr()->eq('uid_foreign', $this->uid),
×
133
                $queryBuilder->expr()->eq('tablenames', $queryBuilder->createNamedParameter($this->table)),
×
134
                $queryBuilder->expr()->eq('sys_language_uid', $this->languageId)
×
135
            );
×
136
        /** @var array<array{uid: int, stem: string, weight: int}> $oldWords */
137
        $oldWords = $queryBuilder->executeQuery()->fetchAllAssociative();
×
138
        return $oldWords;
×
139
    }
140

141
    protected function getPidForRecord(int $uid, string $table): int
142
    {
143
        $connection = $this->connectionPool->getConnectionForTable($table);
×
144
        $record = $connection->select(['pid'], $table, ['uid' => $uid])->fetchAssociative();
×
145
        return (int)($record['pid'] ?? 0);
×
146
    }
147

148
    protected function getSiteRootPageId(): int
149
    {
NEW
150
        return $this->siteService->getSiteRootPageId(
×
NEW
151
            $this->table === 'pages' ? $this->uid : $this->pid
×
NEW
152
        );
×
153
    }
154

155
    protected function getQueryBuilder(): QueryBuilder
156
    {
157
        return $this->connectionPool->getQueryBuilderForTable(self::PROMINENT_WORDS_TABLE);
×
158
    }
159
}
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