• 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

58.97
/Classes/ViewHelpers/Variable/GetViewHelper.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: Get
17
 *
18
 * ViewHelper used to read the value of a current template
19
 * variable. Can be used with dynamic indices in arrays:
20
 *
21
 * ```
22
 * <v:variable.get name="array.{dynamicIndex}" />
23
 * <v:variable.get name="array.{v:variable.get(name: 'arrayOfSelectedKeys.{indexInArray}')}" />
24
 * <f:for each="{v:variable.get(name: 'object.arrayProperty.{dynamicIndex}')}" as="nestedObject">
25
 *     ...
26
 * </f:for>
27
 * ```
28
 *
29
 * Or to read names of variables which contain dynamic parts:
30
 *
31
 * ```
32
 * <!-- if {variableName} is "Name", outputs value of {dynamicName} -->
33
 * {v:variable.get(name: 'dynamic{variableName}')}
34
 * ```
35
 *
36
 * If your target object is an array with unsequential yet
37
 * numeric indices (e.g. {123: 'value1', 513: 'value2'},
38
 * commonly seen in reindexed UID map arrays) use
39
 * `useRawKeys="TRUE"` to indicate you do not want your
40
 * array/QueryResult/Iterator to be accessed by locating
41
 * the Nth element - which is the default behavior.
42
 *
43
 * ```warning
44
 * Do not try `useRawKeys="TRUE"` on QueryResult or
45
 * ObjectStorage unless you are fully aware what you are
46
 * doing. These particular types require an unpredictable
47
 * index value - the SPL object hash value - when accessing
48
 * members directly. This SPL indexing and the very common
49
 * occurrences of QueryResult and ObjectStorage variables
50
 * in templates is the very reason why `useRawKeys` by
51
 * default is set to `FALSE`.
52
 * ```
53
 */
54
class GetViewHelper extends AbstractViewHelper
55
{
56
    public function initializeArguments(): void
57
    {
58
        $this->registerArgument('name', 'string', 'Name of variable to retrieve');
3✔
59
        $this->registerArgument(
3✔
60
            'useRawKeys',
3✔
61
            'boolean',
3✔
62
            'If TRUE, the path is directly passed to ObjectAccess. If FALSE, a custom and compatible VHS method is used'
3✔
63
        );
3✔
64
    }
65

66
    /**
67
     * @return mixed
68
     */
69
    public static function renderStatic(
70
        array $arguments,
71
        \Closure $renderChildrenClosure,
72
        RenderingContextInterface $renderingContext
73
    ) {
74
        $variableProvider = $renderingContext->getVariableProvider();
6✔
75
        /** @var string $name */
76
        $name = $arguments['name'];
6✔
77
        $useRawKeys = $arguments['useRawKeys'];
6✔
78
        if (false === strpos($name, '.')) {
6✔
79
            if ($variableProvider->exists($name)) {
3✔
80
                return $variableProvider->get($name);
3✔
81
            }
82
        } else {
83
            $segments = explode('.', $name);
3✔
84
            $lastSegment = array_shift($segments);
3✔
85
            $templateVariableRootName = $lastSegment;
3✔
86
            if ($variableProvider->exists($templateVariableRootName)) {
3✔
87
                /** @var array|object $templateVariableRoot */
88
                $templateVariableRoot = $variableProvider->get($templateVariableRootName);
3✔
89
                if ($useRawKeys) {
3✔
90
                    return ObjectAccess::getPropertyPath($templateVariableRoot, implode('.', $segments));
×
91
                }
92
                try {
93
                    $value = $templateVariableRoot;
3✔
94
                    foreach ($segments as $segment) {
3✔
95
                        if (is_numeric($segment) && (int) $segment == $segment) {
3✔
96
                            $segment = intval($segment);
×
97
                            $index = 0;
×
98
                            $found = false;
×
99
                                // Note: this loop approach is not a stupid solution. If you doubt this,
100
                                // attempt to feth a number at a numeric index from ObjectStorage ;)
101
                            /** @var iterable $value */
102
                            foreach ($value as $possibleValue) {
×
103
                                if ($index === $segment) {
×
104
                                    /** @var array|object $value */
105
                                    $value = $possibleValue;
×
106
                                    $found = true;
×
107
                                    break;
×
108
                                }
109
                                ++ $index;
×
110
                            }
111
                            if (!$found) {
×
112
                                return null;
×
113
                            }
114
                            continue;
×
115
                        }
116
                        /** @var array|object $value */
117
                        $value = ObjectAccess::getProperty($value, $segment);
3✔
118
                    }
119
                    return $value;
3✔
120
                } catch (\Exception $e) {
×
121
                    return null;
×
122
                }
123
            }
124
        }
125
        return null;
×
126
    }
127
}
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