From b4c64c419860d16d05b9c8080c9734cc5ab9afcf Mon Sep 17 00:00:00 2001 From: Aaron Carlino Date: Wed, 4 Aug 2021 16:13:11 +1200 Subject: [PATCH] Fix race condition in interface builder adding to queries before interfaces are ready --- _config/schema-global.yml | 2 -- src/Schema/DataObject/InterfaceBuilder.php | 22 ++++++++++++++++++-- src/Schema/DataObject/Plugin/Inheritance.php | 21 +++++++++++-------- 3 files changed, 32 insertions(+), 13 deletions(-) diff --git a/_config/schema-global.yml b/_config/schema-global.yml index 5900ee7d..03fdfec7 100644 --- a/_config/schema-global.yml +++ b/_config/schema-global.yml @@ -29,8 +29,6 @@ SilverStripe\GraphQL\Schema\Schema: before: scalarDBField inheritance: useUnionQueries: false - hideAncestors: - - SilverStripe\CMS\Model\SiteTree after: 'versioning' scalarDBField: after: dbFieldArgs diff --git a/src/Schema/DataObject/InterfaceBuilder.php b/src/Schema/DataObject/InterfaceBuilder.php index c4dc48e4..aaa07634 100644 --- a/src/Schema/DataObject/InterfaceBuilder.php +++ b/src/Schema/DataObject/InterfaceBuilder.php @@ -34,13 +34,20 @@ class InterfaceBuilder */ private $schema; + /** + * @var array + */ + private $hideAncestors = []; + /** * InterfaceBuilderTest constructor. * @param Schema $schema + * @param array $hideAncestors */ - public function __construct(Schema $schema) + public function __construct(Schema $schema, array $hideAncestors = []) { $this->setSchema($schema); + $this->hideAncestors = $hideAncestors; } /** @@ -86,7 +93,9 @@ public function createInterfaces(ModelType $modelType, array $interfaceStack = [ $interfaceStack[] = $interface; $modelType->addInterface($interface->getName()); - $chain = InheritanceChain::create($modelType->getModel()->getSourceClass()); + $chain = InheritanceChain::create($modelType->getModel()->getSourceClass()) + ->hideAncestors($this->hideAncestors); + foreach ($chain->getDirectDescendants() as $class) { if ($childType = $this->getSchema()->getModelByClassName($class)) { $this->createInterfaces($childType, $interfaceStack); @@ -130,6 +139,7 @@ public function applyBaseInterface(): InterfaceBuilder /** * @param ModelType $type + * @throws ReflectionException * @throws SchemaBuilderException * @return $this */ @@ -157,6 +167,14 @@ public function applyInterfacesToQueries(ModelType $type): InterfaceBuilder $this->schema->eagerLoad($modelType->getName()); } } + $chain = InheritanceChain::create($type->getModel()->getSourceClass()) + ->hideAncestors($this->hideAncestors); + + foreach ($chain->getDirectDescendants() as $class) { + if ($modelType = $schema->getModelByClassName($class)) { + $this->applyInterfacesToQueries($modelType); + } + } return $this; } diff --git a/src/Schema/DataObject/Plugin/Inheritance.php b/src/Schema/DataObject/Plugin/Inheritance.php index cca0fc61..a68b8abc 100644 --- a/src/Schema/DataObject/Plugin/Inheritance.php +++ b/src/Schema/DataObject/Plugin/Inheritance.php @@ -57,8 +57,12 @@ public function apply(ModelType $type, Schema $schema, array $config = []): void $useUnions = $config['useUnionQueries'] ?? false; $hideAncestors = $config['hideAncestors'] ?? []; + if (in_array($type->getModel()->getSourceClass(), $hideAncestors)) { + return; + } + $inheritance = InheritanceBuilder::create($schema, $hideAncestors); - $interfaces = InterfaceBuilder::create($schema); + $interfaces = InterfaceBuilder::create($schema, $hideAncestors); $class = $type->getModel()->getSourceClass(); if ($inheritance->isLeafModel($class)) { @@ -66,14 +70,13 @@ public function apply(ModelType $type, Schema $schema, array $config = []): void } elseif ($inheritance->isBaseModel($class)) { $inheritance->fillDescendants($type); $interfaces->createInterfaces($type); - } - - if ($useUnions) { - InheritanceUnionBuilder::create($schema) - ->createUnions($type) - ->applyUnionsToQueries($type); - } else { - $interfaces->applyInterfacesToQueries($type); + if ($useUnions) { + InheritanceUnionBuilder::create($schema) + ->createUnions($type) + ->applyUnionsToQueries($type); + } else { + $interfaces->applyInterfacesToQueries($type); + } } } }