From c42eff199dff313b171ea0acbac70aa0417e00c5 Mon Sep 17 00:00:00 2001 From: Jacob Dreesen Date: Thu, 4 Apr 2024 18:38:24 +0200 Subject: [PATCH 1/2] Refactor ArrayPropertyMappingPopulator --- .../ArrayPropertyMappingPopulator.php | 35 ++++++++++++------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/src/Populator/ArrayPropertyMappingPopulator.php b/src/Populator/ArrayPropertyMappingPopulator.php index 7f4cc4a..3f98b30 100644 --- a/src/Populator/ArrayPropertyMappingPopulator.php +++ b/src/Populator/ArrayPropertyMappingPopulator.php @@ -45,25 +45,34 @@ public function __construct( public function populate(object $target, object $source, ?object $ctx = null): void { try { - $sourceArrayPropertyValues = $this->accessor->getValue($source, $this->sourceArrayProperty); - - $unwrappedArray = []; - if (\is_array($sourceArrayPropertyValues) && [] !== $sourceArrayPropertyValues) { - $unwrappedArray = array_map( - fn ($item) => null !== $this->sourceArrayItemProperty - ? $this->arrayItemAccessor->getValue($item, $this->sourceArrayItemProperty) - : $item, - $sourceArrayPropertyValues, - ); - } - $this->accessor->setValue( $target, $this->targetProperty, - array_map(fn ($item) => ($this->mapper)($item, $ctx), $unwrappedArray), + $this->unwrapAndMap($this->accessor->getValue($source, $this->sourceArrayProperty)), ); } catch (\Throwable $exception) { throw new PopulationException($this->sourceArrayProperty, $this->targetProperty, $exception); } } + + /** + * @param TContext $ctx + * + * @return array + */ + private function unwrapAndMap(mixed $sourceArrayPropertyValues, ?object $ctx = null): array + { + if (!\is_array($sourceArrayPropertyValues) || [] === $sourceArrayPropertyValues) { + return []; + } + + if (null === $this->sourceArrayItemProperty) { + return array_map(fn ($item) => ($this->mapper)($item, $ctx), $sourceArrayPropertyValues); + } + + return array_map( + fn ($item) => ($this->mapper)($this->arrayItemAccessor->getValue($item, $this->sourceArrayItemProperty), $ctx), + $sourceArrayPropertyValues, + ); + } } From 3cd6a8a90b0417aaec46e39dd4f46c188b8746cd Mon Sep 17 00:00:00 2001 From: Jacob Dreesen Date: Thu, 4 Apr 2024 19:06:30 +0200 Subject: [PATCH 2/2] Reuse PropertyMappingPopulator in ArrayPropertyMappingPopulator --- .../ArrayPropertyMappingPopulator.php | 51 ++++++++++--------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/src/Populator/ArrayPropertyMappingPopulator.php b/src/Populator/ArrayPropertyMappingPopulator.php index 3f98b30..1e6d93e 100644 --- a/src/Populator/ArrayPropertyMappingPopulator.php +++ b/src/Populator/ArrayPropertyMappingPopulator.php @@ -18,25 +18,33 @@ */ final class ArrayPropertyMappingPopulator implements Populator { - /** @var \Closure(mixed, TContext=):mixed */ - private \Closure $mapper; + private ?string $sourceArrayItemProperty; + /** @var \Closure(mixed, TContext=):mixed|null */ + private ?\Closure $mapper; private PropertyAccessorInterface $arrayItemAccessor; - private PropertyAccessorInterface $accessor; + private PropertyMappingPopulator $populator; /** * @param \Closure(mixed, TContext=):mixed|null $mapper */ public function __construct( - private string $targetProperty, - private string $sourceArrayProperty, - private ?string $sourceArrayItemProperty = null, + string $targetProperty, + string $sourceArrayProperty, + ?string $sourceArrayItemProperty = null, ?\Closure $mapper = null, ?PropertyAccessorInterface $arrayItemAccessor = null, ?PropertyAccessorInterface $accessor = null, ) { - $this->mapper = $mapper ?? static fn ($v) => $v; + $this->sourceArrayItemProperty = $sourceArrayItemProperty; + $this->mapper = $mapper; $this->arrayItemAccessor = $arrayItemAccessor ?? PropertyAccess::createPropertyAccessor(); - $this->accessor = $accessor ?? PropertyAccess::createPropertyAccessor(); + $this->populator = new PropertyMappingPopulator( + $targetProperty, + $sourceArrayProperty, + null, + $this->unwrapAndMap(...), + $accessor, + ); } /** @@ -44,15 +52,7 @@ public function __construct( */ public function populate(object $target, object $source, ?object $ctx = null): void { - try { - $this->accessor->setValue( - $target, - $this->targetProperty, - $this->unwrapAndMap($this->accessor->getValue($source, $this->sourceArrayProperty)), - ); - } catch (\Throwable $exception) { - throw new PopulationException($this->sourceArrayProperty, $this->targetProperty, $exception); - } + $this->populator->populate($target, $source, $ctx); } /** @@ -60,19 +60,22 @@ public function populate(object $target, object $source, ?object $ctx = null): v * * @return array */ - private function unwrapAndMap(mixed $sourceArrayPropertyValues, ?object $ctx = null): array + private function unwrapAndMap(mixed $values, ?object $ctx = null): array { - if (!\is_array($sourceArrayPropertyValues) || [] === $sourceArrayPropertyValues) { + if (!\is_array($values) || [] === $values) { return []; } if (null === $this->sourceArrayItemProperty) { - return array_map(fn ($item) => ($this->mapper)($item, $ctx), $sourceArrayPropertyValues); + return $this->mapper ? array_map(fn ($item) => ($this->mapper)($item, $ctx), $values) : $values; } - return array_map( - fn ($item) => ($this->mapper)($this->arrayItemAccessor->getValue($item, $this->sourceArrayItemProperty), $ctx), - $sourceArrayPropertyValues, - ); + $mapper = fn ($item) => $this->arrayItemAccessor->getValue($item, $this->sourceArrayItemProperty); + + if ($this->mapper) { + $mapper = fn ($item) => ($this->mapper)($mapper($item), $ctx); + } + + return array_map($mapper, $values); } }