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

Yoast / Yoast-SEO-for-TYPO3 / 21916594510

11 Feb 2026 05:54PM UTC coverage: 10.09% (+8.8%) from 1.275%
21916594510

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

28 of 550 new or added lines in 53 files covered. (5.09%)

33 existing lines in 21 files now uncovered.

268 of 2656 relevant lines covered (10.09%)

0.27 hits per line

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

0.0
/Classes/StructuredData/BreadcrumbStructuredDataProvider.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\StructuredData;
13

14
use TYPO3\CMS\Core\Context\Context;
15
use TYPO3\CMS\Core\Exception\SiteNotFoundException;
16
use TYPO3\CMS\Core\Site\SiteFinder;
17
use TYPO3\CMS\Core\Utility\GeneralUtility;
18
use YoastSeoForTypo3\YoastSeo\Service\Frontend\FrontendServiceInterface;
19

20
class BreadcrumbStructuredDataProvider implements StructuredDataProviderInterface
21
{
22
    /** @var array<string, mixed> */
23
    protected array $configuration;
24

25
    public function __construct(
26
        protected SiteFinder $siteFinder,
27
        protected Context $context,
28
        protected FrontendServiceInterface $frontendService,
UNCOV
29
    ) {}
×
30

31
    /**
32
     * @return array<array<string, mixed>>
33
     */
34
    public function getData(): array
35
    {
36
        $breadcrumbs = [];
×
37
        $excludedDoktypes = $this->getExcludedDoktypes();
×
38
        $iterator = 1;
×
39
        $siteRootFound = false;
×
40
        foreach ($this->getRootLine() as $page) {
×
41
            if ($page['hidden'] === 1) {
×
42
                continue;
×
43
            }
44
            $siteRootFound = $siteRootFound || $page['is_siteroot'];
×
45
            if (!$siteRootFound || in_array((int)$page['doktype'], $excludedDoktypes, true)) {
×
46
                continue;
×
47
            }
48
            $url = $this->getUrlForPage($page['uid']);
×
49
            if (empty($url)) {
×
50
                continue;
×
51
            }
52
            $breadcrumbs[] = [
×
53
                '@type' => 'ListItem',
×
54
                'position' => $iterator,
×
55
                'item' => [
×
56
                    '@id' => $url,
×
57
                    'name' => $page['nav_title'] ?: $page['title'],
×
58
                ],
×
59
            ];
×
60
            $iterator++;
×
61
        }
62

63
        return $this->getBreadcrumbList($breadcrumbs);
×
64
    }
65

66
    /**
67
     * @param array<array<string, mixed>> $breadcrumbs
68
     * @return array<array<string, mixed>>
69
     */
70
    protected function getBreadcrumbList(array $breadcrumbs): array
71
    {
72
        if (empty($breadcrumbs)) {
×
73
            return [];
×
74
        }
75

76
        return [
×
77
            [
×
78
                '@context' => 'https://www.schema.org',
×
79
                '@type' => 'BreadcrumbList',
×
80
                'itemListElement' => $breadcrumbs,
×
81
            ],
×
82
        ];
×
83
    }
84

85
    /**
86
     * @return int[]
87
     */
88
    protected function getExcludedDoktypes(): array
89
    {
90
        if (!empty($this->configuration['excludedDoktypes'] ?? '')) {
×
91
            return GeneralUtility::intExplode(',', $this->configuration['excludedDoktypes']);
×
92
        }
93
        return [];
×
94
    }
95

96
    /**
97
     * @return array<array<string, mixed>>
98
     */
99
    protected function getRootLine(): array
100
    {
NEW
101
        $rootLine = $this->frontendService->getRootLine();
×
102
        ksort($rootLine);
×
103
        return $rootLine;
×
104
    }
105

106
    protected function getUrlForPage(int $pageId): string
107
    {
108
        try {
109
            $site = $this->siteFinder->getSiteByPageId($pageId);
×
110
            return (string)$site->getRouter()->generateUri(
×
111
                $pageId,
×
112
                ['_language' => (int)$this->context->getPropertyFromAspect('language', 'id')]
×
113
            );
×
114
        } catch (SiteNotFoundException|\InvalidArgumentException) {
×
115
            return '';
×
116
        }
117
    }
118

119
    /**
120
     * @param array<string, mixed> $configuration
121
     */
122
    public function setConfiguration(array $configuration): void
123
    {
124
        $this->configuration = $configuration;
×
125
    }
126
}
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