Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .scrutinizer.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
tools:
external_code_coverage:
timeout: 600
timeout: 1200
build:
tests:
override:
Expand Down
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ before_install:

install: composer update --prefer-dist --no-interaction

script: if [ "$TRAVIS_PHP_VERSION" == "5.6" ]; then php -d xdebug.max_nesting_level=1000 vendor/bin/phpunit --coverage-clover=coverage.clover; else vendor/bin/phpunit; fi
script: if [ "$TRAVIS_PHP_VERSION" == "5.6" ]; then php -d xdebug.max_nesting_level=1000 vendor/bin/phpunit --debug --coverage-clover=coverage.clover; else vendor/bin/phpunit --debug; fi

after_script:
- if [ "$TRAVIS_PHP_VERSION" == "5.6" ]; then wget https://scrutinizer-ci.com/ocular.phar && php ocular.phar code-coverage:upload --format=php-clover coverage.clover; fi
12 changes: 6 additions & 6 deletions Definition/Builder/TypeBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

namespace Overblog\GraphQLBundle\Definition\Builder;

use GraphQL\Type\Definition\Type;
use Overblog\GraphQLBundle\Definition\Type;
use Overblog\GraphQLBundle\Resolver\ResolverInterface;

class TypeBuilder
Expand All @@ -23,11 +23,11 @@ class TypeBuilder
'relay-node' => 'Overblog\\GraphQLBundle\\Relay\\Node\\NodeInterfaceType',
'relay-mutation-input' => 'Overblog\\GraphQLBundle\\Relay\\Mutation\\InputType',
'relay-mutation-payload' => 'Overblog\\GraphQLBundle\\Relay\\Mutation\\PayloadType',
'object' => 'GraphQL\\Type\\Definition\\ObjectType',
'enum' => 'GraphQL\\Type\\Definition\\EnumType',
'interface' => 'GraphQL\\Type\\Definition\\InterfaceType',
'union' => 'GraphQL\\Type\\Definition\\UnionType',
'input-object' => 'GraphQL\\Type\\Definition\\InputObjectType',
'object' => 'Overblog\\GraphQLBundle\\Definition\\ObjectType',
'enum' => 'Overblog\\GraphQLBundle\\Definition\\EnumType',
'interface' => 'Overblog\\GraphQLBundle\\Definition\\InterfaceType',
'union' => 'Overblog\\GraphQLBundle\\Definition\\UnionType',
'input-object' => 'Overblog\\GraphQLBundle\\Definition\\InputObjectType',
];

public function __construct(ResolverInterface $configResolver)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,10 @@
* file that was distributed with this source code.
*/

namespace Overblog\GraphQLBundle\Definition\Builder;
namespace Overblog\GraphQLBundle\Definition;

interface ConfigBuilderInterface
{
public function create($type, array $config);
use GraphQL\Type\Definition\EnumType as BaseEnumType;

public function getBaseClassName($type);
class EnumType extends BaseEnumType
{
}
80 changes: 80 additions & 0 deletions Definition/FieldDefinition.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?php

/*
* This file is part of the OverblogGraphQLBundle package.
*
* (c) Overblog <http://github.com/overblog/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Overblog\GraphQLBundle\Definition;

use GraphQL\Type\Definition\Config;
use GraphQL\Type\Definition\FieldDefinition as BaseFieldDefinition;

class FieldDefinition extends BaseFieldDefinition
{
const DEFAULT_COMPLEXITY_FN = '\Overblog\GraphQLBundle\Definition\FieldDefinition::defaultComplexity';

/**
* @var callable
*/
private $complexityFn;

public static function getDefinition()
{
return array_merge(
parent::getDefinition(),
[
'complexity' => Config::CALLBACK,
]
);
}

public static function createMap(array $fields)
{
$map = [];
foreach ($fields as $name => $field) {
if (!isset($field['name'])) {
$field['name'] = $name;
}
$map[$name] = static::create($field);
}

return $map;
}

/**
* @param array $field
*
* @return FieldDefinition
*/
public static function create($field)
{
Config::validate($field, static::getDefinition());

return new static($field);
}

protected function __construct(array $config)
{
parent::__construct($config);

$this->complexityFn = isset($config['complexity']) ? $config['complexity'] : static::DEFAULT_COMPLEXITY_FN;
}

/**
* @return callable|\Closure
*/
public function getComplexityFn()
{
return $this->complexityFn;
}

public static function defaultComplexity($childrenComplexity)
{
return $childrenComplexity + 1;
}
}
18 changes: 18 additions & 0 deletions Definition/InputObjectType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

/*
* This file is part of the OverblogGraphQLBundle package.
*
* (c) Overblog <http://github.com/overblog/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Overblog\GraphQLBundle\Definition;

use GraphQL\Type\Definition\InputObjectType as BaseInputObjectType;

class InputObjectType extends BaseInputObjectType
{
}
18 changes: 18 additions & 0 deletions Definition/InterfaceType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

/*
* This file is part of the OverblogGraphQLBundle package.
*
* (c) Overblog <http://github.com/overblog/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Overblog\GraphQLBundle\Definition;

use GraphQL\Type\Definition\InterfaceType as BaseInterfaceType;

class InterfaceType extends BaseInterfaceType
{
}
88 changes: 88 additions & 0 deletions Definition/ObjectType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<?php

/*
* This file is part of the OverblogGraphQLBundle package.
*
* (c) Overblog <http://github.com/overblog/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Overblog\GraphQLBundle\Definition;

use GraphQL\Type\Definition\Config;
use GraphQL\Type\Definition\ObjectType as BaseObjectType;
use GraphQL\Type\Definition\ResolveInfo;
use GraphQL\Utils;

class ObjectType extends BaseObjectType
{
private $isTypeOf;

/**
* @var FieldDefinition[]
*/
private $fields;

/**
* @param array $config
*
* @todo open PR on lib to ease inheritance
*/
public function __construct(array $config)
{
Utils::invariant(!empty($config['name']), 'Every type is expected to have name');

Config::validate($config, [
'name' => Config::STRING | Config::REQUIRED,
'fields' => Config::arrayOf(
FieldDefinition::getDefinition(),
Config::KEY_AS_NAME | Config::MAYBE_THUNK
),
'description' => Config::STRING,
'interfaces' => Config::arrayOf(
Config::INTERFACE_TYPE,
Config::MAYBE_THUNK
),
'isTypeOf' => Config::CALLBACK, // ($value, ResolveInfo $info) => boolean
'resolveField' => Config::CALLBACK,
]);

$this->name = $config['name'];
$this->description = isset($config['description']) ? $config['description'] : null;
$this->resolveFieldFn = isset($config['resolveField']) ? $config['resolveField'] : null;
$this->isTypeOf = isset($config['isTypeOf']) ? $config['isTypeOf'] : null;
$this->config = $config;

if (isset($config['interfaces'])) {
InterfaceType::addImplementationToInterfaces($this);
}
}

public function getFields()
{
if (null === $this->fields) {
$fields = isset($this->config['fields']) ? $this->config['fields'] : [];
$fields = is_callable($fields) ? call_user_func($fields) : $fields;
$this->fields = FieldDefinition::createMap($fields);
}

return $this->fields;
}

public function getField($name)
{
if (null === $this->fields) {
$this->getFields();
}
Utils::invariant(isset($this->fields[$name]), "Field '%s' is not defined for type '%s'", $name, $this->name);

return $this->fields[$name];
}

public function isTypeOf($value, ResolveInfo $info)
{
return isset($this->isTypeOf) ? call_user_func($this->isTypeOf, $value, $info) : null;
}
}
18 changes: 18 additions & 0 deletions Definition/Type.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

/*
* This file is part of the OverblogGraphQLBundle package.
*
* (c) Overblog <http://github.com/overblog/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Overblog\GraphQLBundle\Definition;

use GraphQL\Type\Definition\Type as BaseType;

class Type extends BaseType
{
}
18 changes: 18 additions & 0 deletions Definition/UnionType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

/*
* This file is part of the OverblogGraphQLBundle package.
*
* (c) Overblog <http://github.com/overblog/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Overblog\GraphQLBundle\Definition;

use GraphQL\Type\Definition\UnionType as BaseUnionType;

class UnionType extends BaseUnionType
{
}
36 changes: 24 additions & 12 deletions DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace Overblog\GraphQLBundle\DependencyInjection;

use Overblog\GraphQLBundle\Request\Validator\Rule\QueryDepth;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;

Expand Down Expand Up @@ -92,23 +93,34 @@ public function getConfigTreeBuilder()
->arrayNode('security')
->addDefaultsIfNotSet()
->children()
->integerNode('query_max_depth')
->info('Limit query depth. Disabled if equal to false or 0.')
->beforeNormalization()
->ifTrue(function ($v) { return false === $v; })
->then(function () { return 0; })
->end()
->defaultFalse()
->validate()
->ifTrue(function ($v) { return $v < 0; })
->thenInvalid('"overblog_graphql.security.query_max_depth" must be greater or equal to 0.')
->end()
->end()
->append($this->addSecurityQuerySection('query_max_depth', QueryDepth::DISABLED))
->append($this->addSecurityQuerySection('query_max_complexity', QueryDepth::DISABLED))
->end()
->end()
->end()
->end();

return $treeBuilder;
}

private function addSecurityQuerySection($name, $disabledValue)
{
$builder = new TreeBuilder();
$node = $builder->root($name, 'integer');

$node
->info('Disabled if equal to false.')
->beforeNormalization()
->ifTrue(function ($v) { return false === $v; })
->then(function () use ($disabledValue) { return $disabledValue; })
->end()
->defaultFalse()
->validate()
->ifTrue(function ($v) { return $v < 0; })
->thenInvalid('"overblog_graphql.security.'.$name.'" must be greater or equal to 0.')
->end()
;

return $node;
}
}
10 changes: 9 additions & 1 deletion DependencyInjection/OverblogGraphQLExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,19 @@ private function setSecurity(array $config, ContainerBuilder $container)
{
if (isset($config['security']['query_max_depth'])) {
$container
->getDefinition($this->getAlias().'.request_validator_rule_max_query_depth')
->getDefinition($this->getAlias().'.request_validator_rule_query_depth')
->addMethodCall('setMaxQueryDepth', [$config['security']['query_max_depth']])
->setPublic(true)
;
}

if (isset($config['security']['query_max_complexity'])) {
$container
->getDefinition($this->getAlias().'.request_validator_rule_query_complexity')
->addMethodCall('setMaxQueryComplexity', [$config['security']['query_max_complexity']])
->setPublic(true)
;
}
}

private function setGraphiQLTemplate(array $config, ContainerBuilder $container)
Expand Down
3 changes: 3 additions & 0 deletions DependencyInjection/TypesConfiguration.php
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,9 @@ private function addFieldsSelection($name, $enabledBuilder = true)
}

$prototype
->scalarNode('complexity')
->info('Custom complexity calculator.')
->end()
->end()
->end();

Expand Down
Loading