Passed
Push — master ( 17e6cc...350d8b )
by Aleksandr
41:29 queued 06:24
created

EntityFactory::handleField()   A

Complexity

Conditions 5
Paths 16

Size

Total Lines 22
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 5

Importance

Changes 0
Metric Value
cc 5
eloc 14
nc 16
nop 1
dl 0
loc 22
ccs 14
cts 14
cp 1
crap 5
rs 9.4888
c 0
b 0
f 0
1
<?php
2
/**
3
 * This file is part of the eav package.
4
 *
5
 * @author    Alex Kuperwood <[email protected]>
6
 * @copyright 2025 Alex Kuperwood
7
 * @license   https://opensource.org/license/mit  The MIT License
8
 */
9
declare(strict_types=1);
10
11
namespace Kuperwood\Eav\Factory;
12
13
use Kuperwood\Eav\Enum\_ATTR;
14
use Kuperwood\Eav\Enum\_PIVOT;
15
use Kuperwood\Eav\Enum\_VALUE;
16
use Kuperwood\Eav\Enum\ATTR_FACTORY;
17
use Kuperwood\Eav\Enum\ATTR_TYPE;
18
use Kuperwood\Eav\Exception\AttributeException;
19
use Kuperwood\Eav\Exception\EntityFactoryException;
20
use Kuperwood\Eav\Result\EntityFactoryResult;
21
use Kuperwood\Eav\Traits\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)) {
61 1
                throw new EntityFactoryException("Group key must be provided!");
62
            }
63
        }
64 9
        $groups = array_unique(array_column($fields, ATTR_FACTORY::GROUP));
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], $domainKey);
81 4
        if (!is_bool($record)) {
82 1
            $attrKey = $record[_ATTR::ID];
83 1
            $attrData = array_intersect_key($config, [
84 1
                _ATTR::NAME => null,
85 1
                _ATTR::TYPE => null,
86 1
                _ATTR::STRATEGY => null,
87 1
                _ATTR::SOURCE => null,
88 1
                _ATTR::DEFAULT_VALUE => null,
89 1
                _ATTR::DESCRIPTION => 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 => $attrKey,
97 4
            _ATTR::NAME => $config[_ATTR::NAME]
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)
112 3
            $pivotKey = $factory->createPivot($domainKey, $setKey, $groupKey, $attrKey);
113
        else {
114 1
            $pivotKey = $pivotRecord[_PIVOT::ID];
115
        }
116
117 4
        $result->addPivot($attrKey, $pivotKey);
118 4
        return $pivotKey;
119
    }
120
121
    /**
122
     * @throws \Exception
123
     */
124 2
    public function handleValue($type, int $entityKey, int $attrKey, $value)
125
    {
126 2
        $result = $this->getResult();
127 2
        $valueModel = $this->makeValueModel();
128 2
        $domainKey = $result->getDomainKey();
129 2
130
        $record = $valueModel->find($type, $domainKey, $entityKey, $attrKey);
131 2
        if($record === false) {
132 2
            $key = $valueModel->create($type, $domainKey, $entityKey, $attrKey, $value);
133 1
        } else {
134
            $key = $record[_VALUE::ID];
135 1
            $valueModel->update($type, $domainKey, $entityKey, $attrKey, $value);
136 1
        }
137
        $result->addValue($attrKey, $key);
138 2
        return $key;
139 2
    }
140
141
    private function handleField(array $field)
142 7
    {
143
        $result = $this->getResult();
144 7
        $entityKey = $result->getEntityKey();
145 7
146
        if (!key_exists(ATTR_FACTORY::ATTRIBUTE, $field)) {
147 7
            EntityFactoryException::undefinedAttributeArray();
148 1
        }
149
        $attrConfig = $field[ATTR_FACTORY::ATTRIBUTE];
150 6
        if (!key_exists(_ATTR::NAME, $attrConfig)) {
151 6
            AttributeException::undefinedAttributeName();
152 1
        }
153
        if (!key_exists(_ATTR::TYPE, $attrConfig)) {
154 5
            AttributeException::undefinedAttributeType();
155 1
        }
156
157
        $attrType = ATTR_TYPE::getCase($attrConfig[_ATTR::TYPE]);
158 4
        $attrKey = $this->handleAttribute($attrConfig);
159 3
        $this->handlePivot($attrKey, $field[ATTR_FACTORY::GROUP]);
160 3
161
        if(isset($field[ATTR_FACTORY::VALUE]))
162 3
            $this->handleValue($attrType, $entityKey, $attrKey, $field[ATTR_FACTORY::VALUE]);
163 1
    }
164
}
165