Exemplo n.º 1
0
 /**
  * Extracts the model's relationships, per JSON API spec.
  *
  * @param   array           $data
  * @param   EntityMetadata  $metadata
  * @return  array
  */
 protected function extractRelationships(array $data, EntityMetadata $metadata)
 {
     $flattened = [];
     if (!isset($data['relationships']) || !is_array($data['relationships'])) {
         return $flattened;
     }
     foreach ($metadata->getRelationships() as $key => $relMeta) {
         if (!isset($data['relationships'][$key])) {
             continue;
         }
         $rel = $data['relationships'][$key];
         // Need to use array_key_exists over isset because 'null' is valid. Creating a key map for each relationship is too costly since every relationship needs the data check.
         if (false === array_key_exists('data', $rel)) {
             throw NormalizerException::badRequest(sprintf('The "data" member was missing from the payload for relationship "%s"', $key));
         }
         if (empty($rel['data'])) {
             $flattened[$key] = $relMeta->isOne() ? null : [];
             continue;
         }
         if (!is_array($rel['data'])) {
             throw NormalizerException::badRequest(sprintf('The "data" member is not valid in the payload for relationship "%s"', $key));
         }
         if (true === $relMeta->isOne() && true === $this->isSequentialArray($rel['data'])) {
             throw NormalizerException::badRequest(sprintf('The data payload for relationship "%s" is malformed. Data types of "one" must be an associative array, sequential found.', $key));
         }
         if (true === $relMeta->isMany() && false === $this->isSequentialArray($rel['data'])) {
             throw NormalizerException::badRequest(sprintf('The data payload for relationship "%s" is malformed. Data types of "many" must be a sequential array, associative found.', $key));
         }
         $flattened[$key] = $rel['data'];
     }
     return $flattened;
 }
 /**
  * {@inheritDoc}
  */
 public function handleValidate(EntityMetadata $metadata)
 {
     $persistence = $metadata->persistence;
     $validIdStrategies = ['object'];
     if (!in_array($persistence->idStrategy, $validIdStrategies)) {
         throw MetadataException::invalidMetadata($metadata->type, sprintf('The persistence id strategy "%s" is invalid. Valid types are "%s"', $persistence->idStrategy, implode('", "', $validIdStrategies)));
     }
     if (false === $metadata->isChildEntity() && (empty($persistence->db) || empty($persistence->collection))) {
         throw MetadataException::invalidMetadata($metadata->type, 'The persistence database and collection names cannot be empty.');
     }
     if (false === $this->entityUtil->isEntityTypeValid($persistence->collection)) {
         throw MetadataException::invalidMetadata($metadata->type, sprintf('The entity persistence collection "%s" is invalid based on the configured name format "%s"', $persistence->collection, $this->entityUtil->getRestConfig()->getEntityFormat()));
     }
 }
Exemplo n.º 3
0
 protected function setMixins(Metadata\EntityMetadata $metadata, array $mixins)
 {
     foreach ($mixins as $mixinName) {
         $mixinMeta = $this->loadMetadataForMixin($mixinName);
         $metadata->addMixin($mixinMeta);
     }
     return $metadata;
 }
Exemplo n.º 4
0
 /**
  * Validates that a model type can be set to an owning metadata type.
  *
  * @param   EntityMetadata  $owningMeta The metadata the type will be added to.
  * @param   string          $typeToAdd  The type to add.
  * @return  self
  * @throws  StoreException  If the type to add is not supported.
  */
 public function validateRelationshipSet(EntityMetadata $owningMeta, $typeToAdd)
 {
     if (true === $owningMeta->isPolymorphic()) {
         $canSet = in_array($typeToAdd, $owningMeta->ownedTypes);
     } else {
         $canSet = $owningMeta->type === $typeToAdd;
     }
     if (false === $canSet) {
         throw StoreException::badRequest(sprintf('The model type "%s" cannot be added to "%s", as it is not supported.', $typeToAdd, $owningMeta->type));
     }
     return $this;
 }
Exemplo n.º 5
0
 /**
  * Determines if the model uses a particlar mixin.
  *
  * @api
  * @param   string  $name
  * @return  bool
  */
 public function usesMixin($name)
 {
     return $this->metadata->hasMixin($name);
 }
Exemplo n.º 6
0
 /**
  * Gets standard database retrieval criteria for an entity and the provided identifiers.
  *
  * @param   EntityMetadata  $metadata       The entity to retrieve database records for.
  * @param   string|array    $identifiers    The IDs to query.
  * @return  array
  */
 protected function getRetrieveCritiera(EntityMetadata $metadata, $identifiers)
 {
     $idKey = $this->getIdentifierKey();
     $criteria[$idKey] = $this->getIdentifierCriteria($identifiers);
     if (empty($criteria[$idKey])) {
         unset($criteria[$idKey]);
     }
     if (true === $metadata->isChildEntity()) {
         $criteria[$this->getPolymorphicKey()] = $metadata->type;
     }
     return $criteria;
 }
Exemplo n.º 7
0
 /**
  * Validates entity relationships on EntityMetadata.
  *
  * @param   EntityMetadata  $metadata
  * @param   MetadataFactory $mf
  * @return  bool
  * @throws  MetadataException
  */
 public function validateMetadataRelationships(EntityMetadata $metadata, MetadataFactory $mf)
 {
     foreach ($metadata->getRelationships() as $key => $relationship) {
         if ($key != $relationship->key) {
             throw MetadataException::invalidMetadata($metadata->type, sprintf('Relationship key mismtach. "%s" !== "%s"', $key, $relationship->key));
         }
         if (false === $this->isFieldKeyValid($relationship->key)) {
             throw MetadataException::invalidMetadata($metadata->type, sprintf('The relationship key "%s" is invalid based on the configured name format "%s"', $relationship->key, $this->config->getFieldKeyFormat()));
         }
         if (true === $metadata->isChildEntity()) {
             $parent = $mf->getMetadataForType($metadata->extends);
             if ($parent->hasRelationship($relationship->key)) {
                 throw MetadataException::invalidMetadata($metadata->type, sprintf('Parent entity type "%s" already contains relationship field "%s"', $parent->type, $relationship->key));
             }
         }
         if (false === $this->isEntityTypeValid($relationship->entityType)) {
             throw MetadataException::invalidMetadata($metadata->type, sprintf('The related model "%s" for relationship "%s" is invalid based on the configured name format "%s"', $relationship->entityType, $relationship->key, $this->config->getEntityFormat()));
         }
         if (false === $mf->metadataExists($relationship->entityType)) {
             throw MetadataException::invalidMetadata($metadata->type, sprintf('The related model "%s" for relationship "%s" does not exist.', $relationship->entityType, $relationship->key));
         }
         if (true === $relationship->isInverse) {
             if ('one' === $relationship->relType) {
                 throw MetadataException::invalidMetadata($metadata->type, 'The relationship is inverse and one, which is currently not supported.');
             }
             if (empty($relationship->inverseField)) {
                 throw MetadataException::invalidMetadata($metadata->type, 'The relationship is inverse, but no inverse field was specified.');
             }
             $related = $relationship->entityType === $metadata->type ? $metadata : $mf->getMetadataForType($relationship->entityType);
             if (false === $related->hasRelationship($relationship->inverseField)) {
                 throw MetadataException::invalidMetadata($metadata->type, 'The relationship is inverse, but the related model does not contain the specified inverse field.');
             }
             $relatedRel = $related->getRelationship($relationship->inverseField);
             if (true === $relatedRel->isInverse) {
                 throw MetadataException::invalidMetadata($metadata->type, 'The relationship is inverse, but the relationship it references is also inverse.');
             }
             if ('one' !== $relatedRel->relType) {
                 throw MetadataException::invalidMetadata($metadata->type, 'The relationship is inverse and many, but it\'s reference is not a type of one.');
             }
         }
     }
     return true;
 }