Skip to content

Commit 639a303

Browse files
committed
wip
1 parent 0ee9fb8 commit 639a303

File tree

3 files changed

+51
-11
lines changed

3 files changed

+51
-11
lines changed

src/Persistence/PersistenceManager.php

+19-10
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@ final class PersistenceManager
3131
private bool $flush = true;
3232
private bool $persist = true;
3333

34-
/** @var list<object> */
34+
/** @var list<list<object>> */
3535
private array $objectsToPersist = [];
3636

37-
/** @var list<callable():void> */
37+
/** @var list<list<callable():void>> */
3838
private array $afterPersistCallbacks = [];
3939

4040
/**
@@ -61,6 +61,12 @@ public function enablePersisting(): void
6161
$this->persist = true;
6262
}
6363

64+
public function startTransaction(): void
65+
{
66+
$this->objectsToPersist[] = [];
67+
$this->afterPersistCallbacks[] = [];
68+
}
69+
6470
/**
6571
* @template T of object
6672
*
@@ -81,11 +87,17 @@ public function save(object $object): object
8187
return $object;
8288
}
8389

84-
public function saveAll(): void
90+
public function commit(): void
8591
{
8692
$objectManagers = [];
8793

88-
foreach ($this->objectsToPersist as $object) {
94+
$objectsToPersist = array_pop($this->objectsToPersist);
95+
96+
if ($objectsToPersist === null) {
97+
return;
98+
}
99+
100+
foreach ($objectsToPersist as $object) {
89101
$om = $this->strategyFor($object::class)->objectManagerFor($object::class);
90102
$om->persist($object);
91103

@@ -94,8 +106,6 @@ public function saveAll(): void
94106
}
95107
}
96108

97-
$this->objectsToPersist = [];
98-
99109
foreach ($objectManagers as $om) {
100110
$this->flush($om);
101111
}
@@ -117,9 +127,9 @@ public function scheduleForInsert(object $object, array $afterPersistCallbacks =
117127
$object = unproxy($object);
118128
}
119129

120-
$this->objectsToPersist[] = $object;
130+
$this->objectsToPersist[array_key_last($this->objectsToPersist)][] = $object;
121131

122-
$this->afterPersistCallbacks = [...$this->afterPersistCallbacks, ...$afterPersistCallbacks];
132+
$this->afterPersistCallbacks[array_key_last($this->afterPersistCallbacks)] = [...$this->afterPersistCallbacks[array_key_last($this->afterPersistCallbacks)], ...$afterPersistCallbacks];
123133

124134
return $object;
125135
}
@@ -168,8 +178,7 @@ private function callPostPersistCallbacks(): void
168178
return;
169179
}
170180

171-
$afterPersistCallbacks = $this->afterPersistCallbacks;
172-
$this->afterPersistCallbacks = [];
181+
$afterPersistCallbacks = array_pop($this->afterPersistCallbacks);
173182

174183
foreach ($afterPersistCallbacks as $afterPersistCallback) {
175184
$afterPersistCallback();

src/Persistence/PersistentObjectFactory.php

+5-1
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,10 @@ final public static function truncate(): void
198198
*/
199199
public function create(callable|array $attributes = []): object
200200
{
201+
if (PersistMode::PERSIST === $this->persistMode() && $this->isRootFactory) {
202+
Configuration::instance()->persistence()->startTransaction();
203+
}
204+
201205
$object = parent::create($attributes);
202206

203207
foreach ($this->tempAfterInstantiate as $callback) {
@@ -218,7 +222,7 @@ public function create(callable|array $attributes = []): object
218222
throw new \LogicException('Persistence cannot be used in unit tests.');
219223
}
220224

221-
$configuration->persistence()->saveAll();
225+
$configuration->persistence()->commit();
222226

223227
return $object;
224228
}

tests/Integration/ORM/EntityRelationship/EntityFactoryRelationshipTestCase.php

+27
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,33 @@ public function can_call_create_in_nested_after_persist_callback(): void
553553
self::assertCount(1, $contact->getCategory()?->getSecondaryContacts() ?? []);
554554
}
555555

556+
/** @test */
557+
#[Test]
558+
#[DataProvider('provideCascadeRelationshipsCombinations')]
559+
#[UsingRelationships(Address::class, ['contact'])]
560+
#[UsingRelationships(Contact::class, ['category'])]
561+
public function inverse_one_to_one_with_forced_flush(): void
562+
{
563+
$address = static::addressFactory()::createOne(
564+
[
565+
'contact' => static::contactFactory()
566+
->beforeInstantiate(
567+
function (array $attributes): array {
568+
$attributes['category'] = static::categoryFactory()->create();
569+
return $attributes;
570+
}
571+
),
572+
]
573+
);
574+
575+
static::addressFactory()::assert()->count(1);
576+
static::contactFactory()::assert()->count(1);
577+
static::categoryFactory()::assert()->count(1);
578+
579+
self::assertNotNull($address->getContact());
580+
self::assertNotNull($address->getContact()->getCategory());
581+
}
582+
556583
/** @return PersistentObjectFactory<Contact> */
557584
protected static function contactFactoryWithoutCategory(): PersistentObjectFactory
558585
{

0 commit comments

Comments
 (0)