Skip to content

Commit

Permalink
Merge pull request #828 from nikophil/merge-2.3.x
Browse files Browse the repository at this point in the history
  • Loading branch information
nikophil authored Feb 24, 2025
2 parents dea6246 + 413bb10 commit 4ac3439
Show file tree
Hide file tree
Showing 14 changed files with 179 additions and 82 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# CHANGELOG

## [v2.3.5](https://github.com/zenstruck/foundry/releases/tag/v2.3.5)

February 24th, 2025 - [v2.3.4...v2.3.5](https://github.com/zenstruck/foundry/compare/v2.3.4...v2.3.5)

* fbf0981 fix: actually disable persistence cascade (#817) by @nikophil
* 2426f3e fix: trigger after persist callbacks for entities scheduled for insert (#822) by @nikophil

## [v2.3.4](https://github.com/zenstruck/foundry/releases/tag/v2.3.4)

February 14th, 2025 - [v2.3.3...v2.3.4](https://github.com/zenstruck/foundry/compare/v2.3.3...v2.3.4)
Expand Down
38 changes: 19 additions & 19 deletions bin/tools/phpstan/composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ parameters:
- identifier: property.readOnlyByPhpDocDefaultValue
paths:
- src/Object/Hydrator.php
- src/Factory.php
- src/ObjectFactory.php
- src/Persistence/PersistentObjectFactory.php

Expand Down
9 changes: 1 addition & 8 deletions src/Factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,6 @@
*/
abstract class Factory
{
/**
* Memoization of normalized parameters.
*
* @internal
* @var Parameters|null
*/
protected ?array $normalizedParameters = null;
/** @phpstan-var Attributes[] */
private array $attributes;

Expand Down Expand Up @@ -208,7 +201,7 @@ protected function initializeInternal(): static
*/
protected function normalizeParameters(array $parameters): array
{
return $this->normalizedParameters = \array_combine(
return \array_combine(
\array_keys($parameters),
\array_map($this->normalizeParameter(...), \array_keys($parameters), $parameters)
);
Expand Down
12 changes: 7 additions & 5 deletions src/Persistence/IsProxy.php
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,14 @@ public function _set(string $property, mixed $value): static
return $this;
}

public function _real(): object
public function _real(bool $withAutoRefresh = true): object
{
try {
// we don't want the auto-refresh mechanism to break "real" object retrieval
$this->_autoRefresh();
} catch (\Throwable) {
if ($withAutoRefresh) {
try {
// we don't want the auto-refresh mechanism to break "real" object retrieval
$this->_autoRefresh();
} catch (\Throwable) {
}
}

return $this->initializeLazyObject();
Expand Down
20 changes: 18 additions & 2 deletions src/Persistence/PersistenceManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ final class PersistenceManager
private bool $flush = true;
private bool $persist = true;

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

/**
* @param iterable<PersistenceStrategy> $strategies
*/
Expand Down Expand Up @@ -72,17 +75,28 @@ public function save(object $object): object
$om->persist($object);
$this->flush($om);

if ($this->afterPersistCallbacks) {
foreach ($this->afterPersistCallbacks as $afterPersistCallback) {
$afterPersistCallback();
}

$this->afterPersistCallbacks = [];

$this->save($object);
}

return $object;
}

/**
* @template T of object
*
* @param T $object
* @param T $object
* @param list<callable():void> $afterPersistCallbacks
*
* @return T
*/
public function scheduleForInsert(object $object): object
public function scheduleForInsert(object $object, array $afterPersistCallbacks = []): object
{
if ($object instanceof Proxy) {
$object = unproxy($object);
Expand All @@ -91,6 +105,8 @@ public function scheduleForInsert(object $object): object
$om = $this->strategyFor($object::class)->objectManagerFor($object::class);
$om->persist($object);

$this->afterPersistCallbacks = [...$this->afterPersistCallbacks, ...$afterPersistCallbacks];

return $object;
}

Expand Down
49 changes: 18 additions & 31 deletions src/Persistence/PersistentObjectFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -218,16 +218,6 @@ public function create(callable|array $attributes = []): object

$configuration->persistence()->save($object);

if ($this->afterPersist) {
$attributes = $this->normalizedParameters ?? throw new \LogicException('Factory::$normalizedParameters has not been initialized.');

foreach ($this->afterPersist as $callback) {
$callback($object, $attributes, $this);
}

$configuration->persistence()->save($object);
}

return $object;
}

Expand Down Expand Up @@ -310,8 +300,7 @@ protected function normalizeParameter(string $field, mixed $value): mixed
// auto-refresh computes changeset and prevents the placeholder object to be cleanly
// forgotten fom the persistence manager
if ($inversedObject instanceof Proxy) {
$inversedObject->_disableAutoRefresh();
$inversedObject = $inversedObject->_real();
$inversedObject = $inversedObject->_real(withAutoRefresh: false);
}

$this->tempAfterInstantiate[] = static function(object $object) use ($inversedObject, $inverseField, $pm, $placeholder) {
Expand Down Expand Up @@ -363,36 +352,26 @@ protected function normalizeCollection(string $field, FactoryCollection $collect
}

/**
* This method will try to find entities in database if they are detached.
*
* @internal
*/
protected function normalizeObject(object $object): object
{
$reflectionClass = new \ReflectionClass($object::class);

if ($reflectionClass->isFinal()) {
return $object;
}

// readonly classes exist since php 8.2 and proxyHelper supports them since 8.3
if (80200 <= \PHP_VERSION_ID && \PHP_VERSION_ID < 80300 && $reflectionClass->isReadonly()) {
return $object;
}

$configuration = Configuration::instance();

if (!$configuration->isPersistenceAvailable()) {
if (
!$this->isPersisting()
|| !$configuration->isPersistenceAvailable()
) {
return $object;
}

$persistenceManager = $configuration->persistence();

if ($object instanceof Proxy) {
$proxy = $object;
$proxy->_disableAutoRefresh();
$object = $proxy->_real();
$proxy->_enableAutoRefresh();
$object = $object->_real(withAutoRefresh: false);
}

$persistenceManager = $configuration->persistence();
if (!$persistenceManager->hasPersistenceFor($object)) {
return $object;
}
Expand Down Expand Up @@ -429,7 +408,15 @@ static function(object $object, array $parameters, PersistentObjectFactory $fact
return;
}

Configuration::instance()->persistence()->scheduleForInsert($object);
$afterPersistCallbacks = [];

foreach ($factoryUsed->afterPersist as $afterPersist) {
$afterPersistCallbacks[] = static function() use ($object, $afterPersist, $parameters, $factoryUsed): void {
$afterPersist($object, $parameters, $factoryUsed);
};
}

Configuration::instance()->persistence()->scheduleForInsert($object, $afterPersistCallbacks);
}
);

Expand Down
2 changes: 1 addition & 1 deletion src/Persistence/Proxy.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public function _set(string $property, mixed $value): static;
/**
* @return T
*/
public function _real(): object;
public function _real(bool $withAutoRefresh = true): object;

/**
* @psalm-return T&Proxy<T>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ protected function defaults(): array|callable
{
return [
'prop1' => self::faker()->text(),
'propInteger' => self::faker()->randomNumber(),
];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ protected function defaults(): array|callable
return [
'date' => \DateTimeImmutable::createFromMutable(self::faker()->dateTime()),
'prop1' => self::faker()->text(),
'propInteger' => self::faker()->randomNumber(),
];
}

Expand Down
14 changes: 14 additions & 0 deletions tests/Fixture/Model/GenericModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ abstract class GenericModel
#[MongoDB\Field(type: 'string')]
private string $prop1;

#[ORM\Column]
#[MongoDB\Field(type: 'int')]
private int $propInteger = 0;

#[ORM\Column(nullable: true)]
#[MongoDB\Field(type: 'date_immutable', nullable: true)]
private ?\DateTimeImmutable $date = null;
Expand All @@ -52,6 +56,16 @@ public function setProp1(string $prop1): void
$this->prop1 = $prop1;
}

public function getPropInteger(): int
{
return $this->propInteger;
}

public function setPropInteger(int $propInteger): void
{
$this->propInteger = $propInteger;
}

public function getDate(): ?\DateTimeImmutable
{
return $this->date;
Expand Down
Loading

0 comments on commit 4ac3439

Please sign in to comment.