Skip to content
This repository has been archived by the owner on Mar 8, 2023. It is now read-only.

Commit

Permalink
Add initial support for building schema
Browse files Browse the repository at this point in the history
  • Loading branch information
crisu83 committed Feb 28, 2018
1 parent 974e772 commit f968d89
Show file tree
Hide file tree
Showing 95 changed files with 1,381 additions and 204 deletions.
3 changes: 3 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,13 @@
},
"autoload": {
"files": [
"./src/Execution/values.php",
"./src/Language/blockStringValue.php",
"./src/Language/buildSchema.php",
"./src/Language/helpers.php",
"./src/Language/parse.php",
"./src/Language/print.php",
"./src/Language/valueFromAST.php",
"./src/Type/definition.php",
"./src/Type/directives.php",
"./src/Type/scalars.php",
Expand Down
32 changes: 32 additions & 0 deletions src/Cache/CacheInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

namespace Digia\GraphQL\Cache;

interface CacheInterface
{

/**
* @param string $key
* @return mixed|null
*/
public function getItem(string $key);

/**
* @param string $key
* @return bool
*/
public function hasItem(string $key): bool;

/**
* @param string $key
* @return bool
*/
public function deleteItem(string $key): bool;

/**
* @param string $key
* @param mixed $value
* @return bool
*/
public function setItem(string $key, $value): bool;
}
57 changes: 57 additions & 0 deletions src/Cache/RuntimeCache.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php

namespace Digia\GraphQL\Cache;

class RuntimeCache implements CacheInterface
{

/**
* @var array
*/
private $_cache = [];

/**
* @inheritdoc
*/
public function getItem(string $key)
{
return $this->_cache[$key] ?? null;
}

/**
* @inheritdoc
*/
public function hasItem(string $key): bool
{
return isset($this->_cache[$key]);
}

/**
* @param string $key
* @return bool
*/
public function deleteItem(string $key): bool
{
unset($this->_cache[$key]);
return true;
}

/**
* @param string $key
* @param mixed $value
* @return bool
*/
public function setItem(string $key, $value): bool
{
$this->_cache[$key] = $value;
return true;
}

/**
* @return bool
*/
public function commit(): bool
{
return true;
}
}
117 changes: 117 additions & 0 deletions src/Execution/values.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
<?php

namespace Digia\GraphQL\Execution;

use Digia\GraphQL\Error\GraphQLError;
use Digia\GraphQL\Language\AST\Node\ArgumentNode;
use Digia\GraphQL\Language\AST\Node\Behavior\DirectivesTrait;
use Digia\GraphQL\Language\AST\Node\Contract\NodeInterface;
use Digia\GraphQL\Language\AST\Node\DirectiveNode;
use Digia\GraphQL\Language\AST\Node\FieldNode;
use Digia\GraphQL\Language\AST\Node\NamedTypeNode;
use Digia\GraphQL\Language\AST\Node\VariableNode;
use Digia\GraphQL\Type\Definition\Contract\DirectiveInterface;
use Digia\GraphQL\Type\Definition\Field;
use Digia\GraphQL\Type\Definition\NonNullType;
use function Digia\GraphQL\Language\valueFromAST;
use function Digia\GraphQL\Util\find;
use function Digia\GraphQL\Util\keyMap;

/**
* @param Field|DirectiveInterface $definition
* @param FieldNode|DirectiveNode $node
* @param array $variableValues
* @return array
* @throws GraphQLError
* @throws \Exception
*/
function getArgumentValues($definition, NodeInterface $node, array $variableValues = []): array
{
$coercedValues = [];
$argumentDefinitions = $definition->getArguments();
$argumentNodes = $node->getArguments();

if (empty($argumentDefinitions) || empty($argumentNodes)) {
return $coercedValues;
}

$argumentNodeMap = keyMap($argumentNodes, function (ArgumentNode $value) {
return $value->getNameValue();
});

foreach ($argumentDefinitions as $argumentDefinition) {
$name = $argumentDefinition->getName();
$argumentType = $argumentDefinition->getType();
/** @var ArgumentNode $argumentNode */
$argumentNode = $argumentNodeMap[$name];
$defaultValue = $argumentDefinition->getDefaultValue();

if (null === $argumentNode) {
if (null === $defaultValue) {
$coercedValues[$name] = $defaultValue;
} elseif (!$argumentType instanceof NonNullType) {
throw new GraphQLError(
sprintf('Argument "%s" of required type "%s" was not provided.', $name, $argumentType),
[$node]
);
}
} elseif ($argumentNode instanceof VariableNode) {
$variableName = $argumentNode->getNameValue();

if (!empty($variableValues) && isset($variableValues[$variableName])) {
// Note: this does not check that this variable value is correct.
// This assumes that this query has been validated and the variable
// usage here is of the correct type.
$coercedValues[$name] = $variableValues[$variableName];
} elseif (null !== $defaultValue) {
$coercedValues[$name] = $defaultValue;
} elseif ($argumentType instanceof NonNullType) {
throw new GraphQLError(
sprintf(
'Argument "%s" of required type "%s" was provided the variable "%s" which was not provided a runtime value.',
$name,
$argumentType,
$variableName
),
[$argumentNode->getValue()]
);
}
} else {
$valueNode = $argumentNode->getValue();

$coercedValue = valueFromAST($valueNode, $argumentType, $variableValues);

if (null === $coercedValue) {
// Note: ValuesOfCorrectType validation should catch this before
// execution. This is a runtime check to ensure execution does not
// continue with an invalid argument value.
throw new GraphQLError(
sprintf('Argument "%s" has invalid value %s.', $name, $valueNode),
[$argumentNode->getValue()]
);
}
}
}
}

/**
* @param DirectiveInterface $directive
* @param NodeInterface|DirectivesTrait $node
* @param array $variableValues
* @return array|null
* @throws GraphQLError
* @throws \Exception
*/
function getDirectiveValues(DirectiveInterface $directive, NodeInterface $node, array $variableValues = []): ?array
{
$directiveNode = $node->hasDirectives()
? find($node->getDirectives(), function (NamedTypeNode $value) use ($directive) {
return $value->getNameValue() === $directive->getName();
}) : null;

if (null !== $directiveNode) {
return getArgumentValues($directive, $directiveNode, $variableValues);
}

return null;
}
24 changes: 0 additions & 24 deletions src/Language/AST/Builder/Behavior/ParseAliasTrait.php

This file was deleted.

8 changes: 8 additions & 0 deletions src/Language/AST/Node/Behavior/ArgumentsTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@ trait ArgumentsTrait
*/
protected $arguments;

/**
* @return bool
*/
public function hasArguments(): bool
{
return !empty($this->arguments);
}

/**
* @return InputValueDefinitionNode[]
*/
Expand Down
8 changes: 8 additions & 0 deletions src/Language/AST/Node/Behavior/DescriptionTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@ public function getDescription(): ?StringValueNode
return $this->description;
}

/**
* @return null|string
*/
public function getDescriptionValue(): ?string
{
return null !== $this->description ? $this->description->getValue() : null;
}

/**
* @return array|null
*/
Expand Down
8 changes: 8 additions & 0 deletions src/Language/AST/Node/Behavior/DirectivesTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@ trait DirectivesTrait
*/
protected $directives;

/**
* @return bool
*/
public function hasDirectives(): bool
{
return !empty($this->directives);
}

/**
* @return DirectiveNode[]
*/
Expand Down
8 changes: 8 additions & 0 deletions src/Language/AST/Node/Behavior/EnumValuesTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@ trait EnumValuesTrait
*/
protected $values;

/**
* @return bool
*/
public function hasValues(): bool
{
return !empty($this->values);
}

/**
* @return EnumValueDefinitionNode[]
*/
Expand Down
8 changes: 8 additions & 0 deletions src/Language/AST/Node/Behavior/FieldsTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@ trait FieldsTrait
*/
protected $fields;

/**
* @return bool
*/
public function hasFields(): bool
{
return !empty($this->fields);
}

/**
* @return FieldDefinitionNode[]
*/
Expand Down
8 changes: 8 additions & 0 deletions src/Language/AST/Node/Behavior/InputFieldsTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@ trait InputFieldsTrait
*/
protected $fields;

/**
* @return bool
*/
public function hasFields(): bool
{
return !empty($this->fields);
}

/**
* @return InputValueDefinitionNode[]
*/
Expand Down
8 changes: 8 additions & 0 deletions src/Language/AST/Node/Behavior/InterfacesTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@ trait InterfacesTrait
*/
protected $interfaces;

/**
* @return bool
*/
public function hasInterfaces(): bool
{
return !empty($this->interfaces);
}

/**
* @return NamedTypeNode[]
*/
Expand Down
6 changes: 3 additions & 3 deletions src/Language/AST/Node/Behavior/NameTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ public function getName(): ?NameNode
}

/**
* @return string
* @return string|null
*/
public function getNameValue(): string
public function getNameValue(): ?string
{
return $this->name->getValue();
return null !== $this->name ? $this->name->getValue() : null;
}

/**
Expand Down
8 changes: 4 additions & 4 deletions src/Language/AST/Node/Behavior/TypeTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,20 @@
namespace Digia\GraphQL\Language\AST\Node\Behavior;

use Digia\GraphQL\Contract\SerializationInterface;
use Digia\GraphQL\Language\AST\Node\Contract\TypeNodeInterface;
use Digia\GraphQL\Language\AST\Node\NamedTypeNode;

trait TypeTrait
{

/**
* @var TypeNodeInterface|SerializationInterface
* @var NamedTypeNode|SerializationInterface
*/
protected $type;

/**
* @return TypeNodeInterface
* @return NamedTypeNode
*/
public function getType(): TypeNodeInterface
public function getType()
{
return $this->type;
}
Expand Down

0 comments on commit f968d89

Please sign in to comment.