Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 3 additions & 8 deletions src/AbstractMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,12 @@ abstract class AbstractMapper
/** @var array<string, Collection> */
private array $collections = [];

public EntityFactory $entityFactory { get => $this->hydrator->entityFactory; }

public Styles\Stylable $style { get => $this->entityFactory->style; }

public function __construct(
public readonly EntityFactory $entityFactory = new EntityFactory(),
public readonly Hydrator $hydrator,
) {
$this->tracked = new SplObjectStorage();
$this->pending = new SplObjectStorage();
Expand Down Expand Up @@ -130,8 +132,6 @@ public function registerCollection(string $alias, Collection $collection): void
$this->collections[$alias] = $collection;
}

abstract protected function defaultHydrator(Collection $collection): Hydrator;

/**
* @param array<string, mixed> $columns
*
Expand All @@ -153,11 +153,6 @@ protected function filterColumns(array $columns, Collection $collection): array
return array_intersect_key($columns, array_flip([...$collection->filters, $id]));
}

protected function resolveHydrator(Collection $collection): Hydrator
{
return $collection->hydrator ?? $this->defaultHydrator($collection);
}

protected function registerInIdentityMap(object $entity, Collection $coll): void
{
if ($coll->name === null) {
Expand Down
10 changes: 0 additions & 10 deletions src/Collections/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
use ArrayAccess;
use Respect\Data\AbstractMapper;
use Respect\Data\CollectionNotBound;
use Respect\Data\Hydrator;

/** @implements ArrayAccess<string, Collection> */
class Collection implements ArrayAccess
Expand All @@ -16,8 +15,6 @@ class Collection implements ArrayAccess

public private(set) AbstractMapper|null $mapper = null;

public private(set) Hydrator|null $hydrator = null;

public private(set) Collection|null $parent = null;

public private(set) Collection|null $connectsTo = null;
Expand Down Expand Up @@ -101,13 +98,6 @@ public function bindMapper(AbstractMapper $mapper): static
return $this;
}

public function hydrateFrom(Hydrator $hydrator): static
{
$this->hydrator = $hydrator;

return $this;
}

public function stack(Collection $collection): static
{
$tail = $this->last ?? $this;
Expand Down
11 changes: 9 additions & 2 deletions src/Hydrator.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,17 @@
/** Transforms raw backend data into entity instances mapped to their collections */
interface Hydrator
{
/** @return SplObjectStorage<object, Collection>|false */
public EntityFactory $entityFactory { get; }

/** Returns just the root entity */
public function hydrate(
mixed $raw,
Collection $collection,
EntityFactory $entityFactory,
): object|false;

/** @return SplObjectStorage<object, Collection>|false */
public function hydrateAll(
mixed $raw,
Collection $collection,
): SplObjectStorage|false;
}
39 changes: 32 additions & 7 deletions src/Hydrators/Base.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Respect\Data\Hydrators;

use DomainException;
use Respect\Data\Collections\Collection;
use Respect\Data\Collections\Typed;
use Respect\Data\EntityFactory;
Expand All @@ -13,10 +14,35 @@
/** Base hydrator providing collection-tree entity wiring */
abstract class Base implements Hydrator
{
public function __construct(
public readonly EntityFactory $entityFactory = new EntityFactory(),
) {
}

public function hydrate(
mixed $raw,
Collection $collection,
): object|false {
$entities = $this->hydrateAll($raw, $collection);
if ($entities === false) {
return false;
}

foreach ($entities as $entity) {
if ($entities[$entity] === $collection) {
return $entity;
}
}

throw new DomainException(
'Hydration produced no entity for collection "' . $collection->name . '"',
);
}

/** @param SplObjectStorage<object, Collection> $entities */
protected function wireRelationships(SplObjectStorage $entities, EntityFactory $entityFactory): void
protected function wireRelationships(SplObjectStorage $entities): void
{
$style = $entityFactory->style;
$style = $this->entityFactory->style;
$others = clone $entities;

foreach ($entities as $entity) {
Expand All @@ -40,12 +66,12 @@ protected function wireRelationships(SplObjectStorage $entities, EntityFactory $
continue;
}

$id = $entityFactory->get($other, $style->identifier($otherColl->name));
$id = $this->entityFactory->get($other, $style->identifier($otherColl->name));
if ($id === null) {
continue;
}

$entityFactory->set($entity, $relationName, $other);
$this->entityFactory->set($entity, $relationName, $other);
}
}
}
Expand All @@ -57,13 +83,12 @@ protected function wireRelationships(SplObjectStorage $entities, EntityFactory $
*/
protected function resolveEntityClass(
Collection $collection,
EntityFactory $entityFactory,
object|array $row,
): string {
if ($collection instanceof Typed) {
return $collection->resolveEntityClass($entityFactory, $row);
return $collection->resolveEntityClass($this->entityFactory, $row);
}

return $entityFactory->resolveClass((string) $collection->name);
return $this->entityFactory->resolveClass((string) $collection->name);
}
}
22 changes: 9 additions & 13 deletions src/Hydrators/Nested.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
namespace Respect\Data\Hydrators;

use Respect\Data\Collections\Collection;
use Respect\Data\EntityFactory;
use SplObjectStorage;

use function is_array;
Expand All @@ -14,10 +13,9 @@
final class Nested extends Base
{
/** @return SplObjectStorage<object, Collection>|false */
public function hydrate(
public function hydrateAll(
mixed $raw,
Collection $collection,
EntityFactory $entityFactory,
): SplObjectStorage|false {
if (!is_array($raw)) {
return false;
Expand All @@ -26,10 +24,10 @@ public function hydrate(
/** @var SplObjectStorage<object, Collection> $entities */
$entities = new SplObjectStorage();

$this->hydrateNode($raw, $collection, $entityFactory, $entities);
$this->hydrateNode($raw, $collection, $entities);

if ($entities->count() > 1) {
$this->wireRelationships($entities, $entityFactory);
$this->wireRelationships($entities);
}

return $entities;
Expand All @@ -42,29 +40,28 @@ public function hydrate(
private function hydrateNode(
array $data,
Collection $collection,
EntityFactory $entityFactory,
SplObjectStorage $entities,
): void {
$entity = $entityFactory->create(
$this->resolveEntityClass($collection, $entityFactory, $data),
$entity = $this->entityFactory->create(
$this->resolveEntityClass($collection, $data),
);

foreach ($data as $key => $value) {
if (is_array($value)) {
continue;
}

$entityFactory->set($entity, $key, $value);
$this->entityFactory->set($entity, $key, $value);
}

$entities[$entity] = $collection;

if ($collection->connectsTo !== null) {
$this->hydrateChild($data, $collection->connectsTo, $entityFactory, $entities);
$this->hydrateChild($data, $collection->connectsTo, $entities);
}

foreach ($collection->children as $child) {
$this->hydrateChild($data, $child, $entityFactory, $entities);
$this->hydrateChild($data, $child, $entities);
}
}

Expand All @@ -75,7 +72,6 @@ private function hydrateNode(
private function hydrateChild(
array $parentData,
Collection $child,
EntityFactory $entityFactory,
SplObjectStorage $entities,
): void {
$key = $child->name;
Expand All @@ -85,6 +81,6 @@ private function hydrateChild(

/** @var array<string, mixed> $childData */
$childData = $parentData[$key];
$this->hydrateNode($childData, $child, $entityFactory, $entities);
$this->hydrateNode($childData, $child, $entities);
}
}
12 changes: 5 additions & 7 deletions src/Hydrators/PrestyledAssoc.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
use Respect\Data\Collections\Collection;
use Respect\Data\Collections\Composite;
use Respect\Data\Collections\Filtered;
use Respect\Data\EntityFactory;
use SplObjectStorage;

use function array_keys;
Expand All @@ -31,10 +30,9 @@ final class PrestyledAssoc extends Base
private Collection|null $cachedCollection = null;

/** @return SplObjectStorage<object, Collection>|false */
public function hydrate(
public function hydrateAll(
mixed $raw,
Collection $collection,
EntityFactory $entityFactory,
): SplObjectStorage|false {
if (!$raw || !is_array($raw)) {
return false;
Expand All @@ -59,19 +57,19 @@ public function hydrate(

if (!isset($instances[$basePrefix])) {
$coll = $collMap[$basePrefix];
$class = $this->resolveEntityClass($coll, $entityFactory, $props);
$instances[$basePrefix] = $entityFactory->create($class);
$class = $this->resolveEntityClass($coll, $props);
$instances[$basePrefix] = $this->entityFactory->create($class);
$entities[$instances[$basePrefix]] = $coll;
}

$entity = $instances[$basePrefix];
foreach ($props as $prop => $value) {
$entityFactory->set($entity, $prop, $value, styled: true);
$this->entityFactory->set($entity, $prop, $value, styled: true);
}
}

if ($entities->count() > 1) {
$this->wireRelationships($entities, $entityFactory);
$this->wireRelationships($entities);
}

return $entities;
Expand Down
Loading
Loading