Skip to content

Instantly share code, notes, and snippets.

@maxime-rainville
Created December 14, 2017 23:30
Show Gist options
  • Save maxime-rainville/d9952270f7e8a4ec9a1f843665677194 to your computer and use it in GitHub Desktop.
Save maxime-rainville/d9952270f7e8a4ec9a1f843665677194 to your computer and use it in GitHub Desktop.
A simple Silverstripe 4 GraqhQL QueryCreator for returning a single DataObject by some unique field.
<?php
namespace SmartCookie\GraphQL;
use GraphQL\Type\Definition\ResolveInfo;
use GraphQL\Type\Definition\Type;
use SilverStripe\GraphQL\Manager;
use SilverStripe\GraphQL\OperationResolver;
use SilverStripe\GraphQL\QueryCreator;
use SilverStripe\ORM\DataObject;
use SilverStripe\GraphQL\Scaffolding\Util\ScaffoldingUtil;
use ReflectionClass;
/**
* Creates a GraphQL Query that returns a DataObject by its URL Segment.
*/
class ByUrlSegmentQueryCreator extends QueryCreator implements OperationResolver
{
/**
* A Singleton of the object we want to serve.
* @var SilverStripe\ORM\DataObject
*/
private $do;
/**
* The Short name to use for naming our methods.
* @var string
*/
private $shortName;
/**
* @param SilverStripe\GraphQL\Manager $manager
* @param string $doClass DataObject class name that this query will fetch.
* @param string $shortName Optional suffix to give to the query name. Defaults to the DataOobject classname without
* the namespace.
*/
public function __construct(Manager $manager = null, $doClass, $shortName = false)
{
// Create a singleton instance of our targeted DataObject class.
$this->do = DataObject::singleton($doClass);
// If no short name has been provided, let's infer one from our DO class.
if ($shortName) {
$this->shortName = $shortName;
} else {
$reflect = new ReflectionClass($this->do);
$this->shortName = $reflect->getShortName();
}
parent::__construct($manager);
}
public function attributes()
{
return [
'name' => 'byUrl' . $this->shortName,
'description' => sprintf('Retrieve a single %s by its URL segment.', $this->do->singular_name())
];
}
public function args()
{
return [
'UrlSegment' => ['type' => Type::nonNull(Type::string())]
];
}
public function type()
{
$typeName = ScaffoldingUtil::typeNameForDataObject(get_class($this->do));
return $this->manager->getType($typeName);
}
public function resolve($object, array $args, $context, ResolveInfo $info)
{
$do = $this->do->get()->filter($args)->First();
// Make sure the current user is allowed to view this specific DO
if ($do && !$do->canView($context['currentUser'])) {
throw new \InvalidArgumentException(sprintf(
'%s view access not permitted',
$this->do->getClassName()
));
}
return $do;
}
}
SilverStripe\GraphQL\Controller:
schema:
scaffolding_providers:
- SmartCookie\Models\CarModel
- SmartCookie\Models\Brand
queries:
byUrlCarModel: 'SmartCookie\GraphQL\ByUrlSegmentQueryCreator("SmartCookie\\Models\\CarModel")'
byUrlBrand: 'SmartCookie\GraphQL\ByUrlSegmentQueryCreator("SmartCookie\\Models\\Brand")'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment