Skip to content

Commit

Permalink
NEW Use interfaces for version type
Browse files Browse the repository at this point in the history
  • Loading branch information
chillu committed Feb 21, 2019
1 parent fa931ec commit 5890ef9
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 33 deletions.
56 changes: 23 additions & 33 deletions src/GraphQL/Extensions/DataObjectScaffolderExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,26 @@

namespace SilverStripe\Versioned\GraphQL\Extensions;

use Exception;
use GraphQL\Type\Definition\InterfaceType;
use GraphQL\Type\Definition\ObjectType;
use GraphQL\Type\Definition\Type;
use SilverStripe\Core\Extension;
use SilverStripe\GraphQL\Manager;
use SilverStripe\GraphQL\Scaffolding\Scaffolders\DataObjectScaffolder;
use SilverStripe\GraphQL\Scaffolding\StaticSchema;
use SilverStripe\ORM\DataObject;
use SilverStripe\Security\Member;
use SilverStripe\Versioned\GraphQL\Operations\ReadVersions;
use SilverStripe\Versioned\Versioned;

class DataObjectScaffolderExtension extends Extension
{
/**
* @var string
*/
protected $versionInterfaceName = 'VersionInterface';

/**
* Adds the "Version" and "Versions" fields to any dataobject that has the Versioned extension.
* @param Manager $manager
Expand All @@ -28,53 +36,35 @@ public function onBeforeAddToManager(Manager $manager)
if (!$instance->hasExtension(Versioned::class)) {
return;
}

/* @var ObjectType $rawType */
$rawType = $owner->scaffold($manager);

/** @var InterfaceType $rawVersionInterfaceType */
$rawVersionInterfaceType = $manager->getType('VersionInterface');

$versionName = $this->createVersionedTypeName($class);
$coreFieldsFn = $rawType->config['fields'];
$versionFieldsFn = $rawVersionInterfaceType->config['fields'];

// Create the "version" type for this dataobject. Takes the original fields
// and augments them with the Versioned_Version specific fields
$versionType = new ObjectType([
'name' => $versionName,
'fields' => function () use ($coreFieldsFn, $manager, $memberType) {
'fields' => function () use ($coreFieldsFn, $versionFieldsFn, $manager, $memberType) {
$coreFields = $coreFieldsFn();
$versionFields = [
'Author' => [
'type' => $manager->getType($memberType),
'resolve' => function ($obj) {
return $obj->Author();
}
],
'Publisher' => [
'type' => $manager->getType($memberType),
'resolve' => function ($obj) {
return $obj->Publisher();
}
],
'Published' => [
'type' => Type::boolean(),
'resolve' => function ($obj) {
return $obj->WasPublished;
}
],
'LiveVersion' => [
'type' => Type::boolean(),
'resolve' => function ($obj) {
return $obj->isLiveVersion();
}
],
'LatestDraftVersion' => [
'type' => Type::boolean(),
'resolve' => function ($obj) {
return $obj->isLatestDraftVersion();
}
],
];
$versionFields = $versionFieldsFn();

// Remove this recursive madness.
unset($coreFields['Versions']);

return array_merge($coreFields, $versionFields);
},
'interfaces' => function() use ($rawType, $manager) {
return array_merge(
$rawType->getInterfaces(),
[$manager->getType('VersionInterface')]
);
}
]);

Expand Down
2 changes: 2 additions & 0 deletions src/GraphQL/Extensions/ManagerExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use SilverStripe\Versioned\GraphQL\Types\VersionedQueryMode;
use SilverStripe\Versioned\GraphQL\Types\VersionedStage;
use SilverStripe\Versioned\GraphQL\Types\VersionedStatus;
use SilverStripe\Versioned\GraphQL\Types\VersionInterfaceType;

class ManagerExtension extends Extension
{
Expand All @@ -27,5 +28,6 @@ public function updateConfig(&$config)
$config['types']['VersionedQueryMode'] = VersionedQueryMode::class;
$config['types']['VersionedInputType'] = VersionedInputType::class;
$config['types']['CopyToStageInputType'] = CopyToStageInputType::class;
$config['types']['VersionInterface'] = VersionInterfaceType::class;
}
}
95 changes: 95 additions & 0 deletions src/GraphQL/Types/VersionInterfaceType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<?php

namespace SilverStripe\Versioned\GraphQL\Types;

use Exception;
use GraphQL\Type\Definition\Type;
use SilverStripe\GraphQL\InterfaceTypeCreator;
use SilverStripe\GraphQL\Scaffolding\StaticSchema;
use SilverStripe\ORM\DataObject;
use SilverStripe\Security\Member;

if (!class_exists(InterfaceTypeCreator::class)) {
return;
}

class VersionInterfaceType extends InterfaceTypeCreator
{
/**
* @return array
*/
public function attributes()
{
return [
'name' => 'VersionInterface',
'description' => 'Metadata fields for versioning on a DataObject'
];
}

/**
* @return array
*/
public function fields()
{
$memberType = StaticSchema::inst()->typeNameForDataObject(Member::class);
return [
'Author' => [
'type' => $this->manager->getType($memberType),
'resolve' => function ($obj) {
return $obj->Author();
}
],
'Publisher' => [
'type' => $this->manager->getType($memberType),
'resolve' => function ($obj) {
return $obj->Publisher();
}
],
'Published' => [
'type' => Type::boolean(),
'resolve' => function ($obj) {
return $obj->WasPublished;
}
],
'LiveVersion' => [
'type' => Type::boolean(),
'resolve' => function ($obj) {
return $obj->isLiveVersion();
}
],
'LatestDraftVersion' => [
'type' => Type::boolean(),
'resolve' => function ($obj) {
return $obj->isLatestDraftVersion();
}
],
];
}

/**
* @return \GraphQL\Type\Definition\Type
* @throws Exception
*/
public function resolveType()
{
if (!$obj instanceof DataObject) {
throw new Exception(sprintf(
'Type with class %s is not a DataObject',
get_class($obj)
));
}
$class = get_class($obj);
while ($class !== DataObject::class) {
$typeName = StaticSchema::inst()->typeNameForDataObject($class);
if ($this->manager->hasType($typeName)) {
return $this->manager->getType($typeName);
}
$class = get_parent_class($class);
}
throw new Exception(sprintf(
'There is no type defined for %s, and none of its ancestors are defined.',
get_class($obj)
));
}

}

0 comments on commit 5890ef9

Please sign in to comment.