Created
June 9, 2020 17:29
-
-
Save lorenzulrich/1abe0e415a1a7871ca338e17323cf8f1 to your computer and use it in GitHub Desktop.
ViewHelper used to read the value of a current template variable.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace My\Site\ViewHelpers; | |
/* | |
* ### Variable: Get | |
* | |
* ViewHelper used to read the value of a current template | |
* variable. Can be used with dynamic indices in arrays: | |
* | |
* <v:get name="array.{dynamicIndex}" /> | |
* <v:get name="array.{v:variable.get(name: 'arrayOfSelectedKeys.{indexInArray}')}" /> | |
* <f:for each="{v:get(name: 'object.arrayProperty.{dynamicIndex}')}" as="nestedObject"> | |
* ... | |
* </f:for> | |
* | |
* Or to read names of variables which contain dynamic parts: | |
* | |
* <!-- if {variableName} is "Name", outputs value of {dynamicName} --> | |
* {v:get(name: 'dynamic{variableName}')} | |
* | |
*/ | |
use TYPO3\Flow\Reflection\ObjectAccess; | |
use TYPO3\Fluid\Core\ViewHelper\AbstractViewHelper; | |
class GetValueViewHelper extends AbstractViewHelper | |
{ | |
/** | |
* ### Variable: Get | |
* | |
* Get the variable in $name. Supports dotted-path syntax. | |
* | |
* Can be used to access dynamic variables such as: | |
* | |
* {v:variable.get(name: 'object.arrayProperty.{index}')} | |
* | |
* And can be chained with `v:variable.set` to reassign the | |
* output to another variable: | |
* | |
* {v:variable.get(name: 'myArray.{index}') -> v:variable.set(name: 'myVar')} | |
* | |
* If your target object is an array with unsequential yet | |
* numeric indices (e.g. {123: 'value1', 513: 'value2'}, | |
* commonly seen in reindexed UID map arrays) use | |
* `useRawIndex="TRUE"` to indicate you do not want your | |
* array/QueryResult/Iterator to be accessed by locating | |
* the Nth element - which is the default behavior. | |
* | |
* ```warning | |
* Do not try `useRawKeys="TRUE"` on QueryResult or | |
* ObjectStorage unless you are fully aware what you are | |
* doing. These particular types require an unpredictable | |
* index value - the SPL object hash value - when accessing | |
* members directly. This SPL indexing and the very common | |
* occurrences of QueryResult and ObjectStorage variables | |
* in templates is the very reason why `useRawKeys` by | |
* default is set to `FALSE`. | |
* ``` | |
* | |
* @param string $name | |
* @param boolean $useRawKeys | |
* @return mixed | |
*/ | |
public function render($name, $useRawKeys = false) | |
{ | |
if (false === strpos($name, '.')) { | |
if (true === $this->templateVariableContainer->exists($name)) { | |
return $this->templateVariableContainer->get($name); | |
} | |
} else { | |
$segments = explode('.', $name); | |
$templateVariableRootName = $lastSegment = array_shift($segments); | |
if (true === $this->templateVariableContainer->exists($templateVariableRootName)) { | |
$templateVariableRoot = $this->templateVariableContainer->get($templateVariableRootName); | |
if (true === $useRawKeys) { | |
return ObjectAccess::getPropertyPath($templateVariableRoot, implode('.', $segments)); | |
} | |
try { | |
$value = $templateVariableRoot; | |
foreach ($segments as $segment) { | |
if (true === ctype_digit($segment)) { | |
$segment = intval($segment); | |
$index = 0; | |
// Note: this loop approach is not a stupid solution. If you doubt this, | |
// attempt to feth a number at a numeric index from ObjectStorage ;) | |
foreach ($value as $possibleValue) { | |
if ($index === $segment) { | |
$value = $possibleValue; | |
break; | |
} | |
++$index; | |
} | |
continue; | |
} | |
$value = ObjectAccess::getProperty($value, $segment); | |
} | |
return $value; | |
} catch (\Exception $e) { | |
return null; | |
} | |
} | |
} | |
return null; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment