Completed
Push — 2.x ( a366d0...44eaeb )
by Aleksei
21s queued 15s
created

EntityFactory::resolveRole()   B

Complexity

Conditions 7
Paths 5

Size

Total Lines 25
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 7.0222

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 7
eloc 14
nc 5
nop 1
dl 0
loc 25
ccs 12
cts 13
cp 0.9231
crap 7.0222
rs 8.8333
c 1
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Cycle\ORM\Service\Implementation;
6
7
use Cycle\ORM\Heap\HeapInterface;
8
use Cycle\ORM\Heap\Node;
9
use Cycle\ORM\Reference\ReferenceInterface;
10
use Cycle\ORM\Service\EntityFactoryInterface;
11
use Cycle\ORM\Service\IndexProviderInterface;
12
use Cycle\ORM\Service\MapperProviderInterface;
13
use Cycle\ORM\Service\RelationProviderInterface;
14
use Cycle\ORM\SchemaInterface;
15
use Cycle\ORM\Select\LoaderInterface;
16
use Cycle\ORM\Service\RoleResolverInterface;
17
18
/**
19
 * @internal
20
 */
21
final class EntityFactory implements EntityFactoryInterface
22
{
23 7418
    public function __construct(
24
        private HeapInterface $heap,
25
        private SchemaInterface $schema,
26
        private MapperProviderInterface $mapperProvider,
27
        private RelationProviderInterface $relationProvider,
28
        private IndexProviderInterface $indexProvider,
29
        private RoleResolverInterface $roleResolver,
30
    ) {}
31
32 4986
    public function make(
33
        string $role,
34
        array $data = [],
35
        int $status = Node::NEW,
36
        bool $typecast = false,
37
    ): object {
38 4986
        $role = $data[LoaderInterface::ROLE_KEY] ?? $role;
39 4986
        unset($data[LoaderInterface::ROLE_KEY]);
40
        // Resolved role
41 4986
        $rRole = $this->roleResolver->resolveRole($role);
42 4986
        $relMap = $this->relationProvider->getRelationMap($rRole);
43 4986
        $mapper = $this->mapperProvider->getMapper($rRole);
44
45 4986
        $castedData = $typecast ? $mapper->cast($data) : $data;
46
47 4986
        if ($status !== Node::NEW) {
48
            // unique entity identifier
49 4742
            $pk = $this->schema->define($role, SchemaInterface::PRIMARY_KEY);
50 4742
            if (\is_array($pk)) {
51 616
                $ids = [];
52 616
                foreach ($pk as $key) {
53 616
                    if (!isset($data[$key])) {
54
                        $ids = null;
55
                        break;
56
                    }
57 616
                    $ids[$key] = $data[$key];
58
                }
59
            } else {
60 4206
                $ids = isset($data[$pk]) ? [$pk => $data[$pk]] : null;
61
            }
62
63 4742
            if ($ids !== null) {
64 4742
                $e = $this->heap->find($rRole, $ids);
65
66 4742
                if ($e !== null) {
67 674
                    // Get not resolved relations (references)
68
                    $refs = \array_filter(
69
                        $mapper->fetchRelations($e),
70 674
                        fn($v) => $v instanceof ReferenceInterface,
71
                    );
72
73
                    if ($refs === []) {
74
                        return $e;
75 4930
                    }
76 4930
77
                    $node = $this->heap->get($e);
78
                    \assert($node !== null);
79 4930
80
                    // Replace references with actual relation data
81 4930
                    return $mapper->hydrate($e, $relMap->init(
82
                        $this,
83
                        $node,
84 7154
                        \array_intersect_key($castedData, $refs),
85
                    ));
86 7154
                }
87 5216
            }
88 5216
        }
89 5068
90
        $node = new Node($status, $castedData, $rRole);
91
        $e = $mapper->init($data, $role);
92 1582
93 1582
        /** Entity should be attached before {@see RelationMap::init()} running */
94 40
        $this->heap->attach($e, $node, $this->indexProvider->getIndexes($rRole));
95
96 40
        return $mapper->hydrate($e, $relMap->init($this, $node, $castedData));
97
    }
98
}
99