/** * Validates the embed type. * * @param string $embedType * @return bool * @throws MetadataException */ protected function validateType($embedType) { $valid = ['one', 'many']; if (!in_array($embedType, $valid)) { throw MetadataException::invalidRelType($embedType, $valid); } return true; }
/** * Validates that the field key is not reserved. * * @param string $key * @throws MetadataException */ protected function validateKey($key) { $reserved = ['type', 'id']; if (in_array(strtolower($key), $reserved)) { throw MetadataException::reservedFieldKey($key, $reserved); } }
/** * {@inheritDoc} */ public function getMetadataForType($type) { if (null !== ($metadata = $this->doLoadMetadata($type))) { // Found in memory or from cache implementation return $metadata; } // Loop through the type hierarchy (extension) and merge metadata objects. foreach ($this->driver->getTypeHierarchy($type) as $hierType) { if (null !== ($loaded = $this->doLoadMetadata($hierType))) { // Found in memory or from cache implementation $this->mergeMetadata($metadata, $loaded); continue; } // Load from driver source $loaded = $this->driver->loadMetadataForType($hierType); if (null === $loaded) { throw MetadataException::mappingNotFound($type); } // Validate the metadata object. $this->entityUtil->validateMetadata($hierType, $loaded, $this); // Handle persistence specific loading and validation. $this->loadPersistenceMetadata($loaded); // Handle search specific loading and validation. $this->loadSearchMetadata($loaded); $this->mergeMetadata($metadata, $loaded); $this->dispatchMetadataEvent(Events::onMetadataLoad, $loaded); $this->doPutMetadata($loaded); } if (null === $metadata) { throw MetadataException::mappingNotFound($type); } $this->doPutMetadata($metadata); return $metadata; }
/** * {@inheritdoc} */ protected function validateEmbed(EmbeddedPropMetadata $embed) { if (true === $this->hasAttribute($embed->getKey())) { throw MetadataException::fieldKeyInUse('embed', 'attribute', $embed->getKey(), $this->name); } }
/** * Returns the file path for an entity type or mixin name. * * @param string $metaType The type of metadata, either model or mixin. * @param string $key The file key name, either the model type or the mixin name. * @return string * @throws MetadataException */ protected function getFilePath($metaType, $key) { $method = $this->getFindMethod($metaType); $path = $this->fileLocator->{$method}($key, $this->getExtension()); if (null === $path) { throw MetadataException::fatalDriverError($key, sprintf('No mapping file was found.', $path)); } return $path; }
/** * {@inheritdoc} */ protected function validateRelationship(RelationshipMetadata $relationship) { if (true === $this->hasAttribute($relationship->getKey())) { throw MetadataException::fieldKeyInUse('relationship', 'attribute', $relationship->getKey(), $this->name); } if (true === $this->hasEmbed($relationship->getKey())) { throw MetadataException::fieldKeyInUse('relationship', 'embed', $relationship->getKey(), $this->name); } }
/** * 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; }
/** * Gets the metadata mapping information from the YAML file. * * @param string $metaType The metadata type, either mixin or model. * @param string $key The metadata key name, either the mixin name or model type. * @param string $file The YAML file location. * @return array * @throws MetadataException */ private function getMapping($metaType, $key, $file) { if (isset($this->mappings[$metaType][$key])) { // Set to array cache to prevent multiple gets/parses. return $this->mappings[$metaType][$key]; } $contents = Yaml::parse(file_get_contents($file)); if (!isset($contents[$key])) { throw MetadataException::fatalDriverError($key, sprintf('No mapping key was found at the beginning of the YAML file. Expected "%s"', $key)); } return $this->mappings[$metaType][$key] = $this->setDefaults($metaType, $contents[$key]); }