Skip to content

Commit 41b9d42

Browse files
authored
Never implicitly use fake model for update (#1123)
1 parent 179137d commit 41b9d42

File tree

4 files changed

+41
-1
lines changed

4 files changed

+41
-1
lines changed

src/Model/Join.php

+4
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ abstract class Join
4444
/** Weak join does not update foreign table. */
4545
public bool $weak = false;
4646

47+
/** Foreign table is updated using fake model and thus no regular foreign model hooks are invoked. */
48+
public bool $allowDangerousForeignTableUpdate = false;
49+
4750
/**
4851
* Normally the foreign table is saved first, then it's ID is used in the
4952
* primary table. When deleting, the primary table record is deleted first
@@ -127,6 +130,7 @@ protected function createFakeForeignModel(): Model
127130
$fakeModel = new Model($this->getOwner()->getPersistence(), [
128131
'table' => $this->foreignTable,
129132
'idField' => $this->foreignIdField,
133+
'readOnly' => !$this->allowDangerousForeignTableUpdate,
130134
]);
131135
foreach ($this->getOwner()->getFields() as $ownerField) {
132136
if ($ownerField->hasJoin() && $ownerField->getJoin()->shortName === $this->shortName) {

tests/JoinArrayTest.php

+6
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ public function testJoinSaving1(): void
7878
$user2 = $user->createEntity();
7979
$user2->set('name', 'John');
8080
$user2->set('contact_phone', '+123');
81+
$j->allowDangerousForeignTableUpdate = true;
8182
$user2->save();
8283

8384
self::assertSame(1, $user2->getId());
@@ -134,6 +135,7 @@ public function testJoinSaving2(): void
134135
$user2 = $user->createEntity();
135136
$user2->set('name', 'John');
136137
$user2->set('contact_phone', '+123');
138+
$j->allowDangerousForeignTableUpdate = true;
137139
$user2->save();
138140

139141
self::assertSame(1, $user2->getId());
@@ -194,6 +196,7 @@ public function testJoinSaving3(): void
194196
$user = $user->createEntity();
195197
$user->set('name', 'John');
196198
$user->set('contact_phone', '+123');
199+
$j->allowDangerousForeignTableUpdate = true;
197200
$user->save();
198201

199202
self::assertSame([
@@ -216,6 +219,7 @@ public function testJoinSaving4(): void
216219
$user->set('name', 'John');
217220
$user->set('code', 'C28');
218221
$user->set('contact_phone', '+123');
222+
$j->allowDangerousForeignTableUpdate = true;
219223
$user->save();
220224
221225
self::assertSame([
@@ -290,6 +294,7 @@ public function testJoinUpdate(): void
290294
$user2 = $user->load(1);
291295
$user2->set('name', 'John 2');
292296
$user2->set('contact_phone', '+555');
297+
$j->allowDangerousForeignTableUpdate = true;
293298
$user2->save();
294299

295300
self::assertSame([
@@ -364,6 +369,7 @@ public function testJoinDelete(): void
364369
$j->addField('contact_phone');
365370

366371
$user = $user->load(1);
372+
$j->allowDangerousForeignTableUpdate = true;
367373
$user->delete();
368374

369375
self::assertSame([

tests/JoinSqlTest.php

+30
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ public function testJoinSaving1(): void
116116
$user2 = $user->createEntity();
117117
$user2->set('name', 'John');
118118
$user2->set('contact_phone', '+123');
119+
$j->allowDangerousForeignTableUpdate = true;
119120
$user2->save();
120121

121122
self::assertSame(1, $user2->getId());
@@ -169,6 +170,7 @@ public function testJoinSaving2(): void
169170
$user2 = $user->createEntity();
170171
$user2->set('name', 'John');
171172
$user2->set('contact_phone', '+123');
173+
$j->allowDangerousForeignTableUpdate = true;
172174
$user2->save();
173175

174176
self::assertSame(1, $user2->getId());
@@ -239,6 +241,7 @@ public function testJoinSaving3(): void
239241
$user = $user->createEntity();
240242
$user->set('name', 'John');
241243
$user->set('contact_phone', '+123');
244+
$j->allowDangerousForeignTableUpdate = true;
242245
$user->save();
243246

244247
self::assertSame([
@@ -313,6 +316,7 @@ public function testJoinUpdate(): void
313316
$user2 = $user->load(1);
314317
$user2->set('name', 'John 2');
315318
$user2->set('contact_phone', '+555');
319+
$j->allowDangerousForeignTableUpdate = true;
316320
$user2->save();
317321

318322
self::assertSame([
@@ -405,6 +409,7 @@ public function testJoinDelete(): void
405409
$j->addField('contact_phone');
406410

407411
$user = $user->load(3);
412+
$j->allowDangerousForeignTableUpdate = true;
408413
$user->delete();
409414

410415
self::assertSame([
@@ -432,6 +437,20 @@ public function testJoinDelete(): void
432437
}
433438
}
434439

440+
public function testDangerousForeignTableUpdateException(): void
441+
{
442+
$user = new Model($this->db, ['table' => 'user']);
443+
$j = $user->join('contact');
444+
$j->addField('phone');
445+
446+
$user2 = $user->createEntity();
447+
$user2->set('phone', '+555');
448+
449+
$this->expectException(Exception::class);
450+
$this->expectExceptionMessage('Model is read-only');
451+
$user2->save();
452+
}
453+
435454
public function testDoubleSaveHook(): void
436455
{
437456
$this->setDb([
@@ -458,6 +477,7 @@ public function testDoubleSaveHook(): void
458477

459478
$user = $user->createEntity();
460479
$user->set('name', 'John');
480+
$j->allowDangerousForeignTableUpdate = true;
461481
$user->save();
462482

463483
self::assertSame([
@@ -505,6 +525,8 @@ public function testDoubleJoin(): void
505525

506526
$user2 = $user->load(10);
507527
self::assertSame(['id' => 10, 'contact_id' => 100, 'name' => 'John 2', 'contact_phone' => '+555', 'country_id' => 1, 'country_name' => 'UK'], $user2->get());
528+
$jContact->allowDangerousForeignTableUpdate = true;
529+
$jCountry->allowDangerousForeignTableUpdate = true;
508530
$user2->delete();
509531

510532
$user2 = $user->loadBy('country_name', 'US');
@@ -572,6 +594,8 @@ public function testDoubleReverseJoin(): void
572594

573595
$country2 = $country->load(1);
574596
self::assertSame(['id' => 1, 'name' => 'UK', 'contact_phone' => '+555', 'contact_id' => 100, 'user_name' => 'John 2'], $country2->get());
597+
$jContact->allowDangerousForeignTableUpdate = true;
598+
$jUser->allowDangerousForeignTableUpdate = true;
575599
$country2->delete();
576600

577601
$country2 = $country->loadBy('user_name', 'XX');
@@ -706,6 +730,7 @@ public function testJoinReverseOneOnOne(): void
706730
self::assertSame(['id' => 20, 'name' => 'Peter', 'notes' => 'second note'], $m->get());
707731

708732
// update loaded record
733+
$j->allowDangerousForeignTableUpdate = true;
709734
$m->save(['name' => 'Mark', 'notes' => '2nd note']);
710735
$m = $user->load(20);
711736
self::assertSame(['id' => 20, 'name' => 'Mark', 'notes' => '2nd note'], $m->get());
@@ -726,6 +751,7 @@ public function testJoinReverseOneOnOne(): void
726751
$j->addField('notes');
727752

728753
// insert new record
754+
$j->allowDangerousForeignTableUpdate = true;
729755
$m = $user->createEntity()->save(['name' => 'Olaf', 'notes' => '4th note']);
730756
$m = $user->load(22);
731757
self::assertSame(['id' => 22, 'name' => 'Olaf', 'notes' => '4th note'], $m->get());
@@ -741,6 +767,7 @@ public function testJoinReverseOneOnOne(): void
741767
$j->addField('notes');
742768

743769
// insert new record
770+
$j->allowDangerousForeignTableUpdate = true;
744771
$m = $user->createEntity()->save(['name' => 'Chris', 'notes' => '5th note']);
745772
$m = $user->load(23);
746773
self::assertSame(['id' => 23, 'name' => 'Chris', 'notes' => '5th note'], $m->get());
@@ -788,6 +815,8 @@ public function testJoinActualFieldNamesAndPrefix(): void
788815
$user2->set('name', 'John 2');
789816
$user2->set('j1_phone', '+555');
790817
$user2->set('j2_salary', 111);
818+
$j->allowDangerousForeignTableUpdate = true;
819+
$j2->allowDangerousForeignTableUpdate = true;
791820
$user2->save();
792821

793822
self::{'assertEquals'}([
@@ -869,6 +898,7 @@ protected function setupJoinWithNonDefaultForeignIdField(array $joinDefaults = [
869898
'foreignIdField' => 'uid',
870899
], $joinDefaults));
871900
$this->createMigrator()->createForeignKey($j);
901+
$j->allowDangerousForeignTableUpdate = true;
872902
$j->addField('contact_phone');
873903

874904
return [$masterModel, $joinedModel, $user];

tests/Model/Smbo/Payment.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ protected function init(): void
1717

1818
$this->addCondition('doc_type', 'payment');
1919

20-
$this->jPayment = $this->join('payment.document_id');
20+
$this->jPayment = $this->join('payment.document_id', ['allowDangerousForeignTableUpdate' => true]);
2121

2222
$this->jPayment->addField('cheque_no');
2323
$this->jPayment->hasOne('account_id', ['model' => [Account::class]]);

0 commit comments

Comments
 (0)