PromiseMapper   A
last analyzed

Complexity

Total Complexity 10

Size/Duplication

Total Lines 74
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 36
c 2
b 0
f 0
dl 0
loc 74
ccs 32
cts 32
cp 1
rs 10
wmc 10

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 11 1
A fetchRelations() 0 6 1
A fetchFields() 0 6 1
A extract() 0 4 1
A hydrate() 0 18 5
A init() 0 7 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Cycle\ORM\PromiseMapper;
6
7
use Cycle\ORM\Mapper\DatabaseMapper;
8
use Cycle\ORM\Mapper\Traits\SingleTableTrait;
9
use Cycle\ORM\ORMInterface;
10
use Cycle\ORM\Reference\Promise;
11
use Cycle\ORM\Reference\ReferenceInterface;
12
use Cycle\ORM\SchemaInterface;
13
use Doctrine\Instantiator;
14
use Laminas\Hydrator\HydratorInterface;
15
use Laminas\Hydrator\ReflectionHydrator;
16
17
/**
18
 * Provide the ability to carry data over the specific class instances. Supports table inheritance using
19
 * hidden entity field.
20
 */
21
class PromiseMapper extends DatabaseMapper
22
{
23
    use SingleTableTrait;
24
25
    protected string $entity;
26
    protected array $children = [];
27
    protected HydratorInterface $hydrator;
28
    protected Instantiator\Instantiator $instantiator;
29
30 690
    public function __construct(ORMInterface $orm, string $role)
31
    {
32 690
        parent::__construct($orm, $role);
33
34 690
        $this->schema = $orm->getSchema();
35 690
        $this->entity = $this->schema->define($role, SchemaInterface::ENTITY);
36 690
        $this->children = $this->schema->define($role, SchemaInterface::CHILDREN) ?? [];
37 690
        $this->discriminator = $this->schema->define($role, SchemaInterface::DISCRIMINATOR) ?? $this->discriminator;
38 690
        $this->hydrator = new ReflectionHydrator();
39
40 690
        $this->instantiator = new Instantiator\Instantiator();
41 690
    }
42
43 444
    #[\Override]
44
    public function init(array $data, ?string $role = null): object
45
    {
46 444
        /** @psalm-var class-string $class */
47
        $class = $this->resolveClass($data, $role);
48 434
49
        return $this->instantiator->instantiate($class);
50
    }
51 450
52
    #[\Override]
53
    public function hydrate(object $entity, array $data): object
54 450
    {
55 450
        // Force searching related entities in the Heap
56 450
        $relations = $this->relationMap->getRelations();
57 426
        foreach ($data as $k => $v) {
58
            if (!$v instanceof ReferenceInterface || !\array_key_exists($k, $relations)) {
59 376
                continue;
60 376
            }
61
            $relation = $relations[$k];
62 376
            $relation->resolve($v, false);
63 64
64 352
            $data[$k] = $v->hasValue()
65
                ? $relation->collect($v->getValue())
66
                : new Promise($relation, $v);
67 450
        }
68
69
        return $this->hydrator->hydrate($data, $entity);
70 276
    }
71
72 276
    #[\Override]
73
    public function extract(object $entity): array
74
    {
75
        return $this->hydrator->extract($entity);
76
    }
77
78 240
    /**
79
     * Get entity columns.
80 240
     */
81
    #[\Override]
82 240
    public function fetchFields(object $entity): array
83
    {
84
        $values = \array_intersect_key($this->extract($entity), $this->columns + $this->parentColumns);
85 200
86
        return $values + $this->getDiscriminatorValues($entity);
87 200
    }
88 200
89 200
    #[\Override]
90
    public function fetchRelations(object $entity): array
91
    {
92
        return \array_intersect_key(
93
            $this->extract($entity),
94
            $this->relationMap->getRelations(),
95
        );
96
    }
97
}
98