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

FluidTYPO3 / vhs / 28229884559

26 Jun 2026 09:35AM UTC coverage: 69.872% (-0.04%) from 69.907%
28229884559

push

github

NamelessCoder
[TASK] Add visibility and type on all class constants

6 of 16 new or added lines in 8 files covered. (37.5%)

4803 of 6874 relevant lines covered (69.87%)

4.07 hits per line

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

36.17
/Classes/ViewHelpers/Media/PictureViewHelper.php
1
<?php
2
namespace FluidTYPO3\Vhs\ViewHelpers\Media;
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\Traits\TagViewHelperCompatibility;
12
use TYPO3\CMS\Extbase\Domain\Model\FileReference;
13
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractTagBasedViewHelper;
14
use TYPO3Fluid\Fluid\Core\ViewHelper\Exception;
15
use TYPO3Fluid\Fluid\Core\ViewHelper\TagBuilder;
16

17
/**
18
 * Renders a picture element with different images/sources for specific
19
 * media breakpoints
20
 *
21
 * ### Example
22
 *
23
 * ```
24
 * <v:media.picture src="fileadmin/some-image.png" alt="Some Image" loading="lazy">
25
 *     <v:media.source media="(min-width: 1200px)" width="500c" height="500c" />
26
 *     <v:media.source media="(min-width: 992px)" width="300c" height="300c" />
27
 *     <v:media.source media="(min-width: 768px)" width="200c" height="200c" />
28
 *     <v:media.source width="80c" height="80c" />
29
 * </v:media.picture>
30
 * ```
31
 *
32
 * ### Browser Support
33
 *
34
 * To have the widest Browser-Support you should consider using a polyfill like:
35
 * http://scottjehl.github.io/picturefill/
36
 */
37
class PictureViewHelper extends AbstractTagBasedViewHelper
38
{
39
    use TagViewHelperCompatibility;
40

41
    private const string SCOPE = 'FluidTYPO3\Vhs\ViewHelpers\Media\PictureViewHelper';
42
    private const string SCOPE_VARIABLE_SRC = 'src';
43
    private const string SCOPE_VARIABLE_ID = 'treatIdAsReference';
44
    private const string SCOPE_VARIABLE_DEFAULT_SOURCE = 'default-source';
45

46
    /**
47
     * name of the tag to be created by this view helper
48
     *
49
     * @var string
50
     * @api
51
     */
52
    protected $tagName = 'picture';
53

54
    public function initializeArguments(): void
55
    {
56
        parent::initializeArguments();
2✔
57
        $this->registerArgument('src', 'mixed', 'Path to the image or FileReference.', true);
2✔
58
        $this->registerArgument(
2✔
59
            'treatIdAsReference',
2✔
60
            'boolean',
2✔
61
            'When TRUE treat given src argument as sys_file_reference record.',
2✔
62
            false,
2✔
63
            false
2✔
64
        );
2✔
65
        $this->registerArgument('alt', 'string', 'Text for the alt attribute.', true);
2✔
66
        $this->registerArgument('title', 'string', 'Text for the title attribute.');
2✔
67
        $this->registerArgument('class', 'string', 'CSS class(es) to set.');
2✔
68
        $this->registerArgument(
2✔
69
            'loading',
2✔
70
            'string',
2✔
71
            'Native lazy-loading for images. Can be "lazy", "eager" or "auto"'
2✔
72
        );
2✔
73
    }
74

75
    public function render(): string
76
    {
77
        $src = $this->arguments['src'];
×
78
        $treatIdAsReference = (bool) $this->arguments['treatIdAsReference'];
×
79
        if ($src instanceof FileReference) {
×
80
            $src = $src->getUid();
×
81
            $treatIdAsReference = true;
×
82
        }
83

84
        $viewHelperVariableContainer = $this->renderingContext->getViewHelperVariableContainer();
×
NEW
85
        $viewHelperVariableContainer->addOrUpdate(self::SCOPE, self::SCOPE_VARIABLE_SRC, $src);
×
NEW
86
        $viewHelperVariableContainer->addOrUpdate(self::SCOPE, self::SCOPE_VARIABLE_ID, $treatIdAsReference);
×
87
        $content = $this->renderChildren();
×
NEW
88
        $viewHelperVariableContainer->remove(self::SCOPE, self::SCOPE_VARIABLE_SRC);
×
NEW
89
        $viewHelperVariableContainer->remove(self::SCOPE, self::SCOPE_VARIABLE_ID);
×
90

NEW
91
        if (!$viewHelperVariableContainer->exists(self::SCOPE, self::SCOPE_VARIABLE_DEFAULT_SOURCE)) {
×
92
            throw new Exception('Please add a source without a media query as a default.', 1438116616);
×
93
        }
NEW
94
        $defaultSource = $viewHelperVariableContainer->get(self::SCOPE, self::SCOPE_VARIABLE_DEFAULT_SOURCE);
×
95

96
        /** @var string $alt */
97
        $alt = $this->arguments['alt'];
×
98

99
        $defaultImage = new TagBuilder('img');
×
100
        $defaultImage->addAttribute('src', is_scalar($defaultSource) ? (string) $defaultSource : '');
×
101
        $defaultImage->addAttribute('alt', $alt);
×
102

103
        /** @var string|null $class */
104
        $class = $this->arguments['class'];
×
105
        if (!empty($class)) {
×
106
            $defaultImage->addAttribute('class', $class);
×
107
        }
108

109
        /** @var string|null $title */
110
        $title = $this->arguments['title'];
×
111
        if (!empty($title)) {
×
112
            $defaultImage->addAttribute('title', $title);
×
113
        }
114

115
        /** @var string|null $loading */
116
        $loading = $this->arguments['loading'];
×
117
        if (in_array($loading ?? '', ['lazy', 'eager', 'auto'], true)) {
×
118
            $defaultImage->addAttribute('loading', $loading);
×
119
        }
120

121
        $content .= $defaultImage->render();
×
122

123
        $this->tag->setContent($content);
×
124
        return $this->tag->render();
×
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