• 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/Crawler/CrawlerService.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\Crawler;
13

14
use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface;
15
use TYPO3\CMS\Core\Database\ConnectionPool;
16
use TYPO3\CMS\Core\Registry;
17
use YoastSeoForTypo3\YoastSeo\Constants\TableNames;
18
use YoastSeoForTypo3\YoastSeo\Utility\PageAccessUtility;
19
use YoastSeoForTypo3\YoastSeo\Utility\YoastUtility;
20

21
class CrawlerService
22
{
23
    protected const REGISTRY_NAMESPACE = 'tx_yoastseo';
24
    protected const REGISTRY_KEY = 'crawler-%d-%d';
25
    protected const INDEX_CHUNK = 50;
26

27
    public function __construct(
28
        protected FrontendInterface $cache,
29
        protected Registry $registry,
30
        protected ConnectionPool $connectionPool,
UNCOV
31
    ) {}
×
32

33
    public function getAmountOfPages(int $site, int $languageId): int
34
    {
35
        return count($this->getPagesToIndex($site, $languageId));
×
36
    }
37

38
    /**
39
     * @return array{pages: array<int>, current: int, nextOffset: int, total: int}
40
     */
41
    public function getIndexInformation(int $site, int $languageId, int $offset = 0): array
42
    {
43
        $pagesToIndex = $this->getPagesToIndex($site, $languageId);
×
44
        $total = count($pagesToIndex);
×
45

46
        $progressInformation = $this->getProgressInformation($site, $languageId);
×
47
        $currentOffset = $offset > 0 ? $offset : ($progressInformation['offset'] ?? 0);
×
48
        $this->setProgressInformation($site, $languageId, $currentOffset, $total);
×
49

50
        return [
×
51
            'pages' => array_splice($pagesToIndex, $currentOffset, self::INDEX_CHUNK),
×
52
            'current' => $currentOffset,
×
53
            'nextOffset' => $currentOffset + self::INDEX_CHUNK,
×
54
            'total' => $total,
×
55
        ];
×
56
    }
57

58
    /**
59
     * @return array{offset?: int, total?: int}
60
     */
61
    public function getProgressInformation(int $site, int $languageId): array
62
    {
63
        return (array)$this->registry->get(
×
64
            self::REGISTRY_NAMESPACE,
×
65
            sprintf(self::REGISTRY_KEY, $site, $languageId),
×
66
            []
×
67
        );
×
68
    }
69

70
    protected function setProgressInformation(int $site, int $languageId, int $offset, int $total): void
71
    {
72
        $this->registry->set(
×
73
            self::REGISTRY_NAMESPACE,
×
74
            sprintf(self::REGISTRY_KEY, $site, $languageId),
×
75
            [
×
76
                'offset' => $offset,
×
77
                'total' => $total,
×
78
            ]
×
79
        );
×
80
    }
81

82
    public function resetProgressInformation(int $site, int $languageId): void
83
    {
84
        $this->registry->remove(self::REGISTRY_NAMESPACE, sprintf(self::REGISTRY_KEY, $site, $languageId));
×
85
    }
86

87
    /**
88
     * @return int[]
89
     */
90
    protected function getPagesToIndex(int $site, int $languageId): array
91
    {
92
        $cacheIdentifier = 'YoastSeoCrawler' . $site . '-' . $languageId;
×
93
        if (($pagesToIndex = $this->cache->get($cacheIdentifier)) === false) {
×
94
            $treeList = PageAccessUtility::getPageIds($site);
×
95
            $pagesToIndex = [];
×
96
            foreach (array_chunk($treeList, 1000) as $treeChunk) {
×
NEW
97
                $queryBuilder = $this->connectionPool->getQueryBuilderForTable(TableNames::PAGES);
×
98

99
                if ($languageId > 0) {
×
100
                    $select = 'l10n_parent';
×
101
                    $constraints = [
×
102
                        $queryBuilder->expr()->eq('sys_language_uid', $languageId),
×
103
                        $queryBuilder->expr()->in(
×
104
                            'l10n_parent',
×
105
                            $treeChunk
×
106
                        ),
×
NEW
107
                        $queryBuilder->expr()->eq('tx_yoastseo_disable_analysis', 0),
×
UNCOV
108
                    ];
×
109
                } else {
110
                    $select = 'uid';
×
111
                    $constraints = [
×
112
                        $queryBuilder->expr()->in(
×
113
                            'uid',
×
114
                            $treeChunk
×
115
                        ),
×
NEW
116
                        $queryBuilder->expr()->eq('tx_yoastseo_disable_analysis', 0),
×
UNCOV
117
                    ];
×
118
                }
119

120
                $pages = $queryBuilder->select($select)
×
NEW
121
                    ->from(TableNames::PAGES)
×
122
                    ->where(
×
123
                        $queryBuilder->expr()->in(
×
124
                            'doktype',
×
125
                            YoastUtility::getAllowedDoktypes()
×
126
                        ),
×
127
                        ...$constraints
×
128
                    )->executeQuery()->fetchAllAssociative();
×
129
                $pagesToIndex = array_merge($pagesToIndex, array_column($pages, $select));
×
130
            }
NEW
131
            if (count($pagesToIndex) > 0) {
×
NEW
132
                $this->cache->set($cacheIdentifier, $pagesToIndex);
×
133
            }
134
        }
135
        return $pagesToIndex;
×
136
    }
137
}
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