/** * Sets the entity relationship metadata from the metadata mapping. * * @param Metadata\Interfaces\RelationshipInterface $metadata * @param array $relMapping * @return Metadata\Interfaces\RelationshipInterface * @throws RuntimeException If the related entity type was not found. */ protected function setRelationships(Metadata\Interfaces\RelationshipInterface $metadata, array $relMapping) { foreach ($relMapping as $key => $mapping) { if (!is_array($mapping)) { $mapping = ['type' => null, 'entity' => null]; } if (!isset($mapping['type'])) { $mapping['type'] = null; } if (!isset($mapping['entity'])) { $mapping['entity'] = null; } if (!isset($mapping['search'])) { $mapping['search'] = []; } $relationship = new Metadata\RelationshipMetadata($key, $mapping['type'], $mapping['entity'], $this->isMixin($metadata)); if (isset($mapping['description'])) { $relationship->description = $mapping['description']; } if (isset($mapping['inverse'])) { $relationship->isInverse = true; if (isset($mapping['field'])) { $relationship->inverseField = $mapping['field']; } } $path = $this->getFilePath('model', $mapping['entity']); $relatedEntityMapping = $this->getMapping('model', $mapping['entity'], $path); if (isset($relatedEntityMapping['entity']['polymorphic'])) { $relationship->setPolymorphic(true); $relationship->ownedTypes = $this->getOwnedTypes($mapping['entity']); } if (isset($mapping['search']['store'])) { $relationship->setSearchProperty(true); } $metadata->addRelationship($relationship); } return $metadata; }
/** * Adds a relationship field to this entity. * * @param RelationshipMetadata $relationship * @return self * @throws MetadataException If the relationship key already exists as an attribute. */ public function addRelationship(RelationshipMetadata $relationship) { if (isset($this->attributes[$relationship->getKey()])) { throw MetadataException::fieldKeyInUse('relationship', 'attribute', $relationship->getKey(), $this->type); } $this->relationships[$relationship->getKey()] = $relationship; ksort($this->relationships); return $this; }
/** * Extracts a standard relationship array that the store expects from a raw MongoDB reference value. * * @param RelationshipMetadata $relMeta * @param mixed $reference * @return array * @throws \RuntimeException If the relationship could not be extracted. */ protected function extractRelationship(RelationshipMetadata $relMeta, $reference) { $simple = false === $relMeta->isPolymorphic(); $idKey = $this->getIdentifierKey(); $typeKey = $this->getPolymorphicKey(); if (true === $simple && is_array($reference) && isset($reference[$idKey])) { return ['id' => $reference[$idKey], 'type' => $relMeta->getEntityType()]; } elseif (true === $simple && !is_array($reference)) { return ['id' => $reference, 'type' => $relMeta->getEntityType()]; } elseif (false === $simple && is_array($reference) && isset($reference[$idKey]) && isset($reference[$typeKey])) { return ['id' => $reference[$idKey], 'type' => $reference[$typeKey]]; } else { throw new RuntimeException('Unable to extract a reference id.'); } }
/** * Gets the metadata for a relationship. * * @param RelationshipMetadata $relMeta The relationship metadata. * @return EntityMetadata */ public function getMetadataForRelationship(RelationshipMetadata $relMeta) { return $this->getMetadataForType($relMeta->getEntityType()); }
/** * Serializes a relationship value * * @param Model $owner * @param Model|Model[]|null $relationship * @param RelationshipMetadata $relMeta * @param AdapterInterface $adapter * @return array */ protected function serializeRelationship(Model $owner, $relationship = null, RelationshipMetadata $relMeta, AdapterInterface $adapter) { if ($relMeta->isOne()) { if (is_array($relationship)) { throw SerializerException::badRequest('Invalid relationship value.'); } $serialized = $this->serializeHasOne($owner, $relationship, $adapter); } elseif (is_array($relationship) || null === $relationship) { $serialized = $this->serializeHasMany($owner, $relationship, $adapter); } else { throw SerializerException::badRequest('Invalid relationship value.'); } $ownerMeta = $owner->getMetadata(); $serialized['links'] = ['self' => $adapter->buildUrl($ownerMeta, $owner->getId(), $relMeta->getKey()), 'related' => $adapter->buildUrl($ownerMeta, $owner->getId(), $relMeta->getKey(), true)]; return $serialized; }