Skip to content

Commit 33de0e4

Browse files
committed
Bugfix: Fix an issue where belongs_to would trigger recursion
1 parent 22c5494 commit 33de0e4

File tree

7 files changed

+81
-13
lines changed

7 files changed

+81
-13
lines changed

src/Services/CacheProcessingService.php

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,6 @@ private function updateEdge(EdgeUpdateDto $dto): array
5858
return [];
5959
}
6060

61-
if ($this->alreadyProcessed($edge->getToClassName(), $instance->getField($edge->getRelation().'ID'))) {
62-
return [];
63-
}
64-
6561
$relatedInstance = $instance->getField($edge->getRelation());
6662

6763
if (!$relatedInstance) {
@@ -78,21 +74,17 @@ private function updateEdge(EdgeUpdateDto $dto): array
7874
}
7975

8076
if ($relationType === 'has_many' || $relationType === 'many_many' || $relationType === 'belongs_many_many') {
81-
return $this->updateInstances($instance->{$edge->getRelation()}(), $dto);
77+
return $this->updateInstances($instance->{$edge->getRelation()}());
8278
}
8379

8480
return [];
8581
}
8682

87-
private function updateInstances(DataList $instances, EdgeUpdateDto $dto): array
83+
private function updateInstances(DataList $instances): array
8884
{
8985
$results = [];
9086

9187
foreach ($instances as $relatedInstance) {
92-
if ($this->alreadyProcessed($dto->getEdge()->getToClassName(), $relatedInstance->ID)) {
93-
continue;
94-
}
95-
9688
$results = array_merge(
9789
$results,
9890
$this->updateInstance($relatedInstance)
@@ -104,6 +96,10 @@ private function updateInstances(DataList $instances, EdgeUpdateDto $dto): array
10496

10597
private function updateInstance(DataObject $instance): array
10698
{
99+
if ($this->alreadyProcessed($instance->ClassName, $instance->ID)) {
100+
return [];
101+
}
102+
107103
// Find or create the CacheKey for this instance
108104
$cacheKey = CacheKey::updateOrCreateKey($instance);
109105
$processedUpdate = $this->getUpdatesService()->findOrCreateProcessedUpdate($instance->ClassName, $instance->ID);
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
namespace Terraformers\KeysForCache\Tests\Mocks\Models;
4+
5+
use SilverStripe\Dev\TestOnly;
6+
use SilverStripe\ORM\DataObject;
7+
use SilverStripe\ORM\HasManyList;
8+
use Terraformers\KeysForCache\Extensions\CacheKeyExtension;
9+
use Terraformers\KeysForCache\Tests\Mocks\Pages\CaresPage;
10+
11+
/**
12+
* This model is referenced by CaresPage as a has_one, meaning that this model has a has_many back to CaresPage
13+
*
14+
* @property string $Title
15+
* @method HasManyList|CaresPage CaresPages()
16+
* @mixin CacheKeyExtension
17+
*/
18+
class CaredHasOneNonVersionedModel extends DataObject implements TestOnly
19+
{
20+
private static array $db = [
21+
'Title' => 'Varchar',
22+
];
23+
24+
private static array $has_many = [
25+
'CaresPages' => CaresPage::class,
26+
];
27+
28+
private static string $table_name = 'CaredHasOneNonVersionedModel';
29+
30+
private static bool $has_cache_key = false;
31+
}

tests/Mocks/Pages/CaresPage.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use Terraformers\KeysForCache\Tests\Mocks\Models\CaredBelongsToModel;
1313
use Terraformers\KeysForCache\Tests\Mocks\Models\CaredHasManyModel;
1414
use Terraformers\KeysForCache\Tests\Mocks\Models\CaredHasOneModel;
15+
use Terraformers\KeysForCache\Tests\Mocks\Models\CaredHasOneNonVersionedModel;
1516
use Terraformers\KeysForCache\Tests\Mocks\Models\CaredManyManyModel;
1617
use Terraformers\KeysForCache\Tests\Mocks\Models\CaredThroughModel;
1718
use Terraformers\KeysForCache\Tests\Mocks\Models\PolymorphicCaredHasManyModel;
@@ -20,9 +21,11 @@
2021
/**
2122
* @property int $CaredBelongsToModelID
2223
* @property int $CaredHasOneModelID
24+
* @property int $CaredHasOneNonVersionedModelID
2325
* @property int $PolymorphicHasOneID
2426
* @method CaredBelongsToModel CaredBelongsToModel()
2527
* @method CaredHasOneModel CaredHasOneModel()
28+
* @method CaredHasOneNonVersionedModel CaredHasOneNonVersionedModel()
2629
* @method DataObject PolymorphicHasOne()
2730
* @method HasManyList|CaredHasManyModel[] CaredHasManyModels()
2831
* @method HasManyList|CaresPageCaredThroughModel[] CaresPageCaredThroughModels()
@@ -35,6 +38,7 @@ class CaresPage extends Page implements TestOnly
3538
private static array $has_one = [
3639
'CaredBelongsToModel' => CaredBelongsToModel::class,
3740
'CaredHasOneModel' => CaredHasOneModel::class,
41+
'CaredHasOneNonVersionedModel' => CaredHasOneNonVersionedModel::class,
3842
'PolymorphicHasOne' => DataObject::class,
3943
];
4044

@@ -56,6 +60,7 @@ class CaresPage extends Page implements TestOnly
5660
private static array $cares = [
5761
'CaredBelongsToModel',
5862
'CaredHasOneModel',
63+
'CaredHasOneNonVersionedModel',
5964
'CaredHasManyModels',
6065
'CaredManyManyModels',
6166
'CaredThroughModels',

tests/RelationshipGraph/GraphTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Terraformers\KeysForCache\Tests\Mocks\Models\CaredBelongsToModel;
1616
use Terraformers\KeysForCache\Tests\Mocks\Models\CaredHasManyModel;
1717
use Terraformers\KeysForCache\Tests\Mocks\Models\CaredHasOneModel;
18+
use Terraformers\KeysForCache\Tests\Mocks\Models\CaredHasOneNonVersionedModel;
1819
use Terraformers\KeysForCache\Tests\Mocks\Models\CaredManyManyModel;
1920
use Terraformers\KeysForCache\Tests\Mocks\Models\PolymorphicCaredHasManyModel;
2021
use Terraformers\KeysForCache\Tests\Mocks\Models\PolymorphicTouchedHasManyModel;
@@ -167,6 +168,7 @@ public function testGetRelationshipConfig(): void
167168
$expectPageTwoCares = [
168169
'CaredBelongsToModel' => CaredBelongsToModel::class,
169170
'CaredHasOneModel' => CaredHasOneModel::class,
171+
'CaredHasOneNonVersionedModel' => CaredHasOneNonVersionedModel::class,
170172
'CaredHasManyModels' => CaredHasManyModel::class,
171173
'CaredManyManyModels' => CaredManyManyModel::class,
172174
'CaredThroughModels' => [

tests/Scenarios/CaresTest.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Terraformers\KeysForCache\Tests\Mocks\Models\CaredBelongsToModel;
1010
use Terraformers\KeysForCache\Tests\Mocks\Models\CaredHasManyModel;
1111
use Terraformers\KeysForCache\Tests\Mocks\Models\CaredHasOneModel;
12+
use Terraformers\KeysForCache\Tests\Mocks\Models\CaredHasOneNonVersionedModel;
1213
use Terraformers\KeysForCache\Tests\Mocks\Models\CaredManyManyModel;
1314
use Terraformers\KeysForCache\Tests\Mocks\Models\CaredThroughModel;
1415
use Terraformers\KeysForCache\Tests\Mocks\Models\PolymorphicCaredHasManyModel;
@@ -30,6 +31,7 @@ class CaresTest extends SapphireTest
3031
CaredBelongsToModel::class,
3132
CaredHasManyModel::class,
3233
CaredHasOneModel::class,
34+
CaredHasOneNonVersionedModel::class,
3335
CaredManyManyModel::class,
3436
CaredThroughModel::class,
3537
PolymorphicCaredHasOneModel::class,
@@ -120,6 +122,34 @@ public function testCaresHasOne(): void
120122
$this->assertNotEquals($originalKey, $newKey);
121123
}
122124

125+
public function testCaresHasOneNonVersioned(): void
126+
{
127+
// Updates are processed as part of scaffold, so we need to flush before we kick off
128+
ProcessedUpdatesService::singleton()->flush();
129+
130+
$page = $this->objFromFixture(CaresPage::class, 'page1');
131+
$model = $this->objFromFixture(CaredHasOneNonVersionedModel::class, 'model1');
132+
133+
// Check that we're set up correctly
134+
$this->assertEquals(CaredHasOneNonVersionedModel::class, $model->ClassName);
135+
$this->assertEquals($page->CaredHasOneNonVersionedModelID, $model->ID);
136+
137+
$originalKey = $page->getCacheKey();
138+
139+
$this->assertNotNull($originalKey);
140+
$this->assertNotEmpty($originalKey);
141+
142+
// Begin changes
143+
$model->forceChange();
144+
$model->write();
145+
146+
$newKey = $page->getCacheKey();
147+
148+
$this->assertNotNull($newKey);
149+
$this->assertNotEmpty($newKey);
150+
$this->assertNotEquals($originalKey, $newKey);
151+
}
152+
123153
public function testPolymorphicCaresHasOne(): void
124154
{
125155
// Updates are processed as part of scaffold, so we need to flush before we kick off

tests/Scenarios/CaresTest.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ Terraformers\KeysForCache\Tests\Mocks\Models\CaredHasOneModel:
66
model1:
77
Title: Has One Model 1
88

9+
Terraformers\KeysForCache\Tests\Mocks\Models\CaredHasOneNonVersionedModel:
10+
model1:
11+
Title: Has One Non Versioned Model 1
12+
913
Terraformers\KeysForCache\Tests\Mocks\Models\CaredHasManyModel:
1014
model1:
1115
Title: Has Many Model 1
@@ -31,6 +35,7 @@ Terraformers\KeysForCache\Tests\Mocks\Pages\CaresPage:
3135
Title: Page 1
3236
CaredBelongsToModel: =>Terraformers\KeysForCache\Tests\Mocks\Models\CaredBelongsToModel.model1
3337
CaredHasOneModel: =>Terraformers\KeysForCache\Tests\Mocks\Models\CaredHasOneModel.model1
38+
CaredHasOneNonVersionedModel: =>Terraformers\KeysForCache\Tests\Mocks\Models\CaredHasOneNonVersionedModel.model1
3439
CaredHasManyModels:
3540
- =>Terraformers\KeysForCache\Tests\Mocks\Models\CaredHasManyModel.model1
3641
CaredManyManyModels:

tests/Scenarios/GlobalCaresTest.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,12 @@ class GlobalCaresTest extends SapphireTest
2323

2424
public function testGlobalCares(): void
2525
{
26+
$siteConfig = SiteConfig::current_site_config();
27+
$page = $this->objFromFixture(GlobalCaresPage::class, 'page1');
2628

2729
// Updates are processed as part of scaffold, so we need to flush before we kick off
2830
ProcessedUpdatesService::singleton()->flush();
2931

30-
$siteConfig = SiteConfig::current_site_config();
31-
$page = $this->objFromFixture(GlobalCaresPage::class, 'page1');
32-
3332
// Check we're set up correctly
3433
$originalKey = $page->getCacheKey();
3534

0 commit comments

Comments
 (0)