/** * @param string $className * @return string */ public function showQuery($className) { if ($this->reflectionService->isClassAnnotatedWith($className, Table::class) === FALSE) { throw new \InvalidArgumentException('The class "' . $className . '" is not annotated properly.', 1428332546); } return $this->createTableDefinitionQueryForClassName($className); }
/** * Returns cache cache tag parts for the given object if known, otherwise NULL. * * @param $object * @return mixed */ public function identifyCacheTagForObject($object) { $className = get_class($object); if (property_exists($object, 'Persistence_Object_Identifier') || $this->reflectionService->isClassAnnotatedWith($className, Flow\Entity::class) || $this->reflectionService->isClassAnnotatedWith($className, Flow\ValueObject::class) || $this->reflectionService->isClassAnnotatedWith($className, Doctrine\Entity::class)) { $identifier = $this->persistenceManager->getIdentifierByObject($object); return $className . '_' . $identifier; } }
/** * @param mixed $value * @return mixed object */ protected function getQueryMatchValue($value) { if (is_object($value) && $this->reflectionService->isClassAnnotatedWith(get_class($value), 'TYPO3\\Flow\\Annotations\\Entity')) { return $this->persistenceManager->getIdentifierByObject($value); } return $value; }
/** * Builds a raw configuration array by parsing possible scope and autowiring * annotations from the given class or interface. * * @param string $className * @param array $rawObjectConfiguration * @return array */ protected function enhanceRawConfigurationWithAnnotationOptions($className, array $rawObjectConfiguration) { if ($this->reflectionService->isClassAnnotatedWith($className, 'TYPO3\\Flow\\Annotations\\Scope')) { $rawObjectConfiguration['scope'] = $this->reflectionService->getClassAnnotation($className, 'TYPO3\\Flow\\Annotations\\Scope')->value; } if ($this->reflectionService->isClassAnnotatedWith($className, 'TYPO3\\Flow\\Annotations\\Autowiring')) { $rawObjectConfiguration['autowiring'] = $this->reflectionService->getClassAnnotation($className, 'TYPO3\\Flow\\Annotations\\Autowiring')->enabled; } return $rawObjectConfiguration; }
/** * @Flow\Around("method(TYPO3\Flow\Persistence\Doctrine\EntityManagerFactory->getEventManager())") * @param \TYPO3\Flow\Aop\JoinPointInterface $joinPoint The current join point * @return \Doctrine\Common\EventManager */ public function registerEntityAuditEventListenerToEventManager(\TYPO3\Flow\Aop\JoinPointInterface $joinPoint) { $eventManager = $joinPoint->getAdviceChain()->proceed($joinPoint); $classNamesAnnotatedAsVersionable = $this->reflectionService->getClassNamesByAnnotation('TYPO3\\Doctrine\\Versionable\\Annotations\\Versionable'); if (!is_array($classNamesAnnotatedAsVersionable)) { return; } foreach ($classNamesAnnotatedAsVersionable as $index => $className) { if (!$this->reflectionService->isClassAnnotatedWith($className, 'TYPO3\\Flow\\Annotations\\Entity')) { unset($classNamesAnnotatedAsVersionable[$index]); } } if ($classNamesAnnotatedAsVersionable !== array()) { $auditConfiguration = new \SimpleThings\EntityAudit\AuditConfiguration(); $auditConfiguration->setAuditedEntityClasses($classNamesAnnotatedAsVersionable); $auditManager = new \SimpleThings\EntityAudit\AuditManager($auditConfiguration); $auditManager->registerEvents($eventManager); } return $eventManager; }
/** * Determines which of the given classes are potentially proxyable * and returns their names in an array. * * @param array $classNamesByPackage Names of the classes to check * @return array Names of classes which can be proxied */ protected function getProxyableClasses(array $classNamesByPackage) { $proxyableClasses = array(); foreach ($classNamesByPackage as $classNames) { foreach ($classNames as $className) { if (!in_array(substr($className, 0, 15), $this->blacklistedSubPackages)) { if (!$this->reflectionService->isClassAnnotatedWith($className, 'TYPO3\\Flow\\Annotations\\Aspect') && !$this->reflectionService->isClassFinal($className)) { $proxyableClasses[] = $className; } } } } return $proxyableClasses; }
/** * Determines which of the given classes are potentially proxyable * and returns their names in an array. * * @param array $classNamesByPackage Names of the classes to check * @return array Names of classes which can be proxied */ protected function getProxyableClasses(array $classNamesByPackage) { $proxyableClasses = array(); foreach ($classNamesByPackage as $classNames) { foreach ($classNames as $className) { if (in_array(substr($className, 0, 15), $this->blacklistedSubPackages)) { continue; } if ($this->reflectionService->isClassAnnotatedWith($className, Flow\Aspect::class)) { continue; } $proxyableClasses[] = $className; } } return $proxyableClasses; }
/** * Traverses the $array and replaces known persisted objects with a tuple of * type and identifier. * * @param array $array * @return void * @throws \RuntimeException */ protected function encodeObjectReferences(array &$array) { foreach ($array as &$value) { if (!is_object($value) || is_object($value) && $value instanceof \TYPO3\Flow\Object\DependencyInjection\DependencyProxy) { continue; } $propertyClassName = get_class($value); if ($value instanceof \SplObjectStorage) { throw new \RuntimeException('SplObjectStorage in array properties is not supported', 1375196580); } elseif ($value instanceof \Doctrine\Common\Collections\Collection) { throw new \RuntimeException('Collection in array properties is not supported', 1375196581); } elseif ($value instanceof \ArrayObject) { throw new \RuntimeException('ArrayObject in array properties is not supported', 1375196582); } elseif ($this->persistenceManager->isNewObject($value) === FALSE && ($this->reflectionService->isClassAnnotatedWith($propertyClassName, 'TYPO3\\Flow\\Annotations\\Entity') || $this->reflectionService->isClassAnnotatedWith($propertyClassName, 'TYPO3\\Flow\\Annotations\\ValueObject') || $this->reflectionService->isClassAnnotatedWith($propertyClassName, 'Doctrine\\ORM\\Mapping\\Entity'))) { $value = array('__flow_object_type' => $propertyClassName, '__identifier' => $this->persistenceManager->getIdentifierByObject($value)); } } }
/** * Traverses the $array and replaces known persisted objects with a tuple of * type and identifier. * * @param array $array * @return void * @throws \RuntimeException */ protected function encodeObjectReferences(array &$array) { foreach ($array as &$value) { if (is_array($value)) { $this->encodeObjectReferences($value); } if (!is_object($value) || is_object($value) && $value instanceof DependencyProxy) { continue; } $propertyClassName = TypeHandling::getTypeForValue($value); if ($value instanceof \SplObjectStorage) { throw new \RuntimeException('SplObjectStorage in array properties is not supported', 1375196580); } elseif ($value instanceof \Doctrine\Common\Collections\Collection) { throw new \RuntimeException('Collection in array properties is not supported', 1375196581); } elseif ($value instanceof \ArrayObject) { throw new \RuntimeException('ArrayObject in array properties is not supported', 1375196582); } elseif ($this->persistenceManager->isNewObject($value) === false && ($this->reflectionService->isClassAnnotatedWith($propertyClassName, Flow\Entity::class) || $this->reflectionService->isClassAnnotatedWith($propertyClassName, Flow\ValueObject::class) || $this->reflectionService->isClassAnnotatedWith($propertyClassName, \Doctrine\ORM\Mapping\Entity::class))) { $value = ['__flow_object_type' => $propertyClassName, '__identifier' => $this->persistenceManager->getIdentifierByObject($value)]; } } }
/** * Returns whether the class with the specified name is transient. Only non-transient * classes, that is entities and mapped superclasses, should have their metadata loaded. * * @param string $className * @return boolean */ public function isTransient($className) { return strpos($className, Compiler::ORIGINAL_CLASSNAME_SUFFIX) !== false || !$this->reflectionService->isClassAnnotatedWith($className, Flow\Entity::class) && !$this->reflectionService->isClassAnnotatedWith($className, Flow\ValueObject::class) && !$this->reflectionService->isClassAnnotatedWith($className, ORM\Entity::class) && !$this->reflectionService->isClassAnnotatedWith($className, ORM\MappedSuperclass::class) && !$this->reflectionService->isClassAnnotatedWith($className, ORM\Embeddable::class); }
/** * @test */ public function checkEntityHasAnnotation() { $className = 'CDSRC\\Libraries\\Tests\\Functional\\SoftDeletable\\Fixture\\Model\\Entity'; $annotation = 'CDSRC\\Libraries\\SoftDeletable\\Annotations\\SoftDeletable'; $this->assertTrue($this->reflectionService->isClassAnnotatedWith($className, $annotation)); }
/** * 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\Flow\Reflection\PropertyReflection($className, $propertyName); $propertyValue = $propertyReflection->getValue($object); if (is_object($propertyValue) && $propertyValue instanceof \TYPO3\Flow\Object\DependencyInjection\DependencyProxy) { continue; } 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); foreach ($propertyValue as $storedObject) { $propertyArray[$propertyName][self::VALUE][] = spl_object_hash($storedObject); $this->serializeObjectAsPropertyArray($storedObject, false); } } 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\Flow\Annotations\Entity::class) || $this->reflectionService->isClassAnnotatedWith($propertyClassName, \TYPO3\Flow\Annotations\ValueObject::class) || $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 ($this->objectManager->getScope($propertyObjectName) === \TYPO3\Flow\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\Flow\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 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\\Flow\\Annotations\\Entity') || $this->reflectionService->isClassAnnotatedWith($this->reflectionService->getClassNameByObject($leftOperand), 'Doctrine\\ORM\\Mapping\\Entity'))) { $originalLeftOperand = $leftOperand; $leftOperand = $this->persistenceManager->getIdentifierByObject($leftOperand); } if (is_object($rightOperand) && ($this->reflectionService->isClassAnnotatedWith($this->reflectionService->getClassNameByObject($rightOperand), 'TYPO3\\Flow\\Annotations\\Entity') || $this->reflectionService->isClassAnnotatedWith($this->reflectionService->getClassNameByObject($rightOperand), 'Doctrine\\ORM\\Mapping\\Entity'))) { $originalRightOperand = $rightOperand; $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': if ($rightOperand instanceof Collection) { return $rightOperand->contains(isset($originalLeftOperand) ? $originalLeftOperand : $leftOperand); } return in_array(isset($originalLeftOperand) ? $originalLeftOperand : $leftOperand, $rightOperand); break; case 'contains': if ($leftOperand instanceof Collection) { return $leftOperand->contains(isset($originalRightOperand) ? $originalRightOperand : $rightOperand); } return in_array(isset($originalRightOperand) ? $originalRightOperand : $rightOperand, $leftOperand); break; case 'matches': if ($leftOperand instanceof Collection) { $leftOperand = $leftOperand->toArray(); } if ($rightOperand instanceof Collection) { $rightOperand = $rightOperand->toArray(); } return count(array_intersect($leftOperand, $rightOperand)) !== 0; break; } throw new InvalidQueryRewritingConstraintException('The configured operator of the entity constraint is not valid. Got: ' . $constraintDefinition['operator'], 1277222521); }
/** * Only convert non-persistent types * * @param mixed $source * @param string $targetType * @return boolean */ public function canConvertFrom($source, $targetType) { return !($this->reflectionService->isClassAnnotatedWith($targetType, \TYPO3\Flow\Annotations\Entity::class) || $this->reflectionService->isClassAnnotatedWith($targetType, \TYPO3\Flow\Annotations\ValueObject::class) || $this->reflectionService->isClassAnnotatedWith($targetType, 'Doctrine\\ORM\\Mapping\\Entity')); }
/** * @param string $className * @return boolean */ public function canRead($className) { return $this->reflectionService->isClassAnnotatedWith($className, 'TYPO3\\Flow\\Annotations\\Entity'); }
/** * Returns whether the class with the specified name is transient. Only non-transient * classes, that is entities and mapped superclasses, should have their metadata loaded. * * @param string $className * @return boolean */ public function isTransient($className) { return strpos($className, Compiler::ORIGINAL_CLASSNAME_SUFFIX) !== false || !$this->reflectionService->isClassAnnotatedWith($className, \TYPO3\Flow\Annotations\Entity::class) && !$this->reflectionService->isClassAnnotatedWith($className, \TYPO3\Flow\Annotations\ValueObject::class) && !$this->reflectionService->isClassAnnotatedWith($className, 'Doctrine\\ORM\\Mapping\\Entity') && !$this->reflectionService->isClassAnnotatedWith($className, 'Doctrine\\ORM\\Mapping\\MappedSuperclass'); }
/** * We can only convert if the $targetType is either tagged with entity or value object. * * @param mixed $source * @param string $targetType * @return boolean */ public function canConvertFrom($source, $targetType) { return $this->reflectionService->isClassAnnotatedWith($targetType, 'Doctrine\\ODM\\CouchDB\\Mapping\\Annotations\\Document'); }