/** * @param mixed $candidate * @param RenderingContextInterface $renderingContext * @return mixed */ protected static function getTemplateVariableOrValueItself($candidate, RenderingContextInterface $renderingContext) { $variables = $renderingContext->getVariableProvider()->getAll(); $extractor = new VariableExtractor(); $suspect = $extractor->getByPath($variables, $candidate); if (NULL === $suspect) { return $candidate; } return $suspect; }
/** * Evaluate this node and return the correct object. * * Handles each part (denoted by .) in $this->objectPath in the following order: * - call appropriate getter * - call public property, if exists * - fail * * The first part of the object path has to be a variable in the * VariableProvider. * * @param RenderingContextInterface $renderingContext * @return mixed The evaluated object, can be any object type. */ public function evaluate(RenderingContextInterface $renderingContext) { $objectPath = strtolower($this->objectPath); $variableProvider = $renderingContext->getVariableProvider(); if ($objectPath === '_all') { return $variableProvider->getAll(); } return VariableExtractor::extract($variableProvider, $this->objectPath, $this->accessors); }
/** * Handles the appearance of an object accessor (like {posts.author.email}). * Creates a new instance of \TYPO3Fluid\Fluid\ObjectAccessorNode. * * Handles ViewHelpers as well which are in the shorthand syntax. * * @param ParsingState $state The current parsing state * @param string $objectAccessorString String which identifies which objects to fetch * @param string $delimiter * @param string $viewHelperString * @param string $additionalViewHelpersString * @return void */ protected function objectAccessorHandler(ParsingState $state, $objectAccessorString, $delimiter, $viewHelperString, $additionalViewHelpersString) { $viewHelperString .= $additionalViewHelpersString; $numberOfViewHelpers = 0; // The following post-processing handles a case when there is only a ViewHelper, and no Object Accessor. // Resolves bug #5107. if (strlen($delimiter) === 0 && strlen($viewHelperString) > 0) { $viewHelperString = $objectAccessorString . $viewHelperString; $objectAccessorString = ''; } // ViewHelpers $matches = array(); if (strlen($viewHelperString) > 0 && preg_match_all(Patterns::$SPLIT_PATTERN_SHORTHANDSYNTAX_VIEWHELPER, $viewHelperString, $matches, PREG_SET_ORDER) > 0) { // The last ViewHelper has to be added first for correct chaining. foreach (array_reverse($matches) as $singleMatch) { if (strlen($singleMatch['ViewHelperArguments']) > 0) { $arguments = $this->recursiveArrayHandler($singleMatch['ViewHelperArguments']); } else { $arguments = array(); } $viewHelperNode = $this->initializeViewHelperAndAddItToStack($state, $singleMatch['NamespaceIdentifier'], $singleMatch['MethodIdentifier'], $arguments); if ($viewHelperNode) { $numberOfViewHelpers++; } } } // Object Accessor if (strlen($objectAccessorString) > 0) { if ($state->isCompilable() && !$state->isCompiled()) { $accessors = VariableExtractor::extractAccessors($state->getVariableContainer(), $objectAccessorString); } else { $accessors = array(); } $node = new ObjectAccessorNode($objectAccessorString, $accessors); $this->callInterceptor($node, InterceptorInterface::INTERCEPT_OBJECTACCESSOR, $state); $state->getNodeFromStack()->addChildNode($node); } // Close ViewHelper Tags if needed. for ($i = 0; $i < $numberOfViewHelpers; $i++) { $node = $state->popNodeFromStack(); $this->callInterceptor($node, InterceptorInterface::INTERCEPT_CLOSING_VIEWHELPER, $state); $state->getNodeFromStack()->addChildNode($node); } }
/** * Groups the given array by the specified groupBy property. * * @param array $elements The array / traversable object to be grouped * @param string $groupBy Group by this property * @return array The grouped array in the form array('keys' => array('key1' => [key1value], 'key2' => [key2value], ...), 'values' => array('key1' => array([key1value] => [element1]), ...), ...) * @throws ViewHelper\Exception */ protected function groupElements(array $elements, $groupBy) { $extractor = new VariableExtractor(); $groups = array('keys' => array(), 'values' => array()); foreach ($elements as $key => $value) { if (is_array($value)) { $currentGroupIndex = isset($value[$groupBy]) ? $value[$groupBy] : NULL; } elseif (is_object($value)) { $currentGroupIndex = $extractor->getByPath($value, $groupBy); } else { throw new ViewHelper\Exception('GroupedForViewHelper only supports multi-dimensional arrays and objects', 1253120365); } $currentGroupKeyValue = $currentGroupIndex; if ($currentGroupIndex instanceof \DateTime) { $currentGroupIndex = $currentGroupIndex->format(\DateTime::RFC850); } elseif (is_object($currentGroupIndex)) { $currentGroupIndex = spl_object_hash($currentGroupIndex); } $groups['keys'][$currentGroupIndex] = $currentGroupKeyValue; $groups['values'][$currentGroupIndex][$key] = $value; } return $groups; }
/** * @param mixed $variable * @retrurn array */ protected static function getValuesOfNonScalarVariable($variable) { if ($variable instanceof \ArrayObject || is_array($variable)) { return (array) $variable; } elseif ($variable instanceof \Iterator) { return iterator_to_array($variable); } elseif (is_resource($variable)) { return stream_get_meta_data($variable); } elseif ($variable instanceof \DateTimeInterface) { return ['class' => get_class($variable), 'ISO8601' => $variable->format(\DateTime::ISO8601), 'UNIXTIME' => (int) $variable->format('U')]; } else { $reflection = new \ReflectionObject($variable); $properties = $reflection->getProperties(); $output = array(); foreach ($properties as $property) { $propertyName = $property->getName(); $output[$propertyName] = VariableExtractor::extract($variable, $propertyName); } return $output; } }
/** * @param mixed $subject * @param string $path * @param string $accessor * @param mixed $expected * @test * @dataProvider getExtractRedectAccessorTestValues */ public function testExtractRedetectsAccessorIfUnusableAccessorPassed($subject, $path, $accessor, $expected) { $result = VariableExtractor::extract($subject, 'test', array($accessor)); $this->assertEquals($expected, $result); }
/** * Evaluate this node and return the correct object. * * Handles each part (denoted by .) in $this->objectPath in the following order: * - call appropriate getter * - call public property, if exists * - fail * * The first part of the object path has to be a variable in the * VariableProvider. * * @param RenderingContextInterface $renderingContext * @return object The evaluated object, can be any object type. */ public function evaluate(RenderingContextInterface $renderingContext) { $variableProvider = $renderingContext->getVariableProvider(); switch (strtolower($this->objectPath)) { case '_all': return $variableProvider->getAll(); case 'true': case 'on': case 'yes': return TRUE; case 'false': case 'off': case 'no': return FALSE; default: return VariableExtractor::extract($variableProvider, $this->objectPath, $this->accessors); } }