Issues (188)

src/Iterator.php (3 issues)

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Cycle\ORM;
6
7
use Cycle\ORM\Heap\HeapInterface;
8
use Cycle\ORM\Heap\Node;
9
use Cycle\ORM\Service\EntityFactoryInterface;
10
use Cycle\ORM\Select\LoaderInterface;
11
use IteratorAggregate;
12
13
/**
14
 * Iterates over given data-set and instantiates objects.
15
 *
16
 * @template TEntity
17
 *
18
 * @template-implements IteratorAggregate<array-key|array, TEntity>
19
 */
20
final class Iterator implements \IteratorAggregate
21
{
22
    private function __construct(
23 2356
        private string $role,
24
        private HeapInterface $heap,
25
        private SchemaInterface $schema,
26
        private EntityFactoryInterface $entityFactory,
27
        private iterable $source,
28
        private bool $findInHeap = false,
29
        private bool $typecast = false,
30
    ) {}
31
32
    /**
33
     * @param class-string<TEntity>|string $class
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<TEntity>|string at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<TEntity>|string.
Loading history...
34
     * @param iterable<array-key, array> $source
35
     */
36
    public static function createWithOrm(
37
        ORMInterface $orm,
38 8
        string $class,
39
        iterable $source,
40
        bool $findInHeap = false,
41
        bool $typecast = false,
42
    ): self {
43
        return new self(
44
            $orm->resolveRole($class),
45 8
            $orm->getHeap(),
46 8
            $orm->getSchema(),
47 8
            $orm->getService(EntityFactoryInterface::class),
48 8
            $source,
49 8
            $findInHeap,
50
            $typecast,
51
        );
52
    }
53
54
    /**
55
     * @param non-empty-string $role
0 ignored issues
show
Documentation Bug introduced by
The doc comment non-empty-string at position 0 could not be parsed: Unknown type name 'non-empty-string' at position 0 in non-empty-string.
Loading history...
56
     * @param iterable<array-key, array> $source
57
     */
58
    public static function createWithServices(
59
        HeapInterface $heap,
60 2356
        SchemaInterface $schema,
61
        EntityFactoryInterface $entityProvider,
62
        string $role,
63
        iterable $source,
64
        bool $findInHeap = false,
65
        bool $typecast = false,
66
    ): self {
67
        return new self(
68
            $role,
69 2356
            $heap,
70
            $schema,
71
            $entityProvider,
72
            $source,
73
            $findInHeap,
74
            $typecast,
75
        );
76
    }
77
78
    /**
79
     * Generate entities using incoming data stream. Pivoted data would be
80
     * returned as key value if set.
81
     *
82
     * @return \Generator<array, array-key|TEntity, mixed, void>
83
     */
84
    public function getIterator(): \Generator
85
    {
86 2356
        foreach ($this->source as $index => $data) {
87
            // through-like relations
88 2356
            if (isset($data['@'])) {
89
                $index = $data;
90 2316
                unset($index['@']);
91 616
                $data = $data['@'];
92 616
            }
93 616
94
            // get role from joined table inheritance
95
            $role = $data[LoaderInterface::ROLE_KEY] ?? $this->role;
96
97 2316
            // add pipeline filter support?
98
99
            yield $index => $this->getEntity($data, $role);
100
        }
101 2316
    }
102
103
    /**
104
     * @param class-string<TEntity>|string $role
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<TEntity>|string at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<TEntity>|string.
Loading history...
105
     *
106
     * @return TEntity
107
     */
108
    private function getEntity(array $data, string $role): object
109
    {
110 2316
        if ($this->findInHeap) {
111
            $pk = $this->schema->define($role, SchemaInterface::PRIMARY_KEY);
112 2316
            if (\is_array($pk)) {
113 860
                $e = $this->heap->find($role, $data);
114 860
            } else {
115 56
                $id = $data[$pk] ?? null;
116
117 804
                if ($id !== null) {
118
                    $e = $this->heap->find($role, [$pk => $id]);
119 804
                }
120 804
            }
121
        }
122
123
        return $e ?? $this->entityFactory->make($role, $data, Node::MANAGED, typecast: $this->typecast);
124
    }
125
}
126