/** * 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; }
public function getId($object) { if (is_object($object)) { return $this->persistenceManager->getIdentifierByObject($object); } return null; }
/** * Serializes an object as property array. * * @param object $object The object to store in the registry * @param boolean $isTopLevelItem Internal flag for managing the recursion * @return array The property array */ public function serializeObjectAsPropertyArray($object, $isTopLevelItem = TRUE) { if ($isTopLevelItem) { $this->objectReferences = new \SplObjectStorage(); } $this->objectReferences->attach($object); $className = get_class($object); $propertyArray = array(); foreach ($this->reflectionService->getClassPropertyNames($className) as $propertyName) { if ($this->reflectionService->isPropertyTaggedWith($className, $propertyName, 'transient')) { continue; } $propertyReflection = new \TYPO3\FLOW3\Reflection\PropertyReflection($className, $propertyName); $propertyValue = $propertyReflection->getValue($object); if (is_object($propertyValue) && isset($this->objectReferences[$propertyValue])) { $propertyArray[$propertyName][self::TYPE] = 'object'; $propertyArray[$propertyName][self::VALUE] = \spl_object_hash($propertyValue); continue; } $propertyClassName = is_object($propertyValue) ? get_class($propertyValue) : ''; if ($propertyClassName === 'SplObjectStorage') { $propertyArray[$propertyName][self::TYPE] = 'SplObjectStorage'; $propertyArray[$propertyName][self::VALUE] = array(); foreach ($propertyValue as $storedObject) { $propertyArray[$propertyName][self::VALUE][] = spl_object_hash($storedObject); $this->serializeObjectAsPropertyArray($storedObject, FALSE); } } elseif (is_object($propertyValue) && $propertyValue instanceof \Doctrine\Common\Collections\Collection) { $propertyArray[$propertyName][self::TYPE] = 'Collection'; $propertyArray[$propertyName][self::CLASSNAME] = get_class($propertyValue); $propertyArray[$propertyName][self::VALUE] = $this->buildStorageArrayForArrayProperty($propertyValue->toArray()); } elseif (is_object($propertyValue) && $propertyValue instanceof \ArrayObject) { $propertyArray[$propertyName][self::TYPE] = 'ArrayObject'; $propertyArray[$propertyName][self::VALUE] = $this->buildStorageArrayForArrayProperty($propertyValue->getArrayCopy()); } elseif (is_object($propertyValue) && $this->persistenceManager->isNewObject($propertyValue) === FALSE && ($this->reflectionService->isClassAnnotatedWith($propertyClassName, 'TYPO3\\FLOW3\\Annotations\\Entity') || $this->reflectionService->isClassAnnotatedWith($propertyClassName, 'TYPO3\\FLOW3\\Annotations\\ValueObject') || $this->reflectionService->isClassAnnotatedWith($propertyClassName, 'Doctrine\\ORM\\Mapping\\Entity'))) { $propertyArray[$propertyName][self::TYPE] = 'persistenceObject'; $propertyArray[$propertyName][self::VALUE] = get_class($propertyValue) . ':' . $this->persistenceManager->getIdentifierByObject($propertyValue); } elseif (is_object($propertyValue)) { $propertyObjectName = $this->objectManager->getObjectNameByClassName($propertyClassName); if ($propertyObjectName != '' && $this->objectManager->getScope($propertyObjectName) === \TYPO3\FLOW3\Object\Configuration\Configuration::SCOPE_SINGLETON) { continue; } $propertyArray[$propertyName][self::TYPE] = 'object'; $propertyArray[$propertyName][self::VALUE] = spl_object_hash($propertyValue); $this->serializeObjectAsPropertyArray($propertyValue, FALSE); } elseif (is_array($propertyValue)) { $propertyArray[$propertyName][self::TYPE] = 'array'; $propertyArray[$propertyName][self::VALUE] = $this->buildStorageArrayForArrayProperty($propertyValue); } else { $propertyArray[$propertyName][self::TYPE] = 'simple'; $propertyArray[$propertyName][self::VALUE] = $propertyValue; } } $this->objectsAsArray[spl_object_hash($object)] = array(self::CLASSNAME => $className, self::PROPERTIES => $propertyArray); if ($isTopLevelItem) { return $this->objectsAsArray; } }
/** * Checks, if the given constraint holds for the passed result. * * @param array $constraintDefinition The constraint definition array * @param object $result The result object returned by the persistence manager * @return boolean TRUE if the query result is valid for the given constraint * @throws \TYPO3\FLOW3\Security\Exception\InvalidQueryRewritingConstraintException */ protected function checkSingleConstraintDefinitionOnResultObject(array $constraintDefinition, $result) { $referenceToThisFound = FALSE; if (!is_array($constraintDefinition['leftValue']) && strpos($constraintDefinition['leftValue'], 'this.') === 0) { $referenceToThisFound = TRUE; $propertyPath = substr($constraintDefinition['leftValue'], 5); $leftOperand = $this->getObjectValueByPath($result, $propertyPath); } else { $leftOperand = $this->getValueForOperand($constraintDefinition['leftValue']); } if (!is_array($constraintDefinition['rightValue']) && strpos($constraintDefinition['rightValue'], 'this.') === 0) { $referenceToThisFound = TRUE; $propertyPath = substr($constraintDefinition['rightValue'], 5); $rightOperand = $this->getObjectValueByPath($result, $propertyPath); } else { $rightOperand = $this->getValueForOperand($constraintDefinition['rightValue']); } if ($referenceToThisFound === FALSE) { throw new \TYPO3\FLOW3\Security\Exception\InvalidQueryRewritingConstraintException('An entity security constraint must have at least one operand that references to "this.". Got: "' . $constraintDefinition['leftValue'] . '" and "' . $constraintDefinition['rightValue'] . '"', 1277218400); } if (is_object($leftOperand) && ($this->reflectionService->isClassAnnotatedWith($this->reflectionService->getClassNameByObject($leftOperand), 'TYPO3\\FLOW3\\Annotations\\Entity') || $this->reflectionService->isClassAnnotatedWith($this->reflectionService->getClassNameByObject($leftOperand), 'Doctrine\\ORM\\Mapping\\Entity'))) { $leftOperand = $this->persistenceManager->getIdentifierByObject($leftOperand); } if (is_object($rightOperand) && ($this->reflectionService->isClassAnnotatedWith($this->reflectionService->getClassNameByObject($rightOperand), 'TYPO3\\FLOW3\\Annotations\\Entity') || $this->reflectionService->isClassAnnotatedWith($this->reflectionService->getClassNameByObject($rightOperand), 'Doctrine\\ORM\\Mapping\\Entity'))) { $rightOperand = $this->persistenceManager->getIdentifierByObject($rightOperand); } switch ($constraintDefinition['operator']) { case '!=': return $leftOperand !== $rightOperand; break; case '==': return $leftOperand === $rightOperand; break; case '<': return $leftOperand < $rightOperand; break; case '>': return $leftOperand > $rightOperand; break; case '<=': return $leftOperand <= $rightOperand; break; case '>=': return $leftOperand >= $rightOperand; break; case 'in': return in_array($leftOperand, $rightOperand); break; case 'contains': return in_array($rightOperand, $leftOperand); break; case 'matches': return count(array_intersect($leftOperand, $rightOperand)) !== 0; break; } throw new \TYPO3\FLOW3\Security\Exception\InvalidQueryRewritingConstraintException('The configured operator of the entity constraint is not valid. Got: ' . $constraintDefinition['operator'], 1277222521); }
/** * Checks, whether given value can be resolved and if so, sets $this->value to the resolved value. * If $value is empty, this method checks whether a default value exists. * This method can be overridden by custom RoutePartHandlers to implement custom resolving mechanisms. * * @param string $value value to resolve * @return boolean TRUE if value could be resolved successfully, otherwise FALSE. * @api */ protected function resolveValue($value) { if ($value === NULL) { return FALSE; } if (is_object($value)) { $value = $this->persistenceManager->getIdentifierByObject($value); if ($value === NULL || !is_string($value)) { return FALSE; } } $this->value = (string) $value; if ($this->lowerCase) { $this->value = strtolower($this->value); } return TRUE; }
/** * 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; } }
/** * Fetch the metadata for a given image * * @param \TYPO3\Media\Domain\Model\Image $image * @return string */ public function imageWithMetadataAction(\TYPO3\Media\Domain\Model\Image $image) { $thumbnail = $image->getThumbnail(500, 500); return json_encode(array('imageUuid' => $this->persistenceManager->getIdentifierByObject($image), 'previewImageResourceUri' => $this->resourcePublisher->getPersistentResourceWebUri($thumbnail->getResource()), 'originalSize' => array('w' => $image->getWidth(), 'h' => $image->getHeight()), 'previewSize' => array('w' => $thumbnail->getWidth(), 'h' => $thumbnail->getHeight()))); }
/** * 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(); }