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

FluidTYPO3 / vhs / 12968921053

25 Jan 2025 10:22PM UTC coverage: 72.266% (-0.08%) from 72.341%
12968921053

push

github

NamelessCoder
[BUGFIX] Handle ImageResource return types

API of some core methods has changed to return this new class type.

0 of 11 new or added lines in 2 files covered. (0.0%)

1 existing line in 1 file now uncovered.

5550 of 7680 relevant lines covered (72.27%)

13.47 hits per line

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

41.11
/Classes/ViewHelpers/Media/SourceViewHelper.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\Utility\ContentObjectFetcher;
12
use FluidTYPO3\Vhs\Utility\ContextUtility;
13
use FluidTYPO3\Vhs\Utility\FrontendSimulationUtility;
14
use TYPO3\CMS\Core\Imaging\ImageResource;
15
use TYPO3\CMS\Core\Resource\FileReference;
16
use TYPO3\CMS\Core\Utility\GeneralUtility;
17
use TYPO3\CMS\Core\Utility\MathUtility;
18
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
19
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractTagBasedViewHelper;
20
use TYPO3Fluid\Fluid\Core\ViewHelper\Exception;
21

22
/**
23
 * Used in conjuntion with the `v:media.PictureViewHelper`.
24
 * Please take a look at the `v:media.PictureViewHelper` documentation for more
25
 * information.
26
 */
27
class SourceViewHelper extends AbstractTagBasedViewHelper
28
{
29
    const SCOPE = 'FluidTYPO3\Vhs\ViewHelpers\Media\PictureViewHelper';
30
    const SCOPE_VARIABLE_SRC = 'src';
31
    const SCOPE_VARIABLE_ID = 'treatIdAsReference';
32
    const SCOPE_VARIABLE_DEFAULT_SOURCE = 'default-source';
33

34
    /**
35
     * name of the tag to be created by this view helper
36
     *
37
     * @var string
38
     * @api
39
     */
40
    protected $tagName = 'source';
41
    /**
42
     * @var ConfigurationManagerInterface
43
     */
44
    protected $configurationManager;
45

46
    public function injectConfigurationManager(ConfigurationManagerInterface $configurationManager): void
47
    {
48
        $this->configurationManager = $configurationManager;
12✔
49
    }
50

51
    public function initializeArguments(): void
52
    {
53
        parent::initializeArguments();
6✔
54
        $this->registerUniversalTagAttributes();
6✔
55
        $this->registerArgument('media', 'string', 'Media query for which breakpoint this sources applies');
6✔
56
        $this->registerArgument(
6✔
57
            'width',
6✔
58
            'string',
6✔
59
            'Width of the image. This can be a numeric value representing the fixed width of the image in pixels. ' .
6✔
60
            'But you can also perform simple calculations by adding "m" or "c" to the value. See imgResource.width ' .
6✔
61
            'for possible options.'
6✔
62
        );
6✔
63
        $this->registerArgument(
6✔
64
            'height',
6✔
65
            'string',
6✔
66
            'Height of the image. This can be a numeric value representing the fixed height of the image in pixels. ' .
6✔
67
            'But you can also perform simple calculations by adding "m" or "c" to the value. See imgResource.width ' .
6✔
68
            'for possible options.'
6✔
69
        );
6✔
70
        $this->registerArgument('maxW', 'integer', 'Maximum Width of the image. (no upscaling)');
6✔
71
        $this->registerArgument('maxH', 'integer', 'Maximum Height of the image. (no upscaling)');
6✔
72
        $this->registerArgument('minW', 'integer', 'Minimum Width of the image.');
6✔
73
        $this->registerArgument('minH', 'integer', 'Minimum Height of the image.');
6✔
74
        $this->registerArgument(
6✔
75
            'format',
6✔
76
            'string',
6✔
77
            'Format of the processed file - also determines the target file format. If blank, TYPO3/IM/GM default ' .
6✔
78
            'is taken into account.'
6✔
79
        );
6✔
80
        $this->registerArgument(
6✔
81
            'quality',
6✔
82
            'integer',
6✔
83
            'Quality of the processed image. If blank/not present falls back to the default quality defined ' .
6✔
84
            'in install tool.',
6✔
85
            false,
6✔
86
            $GLOBALS['TYPO3_CONF_VARS']['GFX']['jpg_quality'] ?? 90
6✔
87
        );
6✔
88
        $this->registerArgument('relative', 'boolean', 'Produce a relative URL instead of absolute', false, false);
6✔
89
    }
90

91
    /**
92
     * Render method
93
     *
94
     * @return string
95
     */
96
    public function render()
97
    {
98
        $viewHelperVariableContainer = $this->renderingContext->getViewHelperVariableContainer();
×
99
        /** @var FileReference|string $imageSource */
100
        $imageSource = $viewHelperVariableContainer->get(static::SCOPE, static::SCOPE_VARIABLE_SRC);
×
101
        $treatIdAsRerefence = $viewHelperVariableContainer->get(static::SCOPE, static::SCOPE_VARIABLE_ID);
×
102

103
        $tsfeBackup = FrontendSimulationUtility::simulateFrontendEnvironment();
×
104

105
        $setup = [
×
106
            'width' => $this->arguments['width'],
×
107
            'height' => $this->arguments['height'],
×
108
            'minW' => $this->arguments['minW'],
×
109
            'minH' => $this->arguments['minH'],
×
110
            'maxW' => $this->arguments['maxW'],
×
111
            'maxH' => $this->arguments['maxH'],
×
112
            'treatIdAsReference' => $treatIdAsRerefence,
×
113
            'params' => '',
×
114
        ];
×
115
        /** @var int $quality */
116
        $quality = $this->arguments['quality'];
×
117
        /** @var string $format */
118
        $format = $this->arguments['format'];
×
119

120
        if (!empty($format)) {
×
121
            $setup['ext'] = $format;
×
122
        }
123
        if (0 < intval($quality)) {
×
124
            $quality = MathUtility::forceIntegerInRange($quality, 10, 100, 75);
×
125
            $setup['params'] .= ' -quality ' . $quality;
×
126
        }
127

128
        if (is_string($imageSource) && ContextUtility::isBackend() && '../' === mb_substr($imageSource, 0, 3)) {
×
129
            $imageSource = mb_substr($imageSource, 3);
×
130
        }
131
        $contentObject = ContentObjectFetcher::resolve($this->configurationManager);
×
132
        if ($contentObject === null) {
×
133
            throw new Exception('v:media.source requires a ContentObjectRenderer, none found', 1737807859);
×
134
        }
135

136
        $result = $contentObject->getImgResource($imageSource, $setup);
×
NEW
137
        if ($result instanceof ImageResource) {
×
NEW
138
            $processedFile = $result->getProcessedFile();
×
139
        } else {
NEW
140
            $processedFile = $result['processedFile'] ?? null;
×
141
        }
142

143
        FrontendSimulationUtility::resetFrontendEnvironment($tsfeBackup);
×
144

NEW
145
        if ($processedFile ?? false) {
×
146
            /** @var string $imageUrl */
NEW
147
            $imageUrl = $processedFile->getPublicUrl();
×
148
        } else {
NEW
149
            if ($result instanceof ImageResource) {
×
NEW
150
                $result = $result->getLegacyImageResourceInformation();
×
151
            }
152
            /** @var string $imageUrl */
UNCOV
153
            $imageUrl = $result[3] ?? '';
×
154
        }
155
        $src = $this->preprocessSourceUri(rawurldecode($imageUrl));
×
156

157
        /** @var string|null $media */
158
        $media = $this->arguments['media'];
×
159

160
        if (null === $media) {
×
161
            $viewHelperVariableContainer->addOrUpdate(static::SCOPE, static::SCOPE_VARIABLE_DEFAULT_SOURCE, $src);
×
162
        } else {
163
            $this->tag->addAttribute('media', $media);
×
164
        }
165

166
        $this->tag->addAttribute('srcset', $src);
×
167
        return $this->tag->render();
×
168
    }
169

170
    /**
171
     * Turns a relative source URI into an absolute URL
172
     * if required.
173
     */
174
    public function preprocessSourceUri(string $src): string
175
    {
176
        if (!empty($GLOBALS['TSFE']->tmpl->setup['plugin.']['tx_vhs.']['settings.']['prependPath'])) {
×
177
            $src = $GLOBALS['TSFE']->tmpl->setup['plugin.']['tx_vhs.']['settings.']['prependPath'] . $src;
×
178
        } elseif (ContextUtility::isBackend() || !$this->arguments['relative']) {
×
179
            if (GeneralUtility::isValidUrl($src)) {
×
180
                $src = ltrim($src, '/');
×
181
            } elseif (ContextUtility::isFrontend()) {
×
182
                $src = $GLOBALS['TSFE']->absRefPrefix . ltrim($src, '/');
×
183
            } else {
184
                /** @var string $siteUrl */
185
                $siteUrl = GeneralUtility::getIndpEnv('TYPO3_SITE_URL');
×
186
                $src = $siteUrl . ltrim($src, '/');
×
187
            }
188
        }
189
        return $src;
×
190
    }
191
}
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