/** * Only convert if the given target class has a constructor with one argument being of type given type * * @param string $source * @param string $targetType * @return bool */ public function canConvertFrom($source, $targetType) { if (($this->reflectionService->isClassAnnotatedWith($targetType, Flow\Entity::class) || $this->reflectionService->isClassAnnotatedWith($targetType, Flow\ValueObject::class) || $this->reflectionService->isClassAnnotatedWith($targetType, Entity::class)) === true) { return false; } $methodParameters = $this->reflectionService->getMethodParameters($targetType, '__construct'); if (count($methodParameters) !== 1) { return false; } $methodParameter = array_shift($methodParameters); return $methodParameter['type'] === gettype($source); }
/** * 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, Flow\Scope::class)) { $rawObjectConfiguration['scope'] = $this->reflectionService->getClassAnnotation($className, Flow\Scope::class)->value; } if ($this->reflectionService->isClassAnnotatedWith($className, Flow\Autowiring::class)) { $rawObjectConfiguration['autowiring'] = $this->reflectionService->getClassAnnotation($className, Flow\Autowiring::class)->enabled; } return $rawObjectConfiguration; }
/** * 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 = []; 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_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)]; } } }
/** * Only convert non-persistent types * * @param mixed $source * @param string $targetType * @return boolean */ public function canConvertFrom($source, $targetType) { return !($this->reflectionService->isClassAnnotatedWith($targetType, Flow\Entity::class) || $this->reflectionService->isClassAnnotatedWith($targetType, Flow\ValueObject::class) || $this->reflectionService->isClassAnnotatedWith($targetType, \Doctrine\ORM\Mapping\Entity::class)); }
/** * 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); }
/** * 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 = []; foreach ($this->reflectionService->getClassPropertyNames($className) as $propertyName) { if ($this->reflectionService->isPropertyTaggedWith($className, $propertyName, 'transient')) { continue; } $propertyReflection = new PropertyReflection($className, $propertyName); $propertyValue = $propertyReflection->getValue($object); if (is_object($propertyValue) && $propertyValue instanceof 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] = []; 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, Flow\Entity::class) || $this->reflectionService->isClassAnnotatedWith($propertyClassName, Flow\ValueObject::class) || $this->reflectionService->isClassAnnotatedWith($propertyClassName, ORM\Entity::class))) { $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) === 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)] = [self::CLASSNAME => $className, self::PROPERTIES => $propertyArray]; if ($isTopLevelItem) { return $this->objectsAsArray; } }