Passed
Push — master ( 56d139...0769f1 )
by Aleksandr
02:20
created

EntityFactory::makeNewResult()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
ccs 0
cts 3
cp 0
crap 2
rs 10
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
    private function makeNewResult() : EntityFactoryResult
30
    {
31
        $this->result = new EntityFactoryResult();
32
        return $this->result;
33
    }
34
35
    private function getResult() : EntityFactoryResult
36
    {
37
        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
    private function validateFields(array $fields) : void
55
    {
56
        $result = $this->getResult();
57
        $groupModel = $this->makeGroupModel();
58
        $setKey = $result->getSetKey();
59
        foreach($fields as $field) {
60
            if (!key_exists(ATTR_FACTORY::GROUP->field(), $field)) {
61
                throw new EntityFactoryException("Group key must be provided!");
62
            }
63
        }
64
        $groups = array_unique(array_column($fields, ATTR_FACTORY::GROUP->field()));
65
        foreach($groups as $groupKey)
66
        {
67
            if(!$groupModel->checkGroupInAttributeSet($setKey, $groupKey))
68
            {
69
                throw new EntityFactoryException("This group is not belongs to attribute set");
70
            }
71
        }
72
    }
73
74
    private function handleAttribute($config) : int
75
    {
76
        $result = $this->getResult();
77
        $domainKey = $result->getDomainKey();
78
        $factory = $this->makeEavFactory();
79
        $attributeModel = $this->makeAttributeModel();
80
        $record = $attributeModel->findByName($config[_ATTR::NAME->column()], $domainKey);
81
        if (!is_bool($record)) {
0 ignored issues
show
introduced by
The condition is_bool($record) is always false.
Loading history...
82
            $attrKey = $record[_ATTR::ID->column()];
83
            $attrData = array_intersect_key([
84
                _ATTR::NAME->column() => null,
85
                _ATTR::TYPE->column() => null,
86
                _ATTR::STRATEGY->column() => null,
87
                _ATTR::SOURCE->column() => null,
88
                _ATTR::DEFAULT_VALUE->column() => null,
89
                _ATTR::DESCRIPTION->column() => null
90
            ], $config);
91
            $attributeModel->updateByArray($attrKey, $attrData);
92
        } else {
93
            $attrKey = $factory->createAttribute($domainKey, $config);
94
        }
95
        $result->addAttribute([
96
            _ATTR::ID->column() => $attrKey,
97
            _ATTR::NAME->column() => $config[_ATTR::NAME->column()]
98
        ]);
99
100
        return $attrKey;
101
    }
102
103
    private function handlePivot(int $attrKey, int $groupKey) : int
104
    {
105
        $result = $this->getResult();
106
        $domainKey = $result->getDomainKey();
107
        $setKey = $result->getSetKey();
108
        $pivotModel = $this->makePivotModel();
109
        $factory = $this->makeEavFactory();
110
        $pivotRecord = $pivotModel->findOne($domainKey, $setKey, $groupKey, $attrKey);
111
        if($pivotRecord === false)
0 ignored issues
show
introduced by
The condition $pivotRecord === false is always false.
Loading history...
112
            $pivotKey = $factory->createPivot($domainKey, $setKey, $groupKey, $attrKey);
113
        else
114
            $pivotKey = $pivotRecord[_PIVOT::ID->column()];
115
        $result->addPivot($attrKey, $pivotKey);
116
        return $pivotKey;
117
    }
118
119
    private function handleValue(ATTR_TYPE $type, int $entityKey, int $attrKey, mixed $value)
120
    {
121
        $result = $this->getResult();
122
        $valueModel = $this->makeValueModel();
123
        $valueParser = $this->makeValueParser();
124
        $domainKey = $result->getDomainKey();
125
        $valueTable = $type->valueTable();
126
127
        $record = $valueModel->find($valueTable, $domainKey, $entityKey, $attrKey);
128
        if($record === false) {
0 ignored issues
show
introduced by
The condition $record === false is always false.
Loading history...
129
            $key = $valueModel->create($valueTable, $domainKey, $entityKey, $attrKey, $valueParser->parse($type, $value));
130
        } else {
131
            $key = $record[_VALUE::ID->column()];
132
            $valueModel->update($valueTable, $domainKey, $entityKey, $attrKey, $valueParser->parse($type, $value));
133
        }
134
        $result->addValue($attrKey, $key);
135
        return $key;
136
    }
137
138
    private function handleField(array $field)
139
    {
140
        $result = $this->getResult();
141
        $entityKey = $result->getEntityKey();
142
143
        if (!key_exists(ATTR_FACTORY::ATTRIBUTE->field(), $field)) {
144
            EntityFactoryException::undefinedAttributeArray();
145
        }
146
        $attrConfig = $field[ATTR_FACTORY::ATTRIBUTE->field()];
147
        if (!key_exists(_ATTR::NAME->column(), $attrConfig)) {
148
            AttributeException::undefinedAttributeName();
149
        }
150
        if (!key_exists(_ATTR::TYPE->column(), $attrConfig)) {
151
            AttributeException::undefinedAttributeType();
152
        }
153
154
        $attrType = ATTR_TYPE::getCase($attrConfig[_ATTR::TYPE->column()]);
155
        $attrKey = $this->handleAttribute($attrConfig);
156
        $this->handlePivot($attrKey, $field[ATTR_FACTORY::GROUP->field()]);
157
158
        if(isset($field[ATTR_FACTORY::VALUE->field()]))
159
            $this->handleValue($attrType, $entityKey, $attrKey, $field[ATTR_FACTORY::VALUE->field()]);
160
    }
161
}
162