Skip to content

Commit

Permalink
FIX Handle using injected subclasses
Browse files Browse the repository at this point in the history
Co-authored-by: Will Rossiter <will@fullscreen.io>
  • Loading branch information
emteknetnz and wilr committed Aug 21, 2023
1 parent ca0b864 commit c74fa1c
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 7 deletions.
20 changes: 13 additions & 7 deletions src/Schema/DataObject/InheritanceBuilder.php
Expand Up @@ -49,15 +49,21 @@ public function fillAncestry(ModelType $modelType): void
$chain = InheritanceChain::create($modelType->getModel()->getSourceClass())
->hideAncestors($this->hideAncestors);
$ancestors = $chain->getAncestralModels();
if (empty($ancestors)) {
$ancestorModel = null;
foreach ($ancestors as $ancestor) {
$ancestorModel = $this->getSchema()->findOrMakeModel($ancestor);
if ($ancestorModel && $ancestorModel->getName() !== $modelType->getName()) {
break;
}
$ancestorModel = null;
}
if (!$ancestorModel) {
return;
}
$parent = $ancestors[0];
$parentModel = $this->getSchema()->findOrMakeModel($parent);
// Merge descendant fields up into the ancestor
foreach ($modelType->getFields() as $fieldObj) {
// If the field already exists on the ancestor with the same config, skip it
if ($existing = $parentModel->getFieldByName($fieldObj->getName())) {
if ($existing = $ancestorModel->getFieldByName($fieldObj->getName())) {
if ($existing->getSignature() === $fieldObj->getSignature()) {
continue;
}
Expand All @@ -66,12 +72,12 @@ public function fillAncestry(ModelType $modelType): void
? $fieldObj->getPropertyName()
: $fieldObj->getName();
// If the field is unique to the descendant, skip it.
if ($parentModel->getModel()->hasField($fieldName)) {
if ($ancestorModel->getModel()->hasField($fieldName)) {
$clone = clone $fieldObj;
$parentModel->addField($fieldObj->getName(), $clone);
$ancestorModel->addField($fieldObj->getName(), $clone);
}
}
$this->fillAncestry($parentModel);
$this->fillAncestry($ancestorModel);
}

/**
Expand Down
17 changes: 17 additions & 0 deletions tests/Fake/Inheritance/MyOrig.php
@@ -0,0 +1,17 @@
<?php


namespace SilverStripe\GraphQL\Tests\Fake\Inheritance;

use SilverStripe\Dev\TestOnly;
use SilverStripe\ORM\DataList;
use SilverStripe\ORM\DataObject;

class MyOrig extends DataObject implements TestOnly
{
private static $db = [
'MyField' => 'Varchar',
];

private static $table_name = 'MyOrig_test';
}
16 changes: 16 additions & 0 deletions tests/Fake/Inheritance/MySubclass.php
@@ -0,0 +1,16 @@
<?php


namespace SilverStripe\GraphQL\Tests\Fake\Inheritance;

use SilverStripe\Dev\TestOnly;
use SilverStripe\ORM\DataList;

class MySubclass extends MyOrig implements TestOnly
{
private static $db = [
'MySubclassField' => 'Varchar',
];

private static $table_name = 'MySubclass_test';
}
29 changes: 29 additions & 0 deletions tests/Schema/DataObject/InheritanceBuilderTest.php
Expand Up @@ -21,6 +21,10 @@
use SilverStripe\GraphQL\Tests\Fake\Inheritance\C1;
use SilverStripe\GraphQL\Tests\Fake\Inheritance\C2;
use SilverStripe\GraphQL\Tests\Fake\Inheritance\C2a;
use SilverStripe\GraphQL\Tests\Fake\Inheritance\MyOrig;
use SilverStripe\GraphQL\Tests\Fake\Inheritance\MySubclass;
use SilverStripe\Core\Config\Config;
use SilverStripe\Core\Injector\Injector;

class InheritanceBuilderTest extends SapphireTest
{
Expand All @@ -40,6 +44,8 @@ class InheritanceBuilderTest extends SapphireTest
C1::class,
C2::class,
C2a::class,
MyOrig::class,
MySubclass::class,
];

public function testBaseModel()
Expand Down Expand Up @@ -314,4 +320,27 @@ private function assertFields(array $fields, Type $type)
$this->assertEmpty(array_diff($expected ?? [], $compare));
$this->assertEmpty(array_diff($compare ?? [], $expected));
}

public function testFillAncestryInjectorSubclass()
{
Config::modify()->merge(Injector::class, MyOrig::class, ['class' => MySubclass::class]);
$obj = MyOrig::create();
$this->assertSame(MySubclass::class, get_class($obj));
$schema = new TestSchema();
$schema->applyConfig([
'models' => [
MyOrig::class => [
'fields' => [
'MyField' => true,
'MySubclassField' => true,
],
],
]
]);
$schema->createStoreableSchema();
$modelType = $schema->getModelByClassName(MySubclass::class);
$builder = new InheritanceBuilder($schema);
$builder->fillAncestry($modelType);
$this->assertFields(['id', 'MyField', 'MySubclassField'], $modelType);
}
}

0 comments on commit c74fa1c

Please sign in to comment.