/** * @param string $className * @param string $annotationName * @param string|boolean $propertyName * @return array|boolean */ public static function getAnnotationValueFromClass($className, $annotationName, $propertyName = NULL) { $reflection = new ClassReflection($className); $sample = new $className(); $annotations = array(); if (NULL === $propertyName) { if (FALSE === $reflection->isTaggedWith($annotationName)) { return FALSE; } $annotations = $reflection->getTagValues($annotationName); } elseif (FALSE === $propertyName) { $properties = ObjectAccess::getGettablePropertyNames($sample); foreach ($properties as $reflectedPropertyName) { if (FALSE === property_exists($className, $reflectedPropertyName)) { continue; } $propertyAnnotationValues = self::getPropertyAnnotations($reflection, $reflectedPropertyName, $annotationName); if (NULL !== $propertyAnnotationValues) { $annotations[$reflectedPropertyName] = $propertyAnnotationValues; } } } else { $annotations = self::getPropertyAnnotations($reflection, $propertyName, $annotationName); } $annotations = self::parseAnnotation($annotations); return NULL !== $propertyName && TRUE === isset($annotations[$propertyName]) ? $annotations[$propertyName] : $annotations; }
/** * @param $model * @return \stdClass */ public function transform($model) { if ($model instanceof \Traversable) { $out = array(); foreach ($model as $subModel) { $out[] = $this->transform($subModel); } return $out; } else { if ($model instanceof \TYPO3\CMS\Extbase\DomainObject\DomainObjectInterface) { $transformedObject = new \stdClass(); $properties = \TYPO3\CMS\Extbase\Reflection\ObjectAccess::getGettablePropertyNames($model); $class = get_class($model); foreach ($properties as $property) { $getMethodName = 'get' . ucfirst($property); $methodTags = $this->reflectionService->getMethodTagsValues($class, $getMethodName); // The Goal here is to be able to expose properties and methods with the JSONExpose annotation. if ($property == 'uid' || array_key_exists('JSONExpose', $methodTags) || $this->reflectionService->isPropertyTaggedWith($class, $property, 'JSONExpose')) { $value = $model->{$getMethodName}(); // TODO, not sure about this check for lazy loading. Would be good to write a test for it. if ($value instanceof \TYPO3\CMS\Extbase\Persistence\Generic\LazyLoadingProxy) { $transformedObject->{$property} = 'lazy'; } elseif ($this->typeHandlingService->isSimpleType(gettype($value))) { $transformedObject->{$property} = $value; } elseif (is_object($value)) { if ($value instanceof \TYPO3\CMS\Extbase\Persistence\ObjectStorage) { $transformedObject->{$property} = $this->transform($value); } else { $transformedObject->{$property} = get_class($value); } } } } return $transformedObject; } else { return NULL; } } }
/** * @param string $className * @param string $annotationName * @param string|boolean $propertyName * @return string */ public static function getAnnotationValueFromClass($className, $annotationName, $propertyName = FALSE) { if (TRUE === isset(self::$cache['reflections'][$className])) { $reflection = self::$cache['reflections'][$className]; } else { $reflection = self::$cache['reflections'][$className] = new ClassReflection($className); } if (FALSE === isset(self::$cache['annotations'][$className])) { self::$cache['annotations'][$className] = array(); } if (TRUE === isset(self::$cache['annotations'][$className][$annotationName])) { $annotations = self::$cache['annotations'][$className][$annotationName]; } else { $sample = new $className(); $annotations = array(); if (FALSE === $propertyName) { if (TRUE === $reflection->isTaggedWith($annotationName)) { $annotations = $reflection->getTagValues($annotationName); } } else { $properties = ObjectAccess::getGettablePropertyNames($sample); foreach ($properties as $reflectedPropertyName) { if (FALSE === property_exists($className, $reflectedPropertyName)) { continue; } $reflectedProperty = $reflection->getProperty($reflectedPropertyName); if (TRUE === $reflectedProperty->isTaggedWith($annotationName)) { $annotations[$reflectedPropertyName] = $reflectedProperty->getTagValues($annotationName); } } } $annotations = self::parseAnnotation($annotations); } self::$cache['annotations'][$className][$annotationName] = $annotations; if (NULL !== $propertyName && TRUE === isset($annotations[$propertyName])) { return $annotations[$propertyName]; } return $annotations; }
/** * Traverses the given object structure in order to transform it into an * array structure. * * @param object $object Object to traverse * @param array $configuration Configuration for transforming the given object or NULL * @return array Object structure as an array */ protected function transformObject($object, array $configuration) { if ($object instanceof \DateTime) { return $object->format(\DateTime::ISO8601); } else { $propertyNames = \TYPO3\CMS\Extbase\Reflection\ObjectAccess::getGettablePropertyNames($object); $propertiesToRender = array(); foreach ($propertyNames as $propertyName) { if (isset($configuration['_only']) && is_array($configuration['_only']) && !in_array($propertyName, $configuration['_only'])) { continue; } if (isset($configuration['_exclude']) && is_array($configuration['_exclude']) && in_array($propertyName, $configuration['_exclude'])) { continue; } $propertyValue = \TYPO3\CMS\Extbase\Reflection\ObjectAccess::getProperty($object, $propertyName); if (!is_array($propertyValue) && !is_object($propertyValue)) { $propertiesToRender[$propertyName] = $propertyValue; } elseif (isset($configuration['_descend']) && array_key_exists($propertyName, $configuration['_descend'])) { $propertiesToRender[$propertyName] = $this->transformValue($propertyValue, $configuration['_descend'][$propertyName]); } } if (isset($configuration['_exposeObjectIdentifier']) && $configuration['_exposeObjectIdentifier'] === TRUE) { if (isset($configuration['_exposedObjectIdentifierKey']) && strlen($configuration['_exposedObjectIdentifierKey']) > 0) { $identityKey = $configuration['_exposedObjectIdentifierKey']; } else { $identityKey = '__identity'; } $propertiesToRender[$identityKey] = $this->persistenceManager->getIdentifierByObject($object); } if (isset($configuration['_exposeClassName']) && ($configuration['_exposeClassName'] === self::EXPOSE_CLASSNAME_FULLY_QUALIFIED || $configuration['_exposeClassName'] === self::EXPOSE_CLASSNAME_UNQUALIFIED)) { $className = get_class($object); $classNameParts = explode('\\', $className); $propertiesToRender['__class'] = $configuration['_exposeClassName'] === self::EXPOSE_CLASSNAME_FULLY_QUALIFIED ? $className : array_pop($classNameParts); } return $propertiesToRender; } }
/** * @test */ public function getGettablePropertyNamesReturnsAllPropertiesWhichAreAvailable() { $gettablePropertyNames = \TYPO3\CMS\Extbase\Reflection\ObjectAccess::getGettablePropertyNames($this->dummyObject); $expectedPropertyNames = array('anotherBooleanProperty', 'anotherProperty', 'booleanProperty', 'property', 'property2', 'publicProperty', 'publicProperty2'); $this->assertEquals($gettablePropertyNames, $expectedPropertyNames, 'getGettablePropertyNames returns not all gettable properties.'); }
/** * @test */ public function specialSupportGettersReturnExpectedTypes() { $file = $this->getAbsoluteAssetFixturePath(); $asset = Asset::createFromFile($file); $gettableProperties = ObjectAccess::getGettablePropertyNames($asset); $objectManager = GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager'); foreach ($gettableProperties as $propertyName) { if (FALSE === property_exists('FluidTYPO3\\Vhs\\Asset', $propertyName)) { continue; } $propertyValue = ObjectAccess::getProperty($asset, $propertyName); /** @var \TYPO3\CMS\Extbase\Reflection\PropertyReflection $propertyReflection */ $propertyReflection = $objectManager->get('TYPO3\\CMS\\Extbase\\Reflection\\PropertyReflection', 'FluidTYPO3\\Vhs\\Asset', $propertyName); $expectedDataType = array_pop($propertyReflection->getTagValues('var')); $constraint = new \PHPUnit_Framework_Constraint_IsType($expectedDataType); $this->assertThat($propertyValue, $constraint); } $constraint = new \PHPUnit_Framework_Constraint_IsType('array'); $this->assertThat($asset->getDebugInformation(), $constraint); $this->assertThat($asset->getAssetSettings(), $constraint); $this->assertGreaterThan(0, count($asset->getAssetSettings())); $this->assertThat($asset->getSettings(), $constraint); $this->assertGreaterThan(0, count($asset->getSettings())); $this->assertNotNull($asset->getContent()); }
/** * @return string */ public function render() { $nodes = array(); foreach ($this->childViewHelperNodes as $viewHelperNode) { $viewHelper = $viewHelperNode->getUninitializedViewHelper(); $arguments = $viewHelper->prepareArguments(); $givenArguments = $viewHelperNode->getArguments(); $viewHelperReflection = new \ReflectionClass($viewHelper); $viewHelperDescription = $viewHelperReflection->getDocComment(); $viewHelperDescription = htmlentities($viewHelperDescription); $viewHelperDescription = '[CLASS DOC]' . LF . $viewHelperDescription . LF; $renderMethodDescription = $viewHelperReflection->getMethod('render')->getDocComment(); $renderMethodDescription = htmlentities($renderMethodDescription); $renderMethodDescription = implode(LF, array_map('trim', explode(LF, $renderMethodDescription))); $renderMethodDescription = '[RENDER METHOD DOC]' . LF . $renderMethodDescription . LF; $argumentDefinitions = array(); foreach ($arguments as $argument) { $name = $argument->getName(); $argumentDefinitions[$name] = ObjectAccess::getGettableProperties($argument); } $sections = array($viewHelperDescription, DebuggerUtility::var_dump($argumentDefinitions, '[ARGUMENTS]', 4, TRUE, FALSE, TRUE), DebuggerUtility::var_dump($givenArguments, '[CURRENT ARGUMENTS]', 4, TRUE, FALSE, TRUE), $renderMethodDescription); array_push($nodes, implode(LF, $sections)); } if (0 < count($this->childObjectAccessorNodes)) { array_push($nodes, '[VARIABLE ACCESSORS]'); $templateVariables = $this->templateVariableContainer->getAll(); foreach ($this->childObjectAccessorNodes as $objectAccessorNode) { $path = $objectAccessorNode->getObjectPath(); $segments = explode('.', $path); try { $value = ObjectAccess::getProperty($templateVariables, array_shift($segments)); foreach ($segments as $segment) { $value = ObjectAccess::getProperty($value, $segment); } $type = gettype($value); } catch (PropertyNotAccessibleException $error) { $value = NULL; $type = 'UNDEFINED/INACCESSIBLE'; } $sections = array('Path: {' . $path . '}', 'Value type: ' . $type); if (TRUE === is_object($value)) { $sections[] = 'Accessible properties on {' . $path . '}:'; $gettable = ObjectAccess::getGettablePropertyNames($value); unset($gettable[0]); foreach ($gettable as $gettableProperty) { $sections[] = ' {' . $path . '.' . $gettableProperty . '} (' . gettype(ObjectAccess::getProperty($value, $gettableProperty)) . ')'; } } elseif (NULL !== $value) { $sections[] = DebuggerUtility::var_dump($value, 'Dump of variable "' . $path . '"', 4, TRUE, FALSE, TRUE); } array_push($nodes, implode(LF, $sections)); } } return '<pre>' . implode(LF . LF, $nodes) . '</pre>'; }
/** * Traverses the given object structure in order to transform it into an * array structure. * * @param object $object Object to traverse * @param mixed $configuration Configuration for transforming the given object or NULL * @return array Object structure as an aray * @author Christopher Hlubek <*****@*****.**> * @author Dennis Ahrens <*****@*****.**> */ protected function transformObject($object, $configuration) { // hand over DateTime as ISO formatted string if ($object instanceof DateTime) { return $object->format('c'); } // load LayzyLoadingProxy instances if ($object instanceof \TYPO3\CMS\Extbase\Persistence\Generic\LazyLoadingProxy) { $object = $object->_loadRealInstance(); } $propertyNames = \TYPO3\CMS\Extbase\Reflection\ObjectAccess::getGettablePropertyNames($object); $propertiesToRender = array(); foreach ($propertyNames as $propertyName) { if (isset($configuration['_only']) && is_array($configuration['_only']) && !in_array($propertyName, $configuration['_only'])) { continue; } if (isset($configuration['_exclude']) && is_array($configuration['_exclude']) && in_array($propertyName, $configuration['_exclude'])) { continue; } $propertyValue = \TYPO3\CMS\Extbase\Reflection\ObjectAccess::getProperty($object, $propertyName); if (!is_array($propertyValue) && !is_object($propertyValue)) { $propertiesToRender[$propertyName] = $propertyValue; } elseif (isset($configuration['_descend']) && array_key_exists($propertyName, $configuration['_descend'])) { $propertiesToRender[$propertyName] = $this->transformValue($propertyValue, $configuration['_descend'][$propertyName]); } else { } } if (isset($configuration['_exposeObjectIdentifier']) && $configuration['_exposeObjectIdentifier'] === true) { // we don't use the IdentityMap like its done in FLOW3 because there are some cases objects are not registered there. // TODO: rethink this solution - it is really quick and dirty... $propertiesToRender['__identity'] = $object->getUid(); } return $propertiesToRender; }