protected function setPropertyType(DoctrineClassMetadata $doctrineMetadata, PropertyMetadata $propertyMetadata) { /** @var \Doctrine\ODM\PHPCR\Mapping\ClassMetadata $doctrineMetadata */ $propertyName = $propertyMetadata->name; if ($doctrineMetadata->hasField($propertyName) && ($fieldType = $this->normalizeFieldType($doctrineMetadata->getTypeOfField($propertyName)))) { $field = $doctrineMetadata->getFieldMapping($propertyName); if (!empty($field['multivalue'])) { $fieldType = 'array'; } $propertyMetadata->setType($fieldType); } elseif ($doctrineMetadata->hasAssociation($propertyName)) { try { $targetEntity = $doctrineMetadata->getAssociationTargetClass($propertyName); } catch (\Exception $e) { return; } if (null === $this->tryLoadingDoctrineMetadata($targetEntity)) { return; } if (!$doctrineMetadata->isSingleValuedAssociation($propertyName)) { $targetEntity = "ArrayCollection<{$targetEntity}>"; } $propertyMetadata->setType($targetEntity); } }
/** * Hydrate $object with the provided $data. * * @param array $data * @param object $object * @throws \Exception * @return object */ public function hydrate(array $data, $object) { $this->metadata = $this->objectManager->getClassMetadata(get_class($object)); $object = $this->tryConvertArrayToObject($data, $object); foreach ($data as $field => &$value) { $value = $this->hydrateValue($field, $value); if ($value === null) { continue; } // @todo DateTime (and other types) conversion should be handled by doctrine itself in future if (in_array($this->metadata->getTypeOfField($field), array('datetime', 'time', 'date'))) { if (is_int($value)) { $dt = new DateTime(); $dt->setTimestamp($value); $value = $dt; } elseif (is_string($value)) { $value = new DateTime($value); } } if ($this->metadata->hasAssociation($field)) { $target = $this->metadata->getAssociationTargetClass($field); if ($this->metadata->isSingleValuedAssociation($field)) { $value = $this->toOne($value, $target); } elseif ($this->metadata->isCollectionValuedAssociation($field)) { $value = $this->toMany($value, $target); // Automatically merge collections using helper utility $propertyRefl = $this->metadata->getReflectionClass()->getProperty($field); $propertyRefl->setAccessible(true); $previousValue = $propertyRefl->getValue($object); $value = CollectionUtils::intersectUnion($previousValue, $value); } } } return $this->hydrator->hydrate($data, $object); }
protected function getEntityFields(ClassMetadata $metaData, array $data) { // change data keys to camelcase $result = array(); foreach ($data as $key => $value) { // convert to camelcase if underscore is in name if (strpos($key, '_') !== false) { $key = implode('', array_map('ucfirst', explode('_', $key))); } $result[$key] = $value; } $data = $result; // get all fields $fieldNames = $metaData->getFieldNames(); $fields = array(); foreach ($fieldNames as $fieldName) { if (!isset($data[$fieldName])) { continue; } $type = $metaData->getTypeOfField($fieldName); $value = $this->getColumnTypeValue($type, $data[$fieldName]); $fields[$fieldName] = $value; } return $fields; }
/** * {@inheritdoc} */ public function getTransformerInfo(ColumnInfoInterface $columnInfo, ClassMetadata $metadata) { if (!$metadata->hasField($columnInfo->getPropertyPath()) || $this->type != $metadata->getTypeOfField($columnInfo->getPropertyPath())) { return; } return array($this->transformer, array()); }
/** * Creates a new entity choice list. * * @param ObjectManager $manager An EntityManager instance * @param string $class The class name * @param string $labelPath The property path used for the label * @param EntityLoaderInterface $entityLoader An optional query builder * @param array $entities An array of choices * @param string $groupPath A property path pointing to the property used * to group the choices. Only allowed if * the choices are given as flat array. */ public function __construct(ObjectManager $manager, $class, $labelPath = null, EntityLoaderInterface $entityLoader = null, $entities = null, $groupPath = null) { $this->em = $manager; $this->entityLoader = $entityLoader; $this->classMetadata = $manager->getClassMetadata($class); $this->class = $this->classMetadata->getName(); $this->loaded = is_array($entities) || $entities instanceof \Traversable; $identifier = $this->classMetadata->getIdentifierFieldNames(); if (1 === count($identifier)) { $this->idField = $identifier[0]; $this->idAsValue = true; if ('integer' === $this->classMetadata->getTypeOfField($this->idField)) { $this->idAsIndex = true; } } if (!$this->loaded) { // Make sure the constraints of the parent constructor are // fulfilled $entities = array(); } if (version_compare(Kernel::VERSION, '2.1') <= 0) { $this->labelPath = $labelPath ? new DepPropertyPath($labelPath) : null; $this->groupPath = $groupPath ? new DepPropertyPath($groupPath) : null; } else { $this->labelPath = $labelPath ? new PropertyPath($labelPath) : null; $this->groupPath = $groupPath ? new PropertyPath($groupPath) : null; } parent::__construct($entities, array(), array()); }
public function __construct(ObjectManager $om, ClassMetadata $classMetadata) { $ids = $classMetadata->getIdentifierFieldNames(); $idType = $classMetadata->getTypeOfField(current($ids)); $this->om = $om; $this->classMetadata = $classMetadata; $this->singleId = 1 === count($ids); $this->intId = $this->singleId && in_array($idType, array('integer', 'smallint', 'bigint')); $this->idField = current($ids); }
public function guessFormat($fieldName, ClassMetadata $class) { //echo "wybrany typ:" . "\n"; $generator = $this->generator; $type = $class->getTypeOfField($fieldName); switch ($type) { case 'boolean': return function () use($generator) { return $generator->boolean; }; case 'decimal': $size = isset($class->fieldMappings[$fieldName]['precision']) ? $class->fieldMappings[$fieldName]['precision'] : 2; return function () use($generator, $size) { return $generator->randomNumber($size + 2) / 100; }; case 'smallint': return function () { return mt_rand(0, 65535); }; case 'integer': return function () { return mt_rand(0, intval('2147483647')); }; case 'bigint': return function () { return mt_rand(0, intval('18446744073709551615')); }; case 'float': return function () { return mt_rand(0, intval('4294967295')) / mt_rand(1, intval('4294967295')); }; case 'array': return array(); case 'string': $size = isset($class->fieldMappings[$fieldName]['length']) ? $class->fieldMappings[$fieldName]['length'] : 255; return function () use($generator, $size) { return $generator->text($size); }; case 'text': return function () use($generator) { return $generator->text; }; case 'datetime': case 'date': case 'time': return function () use($generator) { return $generator->datetime; }; default: // //echo "null ! ".$type."\n"; // no smart way to guess what the user expects here return null; } }
public function guessFormat($fieldName, ClassMetadata $class) { $generator = $this->generator; $type = $class->getTypeOfField($fieldName); switch ($type) { case 'boolean': return function () use($generator) { return $generator->boolean; }; case 'decimal': $size = isset($class->fieldMappings[$fieldName]['precision']) ? $class->fieldMappings[$fieldName]['precision'] : 2; return function () use($generator, $size) { return $generator->randomNumber($size + 2) / 100; }; case 'smallint': return function () { return mt_rand(0, 65535); }; case 'integer': return function () { return mt_rand(0, 4294967295.0); }; case 'bigint': return function () { return mt_rand(0, 1.8446744073709552E+19); }; case 'float': return function () { return mt_rand(0, 4294967295.0) / mt_rand(1, 4294967295.0); }; case 'string': $size = isset($class->fieldMappings[$fieldName]['length']) ? $class->fieldMappings[$fieldName]['length'] : 255; return function () use($generator, $size) { return $generator->text($size); }; case 'text': return function () use($generator) { return $generator->text; }; case 'datetime': case 'date': case 'time': return function () use($generator) { return $generator->datetime; }; default: // no smart way to guess what the user expects here return null; } }
protected function getEntityColumns(ClassMetadata $metaData) { $columns = $metaData->getColumnNames(); $result = array(); foreach ($columns as $columnName) { $type = $this->getColumnTypeValue($metaData->getTypeOfField($columnName)); if ($metaData->isIdentifier($metaData->getFieldName($columnName))) { $type |= TableInterface::PRIMARY_KEY; if ($metaData->isIdGeneratorIdentity() || $metaData->isIdGeneratorSequence()) { $type |= TableInterface::AUTO_INCREMENT; } } $result[$columnName] = $type; } return $result; }
public function __construct(ObjectManager $om, ClassMetadata $classMetadata) { $ids = $classMetadata->getIdentifierFieldNames(); $idType = $classMetadata->getTypeOfField(current($ids)); $this->om = $om; $this->classMetadata = $classMetadata; $this->singleId = 1 === count($ids); $this->intId = $this->singleId && in_array($idType, array('integer', 'smallint', 'bigint')); $this->idField = current($ids); // single field association are resolved, since the schema column could be an int if ($this->singleId && $classMetadata->hasAssociation($this->idField)) { $this->associationIdReader = new self($om, $om->getClassMetadata($classMetadata->getAssociationTargetClass($this->idField))); $this->singleId = $this->associationIdReader->isSingleId(); $this->intId = $this->associationIdReader->isIntId(); } }
/** * Get the default hydrator * * @param ClassMetadata $metadata * @param HydratorInterface $hydrator * * @return HydratorInterface */ private function createEntityHydrator(ClassMetadata $metadata, HydratorInterface $hydrator = null) { $hydrator = $hydrator ?: new ClassMethods(); foreach ($metadata->getFieldNames() as $field) { switch ($metadata->getTypeOfField($field)) { case Type::DATETIME: $hydrator->addStrategy($field, new DateTimeStrategy()); break; case Type::SIMPLE_ARRAY: $hydrator->addStrategy($field, new SimpleArrayStrategy()); break; case Type::BOOLEAN: $hydrator->addStrategy($field, new BooleanStrategy()); break; } } return $hydrator; }
protected function setPropertyType(DoctrineClassMetadata $doctrineMetadata, PropertyMetadata $propertyMetadata) { $propertyName = $propertyMetadata->name; if ($doctrineMetadata->hasField($propertyName) && ($fieldType = $this->normalizeFieldType($doctrineMetadata->getTypeOfField($propertyName)))) { $propertyMetadata->setType($fieldType); } elseif ($doctrineMetadata->hasAssociation($propertyName)) { $targetEntity = $doctrineMetadata->getAssociationTargetClass($propertyName); if (null === ($targetMetadata = $this->tryLoadingDoctrineMetadata($targetEntity))) { return; } // For inheritance schemes, we cannot add any type as we would only add the super-type of the hierarchy. // On serialization, this would lead to only the supertype being serialized, and properties of subtypes // being ignored. if ($targetMetadata instanceof DoctrineClassMetadata && !$targetMetadata->isInheritanceTypeNone()) { return; } if (!$doctrineMetadata->isSingleValuedAssociation($propertyName)) { $targetEntity = "ArrayCollection<{$targetEntity}>"; } $propertyMetadata->setType($targetEntity); } }
/** * Creates a new entity choice list. * * @param ObjectManager $manager An EntityManager instance * @param string $class The class name * @param string $labelPath The property path used for the label * @param EntityLoaderInterface $entityLoader An optional query builder * @param array $entities An array of choices * @param array $preferredEntities An array of preferred choices * @param string $groupPath A property path pointing to the property used * to group the choices. Only allowed if * the choices are given as flat array. * @param PropertyAccessorInterface $propertyAccessor The reflection graph for reading property paths. */ public function __construct(ObjectManager $manager, $class, $labelPath = null, EntityLoaderInterface $entityLoader = null, $entities = null, array $preferredEntities = array(), $groupPath = null, PropertyAccessorInterface $propertyAccessor = null) { $this->em = $manager; $this->entityLoader = $entityLoader; $this->classMetadata = $manager->getClassMetadata($class); $this->class = $this->classMetadata->getName(); $this->loaded = is_array($entities) || $entities instanceof \Traversable; $this->preferredEntities = $preferredEntities; $identifier = $this->classMetadata->getIdentifierFieldNames(); if (1 === count($identifier)) { $this->idField = $identifier[0]; $this->idAsValue = true; if (in_array($this->classMetadata->getTypeOfField($this->idField), array('integer', 'smallint', 'bigint'))) { $this->idAsIndex = true; } } if (!$this->loaded) { // Make sure the constraints of the parent constructor are // fulfilled $entities = array(); } parent::__construct($entities, $labelPath, $preferredEntities, $groupPath, null, $propertyAccessor); }
/** * {@inheritdoc} */ public function readMetadata(ClassMetadata $doctrineMeta, array &$meta) { if (!isset($meta['updated_at'])) { $meta['updatedAt'] = null; } foreach ($doctrineMeta->getReflectionClass()->getProperties() as $property) { $annotation = $this->reader->getPropertyAnnotation($property, UpdatedAt::ANNOTATION); if (!$annotation instanceof UpdatedAt) { continue; } if (!empty($meta['updatedAt'])) { if ($meta['updatedAt'] === $property->getName()) { continue; } throw $this->createPropertyAnnotationInvalidException(UpdatedAt::ANNOTATION, $doctrineMeta->getName(), $property->getName(), sprintf('property "%s" is already annotated with this annotation', $meta['updatedAt'])); } $fieldType = $doctrineMeta->getTypeOfField($property->getName()); if (Type::DATETIME !== $fieldType) { throw $this->createPropertyAnnotationInvalidException(UpdatedAt::ANNOTATION, $doctrineMeta->getName(), $property->getName(), sprintf('field must be of type "%s", "%s" provided', Type::DATETIME, $fieldType)); } $meta['updatedAt'] = $property->getName(); } }
/** * Return "false" if can't find config for field, "null" if field type is unknown for given field * or array with config data for given field * * @param ClassMetadata $metadata * @param $field * @return array|bool */ protected function guessAttributeParametersScalarField(ClassMetadata $metadata, $field) { if ($metadata->hasField($field)) { $doctrineType = $metadata->getTypeOfField($field); if (!isset($this->doctrineTypeMapping[$doctrineType])) { return null; } return $this->formatResult($this->getLabel($metadata->getName(), $field), $this->doctrineTypeMapping[$doctrineType]['type'], $this->doctrineTypeMapping[$doctrineType]['options']); } elseif ($this->entityConfigProvider->hasConfig($metadata->getName(), $field)) { $entityConfig = $this->entityConfigProvider->getConfig($metadata->getName(), $field); $fieldType = $entityConfig->getId()->getFieldType(); if (!$metadata->hasAssociation($field)) { return $this->formatResult($entityConfig->get('label'), $this->doctrineTypeMapping[$fieldType]['type'], $this->doctrineTypeMapping[$fieldType]['options']); } } return false; }
/** * {@inheritDoc} */ public static function validate(array $options, ClassMetadata $meta) { if ($meta->getTypeOfField($options['dateField']) !== 'datetime') { throw new InvalidMappingException("Unable to find datetime field - [{$options['dateField']}] in class - {$meta->name}"); } }
/** * Builds the field value. * * @param ClassMetadata $metadata * @param string $propertyPath * @param string $value * * @return mixed * @throws \Exception */ private function buildFieldValue(ClassMetadata $metadata, $propertyPath, $value) { $type = $metadata->getTypeOfField($propertyPath); switch ($type) { case 'smallint': case 'integer': case 'bigint': if (!is_int($value)) { throw new \Exception('Expected integer.'); } return intval($value); case 'boolean': if (!is_bool($value)) { throw new \Exception('Expected boolean.'); } return (bool) $value; case 'float': case 'double': case 'decimal': if (!is_numeric($value)) { throw new \Exception('Expected float.'); } return floatval($value); case 'datetime': return new \DateTime($value); case 'string': return (string) $value; } throw new \Exception("Unsupported field type '{$type}' for path '{$propertyPath}'."); }
/** * Normalizes the value. If the key is an ID, get the real ID value. If is null, set the value to null. Otherwise * return unchanged value. * * @param ClassMetadata $metadata * @param string $property * @param string $value * * @return null|string */ private function normalizeValue(ClassMetadata $metadata, $property, $value) { if (self::PARAMETER_ID_KEY === $property) { return $this->getFilterValueFromUrl($value); } if (self::PARAMETER_NULL_VALUE === $value) { return null; } switch ($metadata->getTypeOfField($property)) { case 'boolean': return (bool) $value; case 'integer': return (int) $value; case 'float': return (double) $value; case 'datetime': // the input has the format `2015-04-28T02:23:50 00:00`, transform it to match the database format // `2015-04-28 02:23:50` return preg_replace('/(\\d{4}(-\\d{2}){2})T(\\d{2}(:\\d{2}){2}) \\d{2}:\\d{2}/', '$1 $3', $value); } return $value; }
protected function unserializeSingleValue($data, ClassMetadata $metadata, $field) { if (!isset($data[$field])) { return null; } $type = $metadata->getTypeOfField($field); if (isset($this->typeSerializers[$type])) { return $this->serviceLocator->get($this->typeSerializers[$type])->unserialize($data[$field], $metadata, $field); } if ($type == 'float' && is_integer($data[$field])) { return (double) $data[$field]; } return $data[$field]; }
/** * Get identifier information for a class. * * @param ClassMetadata $classMetadata The entity metadata * * @return array Return an array with idAsIndex, idAsValue and identifier */ private function getIdentifierInfoForClass(ClassMetadata $classMetadata) { $identifier = null; $idAsIndex = false; $idAsValue = false; $identifiers = $classMetadata->getIdentifierFieldNames(); if (1 === count($identifiers)) { $identifier = $identifiers[0]; if (!$classMetadata->hasAssociation($identifier)) { $idAsValue = true; if (in_array($classMetadata->getTypeOfField($identifier), array('integer', 'smallint', 'bigint'))) { $idAsIndex = true; } } } return array($idAsIndex, $idAsValue, $identifier); }
protected function serializeSingleValue(ClassMetadata $metadata, $value, $field) { $type = $metadata->getTypeOfField($field); if (array_key_exists($type, $this->typeSerializers)) { return $this->getTypeSerializer($type)->serialize($value, $metadata, $field); } return $value; }