/**
  * {@inheritdoc}
  *
  * @param object $element
  * @param string $propertyPath
  * @return mixed
  */
 protected function getPropertyPath($element, $propertyPath)
 {
     if ($propertyPath[0] === '_') {
         return \TYPO3\FLOW3\Reflection\ObjectAccess::getPropertyPath($element, substr($propertyPath, 1));
     } else {
         return $element->getProperty($propertyPath);
     }
 }
 /**
  * @test
  */
 public function overridingFromTypoScriptInFilesystemFollowingNodePathsWorks()
 {
     $typoScriptService = $this->objectManager->get('TYPO3\\TYPO3\\Domain\\Service\\TypoScriptService');
     ObjectAccess::setProperty($typoScriptService, 'typoScriptsPathPattern', __DIR__ . '/Fixtures/ResourcesFixture/TypoScripts', TRUE);
     $objectTree = $typoScriptService->getMergedTypoScriptObjectTree($this->homeNode, $this->homeNode->getNode('about-us/history'));
     $this->assertEquals('Root', $objectTree['text1']['value']);
     $this->assertEquals('AboutUs', $objectTree['text2']['value']);
     $this->assertEquals('History', $objectTree['text3']['value']);
     $this->assertEquals('Additional', $objectTree['text4']['value']);
 }
 public function setUp()
 {
     parent::setUp();
     $nodeRepository = $this->objectManager->get('TYPO3\\TYPO3CR\\Domain\\Repository\\NodeRepository');
     \TYPO3\FLOW3\Reflection\ObjectAccess::setProperty($nodeRepository, 'context', new \TYPO3\TYPO3\Domain\Service\ContentContext('live'), TRUE);
     $siteImportService = $this->objectManager->get('TYPO3\\TYPO3\\Domain\\Service\\SiteImportService');
     $siteImportService->importSitesFromFile(__DIR__ . '/Fixtures/NodeStructure.xml');
     $this->persistenceManager->persistAll();
     $propertyMapper = $this->objectManager->get('TYPO3\\FLOW3\\Property\\PropertyMapper');
     $this->node = $propertyMapper->convert('/sites/example/home', 'TYPO3\\TYPO3CR\\Domain\\Model\\Node');
     $this->assertFalse($propertyMapper->getMessages()->hasErrors());
 }
Exemple #4
0
 /**
  * Updates the password credential from the POST vars, if the POST parameters
  * are available. Sets the authentication status to AUTHENTICATION_NEEDED, if credentials have been sent.
  *
  * Note: You need to send the password in this POST parameter:
  *       __authentication[TYPO3][FLOW3][Security][Authentication][Token][PasswordToken][password]
  *
  * @param \TYPO3\FLOW3\Mvc\ActionRequest $actionRequest The current action request
  * @return void
  */
 public function updateCredentials(\TYPO3\FLOW3\Mvc\ActionRequest $actionRequest)
 {
     if ($actionRequest->getHttpRequest()->getMethod() !== 'POST') {
         return;
     }
     $postArguments = $actionRequest->getInternalArguments();
     $password = \TYPO3\FLOW3\Reflection\ObjectAccess::getPropertyPath($postArguments, '__authentication.TYPO3.FLOW3.Security.Authentication.Token.PasswordToken.password');
     if (!empty($password)) {
         $this->credentials['password'] = $password;
         $this->setAuthenticationStatus(self::AUTHENTICATION_NEEDED);
     }
 }
 public function getMapping($key)
 {
     if (isset($this->mappings[$key])) {
         $property = $this->mappings[$key];
         if (isset($this->object->properties[$property])) {
             return $this->object->properties[$property]->value;
         }
         return \TYPO3\FLOW3\Reflection\ObjectAccess::getProperty($this->object->object, $property);
     }
     if (isset($this->object->properties[$key])) {
         return $this->object->properties[$key]->value;
     }
     #		$getter = "get" . ucfirst($key);
     #		if(method_exists($this->object->object, $getter))
     #			return call_user_func(array($this->object->object, $getter));
     return false;
 }
 /**
  * {@inheritdoc}
  *
  * @param \TYPO3\Eel\FlowQuery\FlowQuery $flowQuery the FlowQuery object
  * @param array $arguments the arguments for this operation
  * @return mixed|null if the operation is final, the return value
  */
 public function evaluate(\TYPO3\Eel\FlowQuery\FlowQuery $flowQuery, array $arguments)
 {
     if (!isset($arguments[0]) || empty($arguments[0])) {
         throw new \TYPO3\Eel\FlowQuery\FlowQueryException('property() does not support returning all attributes yet', 1332492263);
     } else {
         $context = $flowQuery->getContext();
         $propertyPath = $arguments[0];
         if (!isset($context[0])) {
             return NULL;
         }
         $element = $context[0];
         if ($propertyPath[0] === '_') {
             return \TYPO3\FLOW3\Reflection\ObjectAccess::getPropertyPath($element, substr($propertyPath, 1));
         } else {
             return $element->getProperty($propertyPath);
         }
     }
 }
Exemple #7
0
 /**
  * Check the property value for allowed types and throw exceptions for
  * unsupported types.
  *
  * @param object $object The object with the property to check
  * @param string $propertyName The name of the property to check
  * @param array $propertyMetaData Property metadata
  * @return mixed The value of the property
  * @throws \TYPO3\FLOW3\Persistence\Generic\Exception\UnexpectedTypeException
  * @throws \TYPO3\FLOW3\Persistence\Exception
  * @throws \TYPO3\FLOW3\Persistence\Exception\IllegalObjectTypeException
  * @api
  */
 protected function checkPropertyValue($object, $propertyName, array $propertyMetaData)
 {
     $propertyValue = \TYPO3\FLOW3\Reflection\ObjectAccess::getProperty($object, $propertyName, TRUE);
     $propertyType = $propertyMetaData['type'];
     if ($propertyType === 'ArrayObject') {
         throw new \TYPO3\FLOW3\Persistence\Exception('ArrayObject properties are not supported - missing feature?!?', 1283524355);
     }
     if (is_object($propertyValue)) {
         if ($propertyType === 'object') {
             if (!$propertyValue instanceof \TYPO3\FLOW3\Persistence\Aspect\PersistenceMagicInterface) {
                 throw new \TYPO3\FLOW3\Persistence\Exception\IllegalObjectTypeException('Property of generic type object holds "' . get_class($propertyValue) . '", which is not persistable (no entity or value object), in ' . get_class($object) . '::' . $propertyName, 1283531761);
             }
         } elseif (!$propertyValue instanceof $propertyType) {
             throw new \TYPO3\FLOW3\Persistence\Generic\Exception\UnexpectedTypeException('Expected property of type ' . $propertyType . ', but got ' . get_class($propertyValue) . ' for ' . get_class($object) . '::' . $propertyName, 1244465558);
         }
     } elseif ($propertyValue !== NULL && $propertyType !== $this->getType($propertyValue)) {
         throw new \TYPO3\FLOW3\Persistence\Generic\Exception\UnexpectedTypeException('Expected property of type ' . $propertyType . ', but got ' . gettype($propertyValue) . ' for ' . get_class($object) . '::' . $propertyName, 1244465559);
     }
     return $propertyValue;
 }
Exemple #8
0
 /**
  * Creates a URI representation (path segment) for the given object matching $this->uriPattern.
  *
  * @param mixed $object object of type $this->objectType
  * @return string URI representation (path segment) of the given object
  * @throws \TYPO3\FLOW3\Mvc\Exception\InvalidUriPatternException
  */
 protected function createPathSegmentForObject($object)
 {
     $uriPattern = $this->getUriPattern();
     if ($uriPattern === '') {
         return $this->rewriteForUri($this->persistenceManager->getIdentifierByObject($object));
     }
     $matches = array();
     preg_match_all('/(?P<dynamic>{?)(?P<content>[^}{]+)}?/', $uriPattern, $matches, PREG_SET_ORDER);
     $pathSegment = '';
     foreach ($matches as $match) {
         if (empty($match['dynamic'])) {
             $pathSegment .= $match['content'];
         } else {
             $dynamicPathSegmentParts = explode(':', $match['content']);
             $propertyPath = $dynamicPathSegmentParts[0];
             $dynamicPathSegment = \TYPO3\FLOW3\Reflection\ObjectAccess::getPropertyPath($object, $propertyPath);
             if (is_object($dynamicPathSegment)) {
                 if ($dynamicPathSegment instanceof \DateTime) {
                     $dateFormat = isset($dynamicPathSegmentParts[1]) ? trim($dynamicPathSegmentParts[1]) : 'Y-m-d';
                     $pathSegment .= $this->rewriteForUri($dynamicPathSegment->format($dateFormat));
                 } else {
                     throw new \TYPO3\FLOW3\Mvc\Exception\InvalidUriPatternException('Invalid uriPattern "' . $uriPattern . '" for route part "' . $this->getName() . '". Property "' . $propertyPath . '" must be of type string or \\DateTime. "' . (is_object($dynamicPathSegment) ? get_class($dynamicPathSegment) : gettype($dynamicPathSegment)) . '" given.', 1316442409);
                 }
             } else {
                 $pathSegment .= $this->rewriteForUri($dynamicPathSegment);
             }
         }
     }
     return $pathSegment;
 }
Exemple #9
0
 /**
  * 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
  */
 protected function transformObject($object, $configuration)
 {
     if ($object instanceof \DateTime) {
         return $object->format('Y-m-d\\TH:i:s');
     } else {
         $propertyNames = \TYPO3\FLOW3\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\FLOW3\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);
         }
         return $propertiesToRender;
     }
 }
Exemple #10
0
 /**
  * Convert an object from $source to an object.
  *
  * @param mixed $source
  * @param string $targetType
  * @param array $convertedChildProperties
  * @param \TYPO3\FLOW3\Property\PropertyMappingConfigurationInterface $configuration
  * @return object the target type
  * @throws \TYPO3\FLOW3\Property\Exception\InvalidTargetException
  * @throws \TYPO3\FLOW3\Property\Exception\InvalidDataTypeException
  * @throws \TYPO3\FLOW3\Property\Exception\InvalidPropertyMappingConfigurationException
  */
 public function convertFrom($source, $targetType, array $convertedChildProperties = array(), \TYPO3\FLOW3\Property\PropertyMappingConfigurationInterface $configuration = NULL)
 {
     $effectiveTargetType = $targetType;
     if (isset($source['__type'])) {
         if ($configuration->getConfigurationValue('TYPO3\\FLOW3\\Property\\TypeConverter\\ObjectConverter', self::CONFIGURATION_OVERRIDE_TARGET_TYPE_ALLOWED) !== TRUE) {
             throw new \TYPO3\FLOW3\Property\Exception\InvalidPropertyMappingConfigurationException('Override of target type not allowed. To enable this, you need to set the PropertyMappingConfiguration Value "CONFIGURATION_OVERRIDE_TARGET_TYPE_ALLOWED" to TRUE.', 1317051258);
         }
         $effectiveTargetType = $source['__type'];
     }
     $object = $this->buildObject($convertedChildProperties, $effectiveTargetType);
     if ($effectiveTargetType !== $targetType && !$object instanceof $targetType) {
         throw new \TYPO3\FLOW3\Property\Exception\InvalidDataTypeException('The given type "' . $source['__type'] . '" is not a subtype of "' . $targetType . '"', 1317051266);
     }
     foreach ($convertedChildProperties as $propertyName => $propertyValue) {
         $result = \TYPO3\FLOW3\Reflection\ObjectAccess::setProperty($object, $propertyName, $propertyValue);
         if ($result === FALSE) {
             throw new \TYPO3\FLOW3\Property\Exception\InvalidTargetException('Property "' . $propertyName . '" having a value of type "' . (is_object($propertyValue) ? get_class($propertyValue) : gettype($propertyValue)) . '" could not be set in target object of type "' . $targetType . '".', 1304538165);
         }
     }
     return $object;
 }
Exemple #11
0
 /**
  * Renders a dump of the given object
  *
  * @param object $object
  * @param integer $level
  * @param boolean $renderProperties
  * @param boolean $plaintext
  * @param boolean $ansiColors
  * @return string
  */
 protected static function renderObjectDump($object, $level, $renderProperties = TRUE, $plaintext = FALSE, $ansiColors = FALSE)
 {
     $dump = '';
     $scope = '';
     $additionalAttributes = '';
     if ($object instanceof \Doctrine\Common\Collections\Collection) {
         return self::renderArrayDump(\Doctrine\Common\Util\Debug::export($object, 12), $level, $plaintext, $ansiColors);
     }
     // Objects returned from Doctrine's Debug::export function are stdClass with special properties:
     try {
         $objectIdentifier = ObjectAccess::getProperty($object, 'FLOW3_Persistence_Identifier', TRUE);
     } catch (\TYPO3\FLOW3\Reflection\Exception\PropertyNotAccessibleException $exception) {
         $objectIdentifier = spl_object_hash($object);
     }
     $className = $object instanceof \stdClass && isset($object->__CLASS__) ? $object->__CLASS__ : get_class($object);
     if (preg_match(self::$blacklistedClassNames, $className) !== 0 || isset(self::$renderedObjects[$objectIdentifier])) {
         $renderProperties = FALSE;
     }
     self::$renderedObjects[$objectIdentifier] = TRUE;
     if (self::$objectManager !== NULL) {
         $objectName = self::$objectManager->getObjectNameByClassName(get_class($object));
         if ($objectName !== FALSE) {
             switch (self::$objectManager->getScope($objectName)) {
                 case \TYPO3\FLOW3\Object\Configuration\Configuration::SCOPE_PROTOTYPE:
                     $scope = 'prototype';
                     break;
                 case \TYPO3\FLOW3\Object\Configuration\Configuration::SCOPE_SINGLETON:
                     $scope = 'singleton';
                     break;
                 case \TYPO3\FLOW3\Object\Configuration\Configuration::SCOPE_SESSION:
                     $scope = 'session';
                     break;
             }
         } else {
             $additionalAttributes .= ' debug-unregistered';
         }
     }
     if ($renderProperties === TRUE && !$plaintext) {
         if ($scope === '') {
             $scope = 'prototype';
         }
         $scope .= '<a id="o' . $objectIdentifier . '"></a>';
     }
     if ($plaintext) {
         $dump .= $className;
         $dump .= $scope !== '' ? ' ' . self::ansiEscapeWrap($scope, '44;37', $ansiColors) : '';
     } else {
         $dump .= '<span class="debug-object' . $additionalAttributes . '" title="' . $objectIdentifier . '">' . $className . '</span>';
         $dump .= $scope !== '' ? '<span class="debug-scope">' . $scope . '</span>' : '';
     }
     if (property_exists($object, 'FLOW3_Persistence_Identifier')) {
         $persistenceIdentifier = $objectIdentifier;
         $persistenceType = 'persistable';
     } else {
         $persistenceIdentifier = 'unknown';
         $persistenceType = 'object';
     }
     if ($plaintext) {
         $dump .= ' ' . self::ansiEscapeWrap($persistenceType, '42;37', $ansiColors);
     } else {
         $dump .= '<span class="debug-ptype" title="' . $persistenceIdentifier . '">' . $persistenceType . '</span>';
     }
     if ($object instanceof \TYPO3\FLOW3\Object\Proxy\ProxyInterface || isset($object->__IS_PROXY__) && $object->__IS_PROXY__ === TRUE) {
         if ($plaintext) {
             $dump .= ' ' . self::ansiEscapeWrap('proxy', '41;37', $ansiColors);
         } else {
             $dump .= '<span class="debug-proxy" title="' . $className . '">proxy</span>';
         }
     }
     if ($renderProperties === TRUE) {
         if ($object instanceof \SplObjectStorage) {
             $dump .= ' (' . (count($object) ?: 'empty') . ')';
             foreach ($object as $value) {
                 $dump .= chr(10);
                 $dump .= str_repeat(' ', $level);
                 $dump .= self::renderObjectDump($value, 0, FALSE, $plaintext, $ansiColors);
             }
         } else {
             $classReflection = new \ReflectionClass($className);
             $properties = $classReflection->getProperties();
             foreach ($properties as $property) {
                 if (preg_match(self::$blacklistedPropertyNames, $property->getName())) {
                     continue;
                 }
                 $dump .= chr(10);
                 $dump .= str_repeat(' ', $level) . ($plaintext ? '' : '<span class="debug-property">') . self::ansiEscapeWrap($property->getName(), '36', $ansiColors) . ($plaintext ? '' : '</span>') . ' => ';
                 $property->setAccessible(TRUE);
                 $value = $property->getValue($object);
                 if (is_array($value)) {
                     $dump .= self::renderDump($value, $level + 1, $plaintext, $ansiColors);
                 } elseif (is_object($value)) {
                     $dump .= self::renderObjectDump($value, $level + 1, TRUE, $plaintext, $ansiColors);
                 } else {
                     $dump .= self::renderDump($value, $level, $plaintext, $ansiColors);
                 }
             }
         }
     } elseif (isset(self::$renderedObjects[$objectIdentifier])) {
         if (!$plaintext) {
             $dump = '<a href="#o' . $objectIdentifier . '" onclick="document.location.hash=\'#o' . $objectIdentifier . '\'; return false;" class="debug-seeabove" title="see above">' . $dump . '</a>';
         }
     }
     return $dump;
 }
Exemple #12
0
 /**
  * Returns the route value of the current route part.
  * This method can be overridden by custom RoutePartHandlers to implement custom resolving mechanisms.
  *
  * @param array $routeValues An array with key/value pairs to be resolved by Dynamic Route Parts.
  * @return string|array value to resolve.
  * @api
  */
 protected function findValueToResolve(array $routeValues)
 {
     return \TYPO3\FLOW3\Reflection\ObjectAccess::getPropertyPath($routeValues, $this->name);
 }
Exemple #13
0
 /**
  * @test
  */
 public function getPropertyPathReturnsNullIfSubjectOnPathIsNoObject()
 {
     $object = new \stdClass();
     $object->foo = 'Hello World';
     $this->assertNull(\TYPO3\FLOW3\Reflection\ObjectAccess::getPropertyPath($object, 'foo.bar'));
 }
 /**
  * After returning advice, generates the value hash for the object
  *
  * @param \TYPO3\FLOW3\Aop\JoinPointInterface $joinPoint The current join point
  * @return void
  * @FLOW3\Before("classAnnotatedWith(TYPO3\FLOW3\Annotations\ValueObject) && method(.*->__construct())")
  */
 public function generateValueHash(\TYPO3\FLOW3\Aop\JoinPointInterface $joinPoint)
 {
     $proxy = $joinPoint->getProxy();
     $hashSource = get_class($proxy);
     if (property_exists($proxy, 'FLOW3_Persistence_Identifier')) {
         $hashSource .= \TYPO3\FLOW3\Reflection\ObjectAccess::getProperty($proxy, 'FLOW3_Persistence_Identifier', TRUE);
     }
     foreach ($joinPoint->getMethodArguments() as $argumentValue) {
         if (is_array($argumentValue)) {
             $hashSource .= $this->useIgBinary === TRUE ? igbinary_serialize($argumentValue) : serialize($argumentValue);
         } elseif (!is_object($argumentValue)) {
             $hashSource .= $argumentValue;
         } elseif (property_exists($argumentValue, 'FLOW3_Persistence_Identifier')) {
             $hashSource .= \TYPO3\FLOW3\Reflection\ObjectAccess::getProperty($argumentValue, 'FLOW3_Persistence_Identifier', TRUE);
         } elseif ($argumentValue instanceof \DateTime) {
             $hashSource .= $argumentValue->getTimestamp();
         }
     }
     $proxy = $joinPoint->getProxy();
     \TYPO3\FLOW3\Reflection\ObjectAccess::setProperty($proxy, 'FLOW3_Persistence_Identifier', sha1($hashSource), TRUE);
 }
 /**
  * Load the property value to be used for validation.
  *
  * In case the object is a doctrine proxy, we need to load the real instance first.
  *
  * @param object $object
  * @param string $propertyName
  * @return mixed
  */
 protected function getPropertyValue($object, $propertyName)
 {
     if ($object instanceof \Doctrine\ORM\Proxy\Proxy) {
         $reflectionLoadMethod = new \ReflectionMethod($object, '__load');
         $reflectionLoadMethod->setAccessible(TRUE);
         $reflectionLoadMethod->invoke($object);
     }
     if (\TYPO3\FLOW3\Reflection\ObjectAccess::isPropertyGettable($object, $propertyName)) {
         return \TYPO3\FLOW3\Reflection\ObjectAccess::getProperty($object, $propertyName);
     } else {
         return \TYPO3\FLOW3\Reflection\ObjectAccess::getProperty($object, $propertyName, TRUE);
     }
 }
 /**
  * Converts the specified node path into a Node.
  *
  * The node path must be an absolute context node path and can be specified as a string or as an array item with the
  * key "__contextNodePath". The latter case is for updating existing nodes.
  *
  * This conversion method does not support / allow creation of new nodes because new nodes should be created through
  * the createNode() method of an existing reference node.
  *
  * Also note that the context's "current node" is not affected by this object converter, you will need to set it to
  * whatever node your "current" node is, if any.
  *
  * All elements in the source array which start with two underscores (like __contextNodePath) are specially treated
  * by this converter.
  *
  * All elements in the source array which start with a *single underscore (like _hidden) are *directly* set on the Node
  * object.
  *
  * All other elements, not being prefixed with underscore, are properties of the node.
  *
  * @param string|array $source Either a string or array containing the absolute context node path which identifies the node. For example "/sites/mysitecom/homepage/about@user-admin"
  * @param string $targetType not used
  * @param array $subProperties not used
  * @param \TYPO3\FLOW3\Property\PropertyMappingConfigurationInterface $configuration not used
  * @return mixed An object or \TYPO3\FLOW3\Error\Error if the input format is not supported or could not be converted for other reasons
  * @throws \Exception
  */
 public function convertFrom($source, $targetType, array $subProperties = array(), \TYPO3\FLOW3\Property\PropertyMappingConfigurationInterface $configuration = NULL)
 {
     if (is_string($source)) {
         $source = array('__contextNodePath' => $source);
     }
     if (!is_array($source) || !isset($source['__contextNodePath'])) {
         return new Error('Could not convert ' . gettype($source) . ' to Node object, a valid absolute context node path as a string or array is expected.', 1302879936);
     }
     preg_match(NodeInterface::MATCH_PATTERN_CONTEXTPATH, $source['__contextNodePath'], $matches);
     if (!isset($matches['NodePath'])) {
         return new Error('Could not convert array to Node object because the node path was invalid.', 1285162903);
     }
     $nodePath = $matches['NodePath'];
     if ($this->nodeRepository->getContext() === NULL) {
         $workspaceName = isset($matches['WorkspaceName']) ? $matches['WorkspaceName'] : 'live';
         $contentContext = new ContentContext($workspaceName);
         $this->nodeRepository->setContext($contentContext);
     } else {
         $contentContext = $this->nodeRepository->getContext();
         $workspaceName = $contentContext->getWorkspace()->getName();
     }
     if ($workspaceName !== 'live') {
         $contentContext->setInvisibleContentShown(TRUE);
         if ($configuration->getConfigurationValue('TYPO3\\TYPO3\\Routing\\NodeObjectConverter', self::REMOVED_CONTENT_SHOWN) === TRUE) {
             $contentContext->setRemovedContentShown(TRUE);
         }
     }
     $workspace = $contentContext->getWorkspace(FALSE);
     if (!$workspace) {
         return new Error(sprintf('Could not convert %s to Node object because the workspace "%s" as specified in the context node path does not exist.', $source['__contextNodePath'], $workspaceName), 1285162905);
     }
     $currentAccessModeFromContext = $contentContext->isInaccessibleContentShown();
     $contentContext->setInaccessibleContentShown(TRUE);
     $node = $contentContext->getNode($nodePath);
     $contentContext->setInaccessibleContentShown($currentAccessModeFromContext);
     if (!$node) {
         return new Error(sprintf('Could not convert array to Node object because the node "%s" does not exist.', $nodePath), 1285162908);
     }
     $contentTypeProperties = $node->getContentType()->getProperties();
     foreach ($source as $nodePropertyKey => $nodePropertyValue) {
         if (substr($nodePropertyKey, 0, 2) === '__') {
             continue;
         }
         if ($nodePropertyKey[0] === '_') {
             $propertyName = substr($nodePropertyKey, 1);
             // TODO: Hack: we need to create DateTime objects for some properties of Node
             if (($propertyName === 'hiddenBeforeDateTime' || $propertyName === 'hiddenAfterDateTime') && is_string($nodePropertyValue)) {
                 if ($nodePropertyValue !== '') {
                     $nodePropertyValue = \DateTime::createFromFormat('!Y-m-d', $nodePropertyValue);
                 } else {
                     $nodePropertyValue = NULL;
                 }
             }
             \TYPO3\FLOW3\Reflection\ObjectAccess::setProperty($node, $propertyName, $nodePropertyValue);
         } else {
             if (!isset($contentTypeProperties[$nodePropertyKey])) {
                 throw new \Exception('TODO: content type XY does not have a property YY according to the schema');
             }
             if (isset($contentTypeProperties[$nodePropertyKey]['type'])) {
                 $targetType = $contentTypeProperties[$nodePropertyKey]['type'];
                 if ($this->objectManager->isRegistered($targetType)) {
                     $nodePropertyValue = $this->propertyMapper->convert(json_decode($nodePropertyValue, TRUE), $targetType);
                 }
             }
             $node->setProperty($nodePropertyKey, $nodePropertyValue);
         }
     }
     return $node;
 }
Exemple #17
0
 public function toArray()
 {
     $array = array();
     $properties = get_class_vars(get_class($this));
     foreach ($properties as $property => $value) {
         $value = \TYPO3\FLOW3\Reflection\ObjectAccess::getProperty($this, $property);
         if (is_object($value) && is_callable(array($value, "__toString"))) {
             $array[$property] = strval($value);
         } else {
             $array[$property] = $value;
         }
     }
     return $array;
 }
Exemple #18
0
 /**
  * Returns the identifier for the given object either from
  * the session, if the object was registered, or from the object
  * itself using a special uuid property or the internal
  * properties set by AOP.
  *
  * Note: this returns an UUID even if the object has not been persisted
  * in case of AOP-managed entities. Use isNewObject() if you need
  * to distinguish those cases.
  *
  * @param object $object
  * @return string
  * @api
  */
 public function getIdentifierByObject($object)
 {
     if ($this->hasObject($object)) {
         return $this->objectMap[$object];
     }
     $idPropertyNames = $this->reflectionService->getPropertyNamesByTag(get_class($object), 'id');
     if (count($idPropertyNames) === 1) {
         $idPropertyName = $idPropertyNames[0];
         return \TYPO3\FLOW3\Reflection\ObjectAccess::getProperty($object, $idPropertyName, TRUE);
     } elseif (property_exists($object, 'FLOW3_Persistence_Identifier')) {
         return \TYPO3\FLOW3\Reflection\ObjectAccess::getProperty($object, 'FLOW3_Persistence_Identifier', TRUE);
     }
     return NULL;
 }
 /**
  * Wrap the $content identified by $node with the needed markup for
  * the backend.
  * $parameters can be used to further pass parameters to the content element.
  *
  * @param \TYPO3\TYPO3CR\Domain\Model\NodeInterface $node
  * @param string $typoscriptPath
  * @param string $content
  * @param boolean $isPage
  * @return string
  */
 public function wrapContentObject(\TYPO3\TYPO3CR\Domain\Model\NodeInterface $node, $typoscriptPath, $content, $isPage = FALSE)
 {
     $contentType = $node->getContentType();
     $tagBuilder = new \TYPO3\Fluid\Core\ViewHelper\TagBuilder('div');
     $tagBuilder->forceClosingTag(TRUE);
     if (!$node->isRemoved()) {
         $tagBuilder->setContent($content);
     }
     if (!$isPage) {
         $cssClasses = array('t3-contentelement');
         $cssClasses[] = str_replace(array(':', '.'), '-', strtolower($contentType->getName()));
         if ($node->isHidden()) {
             $cssClasses[] = 't3-contentelement-hidden';
         }
         if ($node->isRemoved()) {
             $cssClasses[] = 't3-contentelement-removed';
         }
         $tagBuilder->addAttribute('class', implode(' ', $cssClasses));
         $tagBuilder->addAttribute('id', 'c' . $node->getIdentifier());
     }
     try {
         $this->accessDecisionManager->decideOnResource('TYPO3_TYPO3_Backend_BackendController');
     } catch (\TYPO3\FLOW3\Security\Exception\AccessDeniedException $e) {
         return $tagBuilder->render();
     }
     $tagBuilder->addAttribute('typeof', 'typo3:' . $contentType->getName());
     $tagBuilder->addAttribute('about', $node->getContextPath());
     $this->addScriptTag($tagBuilder, '__workspacename', $node->getWorkspace()->getName());
     $this->addScriptTag($tagBuilder, '_removed', $node->isRemoved() ? 'true' : 'false', 'boolean');
     $this->addScriptTag($tagBuilder, '_typoscriptPath', $typoscriptPath);
     foreach ($contentType->getProperties() as $propertyName => $propertyConfiguration) {
         $dataType = isset($propertyConfiguration['type']) ? $propertyConfiguration['type'] : 'string';
         if ($propertyName[0] === '_') {
             $propertyValue = \TYPO3\FLOW3\Reflection\ObjectAccess::getProperty($node, substr($propertyName, 1));
         } else {
             $propertyValue = $node->getProperty($propertyName);
         }
         // Serialize boolean values to String
         if (isset($propertyConfiguration['type']) && $propertyConfiguration['type'] === 'boolean') {
             $propertyValue = $propertyValue ? 'true' : 'false';
         }
         // Serialize date values to String
         if ($propertyValue !== NULL && isset($propertyConfiguration['type']) && $propertyConfiguration['type'] === 'date') {
             $propertyValue = $propertyValue->format('Y-m-d');
         }
         // Serialize objects to JSON strings
         if (is_object($propertyValue) && $propertyValue !== NULL && isset($propertyConfiguration['type']) && $this->objectManager->isRegistered($propertyConfiguration['type'])) {
             $gettableProperties = \TYPO3\FLOW3\Reflection\ObjectAccess::getGettableProperties($propertyValue);
             $convertedProperties = array();
             foreach ($gettableProperties as $key => $value) {
                 if (is_object($value)) {
                     $entityIdentifier = $this->persistenceManager->getIdentifierByObject($value);
                     if ($entityIdentifier !== NULL) {
                         $value = $entityIdentifier;
                     }
                 }
                 $convertedProperties[$key] = $value;
             }
             $propertyValue = json_encode($convertedProperties);
             $dataType = 'jsonEncoded';
         }
         $this->addScriptTag($tagBuilder, $propertyName, $propertyValue, $dataType);
     }
     if (!$isPage) {
         // add CSS classes
         $this->addScriptTag($tagBuilder, '__contenttype', $contentType->getName());
     } else {
         $tagBuilder->addAttribute('id', 't3-page-metainformation');
         $tagBuilder->addAttribute('data-__sitename', $this->nodeRepository->getContext()->getCurrentSite()->getName());
         $tagBuilder->addAttribute('data-__siteroot', sprintf('/sites/%s@%s', $this->nodeRepository->getContext()->getCurrentSite()->getNodeName(), $this->nodeRepository->getContext()->getWorkspace()->getName()));
     }
     return $tagBuilder->render();
 }
Exemple #20
0
 /**
  * Iterates through all segments in $this->uriPattern and creates
  * appropriate RoutePart instances.
  *
  * @return void
  * @throws \TYPO3\FLOW3\Mvc\Exception\InvalidRoutePartHandlerException
  * @throws \TYPO3\FLOW3\Mvc\Exception\InvalidUriPatternException
  */
 public function parse()
 {
     if ($this->isParsed || $this->uriPattern === NULL || $this->uriPattern === '') {
         return;
     }
     $this->routeParts = array();
     $currentRoutePartIsOptional = FALSE;
     if (substr($this->uriPattern, -1) === '/') {
         throw new \TYPO3\FLOW3\Mvc\Exception\InvalidUriPatternException('The URI pattern "' . $this->uriPattern . '" of route "' . $this->getName() . '" ends with a slash, which is not allowed. You can put the trailing slash in brackets to make it optional.', 1234782997);
     }
     if ($this->uriPattern[0] === '/') {
         throw new \TYPO3\FLOW3\Mvc\Exception\InvalidUriPatternException('The URI pattern "' . $this->uriPattern . '" of route "' . $this->getName() . '" starts with a slash, which is not allowed.', 1234782983);
     }
     $matches = array();
     preg_match_all(self::PATTERN_EXTRACTROUTEPARTS, $this->uriPattern, $matches, PREG_SET_ORDER);
     $lastRoutePart = NULL;
     foreach ($matches as $match) {
         $routePartType = empty($match['dynamic']) ? self::ROUTEPART_TYPE_STATIC : self::ROUTEPART_TYPE_DYNAMIC;
         $routePartName = $match['content'];
         if (!empty($match['optionalStart'])) {
             if ($lastRoutePart !== NULL && $lastRoutePart->isOptional()) {
                 throw new \TYPO3\FLOW3\Mvc\Exception\InvalidUriPatternException('the URI pattern "' . $this->uriPattern . '" of route "' . $this->getName() . '" contains successive optional Route sections, which is not allowed.', 1234562050);
             }
             $currentRoutePartIsOptional = TRUE;
         }
         $routePart = NULL;
         switch ($routePartType) {
             case self::ROUTEPART_TYPE_DYNAMIC:
                 if ($lastRoutePart instanceof \TYPO3\FLOW3\Mvc\Routing\DynamicRoutePartInterface) {
                     throw new \TYPO3\FLOW3\Mvc\Exception\InvalidUriPatternException('the URI pattern "' . $this->uriPattern . '" of route "' . $this->getName() . '" contains successive Dynamic Route Parts, which is not allowed.', 1218446975);
                 }
                 if (isset($this->routePartsConfiguration[$routePartName]['handler'])) {
                     $routePart = $this->objectManager->get($this->routePartsConfiguration[$routePartName]['handler']);
                     if (!$routePart instanceof \TYPO3\FLOW3\Mvc\Routing\DynamicRoutePartInterface) {
                         throw new \TYPO3\FLOW3\Mvc\Exception\InvalidRoutePartHandlerException('routePart handlers must implement "\\TYPO3\\FLOW3\\Mvc\\Routing\\DynamicRoutePartInterface" in route "' . $this->getName() . '"', 1218480972);
                     }
                 } elseif (isset($this->routePartsConfiguration[$routePartName]['objectType'])) {
                     $routePart = new \TYPO3\FLOW3\Mvc\Routing\IdentityRoutePart();
                     $routePart->setObjectType($this->routePartsConfiguration[$routePartName]['objectType']);
                     if (isset($this->routePartsConfiguration[$routePartName]['uriPattern'])) {
                         $routePart->setUriPattern($this->routePartsConfiguration[$routePartName]['uriPattern']);
                     }
                 } else {
                     $routePart = new \TYPO3\FLOW3\Mvc\Routing\DynamicRoutePart();
                 }
                 $routePartDefaultValue = \TYPO3\FLOW3\Reflection\ObjectAccess::getPropertyPath($this->defaults, $routePartName);
                 if ($routePartDefaultValue !== NULL) {
                     $routePart->setDefaultValue($routePartDefaultValue);
                 }
                 break;
             case self::ROUTEPART_TYPE_STATIC:
                 $routePart = new \TYPO3\FLOW3\Mvc\Routing\StaticRoutePart();
                 if ($lastRoutePart !== NULL && $lastRoutePart instanceof \TYPO3\FLOW3\Mvc\Routing\DynamicRoutePartInterface) {
                     $lastRoutePart->setSplitString($routePartName);
                 }
         }
         $routePart->setName($routePartName);
         $routePart->setOptional($currentRoutePartIsOptional);
         $routePart->setLowerCase($this->lowerCase);
         if (isset($this->routePartsConfiguration[$routePartName]['options'])) {
             $routePart->setOptions($this->routePartsConfiguration[$routePartName]['options']);
         }
         if (isset($this->routePartsConfiguration[$routePartName]['toLowerCase'])) {
             $routePart->setLowerCase($this->routePartsConfiguration[$routePartName]['toLowerCase']);
         }
         $this->routeParts[] = $routePart;
         if (!empty($match['optionalEnd'])) {
             if (!$currentRoutePartIsOptional) {
                 throw new \TYPO3\FLOW3\Mvc\Exception\InvalidUriPatternException('The URI pattern "' . $this->uriPattern . '" of route "' . $this->getName() . '" contains an unopened optional section.', 1234564495);
             }
             $currentRoutePartIsOptional = FALSE;
         }
         $lastRoutePart = $routePart;
     }
     if ($currentRoutePartIsOptional) {
         throw new \TYPO3\FLOW3\Mvc\Exception\InvalidUriPatternException('The URI pattern "' . $this->uriPattern . '" of route "' . $this->getName() . '" contains an unterminated optional section.', 1234563922);
     }
     $this->isParsed = TRUE;
 }
 /**
  * Redirects directly to \TYPO3\FLOW3\Reflection\ObjectAccess::getPropertyPath($result, $propertyPath)
  * This is only needed for unit tests!
  *
  * @param mixed $object The object to fetch the property from
  * @param string $path The path to the property to be fetched
  * @return mixed The property value
  */
 protected function getObjectValueByPath($object, $path)
 {
     return \TYPO3\FLOW3\Reflection\ObjectAccess::getPropertyPath($object, $path);
 }
 /**
  * returns the specified property of the mixed variable
  *
  * @param string $property 
  * @param string $mixed 
  * @return void
  * @author Marc Neuhaus
  */
 public function getValue($property, $mixed)
 {
     $value = null;
     try {
         if (is_object($mixed) || is_array($mixed)) {
             $value = \TYPO3\FLOW3\Reflection\ObjectAccess::getProperty($mixed, $property);
         }
     } catch (\TYPO3\FLOW3\Reflection\Exception\PropertyNotAccessibleException $e) {
         var_dump($e);
     }
     return $value;
 }
 /**
  * Registers an object which has been created or cloned during this request.
  *
  * The given object must contain the FLOW3_Persistence_Identifier property, thus
  * the PersistenceMagicInterface type hint. A "new" object does not necessarily
  * have to be known by any repository or be persisted in the end.
  *
  * Objects registered with this method must be known to the getObjectByIdentifier()
  * method.
  *
  * @param \TYPO3\FLOW3\Persistence\Aspect\PersistenceMagicInterface $object The new object to register
  * @return void
  */
 public function registerNewObject(\TYPO3\FLOW3\Persistence\Aspect\PersistenceMagicInterface $object)
 {
     $identifier = \TYPO3\FLOW3\Reflection\ObjectAccess::getProperty($object, 'FLOW3_Persistence_Identifier', TRUE);
     $this->newObjects[$identifier] = $object;
 }
 /**
  * Convert an object from $source to an entity or a value object.
  *
  * @param mixed $source
  * @param string $targetType
  * @param array $convertedChildProperties
  * @param \TYPO3\FLOW3\Property\PropertyMappingConfigurationInterface $configuration
  * @return object the target type
  * @throws \TYPO3\FLOW3\Property\Exception\InvalidTargetException
  * @throws \InvalidArgumentException
  */
 public function convertFrom($source, $targetType, array $convertedChildProperties = array(), \TYPO3\FLOW3\Property\PropertyMappingConfigurationInterface $configuration = NULL)
 {
     if (is_array($source)) {
         if ($this->reflectionService->isClassAnnotatedWith($targetType, 'TYPO3\\FLOW3\\Annotations\\ValueObject')) {
             // Unset identity for valueobject to use constructor mapping, since the identity is determined from
             // constructor arguments
             unset($source['__identity']);
         }
         $object = $this->handleArrayData($source, $targetType, $convertedChildProperties, $configuration);
     } elseif (is_string($source)) {
         if ($source === '') {
             return NULL;
         }
         $object = $this->fetchObjectFromPersistence($source, $targetType);
     } else {
         throw new \InvalidArgumentException('Only strings and arrays are accepted.', 1305630314);
     }
     foreach ($convertedChildProperties as $propertyName => $propertyValue) {
         $result = \TYPO3\FLOW3\Reflection\ObjectAccess::setProperty($object, $propertyName, $propertyValue);
         if ($result === FALSE) {
             throw new \TYPO3\FLOW3\Property\Exception\InvalidTargetException('Property "' . $propertyName . '" having a value of type "' . (is_object($propertyValue) ? get_class($propertyValue) : gettype($propertyValue)) . '" could not be set in target object of type "' . $targetType . '".', 1297935345);
         }
     }
     return $object;
 }
Exemple #25
0
 /**
  * @test
  */
 public function validatePasswordWillUseStrategyIdentifierFromHashedPassword()
 {
     $settings = array('security' => array('cryptography' => array('hashingStrategies' => array('TestStrategy' => 'TYPO3\\FLOW3\\Test\\TestStrategy'))));
     $this->hashService->injectSettings($settings);
     $mockStrategy = $this->getMock('TYPO3\\FLOW3\\Security\\Cryptography\\PasswordHashingStrategyInterface');
     $mockObjectManager = $this->getMock('TYPO3\\FLOW3\\Object\\ObjectManagerInterface');
     $mockObjectManager->expects($this->any())->method('get')->will($this->returnValue($mockStrategy));
     \TYPO3\FLOW3\Reflection\ObjectAccess::setProperty($this->hashService, 'objectManager', $mockObjectManager, TRUE);
     $mockStrategy->expects($this->atLeastOnce())->method('validatePassword')->with('myTestPassword', '---hashed-password---')->will($this->returnValue(TRUE));
     $result = $this->hashService->validatePassword('myTestPassword', 'TestStrategy=>---hashed-password---');
     $this->assertEquals(TRUE, $result);
 }
 public function getStringByProperties($source)
 {
     $properties = $this->getProperties($source);
     $strings = array();
     $count = 0;
     foreach ($properties as $key => $meta) {
         if ($count > 3) {
             break;
         }
         if ($key !== "FLOW3_Persistence_Identifier") {
             if (\TYPO3\FLOW3\Reflection\ObjectAccess::isPropertyGettable($source, $key)) {
                 $value = \TYPO3\FLOW3\Reflection\ObjectAccess::getProperty($source, $key);
                 if (is_string($value)) {
                     $strings[] = $value;
                     $count++;
                 } elseif (is_object($value) && $this->nestingLevel < 3) {
                     $this->nestingLevel++;
                     $string = $this->convertFrom($value, "string");
                     if (!is_null($string)) {
                         $strings[] = $string;
                         $count++;
                     }
                     $this->nestingLevel--;
                 }
             }
         }
     }
     if (!empty($strings)) {
         return implode(", ", $strings);
     }
     return false;
 }
 /**
  * @test
  */
 public function collectionValidatorIsValidEarlyReturnsOnUnitializedDoctrinePersistenceCollections()
 {
     $entityManager = $this->getMock('Doctrine\\ORM\\EntityManager', array(), array(), '', FALSE);
     $collection = new \Doctrine\Common\Collections\ArrayCollection(array());
     $persistentCollection = new \Doctrine\ORM\PersistentCollection($entityManager, '', $collection);
     \TYPO3\FLOW3\Reflection\ObjectAccess::setProperty($persistentCollection, 'initialized', FALSE, TRUE);
     $this->mockValidatorResolver->expects($this->never())->method('createValidator');
     $this->validator->validate($persistentCollection);
 }
 /**
  * MongoDB does not do partial updates, thus this method always collects the
  * full set of properties.
  * Value objects are always inlined.
  *
  * @param string $identifier The object's identifier
  * @param object $object The object to work on
  * @param array $properties The properties to collect (as per class schema)
  * @param boolean $dirty A dirty flag that is passed by reference and set to TRUE if a dirty property was found
  * @author Karsten Dambekalns <*****@*****.**>
  * @author Christopher Hlubek <*****@*****.**>
  */
 protected function collectProperties($identifier, $object, array $properties, &$dirty)
 {
     $propertyData = array();
     foreach ($properties as $propertyName => $propertyMetaData) {
         $this->checkPropertyValue($object, $propertyName, $propertyMetaData);
         $propertyValue = \TYPO3\FLOW3\Reflection\ObjectAccess::getProperty($object, $propertyName, TRUE);
         if ($this->persistenceSession->isDirty($object, $propertyName)) {
             $dirty = TRUE;
         }
         $this->flattenValue($identifier, $object, $propertyName, $propertyMetaData, $propertyData);
     }
     return $propertyData;
 }
Exemple #29
0
 /**
  * Sets the given properties on the object.
  *
  * @param object $object The object to set properties on
  * @param string $identifier The identifier of the object
  * @param array $objectData
  * @return void
  * @throws \TYPO3\FLOW3\Persistence\Exception\UnknownObjectException
  */
 public function thawProperties($object, $identifier, array $objectData)
 {
     $classSchema = $this->reflectionService->getClassSchema($objectData['classname']);
     foreach ($objectData['properties'] as $propertyName => $propertyData) {
         if (!$classSchema->hasProperty($propertyName)) {
             continue;
         }
         $propertyValue = NULL;
         if ($propertyData['value'] !== NULL) {
             switch ($propertyData['type']) {
                 case 'integer':
                     $propertyValue = (int) $propertyData['value'];
                     break;
                 case 'float':
                     $propertyValue = (double) $propertyData['value'];
                     break;
                 case 'boolean':
                     $propertyValue = (bool) $propertyData['value'];
                     break;
                 case 'string':
                     $propertyValue = (string) $propertyData['value'];
                     break;
                 case 'array':
                     $propertyValue = $this->mapArray($propertyData['value']);
                     break;
                 case 'Doctrine\\Common\\Collections\\Collection':
                 case 'Doctrine\\Common\\Collections\\ArrayCollection':
                     $propertyValue = new \Doctrine\Common\Collections\ArrayCollection($this->mapArray($propertyData['value']));
                     break;
                 case 'SplObjectStorage':
                     $propertyMetaData = $classSchema->getProperty($propertyName);
                     $propertyValue = $this->mapSplObjectStorage($propertyData['value'], $propertyMetaData['lazy']);
                     break;
                 case 'DateTime':
                     $propertyValue = $this->mapDateTime($propertyData['value']);
                     break;
                 default:
                     if ($propertyData['value'] === FALSE) {
                         throw new \TYPO3\FLOW3\Persistence\Exception\UnknownObjectException('An expected object was not found by the backend. It was expected for ' . $objectData['classname'] . '::' . $propertyName, 1289509867);
                     }
                     $propertyValue = $this->mapToObject($propertyData['value']);
                     break;
             }
         } else {
             switch ($propertyData['type']) {
                 case 'NULL':
                     continue;
                     break;
                 case 'array':
                     $propertyValue = $this->mapArray(NULL);
                     break;
                 case 'Doctrine\\Common\\Collections\\Collection':
                 case 'Doctrine\\Common\\Collections\\ArrayCollection':
                     $propertyValue = new \Doctrine\Common\Collections\ArrayCollection();
                     break;
                 case 'SplObjectStorage':
                     $propertyValue = $this->mapSplObjectStorage(NULL);
                     break;
             }
         }
         \TYPO3\FLOW3\Reflection\ObjectAccess::setProperty($object, $propertyName, $propertyValue, TRUE);
     }
     if (isset($objectData['metadata'])) {
         $object->FLOW3_Persistence_Metadata = $objectData['metadata'];
     }
     \TYPO3\FLOW3\Reflection\ObjectAccess::setProperty($object, 'FLOW3_Persistence_Identifier', $identifier, TRUE);
 }
Exemple #30
0
 /**
  * Returns the (internal) identifier for the object, if it is known to the
  * backend. Otherwise NULL is returned.
  *
  * Note: this returns an identifier even if the object has not been
  * persisted in case of AOP-managed entities. Use isNewObject() if you need
  * to distinguish those cases.
  *
  * @param object $object
  * @return mixed The identifier for the object if it is known, or NULL
  * @api
  * @todo improve try/catch block
  */
 public function getIdentifierByObject($object)
 {
     if ($this->entityManager->contains($object)) {
         try {
             return current($this->entityManager->getUnitOfWork()->getEntityIdentifier($object));
         } catch (\Doctrine\ORM\ORMException $e) {
             return NULL;
         }
     } elseif (property_exists($object, 'FLOW3_Persistence_Identifier')) {
         return \TYPO3\FLOW3\Reflection\ObjectAccess::getProperty($object, 'FLOW3_Persistence_Identifier', TRUE);
     } else {
         return NULL;
     }
 }