Am I missing something or am I am looking at the issue from a wrong perspective? And of course ideally the above should work nicely with DbSelect so it can be passed to a Paginator.
This can be done in a custom hydrator which uses one of the standard hydrators with added strategies. This custom hydrator modifies the array structure before it is passed to standard hydrator.
Another option can be the AggregateHydrator which handles different parts of the array. But I suggest to try the custom hydrator first.
So I have created this one way Hydrator to convert the array to a nested array.
class NestedArrayHydrator extends AbstractHydrator
{
private string $nestedKey;
public function __construct(string $nestedKey)
{
$this->nestedKey = $nestedKey;
}
public function hydrate(array $data, object $object): array
{
$reflect = new ReflectionClass($object);
$events = $reflect->getProperties(ReflectionProperty::IS_PUBLIC);
foreach($events as $event)
{
$eventName = $event->getName();
if (!array_key_exists($eventName, $data))
{
throw new InvalidKeyProvided("Key '{$eventName}' not found in the array.");
}
$data[$this->nestedKey][$eventName] = $data[$eventName];
unset($data[$eventName]);
}
return $data;
}
public function extract(object $object): array
{
throw new RuntimeException("Not implemented.");
}
}
I hope I am not violating the design
The usage itself can look like this:
$customHydrator = new NestedArrayHydrator('samples');
$restructuredData = $customHydrator->hydrate($data, new Samples());
$hydrator = new ReflectionHydrator();
$hydrator->addStrategy(
'samples',
new HydratorStrategy(new ReflectionHydrator(), Samples::class)
);
$hydratedResult = $hydrator->hydrate($restructuredData, new Someone());
I would be more than happy to get your thoughts guys, thx.
Your class NestedArrayHydrator is not a hydrator because nothing is “hydrated”. In this form this makes no sense.
Here an untested example:
final class MyHydrator implements Laminas\Hydrator\HydratorInterface
{
private Laminas\Hydrator\HydratorInterface $baseHydrator;
public function __construct(Laminas\Hydrator\HydratorInterface $baseHydrator)
{
$this->baseHydrator = $baseHydrator;
}
public function extract(object $object): array
{
$data = $this->baseHydrator->extract($object);
// Reformat data here…
return $data;
}
public function hydrate(array $data, object $object)
{
// Reformat data here…
return $this->baseHydrator->hydrate($data, $object);
}
}
$baseHydrator = new Laminas\Hydrator\ReflectionHydrator();
$baseHydrator->addStrategy(
'samples',
new Laminas\Hydrator\Strategy\HydratorStrategy(
new Laminas\Hydrator\ReflectionHydrator(),
Samples::class
)
);
// Add more strategies here if required
$myHydrator = new MyHydrator($baseHydrator);
$myHydrator->hydrate($flatDataArrayFromDatabase, new Someone());