Passed
Push — master ( 3f1e0c...bf7a69 )
by Aleksandr
02:11
created

EntityFactory::handlePivot()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 14
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 12
nc 2
nop 2
dl 0
loc 14
ccs 12
cts 12
cp 1
crap 2
rs 9.8666
c 0
b 0
f 0
1
<?php
2
/**
3
 * This file is part of the eav package.
4
 *
5
 * @author    Aleksandr Drobotik <[email protected]>
6
 * @copyright 2023 Aleksandr Drobotik
7
 * @license   https://opensource.org/license/mit  The MIT License
8
 */
9
declare(strict_types=1);
10
11
namespace Drobotik\Eav\Factory;
12
13
use Drobotik\Eav\Enum\_ATTR;
14
use Drobotik\Eav\Enum\_PIVOT;
15
use Drobotik\Eav\Enum\_VALUE;
16
use Drobotik\Eav\Enum\ATTR_FACTORY;
17
use Drobotik\Eav\Enum\ATTR_TYPE;
18
use Drobotik\Eav\Exception\AttributeException;
19
use Drobotik\Eav\Exception\EntityFactoryException;
20
use Drobotik\Eav\Result\EntityFactoryResult;
21
use Drobotik\Eav\Trait\SingletonsTrait;
22
23
class EntityFactory
24
{
25
    use SingletonsTrait;
26
27
    private EntityFactoryResult $result;
28
29 10
    private function makeNewResult() : EntityFactoryResult
30
    {
31 10
        $this->result = new EntityFactoryResult();
32 10
        return $this->result;
33
    }
34
35 10
    public function getResult() : EntityFactoryResult
36
    {
37 10
        return $this->result;
38
    }
39
40 11
    public function create(array $fields, int $domainKey, int $setKey): EntityFactoryResult
41
    {
42 11
        $result = $this->makeNewResult();
43 11
        $result->setDomainKey($domainKey);
44 11
        $result->setSetKey($setKey);
45 11
        $this->validateFields($fields);
46 9
        $entityKey = $this->makeEavFactory()->createEntity($domainKey, $setKey);
47 9
        $result->setEntityKey($entityKey);
48 9
        foreach ($fields as $field) {
49 8
            $this->handleField($field);
50
        }
51 5
        return $result;
52
    }
53
54 10
    private function validateFields(array $fields) : void
55
    {
56 10
        $result = $this->getResult();
57 10
        $groupModel = $this->makeGroupModel();
58 10
        $setKey = $result->getSetKey();
59 10
        foreach($fields as $field) {
60 9
            if (!key_exists(ATTR_FACTORY::GROUP->field(), $field)) {
61 1
                throw new EntityFactoryException("Group key must be provided!");
62
            }
63
        }
64 9
        $groups = array_unique(array_column($fields, ATTR_FACTORY::GROUP->field()));
65 9
        foreach($groups as $groupKey)
66
        {
67 8
            if(!$groupModel->checkGroupInAttributeSet($setKey, $groupKey))
68
            {
69 1
                throw new EntityFactoryException("This group is not belongs to attribute set");
70
            }
71
        }
72
    }
73
74 4
    public function handleAttribute($config) : int
75
    {
76 4
        $result = $this->getResult();
77 4
        $domainKey = $result->getDomainKey();
78 4
        $factory = $this->makeEavFactory();
79 4
        $attributeModel = $this->makeAttributeModel();
80 4
        $record = $attributeModel->findByName($config[_ATTR::NAME->column()], $domainKey);
81 4
        if (!is_bool($record)) {
0 ignored issues
show
introduced by
The condition is_bool($record) is always false.
Loading history...
82 1
            $attrKey = $record[_ATTR::ID->column()];
83 1
            $attrData = array_intersect_key($config, [
84 1
                _ATTR::NAME->column() => null,
85 1
                _ATTR::TYPE->column() => null,
86 1
                _ATTR::STRATEGY->column() => null,
87 1
                _ATTR::SOURCE->column() => null,
88 1
                _ATTR::DEFAULT_VALUE->column() => null,
89 1
                _ATTR::DESCRIPTION->column() => null
90 1
            ]);
91 1
            $attributeModel->updateByArray($attrKey, $attrData);
92
        } else {
93 3
            $attrKey = $factory->createAttribute($domainKey, $config);
94
        }
95 4
        $result->addAttribute([
96 4
            _ATTR::ID->column() => $attrKey,
97 4
            _ATTR::NAME->column() => $config[_ATTR::NAME->column()]
98 4
        ]);
99
100 4
        return $attrKey;
101
    }
102
103 4
    public function handlePivot(int $attrKey, int $groupKey) : int
104
    {
105 4
        $result = $this->getResult();
106 4
        $domainKey = $result->getDomainKey();
107 4
        $setKey = $result->getSetKey();
108 4
        $pivotModel = $this->makePivotModel();
109 4
        $factory = $this->makeEavFactory();
110 4
        $pivotRecord = $pivotModel->findOne($domainKey, $setKey, $groupKey, $attrKey);
111 4
        if($pivotRecord === false)
0 ignored issues
show
introduced by
The condition $pivotRecord === false is always false.
Loading history...
112 3
            $pivotKey = $factory->createPivot($domainKey, $setKey, $groupKey, $attrKey);
113
        else
114 1
            $pivotKey = $pivotRecord[_PIVOT::ID->column()];
115 4
        $result->addPivot($attrKey, $pivotKey);
116 4
        return $pivotKey;
117
    }
118
119 2
    public function handleValue(ATTR_TYPE $type, int $entityKey, int $attrKey, mixed $value)
120
    {
121 2
        $result = $this->getResult();
122 2
        $valueModel = $this->makeValueModel();
123 2
        $valueParser = $this->makeValueParser();
124 2
        $domainKey = $result->getDomainKey();
125 2
        $valueTable = $type->valueTable();
126
127 2
        $record = $valueModel->find($valueTable, $domainKey, $entityKey, $attrKey);
128 2
        if($record === false) {
0 ignored issues
show
introduced by
The condition $record === false is always false.
Loading history...
129 1
            $key = $valueModel->create($valueTable, $domainKey, $entityKey, $attrKey, $valueParser->parse($type, $value));
130
        } else {
131 1
            $key = $record[_VALUE::ID->column()];
132 1
            $valueModel->update($valueTable, $domainKey, $entityKey, $attrKey, $valueParser->parse($type, $value));
133
        }
134 2
        $result->addValue($attrKey, $key);
135 2
        return $key;
136
    }
137
138 7
    private function handleField(array $field)
139
    {
140 7
        $result = $this->getResult();
141 7
        $entityKey = $result->getEntityKey();
142
143 7
        if (!key_exists(ATTR_FACTORY::ATTRIBUTE->field(), $field)) {
144 1
            EntityFactoryException::undefinedAttributeArray();
145
        }
146 6
        $attrConfig = $field[ATTR_FACTORY::ATTRIBUTE->field()];
147 6
        if (!key_exists(_ATTR::NAME->column(), $attrConfig)) {
148 1
            AttributeException::undefinedAttributeName();
149
        }
150 5
        if (!key_exists(_ATTR::TYPE->column(), $attrConfig)) {
151 1
            AttributeException::undefinedAttributeType();
152
        }
153
154 4
        $attrType = ATTR_TYPE::getCase($attrConfig[_ATTR::TYPE->column()]);
155 3
        $attrKey = $this->handleAttribute($attrConfig);
156 3
        $this->handlePivot($attrKey, $field[ATTR_FACTORY::GROUP->field()]);
157
158 3
        if(isset($field[ATTR_FACTORY::VALUE->field()]))
159 1
            $this->handleValue($attrType, $entityKey, $attrKey, $field[ATTR_FACTORY::VALUE->field()]);
160
    }
161
}
162