/** * @return SchemaContainer */ private function getExceptedSchemaContainer() { if (self::$expectedSchema !== null) { return self::$expectedSchema; } $episodeType = new Type(); $episodeType->setName('Episode')->setDescription('One of the films in the Star Wars Trilogy')->setValues(['NEWHOPE' => ['value' => 4, 'description' => 'Released in 1977.'], 'EMPIRE' => ['value' => 5, 'description' => 'Released in 1980.'], 'JEDI' => ['value' => 6, 'description' => 'Released in 1983.']]); $characterInterface = new InterfaceType(); $characterInterface->setName('Character')->setDescription('A character in the Star Wars Trilogy')->setFields([$this->createIdField('The id of the character.'), $this->createNameField('The name of the character.'), $this->createFriendsField('The friends of the character, or an empty list if they have none.'), $this->createAppearsInField()]); $homePlanet = new Field(); $homePlanet->setName('homePlanet')->setType('String')->setDescription('The home planet of the human, or null if unknown.'); $humanType = new Type(); $humanType->setName('Human')->setDescription('A humanoid creature in the Star Wars universe.')->setInterfaces(['Character'])->setFields([$this->createIdField('The id of the human.'), $this->createNameField('The name of the human.'), $this->createFriendsField('The friends of the human, or an empty list if they have none.'), $this->createAppearsInField(), $homePlanet]); $primaryFunction = new Field(); $primaryFunction->setName('primaryFunction')->setType('String')->setDescription('The primary function of the droid.'); $droidType = new Type(); $droidType->setName('Droid')->setDescription('A mechanical creature in the Star Wars universe.')->setInterfaces(['Character'])->setFields([$this->createIdField('The id of the droid.'), $this->createNameField('The name of the droid.'), $this->createFriendsField('The friends of the droid, or an empty list if they have none.'), $this->createAppearsInField(), $primaryFunction]); $episodeField = new Field(); $episodeField->setName('episode')->setType('Episode')->setDescription('If omitted, returns the hero of the whole saga. If provided, returns the hero of that particular episode.'); $heroField = new Field(); $heroField->setName('hero')->setType('Character')->setArguments([$episodeField]); $humanField = new Field(); $humanField->setName('human')->setType('Human')->setArguments([$this->createIdField('id of the human')]); $droidField = new Field(); $droidField->setName('droid')->setType('Droid')->setArguments([$this->createIdField('id of the droid')]); $query = new Query(); $query->setFields([$heroField, $humanField, $droidField]); $schema = new SchemaContainer(); $schema->addType($episodeType)->addType($humanType)->addType($droidType)->addInterface($characterInterface)->setQuerySchema($query); return self::$expectedSchema = $schema; }
private function getExceptedSchemaContainer() { if (self::$expectedSchema !== null) { return self::$expectedSchema; } $idField = new Field(); $idField->setName('id')->setDescription('The user primary key')->setType('Int'); $nameField = new Field(); $nameField->setName('name')->setDescription('The user name')->setType('String'); $emailField = new Field(); $emailField->setName('email')->setDescription('The user email')->setType('String'); $friendsField = new Field(); $friendsField->setName('friends')->setDescription('The user friends')->setType('[User]')->setResolveConfig('AppBundle\\Entity\\Friend'); $userType = new Type(); $userType->setName('User')->setDescription('User type description')->setExtends('Item')->setFields([$idField, $nameField, $emailField, $friendsField]); $idField = new Field(); $idField->setName('id')->setDescription('The item primary key')->setType('Int'); $nameField = new Field(); $nameField->setName('name')->setDescription('The item name')->setType('String'); $interface = new InterfaceType(); $interface->setName('Item')->setDescription('Item interface description')->setFields([$idField, $nameField]); $idArg = new Field(); $idArg->setName('id')->setDescription('The ID')->setType('Int'); $adminField = new Field(); $adminField->setName('admin')->setDescription('Admin description')->setType('[User]')->setResolveConfig('AppBundle\\Entity\\User')->setArguments([$idArg]); $idArg = clone $idArg; $userField = new Field(); $userField->setName('user')->setDescription('User description')->setType('User')->setResolveConfig('AppBundle\\Entity\\User')->setArguments([$idArg]); $query = new Query(); $query->setDescription('The root query description')->setFields([$adminField, $userField]); $schema = new SchemaContainer(); $schema->addType($userType)->addInterface($interface)->setQuerySchema($query); return self::$expectedSchema = $schema; }
private function mergeResolveConfig(SchemaContainer $schemaContainer, Field $field) { $config = $field->getResolveConfig(); $typeName = TypeParser::getFinalType($field->getType()); if (!$schemaContainer->hasType($typeName)) { return; } $typeConfig = $schemaContainer->getType($typeName)->getResolveConfig(); $config = array_merge($typeConfig, $config); $field->setResolveConfig($config); }
/** * Apply the resolve config of types that are used by query fields * * @param SchemaContainer $schemaContainer * @param Field $field */ private function mergeResolveConfig(SchemaContainer $schemaContainer, Field $field) { $typeName = TypeParser::getFinalType($field->getType()); if ($schemaContainer->hasType($typeName)) { $typeConfig = $schemaContainer->getType($typeName)->getResolveConfig(); } elseif ($schemaContainer->hasInterface($typeName)) { $typeConfig = $schemaContainer->getInterface($typeName)->getResolveConfig(); } else { return; } $field->mergeResolveConfig($typeConfig); }
/** * @param SchemaContainer $schemaContainer */ public function guess(SchemaContainer $schemaContainer) { $fieldContainers = $schemaContainer->getTypes() + $schemaContainer->getInterfaces(); if (null !== ($query = $schemaContainer->getQuerySchema())) { $fieldContainers[] = $query; } foreach ($fieldContainers as $fieldContainer) { $containerContext = new ContainerContext($fieldContainer, $schemaContainer); $this->guessFields($containerContext); $this->guessTypeResolveConfig($containerContext); } }
/** * @param string $path * @param SchemaContainer $schemaContainer */ private function loadFile($path, SchemaContainer $schemaContainer) { $config = Yaml::parse($this->getFileContent($path)); foreach ($config as $type => $mapping) { switch ($type) { case 'query': $querySchema = $schemaContainer->getQuerySchema(); if (null === $querySchema) { $querySchema = new Query(); $schemaContainer->setQuerySchema($querySchema); } $this->populateFieldContainer($querySchema, $mapping); break; case 'mutation': $mutationSchema = $schemaContainer->getMutationSchema(); if (null === $mutationSchema) { $mutationSchema = new Query(); $schemaContainer->setMutationSchema($mutationSchema); } $this->populateFieldContainer($mutationSchema, $mapping); break; case 'types': foreach ($mapping as $name => $typeMapping) { $type = $this->createType($name, $typeMapping); $schemaContainer->addType($type); } break; case 'interfaces': foreach ($mapping as $name => $interfaceMapping) { $interface = $this->createInterface($name, $interfaceMapping); $schemaContainer->addInterface($interface); } break; default: throw new \UnexpectedValueException(sprintf('Unsupported key "%s"')); } } }
/** * @param SchemaContainer $schemaContainer * @param array $mapping */ private function mapInterfaces(SchemaContainer $schemaContainer, array $mapping) { foreach ($mapping as $name => $interfaceMapping) { $interface = $this->createInterface($name, $interfaceMapping); $schemaContainer->addInterface($interface); } }
/** * @param SchemaContainer $schemaContainer */ private function defineInteracesChildren(SchemaContainer $schemaContainer) { foreach ($schemaContainer->getTypes() as $type) { if (null === $type->getModel()) { continue; } foreach ($type->getInterfaces() as $interfaceName) { $interface = $schemaContainer->getInterface($interfaceName); $interface->setChildClass($type->getName(), $type->getModel()); } } }
/** * @param ClassMetadataInfo $metadata * @param Field $field * @param SchemaContainer $schemaContainer * @return TypeGuess * @throws MappingException */ private function guessAssociation(ClassMetadataInfo $metadata, Field $field, SchemaContainer $schemaContainer) { $property = $field->getProperty() ?: $field->getName(); $multiple = $metadata->isCollectionValuedAssociation($property); $mapping = $metadata->getAssociationMapping($property); foreach ($schemaContainer->getTypes() as $type) { $containerContext = new ContainerContext($type, $schemaContainer); if (!$this->isFieldContainerSupported($containerContext)) { continue; } if ($type->getModel() === $mapping['targetEntity']) { $typeName = $type->getName(); if ($multiple) { $typeName = sprintf('[%s]', $typeName); } return new TypeGuess($typeName, Guess::HIGH_CONFIDENCE); } } }