From eb35ad47bf12b9a48dcf0bf48a58befeaedd8365 Mon Sep 17 00:00:00 2001 From: Damian Mooyman Date: Tue, 20 Dec 2016 14:49:48 +1300 Subject: [PATCH] API Standardise OperationResolver::resolve() (#28) API PaginatedQueryCreator is abstract PSR2 cleanup PHPDoc cleanup --- src/InterfaceTypeCreator.php | 21 +----- src/Manager.php | 54 ++++++-------- src/Pagination/Connection.php | 8 +- src/Pagination/SortDirectionType.php | 40 ++++++++++ src/Pagination/SortInputType.php | 91 +++++++++++++++++++++++ src/Util/CaseInsensitiveFieldAccessor.php | 22 ++---- 6 files changed, 169 insertions(+), 67 deletions(-) create mode 100644 src/Pagination/SortDirectionType.php create mode 100644 src/Pagination/SortInputType.php diff --git a/src/InterfaceTypeCreator.php b/src/InterfaceTypeCreator.php index e6bf750df..1423a8208 100644 --- a/src/InterfaceTypeCreator.php +++ b/src/InterfaceTypeCreator.php @@ -2,20 +2,11 @@ namespace SilverStripe\GraphQL; -use GraphQL\Type\Definition\InterfaceType; +use GraphQL\Type\Definition\InterfaceType as BaseInterfaceType; -/** - * Base type creator for interface type generation. - * - * @link https://github.com/webonyx/graphql-php#interfaces - */ class InterfaceTypeCreator extends TypeCreator { - /** - * Returns a callback to the type resolver for this interface - * - * @return callable - */ + protected function getTypeResolver() { if (!method_exists($this, 'resolveType')) { @@ -23,7 +14,6 @@ protected function getTypeResolver() } $resolver = array($this, 'resolveType'); - return function () use ($resolver) { $args = func_get_args(); return call_user_func_array($resolver, $args); @@ -47,13 +37,8 @@ public function getAttributes() return $attributes; } - /** - * Generates the interface type from its configuration - * - * @return InterfaceType - */ public function toType() { - return new InterfaceType($this->toArray()); + return new BaseInterfaceType($this->toArray()); } } diff --git a/src/Manager.php b/src/Manager.php index 176509454..d90c4a2c1 100644 --- a/src/Manager.php +++ b/src/Manager.php @@ -6,18 +6,14 @@ use GraphQL\Schema; use GraphQL\GraphQL; use SilverStripe\Core\Injector\Injector; -use SilverStripe\Core\Injector\Injectable; use GraphQL\Type\Definition\ObjectType; use GraphQL\Error; use GraphQL\Type\Definition\Type; -use SilverStripe\Security\Member; use SilverStripe\GraphQL\Scaffolding\ScaffoldingProvider; use SilverStripe\GraphQL\Scaffolding\Scaffolders\GraphQLScaffolder; class Manager { - use Injectable; - /** * @var array Map of named {@link Type} */ @@ -45,39 +41,38 @@ class Manager /** * @param array $config An array with optional 'types' and 'queries' keys - * * @return Manager */ public static function createFromConfig($config) { /** @var Manager $manager */ - $manager = Injector::inst()->create(self::class); + $manager = Injector::inst()->create(Manager::class); - if (isset($config['scaffolding'])) { - $scaffolder = GraphQLScaffolder::createFromConfig($config['scaffolding']); + if(isset($config['scaffolding'])) { + $scaffolder = GraphQLScaffolder::createFromConfig($config['scaffolding']); } else { - $scaffolder = new GraphQLScaffolder(); + $scaffolder = new GraphQLScaffolder(); } - if (isset($config['scaffolding_providers'])) { - foreach ($config['scaffolding_providers'] as $provider) { - if (!class_exists($provider)) { + if(isset($config['scaffolding_providers'])) { + foreach($config['scaffolding_providers'] as $provider) { + if(!class_exists($provider)) { throw new InvalidArgumentException(sprintf( 'Scaffolding provider %s does not exist.', $provider - )); - } + )); + } + + $provider = Injector::inst()->create($provider); - $provider = Injector::inst()->create($provider); - - if (!$provider instanceof ScaffoldingProvider) { + if(!$provider instanceof ScaffoldingProvider) { throw new InvalidArgumentException(sprintf( 'All scaffolding providers must implement the %s interface', ScaffoldingProvider::class - )); - } - $scaffolder = $provider->provideGraphQLScaffolding($scaffolder); - } + )); + } + $scaffolder = $provider->provideGraphQLScaffolding($scaffolder); + } } $scaffolder->addToManager($manager); @@ -88,7 +83,7 @@ public static function createFromConfig($config) $typeCreator = Injector::inst()->create($typeCreatorClass, $manager); if (!($typeCreator instanceof TypeCreator)) { throw new InvalidArgumentException(sprintf( - 'The type named "%s" needs to be a class extending '.TypeCreator::class, + 'The type named "%s" needs to be a class extending ' . TypeCreator::class, $name )); } @@ -104,7 +99,7 @@ public static function createFromConfig($config) $queryCreator = Injector::inst()->create($queryCreatorClass, $manager); if (!($queryCreator instanceof QueryCreator)) { throw new InvalidArgumentException(sprintf( - 'The type named "%s" needs to be a class extending '.QueryCreator::class, + 'The type named "%s" needs to be a class extending ' . QueryCreator::class, $name )); } @@ -120,7 +115,7 @@ public static function createFromConfig($config) $mutationCreator = Injector::inst()->create($mutationCreatorClass, $manager); if (!($mutationCreator instanceof MutationCreator)) { throw new InvalidArgumentException(sprintf( - 'The mutation named "%s" needs to be a class extending '.MutationCreator::class, + 'The mutation named "%s" needs to be a class extending ' . MutationCreator::class, $name )); } @@ -189,8 +184,7 @@ public function query($query, $params = [], $schema = null) public function queryAndReturnResult($query, $params = [], $schema = null) { $schema = $this->schema($schema); - $context = $this->getContext(); - $result = GraphQL::executeAndReturnResult($schema, $query, null, $context, $params); + $result = GraphQL::executeAndReturnResult($schema, $query, null, null, $params); return $result; } @@ -198,12 +192,12 @@ public function queryAndReturnResult($query, $params = [], $schema = null) /** * @param Type $type * @param string $name An optional identifier for this type (defaults to 'name' attribute in type definition). - * Needs to be unique in schema + * Needs to be unique in schema. */ public function addType(Type $type, $name = '') { if (!$name) { - $name = (string) $type; + $name = (string)$type; } $this->types[$name] = $type; } @@ -234,7 +228,7 @@ public function hasType($name) /** * @param array $query - * @param string $name Identifier for this query (unique in schema) + * @param string $name Identifier for this query (unique in schema) */ public function addQuery($query, $name) { @@ -253,7 +247,7 @@ public function getQuery($name) /** * @param array $mutation - * @param string $name Identifier for this mutation (unique in schema) + * @param string $name Identifier for this mutation (unique in schema) */ public function addMutation($mutation, $name) { diff --git a/src/Pagination/Connection.php b/src/Pagination/Connection.php index f02a67c58..6eb572265 100644 --- a/src/Pagination/Connection.php +++ b/src/Pagination/Connection.php @@ -2,9 +2,9 @@ namespace SilverStripe\GraphQL\Pagination; +use SilverStripe\Core\Object; use SilverStripe\Core\Injector\Injector; use SilverStripe\GraphQL\OperationResolver; -use SilverStripe\Core\Injector\Injectable; use SilverStripe\ORM\SS_List; use SilverStripe\ORM\Limitable; use SilverStripe\ORM\Sortable; @@ -32,10 +32,8 @@ * } * */ -class Connection implements OperationResolver +class Connection extends Object implements OperationResolver { - use Injectable; - /** * @var string */ @@ -89,6 +87,8 @@ class Connection implements OperationResolver public function __construct($connectionName) { $this->connectionName = $connectionName; + + parent::__construct(); } /** diff --git a/src/Pagination/SortDirectionType.php b/src/Pagination/SortDirectionType.php new file mode 100644 index 000000000..b42d608f0 --- /dev/null +++ b/src/Pagination/SortDirectionType.php @@ -0,0 +1,40 @@ +type) { + $this->type = new EnumType([ + 'name' => 'SortDirection', + 'description' => 'Set order order to either ASC or DESC', + 'values' => [ + 'ASC' => [ + 'value' => 'ASC', + 'description' => 'Lowest value to highest.' + ], + 'DESC' => [ + 'value' => 'DESC', + 'description' => 'Highest value to lowest.' + ] + ] + ]); + } + + return $this->type; + } +} diff --git a/src/Pagination/SortInputType.php b/src/Pagination/SortInputType.php new file mode 100644 index 000000000..d8d46882d --- /dev/null +++ b/src/Pagination/SortInputType.php @@ -0,0 +1,91 @@ +inputName = $name; + } + + /** + * @param array $sortableFields + * + * @return $this + */ + public function setSortableFields($sortableFields) + { + $this->sortableFields = $sortableFields; + + return $this; + } + + /** + * @return Type + */ + public function toType() + { + $values = []; + + foreach ($this->sortableFields as $fieldAlias => $fieldName) { + $values[$fieldAlias] = [ + 'value' => $fieldAlias + ]; + } + + $sortableField = new EnumType([ + 'name' => ucfirst($this->inputName) . 'SortFieldType', + 'description' => 'Field name to sort by.', + 'values' => $values + ]); + + if (!$this->type) { + $this->type = new InputObjectType([ + 'name' => ucfirst($this->inputName) .'SortInputType', + 'description' => 'Define the sorting', + 'fields' => [ + 'field' => [ + 'type' => Type::nonNull($sortableField), + 'description' => 'Sort field name.' + ], + 'direction' => [ + 'type' => Injector::inst()->get(SortDirectionType::class)->toType(), + 'description' => 'Sort direction (ASC / DESC)' + ] + ] + ]); + } + + return $this->type; + } +} diff --git a/src/Util/CaseInsensitiveFieldAccessor.php b/src/Util/CaseInsensitiveFieldAccessor.php index 3c821c77c..27b6a4c2b 100644 --- a/src/Util/CaseInsensitiveFieldAccessor.php +++ b/src/Util/CaseInsensitiveFieldAccessor.php @@ -80,12 +80,12 @@ public function getValue(ViewableData $object, $fieldName, $opts = []) public function setValue(ViewableData $object, $fieldName, $value, $opts = []) { $opts = $opts ?: []; - $opts = array_merge([ - self::HAS_METHOD => true, - self::HAS_FIELD => true, - self::HAS_SETTER => true, - self::DATAOBJECT => true, - ], $opts); + $opts = [ + self::HAS_METHOD => true, + self::HAS_FIELD => true, + self::HAS_SETTER => true, + self::DATAOBJECT => true, + ] + $opts; $objectFieldName = $this->getObjectFieldName($object, $fieldName, $opts); @@ -118,16 +118,8 @@ public function setValue(ViewableData $object, $fieldName, $value, $opts = []) * Example: [ViewableDataCaseInsensitiveFieldMapper::HAS_METHOD => true] * @return null|string Name in actual casing on $object */ - public function getObjectFieldName(ViewableData $object, $fieldName, $opts = []) + protected function getObjectFieldName(ViewableData $object, $fieldName, $opts = []) { - $opts = $opts ?: []; - $opts = array_merge([ - self::HAS_METHOD => true, - self::HAS_FIELD => true, - self::HAS_SETTER => true, - self::DATAOBJECT => true, - ], $opts); - $optFn = function ($type) use (&$opts) { return (in_array($type, $opts) && $opts[$type] === true); };