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

Yoast / Yoast-SEO-for-TYPO3 / 13327579701

14 Feb 2025 10:43AM UTC coverage: 1.276%. First build
13327579701

push

github

web-flow
Merge pull request #597 from Yoast/feature/v11

[FEATURE] Release 11.0.0

21 of 894 new or added lines in 76 files covered. (2.35%)

35 of 2744 relevant lines covered (1.28%)

0.04 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
declare(strict_types=1);
4

5
namespace YoastSeoForTypo3\YoastSeo\Service;
6

7
use TYPO3\CMS\Core\Database\Connection;
8
use TYPO3\CMS\Core\Database\ConnectionPool;
9
use TYPO3\CMS\Core\Database\Query\QueryBuilder;
10
use TYPO3\CMS\Core\Exception\SiteNotFoundException;
11
use TYPO3\CMS\Core\Site\SiteFinder;
12
use TYPO3\CMS\Core\Utility\GeneralUtility;
13

14
class ProminentWordsService
15
{
16
    protected const PROMINENT_WORDS_TABLE = 'tx_yoastseo_prominent_word';
17

18
    protected int $uid;
19
    protected int $pid;
20
    protected string $table;
21
    protected int $languageId;
22

23
    public function __construct(
24
        protected ConnectionPool $connectionPool
25
    ) {}
×
26

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

42
        $wordsToDelete = [];
×
43

44
        $oldWords = $this->getOldWords();
×
45
        foreach ($oldWords as $oldWord) {
×
46
            if (!isset($prominentWords[$oldWord['stem']])) {
×
47
                $wordsToDelete[] = $oldWord['uid'];
×
48
                continue;
×
49
            }
50

51
            $this->updateIfWeightHasChanged($oldWord, (int)$prominentWords[$oldWord['stem']]);
×
52
            unset($prominentWords[$oldWord['stem']]);
×
53
        }
54

55
        $this->deleteProminentWords($wordsToDelete);
×
56
        $this->createNewWords($prominentWords);
×
57
    }
58

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

77
    /**
78
     * @param int[] $wordsToDelete
79
     */
80
    protected function deleteProminentWords(array $wordsToDelete): void
81
    {
82
        if ($wordsToDelete === []) {
×
83
            return;
×
84
        }
85

86
        $queryBuilder = $this->getQueryBuilder();
×
87
        $queryBuilder->delete(self::PROMINENT_WORDS_TABLE)
×
88
            ->where(
×
89
                $queryBuilder->expr()->in(
×
90
                    'uid',
×
91
                    $queryBuilder->createNamedParameter($wordsToDelete, Connection::PARAM_INT_ARRAY)
×
92
                )
×
93
            )
×
94
            ->executeStatement();
×
95
    }
96

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

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

136
    protected function getPidForRecord(int $uid, string $table): int
137
    {
138
        $connection = $this->connectionPool->getConnectionForTable($table);
×
139
        $record = $connection->select(['pid'], $table, ['uid' => $uid])->fetchAssociative();
×
140
        return (int)($record['pid'] ?? 0);
×
141
    }
142

143
    protected function getSiteRootPageId(): int
144
    {
145
        try {
146
            $site = GeneralUtility::makeInstance(SiteFinder::class)->getSiteByPageId(
×
147
                $this->table === 'pages' ? $this->uid : $this->pid
×
148
            );
×
149
            return $site->getRootPageId();
×
150
        } catch (SiteNotFoundException $e) {
×
151
            return 0;
×
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