Skip to content

Commit

Permalink
created group directive
Browse files Browse the repository at this point in the history
  • Loading branch information
chrissm79 committed Mar 24, 2018
1 parent f71a051 commit b419489
Show file tree
Hide file tree
Showing 8 changed files with 258 additions and 32 deletions.
47 changes: 44 additions & 3 deletions src/Schema/Directives/Fields/FieldDirective.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,20 @@ class FieldDirective implements FieldResolver
{
use HandlesDirectives;

/**
* Field resolver.
*
* @var string
*/
protected $resolver;

/**
* Field resolver method.
*
* @var string
*/
protected $method;

/**
* Name of the directive.
*
Expand All @@ -32,14 +46,14 @@ public function name()
public function handle(FieldValue $value)
{
$directive = $this->fieldDirective($value->getField(), $this->name());
$className = $this->getClassName($directive);
$resolver = $this->getResolver($value, $directive);
$method = $this->getMethod($directive);
$data = $this->argValue(collect($directive->arguments)->first(function ($arg) {
return 'args' === data_get($arg, 'name.value');
}));

return $value->setResolver(function ($root, array $args, $context = null, $info = null) use ($className, $method, $data) {
$instance = app($className);
return $value->setResolver(function ($root, array $args, $context = null, $info = null) use ($resolver, $method, $data) {
$instance = app($resolver);

return call_user_func_array(
[$instance, $method],
Expand All @@ -48,6 +62,27 @@ public function handle(FieldValue $value)
});
}

/**
* Get resolver namespace.
*
* @param FieldValue $value
* @param DirectiveNode $directive
*
* @return string
*/
protected function getResolver(FieldValue $value, DirectiveNode $directive)
{
if ($resolver = $this->directiveArgValue($directive, 'resolve')) {
$className = array_get(explode('@', $resolver), '0');

return $value->getNode()->getNamespace($className);
}

return $value->getNode()->getNamespace(
$this->getClassName($directive)
);
}

/**
* Get class name for resolver.
*
Expand Down Expand Up @@ -78,6 +113,12 @@ protected function getClassName(DirectiveNode $directive)
*/
protected function getMethod(DirectiveNode $directive)
{
if ($resolver = $this->directiveArgValue($directive, 'resolve')) {
if ($method = array_get(explode('@', $resolver), '1')) {
return $method;
}
}

$method = $this->directiveArgValue($directive, 'method');

if (! $method) {
Expand Down
89 changes: 89 additions & 0 deletions src/Schema/Directives/Nodes/GroupDirective.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
<?php

namespace Nuwave\Lighthouse\Schema\Directives\Nodes;

use Nuwave\Lighthouse\Schema\Values\NodeValue;
use Nuwave\Lighthouse\Support\Contracts\NodeMiddleware;
use Nuwave\Lighthouse\Support\Exceptions\DirectiveException;
use Nuwave\Lighthouse\Support\Traits\HandlesDirectives;

class GroupDirective implements NodeMiddleware
{
use HandlesDirectives;

/**
* Name of the directive.
*
* @return string
*/
public function name()
{
return 'group';
}

/**
* Handle node value.
*
* @param NodeValue $value
*
* @return NodeValue
*/
public function handle(NodeValue $value)
{
$this->setNamespace($value);
$this->setMiddleware($value);

return $value;
}

/**
* Set namespace on node.
*
* @param NodeValue $value [description]
*/
protected function setNamespace(NodeValue $value)
{
$namespace = $this->directiveArgValue(
$this->nodeDirective($value->getNode(), $this->name()),
'namespace'
);

if ($namespace) {
$value->setNamespace($namespace);
}
}

/**
* Set middleware for field.
*
* @param NodeValue $value
*/
protected function setMiddleware(NodeValue $value)
{
$node = $value->getNodeName();

if (! in_array($node, ['Query', 'Mutation'])) {
$message = 'Middleware can only be placed on a Query or Mutation ['.$node.']';

throw new DirectiveException($message);
}

$middleware = $this->directiveArgValue(
$this->nodeDirective($value->getNode(), $this->name()),
'middleware'
);

$container = graphql()->middleware();
$middleware = is_string($middleware) ? [$middleware] : $middleware;

if (empty($middleware)) {
return;
}

foreach ($value->getNodeFields() as $field) {
'Query' == $node
? $container->registerQuery($field->name->value, $middleware)
: $container->registerMutation($field->name->value, $middleware);
}
}
}
43 changes: 24 additions & 19 deletions src/Schema/Factories/NodeFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,25 +39,6 @@ public function handle(NodeValue $value)
return $this->applyMiddleware($value)->getType();
}

/**
* Extend type definition.
*
* @param Extension $extension
* @param Type $type
*
* @return Type
*/
public function extend(Extension $extension, Type $type)
{
$typeFields = value($type->config['fields']);
$extendedFields = $this->getFields(new NodeValue($extension->definition));
$type->config['fields'] = function () use ($typeFields, $extendedFields) {
return array_merge($typeFields, $extendedFields);
};

return $type;
}

/**
* Check if node has a resolver directive.
*
Expand Down Expand Up @@ -103,6 +84,8 @@ protected function transform(NodeValue $value)
return $this->objectType($value);
case InputObjectTypeDefinitionNode::class:
return $this->inputObjectType($value);
case Extension::class:
return $this->extend($value);
default:
throw new \Exception("Unknown node [{$value->getNodeName()}]");
}
Expand Down Expand Up @@ -204,6 +187,28 @@ public function inputObjectType(NodeValue $value)
return $value->setType($inputType);
}

/**
* Extend type definition.
*
* @param NodeValue $value
*
* @return NodeValue
*/
public function extend(NodeValue $value)
{
$value->setNode(
$value->getNode()->definition
);

$type = $value->getType();
$originalFields = value($type->config['fields']);
$type->config['fields'] = function () use ($originalFields, $value) {
return array_merge($originalFields, $this->getFields($value));
};

return $value;
}

/**
* Get fields for node.
*
Expand Down
4 changes: 3 additions & 1 deletion src/Schema/SchemaBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,9 @@ protected function extendTypes(DocumentNode $document)
$name = $extension->definition->name->value;

if ($type = collect($this->types)->firstWhere('name', $name)) {
app(NodeFactory::class)->extend($extension, $type);
$value = new NodeValue($extension);

app(NodeFactory::class)->handle($value->setType($type));
}
});
}
Expand Down
43 changes: 43 additions & 0 deletions src/Schema/Values/NodeValue.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ class NodeValue
*/
protected $directive;

/**
* Current namespace.
*
* @var string
*/
protected $namespace;

/**
* Create new instance of node value.
*
Expand All @@ -49,6 +56,20 @@ public static function init(Node $node)
return new static($node);
}

/**
* Set current node instance.
*
* @param Node $node
*
* @return self
*/
public function setNode(Node $node)
{
$this->node = $node;

return $this;
}

/**
* Set type definition.
*
Expand All @@ -73,6 +94,16 @@ public function setDirective(DirectiveNode $directive)
$this->directive = $directive;
}

/**
* Set the current namespace.
*
* @param string $namespace
*/
public function setNamespace($namespace)
{
$this->namespace = $namespace;
}

/**
* Get current node.
*
Expand Down Expand Up @@ -103,6 +134,18 @@ public function getType()
return $this->type;
}

/**
* Get current namespace.
*
* @param string $class
*
* @return string
*/
public function getNamespace($class = null)
{
return $class ? $this->namespace.'\\'.$class : $this->namespace;
}

/**
* Get the name of the node.
*
Expand Down
7 changes: 7 additions & 0 deletions src/Support/Contracts/NodeMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@

interface NodeMiddleware
{
/**
* Name of the directive.
*
* @return string
*/
public function name();

/**
* Handle node value.
*
Expand Down
13 changes: 4 additions & 9 deletions src/Support/Http/Controllers/GraphQLController.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,17 @@ class GraphQLController extends Controller
*/
public function __construct(Request $request)
{
// TODO: Query for middleware
// if ($query = $request->get('query')) {
// $middleware = app('graphql')->schema()
// ->parse($query)
// ->middleware();
//
// $this->middleware($middleware->toArray());
// }
$this->middleware(graphql()->middleware()->forRequest(
$request->input('query', '')
));
}

/**
* Execute graphql query.
*
* @param Request $request
*
* @return Response
* @return \Illuminate\Http\Response
*/
public function query(Request $request)
{
Expand Down
Loading

0 comments on commit b419489

Please sign in to comment.