22
22
use Zenstruck \Foundry \ObjectFactory ;
23
23
use Zenstruck \Foundry \Persistence \Exception \NotEnoughObjects ;
24
24
use Zenstruck \Foundry \Persistence \Exception \RefreshObjectFailed ;
25
+ use Zenstruck \Foundry \Persistence \Relationship \OneToManyRelationship ;
26
+ use Zenstruck \Foundry \Persistence \Relationship \OneToOneRelationship ;
25
27
26
28
use function Zenstruck \Foundry \get ;
27
29
use function Zenstruck \Foundry \set ;
@@ -198,7 +200,10 @@ final public static function truncate(): void
198
200
*/
199
201
public function create (callable |array $ attributes = []): object
200
202
{
201
- if (PersistMode::PERSIST === $ this ->persistMode () && $ this ->isRootFactory ) {
203
+ $ transactionStarted = false ;
204
+
205
+ if (Configuration::isBooted () && PersistMode::PERSIST === $ this ->persistMode () && $ this ->isRootFactory ) {
206
+ $ transactionStarted = Configuration::instance ()->persistence ()->isTransactionStarted ();
202
207
Configuration::instance ()->persistence ()->startTransaction ();
203
208
}
204
209
@@ -212,7 +217,7 @@ public function create(callable|array $attributes = []): object
212
217
213
218
$ this ->throwIfCannotCreateObject ();
214
219
215
- if (PersistMode::PERSIST !== $ this ->persistMode () || !$ this ->isRootFactory ) {
220
+ if ($ transactionStarted || PersistMode::PERSIST !== $ this ->persistMode () || !$ this ->isRootFactory ) {
216
221
return $ object ;
217
222
}
218
223
@@ -296,11 +301,11 @@ protected function normalizeParameter(string $field, mixed $value): mixed
296
301
if ($ value instanceof self) {
297
302
$ pm = Configuration::instance ()->persistence ();
298
303
299
- $ inversedRelationshipMetadata = $ pm ->inverseRelationshipMetadata (static ::class (), $ value ::class (), $ field );
304
+ $ relationshipMetadata = $ pm ->inverseRelationshipMetadata (static ::class (), $ value ::class (), $ field );
300
305
301
306
// handle inversed OneToOne
302
- if ($ inversedRelationshipMetadata && !$ inversedRelationshipMetadata -> isCollection ) {
303
- $ inverseField = $ inversedRelationshipMetadata ->inverseField ;
307
+ if ($ relationshipMetadata instanceof OneToOneRelationship && !$ relationshipMetadata -> isOwning ) {
308
+ $ inverseField = $ relationshipMetadata ->inverseField () ;
304
309
305
310
// we need to handle the circular dependency involved by inversed one-to-one relationship:
306
311
// a placeholder object is used, which will be replaced by the real object, after its instantiation
@@ -337,9 +342,9 @@ protected function normalizeCollection(string $field, FactoryCollection $collect
337
342
338
343
$ inverseRelationshipMetadata = $ pm ->inverseRelationshipMetadata (static ::class (), $ collection ->factory ::class (), $ field );
339
344
340
- if ($ inverseRelationshipMetadata && $ inverseRelationshipMetadata -> isCollection ) {
345
+ if ($ inverseRelationshipMetadata instanceof OneToManyRelationship ) {
341
346
$ this ->tempAfterInstantiate [] = function (object $ object ) use ($ collection , $ inverseRelationshipMetadata , $ field ) {
342
- $ inverseField = $ inverseRelationshipMetadata ->inverseField ;
347
+ $ inverseField = $ inverseRelationshipMetadata ->inverseField () ;
343
348
344
349
$ inverseObjects = $ collection ->withPersistMode (
345
350
$ this ->isPersisting () ? PersistMode::NO_PERSIST_BUT_SCHEDULE_FOR_INSERT : PersistMode::WITHOUT_PERSISTING
@@ -371,24 +376,39 @@ protected function normalizeCollection(string $field, FactoryCollection $collect
371
376
*
372
377
* @internal
373
378
*/
374
- protected function normalizeObject (object $ object ): object
379
+ protected function normalizeObject (string $ field , object $ object ): object
375
380
{
376
381
$ configuration = Configuration::instance ();
377
382
378
- if (
379
- !$ this ->isPersisting ()
380
- || !$ configuration ->isPersistenceAvailable ()
381
- ) {
383
+ $ object = unproxy ($ object , withAutoRefresh: false );
384
+
385
+ if (!$ configuration ->isPersistenceAvailable ()) {
382
386
return $ object ;
383
387
}
384
388
385
- $ object = unproxy ($ object , withAutoRefresh: false );
386
-
387
389
$ persistenceManager = $ configuration ->persistence ();
390
+
388
391
if (!$ persistenceManager ->hasPersistenceFor ($ object )) {
389
392
return $ object ;
390
393
}
391
394
395
+ $ inverseRelationship = $ persistenceManager ->inverseRelationshipMetadata (static ::class (), $ object ::class, $ field );
396
+
397
+ if ($ inverseRelationship instanceof OneToOneRelationship) {
398
+ $ this ->tempAfterInstantiate [] = static function (object $ newObject ) use ($ object , $ inverseRelationship ) {
399
+ try {
400
+ set ($ object , $ inverseRelationship ->inverseField (), $ newObject );
401
+ } catch (\Throwable ) {
402
+ }
403
+ };
404
+ }
405
+
406
+ if (
407
+ !$ this ->isPersisting ()
408
+ ) {
409
+ return $ object ;
410
+ }
411
+
392
412
if (!$ persistenceManager ->isPersisted ($ object )) {
393
413
$ persistenceManager ->scheduleForInsert ($ object );
394
414
@@ -435,7 +455,16 @@ static function(object $object, array $parameters, PersistentObjectFactory $fact
435
455
436
456
Configuration::instance ()->persistence ()->scheduleForInsert ($ object , $ afterPersistCallbacks );
437
457
}
438
- );
458
+ )
459
+ ->afterPersist (
460
+ static function (object $ object ): void {
461
+ try {
462
+ Configuration::instance ()->persistence ()->refresh ($ object );
463
+ } catch (RefreshObjectFailed ) {
464
+ }
465
+ }
466
+ )
467
+ ;
439
468
}
440
469
441
470
private function throwIfCannotCreateObject (): void
0 commit comments