/** * @param string $field * @param \StdClass $source * @param object $entity * * @return array|Proxy|object * @throws HydrationException * @throws MappingException */ private function hydrateAssociation($field, $entity, $source) { $accessor = new PropertyAccessor(); $targetClassName = $this->metadata->getAssociationTargetClass($field); $mapping = $this->metadata->getAssociationMapping($field); $targetPersister = $this->manager->getUnitOfWork()->getEntityPersister($targetClassName); $targetMetadata = $this->manager->getClassMetadata($mapping['target']); $apiField = $mapping['api_field']; $field = $mapping['field']; if ($this->metadata->isSingleValuedAssociation($field)) { $identifiers = $this->metadata->getIdentifierValues($entity); if ($mapping['isOwningSide']) { try { $value = $accessor->getValue($source, $apiField); } catch (NoSuchPropertyException $exception) { if ($mapping['nullable']) { return null; } throw new HydrationException(sprintf('Api field %s for property %s does not present in response', $apiField, $field)); } if ($targetMetadata->isIdentifierComposite()) { throw new HydrationException('Composite references not supported'); } $targetIdsNames = $targetMetadata->getIdentifierFieldNames(); $targetIdName = array_shift($targetIdsNames); $type = $this->manager->getConfiguration()->getTypeRegistry()->get($targetMetadata->getTypeOfField($targetIdName)); $identifiers = [$targetIdName => $type->fromApiValue($value)]; } return $targetPersister->getToOneEntity($mapping, $entity, $identifiers); } if ($this->metadata->isCollectionValuedAssociation($field)) { return $targetPersister->getOneToManyCollection($mapping, $entity); } throw new MappingException('Invalid metadata association type'); }
/** * Loads a collection of entities in a one-to-many association. * * @param array $assoc * @param object $sourceEntity * @param AbstractLazyCollection $collection The collection to load/fill. * * @return Collection */ public function loadOneToManyCollection(array $assoc, $sourceEntity, AbstractLazyCollection $collection) { if ($collection instanceof ApiCollection) { foreach ($collection->getIterator() as $entity) { $this->metadata->getReflectionProperty($assoc['mappedBy'])->setValue($entity, $sourceEntity); } } return $collection; }
/** * Adds inherited association mappings to the subclass mapping. * * @param EntityMetadata $subClass * @param EntityMetadata $parentClass * * @return void * * @throws MappingException */ private function addInheritedRelations(EntityMetadata $subClass, EntityMetadata $parentClass) { foreach ($parentClass->associations as $mapping) { if (!isset($mapping['inherited']) && !$parentClass->isMappedSuperclass) { $mapping['inherited'] = $parentClass->name; } if (!isset($mapping['declared'])) { $mapping['declared'] = $parentClass->name; } $subClass->addInheritedAssociationMapping($mapping); } }
/** * @param EntityMetadata $metadata * @param string $type * @param string $name * @param array $association * @param int[] $associationIds */ protected function mapAssociation(EntityMetadata $metadata, $type, $name, $association, $associationIds) { $mapping = $this->fieldToArray($name, $association); $mapping['target'] = $association['target']; switch ($type) { case 'oneToOne': $mapping['type'] = EntityMetadata::ONE_TO_ONE; if (isset($associationIds[$mapping['field']])) { $mapping['id'] = true; } if (array_key_exists('mappedBy', $association)) { $mapping['mappedBy'] = $association['mappedBy']; } if (array_key_exists('inversedBy', $association)) { $mapping['inversedBy'] = $association['inversedBy']; } break; case 'manyToOne': $mapping['type'] = EntityMetadata::MANY_TO_ONE; if (array_key_exists('inversedBy', $association)) { $mapping['inversedBy'] = $association['inversedBy']; } break; case 'oneToMany': $mapping['type'] = EntityMetadata::ONE_TO_MANY; if (array_key_exists('mappedBy', $association)) { $mapping['mappedBy'] = $association['mappedBy']; } if (array_key_exists('orderBy', $association)) { $mapping['orderBy'] = $association['orderBy']; } if (array_key_exists('indexBy', $association)) { $mapping['indexBy'] = $association['indexBy']; } break; } $metadata->mapAssociation($mapping); }