Completed
Push — 2.x ( 0b6590...78009d )
by Aleksei
20s queued 15s
created

EntityFactory::make()   C

Complexity

Conditions 13
Paths 78

Size

Total Lines 70
Code Lines 38

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 34
CRAP Score 13.0901

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 13
eloc 38
nc 78
nop 4
dl 0
loc 70
ccs 34
cts 37
cp 0.9189
crap 13.0901
rs 6.6166
c 1
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
                    $relations = $relMap->getRelations();
68
                    $fetched = $mapper->fetchRelations($e);
69
70 674
                    // Get not resolved (references) or not set relations
71
                    $overwrite = [];
72
                    foreach ($relations as $name => $_) {
73
                        if (!\array_key_exists($name, $fetched) || $fetched[$name] instanceof ReferenceInterface) {
74
                            $overwrite[$name] = true;
75 4930
                        }
76 4930
                    }
77
78
                    if ($overwrite === []) {
79 4930
                        return $e;
80
                    }
81 4930
82
                    $node = $this->heap->get($e);
83
                    \assert($node !== null);
84 7154
85
                    // Replace references with actual relation data
86 7154
                    return $mapper->hydrate($e, $relMap->init(
87 5216
                        $this,
88 5216
                        $node,
89 5068
                        \array_intersect_key($castedData, $overwrite),
90
                    ));
91
                }
92 1582
            }
93 1582
        }
94 40
95
        $node = new Node($status, $castedData, $rRole);
96 40
        $e = $mapper->init($data, $role);
97
98 40
        /** Entity should be attached before {@see RelationMap::init()} running */
99
        $this->heap->attach($e, $node, $this->indexProvider->getIndexes($rRole));
100
101
        return $mapper->hydrate($e, $relMap->init($this, $node, $castedData));
102 40
    }
103
}
104