Skip to content

Commit

Permalink
Reuse PropertyMappingPopulator in ArrayPropertyMappingPopulator
Browse files Browse the repository at this point in the history
  • Loading branch information
jdreesen committed Apr 4, 2024
1 parent cbe4767 commit 1ea1f44
Showing 1 changed file with 27 additions and 24 deletions.
51 changes: 27 additions & 24 deletions src/Populator/ArrayPropertyMappingPopulator.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,61 +18,64 @@
*/
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,
);
}

/**
* @throws PopulationException
*/
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);
}

/**
* @param TContext $ctx
*
* @return array<mixed>
*/
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);
}
}

0 comments on commit 1ea1f44

Please sign in to comment.