From 07088c94e79d1e9c99ea653c7067a350703d376b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Fri, 24 Nov 2023 23:48:39 +0100 Subject: [PATCH] Implemented logic for not (yet) used EntityMerger service --- src/Services/EntityMergers/EntityMerger.php | 47 +++++++++++++++++++ .../Mergers/EntityMergerInterface.php | 3 ++ .../EntityMergers/Mergers/PartMerger.php | 3 +- 3 files changed, 52 insertions(+), 1 deletion(-) diff --git a/src/Services/EntityMergers/EntityMerger.php b/src/Services/EntityMergers/EntityMerger.php index 7dcc91af..0f1355ea 100644 --- a/src/Services/EntityMergers/EntityMerger.php +++ b/src/Services/EntityMergers/EntityMerger.php @@ -23,7 +23,54 @@ declare(strict_types=1); namespace App\Services\EntityMergers; +use App\Services\EntityMergers\Mergers\EntityMergerInterface; +use Symfony\Component\DependencyInjection\Attribute\TaggedIterator; + +/** + * This service is used to merge two entities together. + * It automatically finds the correct merger (implementing EntityMergerInterface) for the two entities if one exists. + */ class EntityMerger { + public function __construct(#[TaggedIterator('app.entity_merger')] protected iterable $mergers) + { + } + /** + * This function finds the first merger that supports merging the other entity into the target entity. + * @param object $target + * @param object $other + * @param array $context + * @return EntityMergerInterface|null + */ + public function findMergerForObject(object $target, object $other, array $context = []): ?EntityMergerInterface + { + foreach ($this->mergers as $merger) { + if ($merger->supports($target, $other, $context)) { + return $merger; + } + } + return null; + } + + /** + * This function merges the other entity into the target entity. If no merger is found an exception is thrown. + * The target entity will be modified and returned. + * @param object $target + * @param object $other + * @param array $context + * @template T of object + * @phpstan-param T $target + * @phpstan-param T $other + * @phpstan-return T + * @return object + */ + public function merge(object $target, object $other, array $context = []): object + { + $merger = $this->findMergerForObject($target, $other, $context); + if ($merger === null) { + throw new \RuntimeException('No merger found for merging '.get_class($other).' into '.get_class($target)); + } + return $merger->merge($target, $other, $context); + } } \ No newline at end of file diff --git a/src/Services/EntityMergers/Mergers/EntityMergerInterface.php b/src/Services/EntityMergers/Mergers/EntityMergerInterface.php index 838bc1d6..046fc0ea 100644 --- a/src/Services/EntityMergers/Mergers/EntityMergerInterface.php +++ b/src/Services/EntityMergers/Mergers/EntityMergerInterface.php @@ -24,9 +24,12 @@ declare(strict_types=1); namespace App\Services\EntityMergers\Mergers; +use Symfony\Component\DependencyInjection\Attribute\AutoconfigureTag; + /** * @template T of object */ +#[AutoconfigureTag('app.entity_merger')] interface EntityMergerInterface { /** diff --git a/src/Services/EntityMergers/Mergers/PartMerger.php b/src/Services/EntityMergers/Mergers/PartMerger.php index 7e96d20f..c29ed960 100644 --- a/src/Services/EntityMergers/Mergers/PartMerger.php +++ b/src/Services/EntityMergers/Mergers/PartMerger.php @@ -32,9 +32,10 @@ use App\Entity\PriceInformations\Orderdetail; use Symfony\Component\DependencyInjection\Attribute\Autoconfigure; /** + * This class merges two parts together. + * * @implements EntityMergerInterface */ -#[Autoconfigure(public: true)] class PartMerger implements EntityMergerInterface {