Source of file VersionedDataObject.php
Size: 5,396 Bytes - Last Modified: 2021-12-23T10:35:47+00:00
/var/www/docs.ssmods.com/process/src/src/GraphQL/Plugins/VersionedDataObject.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145 | <?php namespace SilverStripe\Versioned\GraphQL\Plugins; use SilverStripe\Core\Extensible; use SilverStripe\GraphQL\Schema\DataObject\Plugin\Paginator; use SilverStripe\GraphQL\Schema\DataObject\Plugin\ScalarDBField; use SilverStripe\GraphQL\Schema\Exception\SchemaBuilderException; use SilverStripe\GraphQL\Schema\Field\Field; use SilverStripe\GraphQL\Schema\Field\ModelField; use SilverStripe\GraphQL\Schema\Interfaces\ModelTypePlugin; use SilverStripe\GraphQL\Schema\Interfaces\SchemaUpdater; use SilverStripe\GraphQL\Schema\Plugin\AbstractQuerySortPlugin; use SilverStripe\GraphQL\Schema\Plugin\PaginationPlugin; use SilverStripe\GraphQL\Schema\Plugin\SortPlugin; use SilverStripe\GraphQL\Schema\Schema; use SilverStripe\GraphQL\Schema\Type\InputType; use SilverStripe\GraphQL\Schema\Type\ModelType; use SilverStripe\GraphQL\Schema\Type\Type; use SilverStripe\ORM\DataObject; use SilverStripe\ORM\Sortable; use SilverStripe\Security\Member; use SilverStripe\Versioned\GraphQL\Resolvers\VersionedResolver; use SilverStripe\Versioned\Versioned; use Closure; // GraphQL dependency is optional in versioned, // and the following implementation relies on existence of this class (in GraphQL v4) if (!interface_exists(ModelTypePlugin::class)) { return; } class VersionedDataObject implements ModelTypePlugin, SchemaUpdater { const IDENTIFIER = 'versioning'; /** * @return string */ public function getIdentifier(): string { return self::IDENTIFIER; } /** * @param Schema $schema * @throws SchemaBuilderException */ public static function updateSchema(Schema $schema): void { $schema->addModelbyClassName(Member::class); // Hack.. we can't add a plugin within a plugin, so we have to add sort // and pagination manually. This requires ensuring the sort types are added // to the schema (most of the time this is redundant) if (!$schema->getType('SortDirection')) { AbstractQuerySortPlugin::updateSchema($schema); } if (!$schema->getType('PageInfo')) { PaginationPlugin::updateSchema($schema); } } /** * @param ModelType $type * @param Schema $schema * @param array $config * @throws SchemaBuilderException */ public function apply(ModelType $type, Schema $schema, array $config = []): void { $class = $type->getModel()->getSourceClass(); Schema::invariant( is_subclass_of($class, DataObject::class), 'The %s plugin can only be applied to types generated by %s models', __CLASS__, DataObject::class ); if (!Extensible::has_extension($class, Versioned::class)) { return; } $versionName = $type->getModel()->getTypeName() . 'Version'; $memberType = $schema->getModelByClassName(Member::class); Schema::invariant( $memberType, 'The %s class was not added as a model. Should have been done in %s::%s?', Member::class, __CLASS__, 'updateSchema' ); $memberTypeName = $memberType->getModel()->getTypeName(); $resolver = ['resolver' => [VersionedResolver::class, 'resolveVersionFields']]; $type->addField('version', 'Int', function (ModelField $field) { $field->addResolverAfterware([ScalarDBField::class, 'resolve']); }); $versionType = Type::create($versionName) ->addField('author', ['type' => $memberTypeName] + $resolver) ->addField('publisher', ['type' => $memberTypeName] + $resolver) ->addField('published', ['type' => 'Boolean'] + $resolver) ->addField('liveVersion', ['type' => 'Boolean'] + $resolver) ->addField('deleted', ['type' => 'Boolean'] + $resolver) ->addField('draft', ['type' => 'Boolean'] + $resolver) ->addField('latestDraftVersion', ['type' => 'Boolean'] + $resolver); foreach ($type->getFields() as $field) { $clone = clone $field; $versionType->addField($clone->getName(), $clone); } foreach ($type->getInterfaces() as $interface) { $versionType->addInterface($interface); } $schema->addType($versionType); $type->addField('versions', '[' . $versionName . ']', function (Field $field) use ($type, $schema, $config) { $field->setResolver([VersionedResolver::class, 'resolveVersionList']) ->addResolverContext('sourceClass', $type->getModel()->getSourceClass()); SortPlugin::singleton()->apply($field, $schema, [ 'resolver' => [static::class, 'sortVersions'], 'fields' => [ 'version' => true ], ]); Paginator::singleton()->apply($field, $schema); }); } /** * @param array $config * @return Closure */ public static function sortVersions(array $config): Closure { $fieldName = $config['fieldName']; return function (Sortable $list, array $args) use ($fieldName) { $versionSort = $args[$fieldName]['version'] ?? null; if ($versionSort) { $list = $list->sort('Version', $versionSort); } return $list; }; } } |