Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NEW: GraphQL 4 Compatibility #308

Merged
merged 34 commits into from
Nov 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
fbc67f1
First pass at graphql 4 compat
Aug 5, 2020
1f1e8c9
It works kinda
Aug 7, 2020
209807f
Remove conflict composer
Aug 7, 2020
064ef9b
Replace graphql3 legacy
Aug 20, 2020
602aadf
Fix ApplyVersionFilters conflict
Aug 20, 2020
9082037
Fix paginate plugin bfore
Sep 8, 2020
e834f23
Compatability with flushless schema
Sep 15, 2020
3d9bfdb
Throw if versioned used on nested query
Sep 17, 2020
9466e67
Versioned readone
Sep 21, 2020
979d806
NEW schema defaults
Sep 24, 2020
f724f13
Compliance with new modelConfig
Oct 2, 2020
46aa27d
Fix exlcusion rule
Oct 19, 2020
d74c333
Remove old classes
Oct 19, 2020
1ec0c2b
Proper sort for versions field
Oct 20, 2020
7ed2186
Compatability with field formatting API
Oct 24, 2020
c037818
New graphql 3 compat
Oct 27, 2020
6a6d2b8
compliance with new modeltype constructor
Oct 29, 2020
896a555
Operations tests for v4'
Nov 1, 2020
2860981
new composer constraint for graphql
Nov 1, 2020
c3beac2
Add shims for graphql branches
Nov 1, 2020
61b8e99
Fix git branch
Nov 1, 2020
3974474
Update admin requirement
Nov 2, 2020
fddb7c7
Clean up travis
Nov 2, 2020
a6afd42
Remove admin depdendency
Nov 2, 2020
e93d5d8
Add graphql dependency
Nov 2, 2020
9d671c0
Clean up tests
Nov 2, 2020
0b4f59a
Tests should work now
Nov 2, 2020
0dda4bb
Fix linting
Nov 2, 2020
64f399a
BC tests fixed
Nov 2, 2020
9416f6e
Add missing versioned fields
Nov 6, 2020
1392b0c
Linting
Nov 6, 2020
ff1577a
use stageTable
Nov 12, 2020
3df6414
API Mark GraphQL v3 usage as deprecated
chillu Nov 11, 2020
7d03367
Fixed draft table alias regression
chillu Nov 12, 2020
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
12 changes: 11 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ jobs:
env: DB=MYSQL RECIPE_VERSION=4.x-dev PHPUNIT_TEST=1
- php: 7.4
env: DB=MYSQL RECIPE_VERSION=4.x-dev PHPUNIT_TEST=1
- php: 7.4
env: DB=MYSQL RECIPE_VERSION=4.x-dev PHPUNIT_TEST=1 BACKWARD_COMPAT=1
- php: nightly
env: DB=MYSQL RECIPE_VERSION=4.x-dev PHPUNIT_TEST=1 COMPOSER_ARG=--ignore-platform-reqs

Expand All @@ -37,12 +39,20 @@ before_script:

# Install composer
- composer validate
- composer require silverstripe/recipe-cms:$RECIPE_VERSION --no-update
- composer require silverstripe/recipe-cms:$RECIPE_VERSION --no-update --prefer-dist
# Fix for running phpunit 5 on php 7.4+
- composer require --no-update sminnee/phpunit-mock-objects:^3

######## Remove once GraphQL 4 is merged #########
- composer require silverstripe/admin:"dev-pulls/1/schemageddon as 1.x-dev" silverstripe/asset-admin:"dev-pulls/1/schemageddon as 1.x-dev" silverstripe/versioned-admin:"dev-pulls/1/schemageddon as 1.x-dev" silverstripe/cms:"dev-pulls/4/schemageddon as 4.x-dev" silverstripe/graphql:"4.x-dev as 3.x-dev" --no-update
##################################################
- 'if [[ $BACKWARD_COMPAT ]]; then composer require silverstripe/graphql:"dev-pulls/3/schemageddon-compat as 3.x-dev" --no-update; fi'


- if [[ $DB == PGSQL ]]; then composer require silverstripe/postgresql:^2 --no-update; fi
- composer update --prefer-dist --no-interaction --no-progress --no-suggest --optimize-autoloader --verbose --profile $COMPOSER_ARG


script:
- if [[ $PHPUNIT_TEST ]]; then vendor/bin/phpunit tests/php; fi
- if [[ $PHPCS_TEST ]]; then composer run-script lint; fi
Expand Down
2 changes: 2 additions & 0 deletions _config/graphql.yml → _config/graphql-legacy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
Name: versioned-graphql
Only:
moduleexists: 'silverstripe/graphql'
Except:
classexists: 'SilverStripe\GraphQL\Schema\Schema'
---
SilverStripe\GraphQL\Scaffolding\Scaffolders\CRUD\Read:
extensions:
Expand Down
12 changes: 12 additions & 0 deletions _config/graphql_operations.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
Name: versioned-graphql-dataobject
Only:
moduleexists: 'silverstripe/graphql'
classexists: 'SilverStripe\GraphQL\Schema\Schema'
---
SilverStripe\GraphQL\Schema\DataObject\DataObjectModel:
operations:
copyToStage: 'SilverStripe\Versioned\GraphQL\Operations\CopyToStageCreator'
publish: 'SilverStripe\Versioned\GraphQL\Operations\PublishCreator'
unpublish: 'SilverStripe\Versioned\GraphQL\Operations\UnpublishCreator'
rollback: 'SilverStripe\Versioned\GraphQL\Operations\RollbackCreator'
12 changes: 12 additions & 0 deletions _config/graphql_plugins.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
Name: versioned-graphql-plugins
Only:
moduleexists: 'silverstripe/graphql'
classexists: 'SilverStripe\GraphQL\Schema\Schema'
---
SilverStripe\Core\Injector\Injector:
SilverStripe\GraphQL\Schema\Registry\PluginRegistry:
constructor:
versionedDataobject: '%$SilverStripe\Versioned\GraphQL\Plugins\VersionedDataObject'
unpublishOnDelete: '%$SilverStripe\Versioned\GraphQL\Plugins\UnpublishOnDelete'
readVersionedDataObject: '%$SilverStripe\Versioned\GraphQL\Plugins\VersionedRead'
11 changes: 11 additions & 0 deletions _config/graphql_schema.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
Name: versioned-graphql-schema
Only:
moduleexists: 'silverstripe/graphql'
classexists: 'SilverStripe\GraphQL\Schema\Schema'
---
SilverStripe\GraphQL\Schema\Schema:
schemas:
'*':
unclecheese marked this conversation as resolved.
Show resolved Hide resolved
src:
versionedSrc: 'silverstripe/versioned: _graphql'
50 changes: 50 additions & 0 deletions _graphql/enums.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
VersionedStage:
description: The stage to read from or write to
values:
DRAFT:
value: Stage
description: The draft stage
LIVE:
value: Live
description: The live stage

VersionedQueryMode:
description: The versioned mode to use
values:
unclecheese marked this conversation as resolved.
Show resolved Hide resolved
ARCHIVE:
value: archive
description: Read from a specific date of the archive
LATEST:
value: latest_versions
description: Read the latest version
ALL_VERSIONS:
value: all_versions
description: Reads all versionse
DRAFT:
value: Stage
description: Read from the draft stage
LIVE:
value: Live
description: Read from the live stage
STATUS:
value: status
description: Read only records with a specific status
VERSION:
value: version
description: Read a specific version

VersionedStatus:
description: The stage to read from or write to
values:
PUBLISHED:
value: published
description: Only published records
DRAFT:
value: draft
description: Only draft records
ARCHIVED:
value: archived
description: Only records that have been archived
MODIFIED:
value: modified
description: Only records that have unpublished changes
15 changes: 15 additions & 0 deletions _graphql/modelConfig.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
DataObject:
plugins:
versioning: true
operations:
read:
plugins:
readVersion:
before: paginateList
readOne:
plugins:
readVersion:
before: firstResult
delete:
plugins:
unpublishOnDelete: true
27 changes: 27 additions & 0 deletions _graphql/types.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
CopyToStageInputType:
input: true
fields:
id:
type: ID!
description: The ID of the record to copy
fromVersion:
type: Int
description: The source version number to copy
fromStage:
type: VersionedStage
description: The source stage to copy
toStage:
type: VersionedStage
description: The destination state to copy to

VersionedInputType:
input: true
fields:
mode: VersionedQueryMode = Stage
archiveDate:
type: String
description: The date to use for archive
status:
type: '[VersionedStatus]'
description: If mode is STATUS, specify which versioned statuses
version: Int
8 changes: 4 additions & 4 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,15 @@
},
"require-dev": {
"sminnee/phpunit": "^5.7",
"squizlabs/php_codesniffer": "^3",
"silverstripe/graphql": "^3"
"silverstripe/graphql": "3.x-dev || 4.x-dev",
"squizlabs/php_codesniffer": "^3"
},
"extra": [],
"autoload": {
"psr-4": {
"SilverStripe\\Versioned\\": "src/",
"SilverStripe\\Versioned\\Tests\\": "tests/php/"
}
},
"classmap": ["src/GraphQL/_legacy"]
},
"scripts": {
"lint": "vendor/bin/phpcs src/ tests/php/",
Expand Down
75 changes: 75 additions & 0 deletions src/GraphQL/Operations/AbstractPublishOperationCreator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?php

namespace SilverStripe\Versioned\GraphQL\Operations;

use Exception;
use GraphQL\Type\Definition\ResolveInfo;
use GraphQL\Type\Definition\Type;
use SilverStripe\Core\Config\Configurable;
use SilverStripe\Core\Extensible;
use SilverStripe\Core\Injector\Injectable;
use SilverStripe\GraphQL\Manager;
use SilverStripe\GraphQL\OperationResolver;
use SilverStripe\GraphQL\Scaffolding\Scaffolders\MutationScaffolder;
use SilverStripe\GraphQL\Schema\Exception\SchemaBuilderException;
use SilverStripe\GraphQL\Schema\Field\ModelMutation;
use SilverStripe\GraphQL\Schema\Interfaces\ModelOperation;
use SilverStripe\GraphQL\Schema\Interfaces\OperationCreator;
use SilverStripe\GraphQL\Schema\Interfaces\SchemaModelInterface;
use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\DataObjectInterface;
use SilverStripe\ORM\DB;
use SilverStripe\ORM\ValidationException;
use SilverStripe\Security\Member;
use SilverStripe\Versioned\GraphQL\Resolvers\VersionedResolver;
use SilverStripe\Versioned\Versioned;

if (!interface_exists(OperationCreator::class)) {
return;
}

/**
* Scaffolds a generic update operation for DataObjects.
*/
abstract class AbstractPublishOperationCreator implements OperationCreator
{
use Configurable;
use Injectable;

const ACTION_PUBLISH = 'publish';
const ACTION_UNPUBLISH = 'unpublish';

/**
* @param SchemaModelInterface $model
* @param string $typeName
* @param array $config
* @return ModelOperation|null
* @throws SchemaBuilderException
*/
public function createOperation(
SchemaModelInterface $model,
string $typeName,
array $config = []
): ?ModelOperation {
if (!Extensible::has_extension($model->getSourceClass(), Versioned::class)) {
return null;
}

$plugins = $config['plugins'] ?? [];
$name = $config['name'] ?? null;
if (!$name) {
$name = $this->createOperationName($typeName);
}
return ModelMutation::create($model, $name)
->setPlugins($plugins)
->setType($typeName)
->setResolver([VersionedResolver::class, 'resolvePublishOperation'])
->addResolverContext('action', $this->getAction())
->addResolverContext('dataClass', $model->getSourceClass())
->addArg('id', 'ID!');
}

abstract protected function createOperationName(string $typeName): string;

abstract protected function getAction(): string;
}
66 changes: 66 additions & 0 deletions src/GraphQL/Operations/CopyToStageCreator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php

namespace SilverStripe\Versioned\GraphQL\Operations;

use SilverStripe\Core\Config\Configurable;
use SilverStripe\Core\Extensible;
use SilverStripe\Core\Injector\Injectable;
use SilverStripe\GraphQL\Schema\Exception\SchemaBuilderException;
use SilverStripe\GraphQL\Schema\Field\ModelMutation;
use SilverStripe\GraphQL\Schema\Interfaces\ModelOperation;
use SilverStripe\GraphQL\Schema\Interfaces\OperationCreator;
use SilverStripe\GraphQL\Schema\Interfaces\SchemaModelInterface;
use SilverStripe\Versioned\GraphQL\Resolvers\VersionedResolver;
use SilverStripe\Versioned\Versioned;

if (!interface_exists(OperationCreator::class)) {
return;
}

/**
* Scaffolds a "copy to stage" operation for DataObjects.
*
* copy[TypeName]ToStage(ID!, FromVersion!, FromStage!, ToStage!)
*
*/
class CopyToStageCreator implements OperationCreator
{
use Configurable;
use Injectable;

/**
* @var array
* @config
*/
private static $default_plugins = [];

/**
* @param SchemaModelInterface $model
* @param string $typeName
* @param array $config
* @return ModelOperation|null
* @throws SchemaBuilderException
*/
public function createOperation(
SchemaModelInterface $model,
string $typeName,
array $config = []
): ?ModelOperation {
if (!Extensible::has_extension($model->getSourceClass(), Versioned::class)) {
return null;
}

$plugins = $config['plugins'] ?? [];
$mutationName = $config['name'] ?? null;
if (!$mutationName) {
$mutationName = 'copy' . ucfirst($typeName) . 'ToStage';
}

return ModelMutation::create($model, $mutationName)
->setType($typeName)
->setPlugins($plugins)
->setDefaultResolver([VersionedResolver::class, 'resolveCopyToStage'])
->addResolverContext('dataClass', $model->getSourceClass())
->addArg('input', 'CopyToStageInputType!');
}
}
33 changes: 33 additions & 0 deletions src/GraphQL/Operations/PublishCreator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

namespace SilverStripe\Versioned\GraphQL\Operations;

use SilverStripe\GraphQL\Schema\Interfaces\OperationCreator;

if (!interface_exists(OperationCreator::class)) {
return;
}

/**
* Scaffolds a generic update operation for DataObjects.
*/
class PublishCreator extends AbstractPublishOperationCreator
{

/**
* @param string $typeName
* @return string
*/
protected function createOperationName(string $typeName): string
{
return 'publish' . ucfirst($typeName);
}

/**
* @return string
*/
protected function getAction(): string
{
return AbstractPublishOperationCreator::ACTION_PUBLISH;
}
}
Loading