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

FluidTYPO3 / vhs / 28589440339

02 Jul 2026 12:19PM UTC coverage: 70.574% (+0.04%) from 70.533%
28589440339

push

github

NamelessCoder
[TASK] Clean up v:page.header.alternate

0 of 11 new or added lines in 1 file covered. (0.0%)

4847 of 6868 relevant lines covered (70.57%)

4.45 hits per line

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

36.21
/Classes/ViewHelpers/Page/Header/AlternateViewHelper.php
1
<?php
2
namespace FluidTYPO3\Vhs\ViewHelpers\Page\Header;
3

4
/*
5
 * This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
6
 *
7
 * For the full copyright and license information, please read the
8
 * LICENSE.md file that was distributed with this source code.
9
 */
10

11
use FluidTYPO3\Vhs\Core\ViewHelper\AbstractViewHelper;
12
use FluidTYPO3\Vhs\Service\PageService;
13
use FluidTYPO3\Vhs\Traits\PageRendererTrait;
14
use FluidTYPO3\Vhs\Utility\ContextUtility;
15
use FluidTYPO3\Vhs\Utility\RequestResolver;
16
use TYPO3\CMS\Core\Page\PageRenderer;
17
use TYPO3\CMS\Core\Utility\GeneralUtility;
18
use TYPO3\CMS\Extbase\Mvc\Request;
19
use TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder;
20
use TYPO3Fluid\Fluid\Core\ViewHelper\TagBuilder;
21

22
/**
23
 * Returns the all alternate urls.
24
 */
25
class AlternateViewHelper extends AbstractViewHelper
26
{
27
    use PageRendererTrait;
28

29
    /**
30
     * @var PageService
31
     */
32
    protected $pageService;
33

34
    /**
35
     * @var TagBuilder
36
     */
37
    protected $tagBuilder;
38

39
    public function injectPageService(PageService $pageService): void
40
    {
41
        $this->pageService = $pageService;
×
42
    }
43

44
    public function __construct()
45
    {
46
        /** @var TagBuilder $tagBuilder */
47
        $tagBuilder = GeneralUtility::makeInstance(TagBuilder::class);
×
48
        $this->tagBuilder = $tagBuilder;
×
49
    }
50

51
    public function initializeArguments(): void
52
    {
53
        $this->registerArgument(
2✔
54
            'languages',
2✔
55
            'mixed',
2✔
56
            'The languages (either CSV, array or implementing Traversable)',
2✔
57
            true
2✔
58
        );
2✔
59
        $this->registerArgument('pageUid', 'integer', 'The page uid to check', false, 0);
2✔
60
        $this->registerArgument(
2✔
61
            'normalWhenNoLanguage',
2✔
62
            'boolean',
2✔
63
            'If TRUE, a missing page overlay should be ignored',
2✔
64
            false,
2✔
65
            false
2✔
66
        );
2✔
67
        $this->registerArgument(
2✔
68
            'addQueryString',
2✔
69
            'boolean',
2✔
70
            'If TRUE, the current query parameters will be kept in the URI',
2✔
71
            false,
2✔
72
            false
2✔
73
        );
2✔
74
    }
75

76
    public function render(): string
77
    {
78
        if (ContextUtility::isBackend()) {
×
79
            return '';
×
80
        }
81

82
        /** @var int|null|string $pageUid */
83
        $pageUid = $this->arguments['pageUid'];
×
84

85
        /** @var array<int, string>|string $languages */
86
        $languages = $this->arguments['languages'];
×
87
        if ($languages instanceof \Traversable) {
×
88
            $languages = iterator_to_array($languages);
×
89
        } elseif (is_string($languages)) {
×
90
            $languages = GeneralUtility::trimExplode(',', $languages, true);
×
91
        } else {
92
            $languages = (array) $languages;
×
93
        }
94

95
        $pageUid = (int) ($pageUid ?: RequestResolver::getPageUid());
×
96

97
        /** @var bool $normalWhenNoLanguage */
98
        $normalWhenNoLanguage = $this->arguments['normalWhenNoLanguage'];
×
99
        $addQueryString = (bool) $this->arguments['addQueryString'];
×
100

NEW
101
        $request = RequestResolver::resolveRequestFromRenderingContext($this->renderingContext);
×
NEW
102
        if (!$request instanceof Request) {
×
NEW
103
            $request = new Request($request);
×
104
        }
105

106
        /** @var UriBuilder $uriBuilder */
107
        $uriBuilder = GeneralUtility::makeInstance(UriBuilder::class);
×
NEW
108
        $uriBuilder->setRequest($request);
×
109

110
        $uriBuilder = $uriBuilder->reset()
×
111
            ->setTargetPageUid($pageUid)
×
112
            ->setCreateAbsoluteUri(true)
×
113
            ->setAddQueryString($addQueryString);
×
114

115
        $this->tagBuilder->reset();
×
116
        $this->tagBuilder->setTagName('link');
×
117
        $this->tagBuilder->addAttribute('rel', 'alternate');
×
118

119
        /** @var PageRenderer $pageRenderer */
120
        $pageRenderer = GeneralUtility::makeInstance(PageRenderer::class);
×
121

122
        foreach ($languages as $languageUid => $languageName) {
×
NEW
123
            if ($this->pageService->hidePageForLanguageUid($pageUid, $languageUid, $normalWhenNoLanguage)) {
×
NEW
124
                continue;
×
125
            }
126

NEW
127
            $uri = $uriBuilder->setArguments(['L' => $languageUid])->build();
×
NEW
128
            $this->tagBuilder->addAttribute('href', $uri);
×
NEW
129
            $this->tagBuilder->addAttribute('hreflang', $languageName);
×
130

NEW
131
            $renderedTag = $this->tagBuilder->render();
×
NEW
132
            $pageRenderer->addHeaderData($renderedTag);
×
133
        }
134

135
        return '';
×
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