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

FluidTYPO3 / vhs / 30001290505

23 Jul 2026 10:57AM UTC coverage: 70.309% (-1.7%) from 72.022%
30001290505

push

github

NamelessCoder
[TER] 8.0.0

4819 of 6854 relevant lines covered (70.31%)

6.54 hits per line

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

45.45
/Classes/ViewHelpers/Variable/SetViewHelper.php
1
<?php
2
namespace FluidTYPO3\Vhs\ViewHelpers\Variable;
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 TYPO3\CMS\Extbase\Reflection\ObjectAccess;
13
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
14

15
/**
16
 * ### Variable: Set
17
 *
18
 * Sets a single variable in the TemplateVariableContainer
19
 * scope. The variable then becomes accessible as {var}.
20
 *
21
 * Combines well with `v:variable.get` to set shorter variable
22
 * names referencing dynamic variables, such as:
23
 *
24
 * ```
25
 * <v:variable.set name="myObject" value="{v:variable.get(name: 'arrayVariable.{offset}')}" />
26
 * <!-- If {index} == 4 then {myObject} is now == {arrayVariable.4} -->
27
 * {myObject.name} <!-- corresponds to {arrayVariable.4.name} -->
28
 * ```
29
 *
30
 * Note that `{arrayVariable.{offset}.name}` is not possible
31
 * due to the way Fluid parses nodes; the above piece of
32
 * code would try reading `arrayVariable.{offset}.name`
33
 * as a variable actually called "arrayVariable.{offset}.name"
34
 * rather than the correct `arrayVariable[offset][name]`.
35
 *
36
 * In many ways this ViewHelper works like `f:alias`
37
 * with one exception: in `f:alias` the variable only
38
 * becomes accessible in the tag content, whereas `v:variable.set`
39
 * inserts the variable in the template and leaves it there
40
 * (it "leaks" the variable).
41
 *
42
 * If $name contains a dot, VHS will attempt to load the object
43
 * stored under the named used as the first segment part and
44
 * set the value at the remaining path. E.g.
45
 * `{value -> v:variable.set(name: 'object.property.subProperty')}`
46
 * would attempt to load `{object}` first, then set
47
 * `property.subProperty` on that object/array using
48
 * ObjectAccess::setPropertyPath(). If `{object}` is not
49
 * an object or an array, the variable will not be set. Please
50
 * note: Extbase does not currently support setting variables
51
 * deeper than two levels, meaning a `name` of fx `foo.bar.baz`
52
 * will be ignored. To set values deeper than two levels you
53
 * must first extract the second-level object then set the
54
 * value on that object.
55
 *
56
 * Using as `{value -> v:variable.set(name: 'myVar')}` makes `{myVar}` contain
57
 * `{value}`.
58
 */
59
class SetViewHelper extends AbstractViewHelper
60
{
61
    /**
62
     * @var boolean
63
     */
64
    protected $escapeChildren = false;
65

66
    public function initializeArguments(): void
67
    {
68
        $this->registerArgument('value', 'mixed', 'Value to set');
3✔
69
        $this->registerArgument('name', 'string', 'Name of variable to assign');
3✔
70
    }
71

72
    /**
73
     * @return mixed
74
     */
75
    public static function renderStatic(
76
        array $arguments,
77
        \Closure $renderChildrenClosure,
78
        RenderingContextInterface $renderingContext
79
    ) {
80
        /** @var string $name */
81
        $name = $arguments['name'];
9✔
82
        /** @var mixed $value */
83
        $value = $arguments['value'] ?? $renderChildrenClosure();
9✔
84
        $variableProvider = $renderingContext->getVariableProvider();
9✔
85
        if (false === strpos($name, '.')) {
9✔
86
            if ($variableProvider->exists($name)) {
9✔
87
                $variableProvider->remove($name);
3✔
88
            }
89
            $variableProvider->add($name, $value);
9✔
90
        } elseif (1 === mb_substr_count($name, '.')) {
×
91
            $parts = explode('.', $name);
×
92
            $objectName = array_shift($parts);
×
93
            $path = implode('.', $parts);
×
94
            if (!$variableProvider->exists($objectName)) {
×
95
                return null;
×
96
            }
97
            $object = $variableProvider->get($objectName);
×
98
            try {
99
                ObjectAccess::setProperty($object, $path, $value);
×
100
                // Note: re-insert the variable to ensure unreferenced values like arrays also get updated
101
                $variableProvider->remove($objectName);
×
102
                $variableProvider->add($objectName, $object);
×
103
            } catch (\Exception | \Error $error) {
×
104
                return null;
×
105
            }
106
        }
107
        return null;
9✔
108
    }
109
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc