/** * @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 an entity of this persister's mapped class as part of a single-valued * association from another entity. * * @param array $assoc The association to load. * @param object $sourceEntity The entity that owns the association (not necessarily the "owning side"). * @param array $identifier The identifier of the entity to load. Must be provided if * the association to load represents the owning side, otherwise * the identifier is derived from the $sourceEntity. * * @return object The loaded and managed entity instance or NULL if the entity can not be found. */ public function loadOneToOneEntity(array $assoc, $sourceEntity, array $identifier = []) { if (false !== ($foundEntity = $this->manager->getUnitOfWork()->tryGetById($identifier, $assoc['target']))) { return $foundEntity; } // Get identifiers from entity if the entity is not the owning side if (!$assoc['isOwningSide']) { $identifier = $this->metadata->getIdentifierValues($sourceEntity); } return $this->loadById($identifier); }