Completed
Push — master ( 9f24e3...f5ae7e )
by Alex
16s queued 12s
created

EntityGubbins   A

Complexity

Total Complexity 33

Size/Duplication

Total Lines 229
Duplicated Lines 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
wmc 33
eloc 64
c 3
b 0
f 0
dl 0
loc 229
rs 9.76

17 Methods

Rating   Name   Duplication   Size   Complexity  
A getOdataResourceType() 0 3 1
A getStubs() 0 3 1
A getName() 0 3 1
A setOdataResourceType() 0 7 2
A setFields() 0 22 6
A getKeyFields() 0 3 1
A setStubs() 0 10 3
A setClassName() 0 3 1
A getClassName() 0 3 1
A getFields() 0 3 1
A setName() 0 3 1
A getFieldNames() 0 7 2
A resolveAssociation() 0 3 2
A isOK() 0 6 1
A addAssociation() 0 16 6
A getAssociations() 0 3 1
A getAssociationNames() 0 7 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AlgoWeb\PODataLaravel\Models\ObjectMap\Entities;
6
7
use AlgoWeb\PODataLaravel\Models\ObjectMap\Entities\Associations\Association;
8
use AlgoWeb\PODataLaravel\Models\ObjectMap\Entities\Associations\AssociationMonomorphic;
9
use AlgoWeb\PODataLaravel\Models\ObjectMap\Entities\Associations\AssociationStubBase;
10
use AlgoWeb\PODataLaravel\Models\ObjectMap\Entities\Associations\AssociationStubPolymorphic;
11
use POData\Common\InvalidOperationException;
12
use POData\Providers\Metadata\ResourceEntityType;
13
14
class EntityGubbins
15
{
16
    /**
17
     * @var string
18
     */
19
    private $name;
20
21
    /**
22
     * @var string
23
     */
24
    private $className;
25
26
    /**
27
     * @var EntityField[]
28
     */
29
    private $keyFields = [];
30
31
    /**
32
     * @var EntityField[] keyed by name
33
     */
34
    private $fields = [];
35
36
    /**
37
     * @var AssociationStubBase[]
38
     */
39
    private $stubs = [];
40
41
    /**
42
     * @var Association[]
43
     */
44
    private $associations = [];
45
    /**
46
     * @var ResourceEntityType
47
     */
48
    private $odataResourceType;
49
50
    /**
51
     * @return ResourceEntityType
52
     */
53
    public function getOdataResourceType(): ?ResourceEntityType
54
    {
55
        return $this->odataResourceType;
56
    }
57
58
    /**
59
     * @param ResourceEntityType $odataType
60
     */
61
    public function setOdataResourceType(ResourceEntityType $odataType): void
62
    {
63
        if ($odataType->isAbstract()) {
64
            $msg = 'OData resource entity type must be concrete';
65
            throw new \InvalidArgumentException($msg);
66
        }
67
        $this->odataResourceType = $odataType;
68
    }
69
70
    /**
71
     * @return string
72
     */
73
    public function getName(): ?string
74
    {
75
        return $this->name;
76
    }
77
78
    /**
79
     * @param string $name
80
     */
81
    public function setName($name): void
82
    {
83
        $this->name = $name;
84
    }
85
86
    /**
87
     * @return string
88
     */
89
    public function getClassName(): ?string
90
    {
91
        return $this->className;
92
    }
93
94
    /**
95
     * @param string $className
96
     */
97
    public function setClassName($className): void
98
    {
99
        $this->className = $className;
100
    }
101
102
    /**
103
     * @return EntityField[]
104
     */
105
    public function getKeyFields(): array
106
    {
107
        return $this->keyFields;
108
    }
109
110
    /**
111
     * @return EntityField[]
112
     */
113
    public function getFields(): array
114
    {
115
        return $this->fields;
116
    }
117
118
    /**
119
     * @param  EntityField[] $fields
120
     * @throws \Exception
121
     */
122
    public function setFields(array $fields): void
123
    {
124
        if (0 == count($fields)) {
125
            $msg = 'Fields array must not be empty for ' . $this->getClassName();
126
            throw new \Exception($msg);
127
        }
128
        $keys = [];
129
        foreach ($fields as $propName => $field) {
130
            if (!$field instanceof EntityField) {
131
                $msg = 'Fields array must only have EntityField objects for ' . $this->getClassName();
132
                throw new \Exception($msg);
133
            }
134
            if ($field->getIsKeyField()) {
135
                $keys[$propName] = $field;
136
            }
137
        }
138
        if (0 == count($keys)) {
139
            $msg = 'No key field supplied in fields array for ' . $this->getClassName();
140
            throw new \Exception($msg);
141
        }
142
        $this->fields    = $fields;
143
        $this->keyFields = $keys;
144
    }
145
146
    /**
147
     * @return AssociationStubBase[]
148
     */
149
    public function getStubs(): array
150
    {
151
        return $this->stubs;
152
    }
153
154
    /**
155
     * @param  AssociationStubBase[] $stubs
156
     * @throws \Exception
157
     */
158
    public function setStubs(array $stubs): void
159
    {
160
        foreach ($stubs as $field) {
161
            if (!$field instanceof AssociationStubBase) {
162
                $msg = 'Stubs array must only have AssociationStubBase objects';
163
                throw new \Exception($msg);
164
            }
165
            $field->setEntity($this);
166
        }
167
        $this->stubs = $stubs;
168
    }
169
170
    /**
171
     * @param  Association               $association
172
     * @param  bool                      $isFirst
173
     * @throws InvalidOperationException
174
     */
175
    public function addAssociation(Association $association, $isFirst = true): void
176
    {
177
        if ($association instanceof AssociationMonomorphic) {
178
            $stub = $isFirst ? $association->getFirst() : $association->getLast();
179
            // $stub is required to be not null, as getFirst and getLast return type hints prohibit returning null
180
            $exists = in_array($stub, $this->stubs);
181
182
            if (!($exists || ($stub instanceof AssociationStubPolymorphic))) {
183
                throw new \InvalidArgumentException('Association cannot be connected to this entity');
184
            }
185
            $propertyName = $stub->getRelationName();
186
        }
187
        if (empty($propertyName)) {
188
            throw new InvalidOperationException('');
189
        }
190
        $this->associations[$propertyName] = $association;
191
    }
192
193
    /**
194
     * @return String[]
195
     */
196
    protected function getFieldNames(): array
197
    {
198
        $fieldNames = [];
199
        foreach ($this->fields as $field) {
200
            $fieldNames[] = $field->getName();
201
        }
202
        return $fieldNames;
203
    }
204
205
    /**
206
     * @return String[]
207
     */
208
    protected function getAssociationNames(): array
209
    {
210
        $associationNames = [];
211
        foreach ($this->stubs as $stub) {
212
            $associationNames[] = $stub->getRelationName();
213
        }
214
        return $associationNames;
215
    }
216
217
    /**
218
     * @return Associations\Association[]
219
     */
220
    public function getAssociations(): array
221
    {
222
        return $this->associations;
223
    }
224
225
    /**
226
     * @param string $relName
227
     * @return Association|null
228
     */
229
    public function resolveAssociation($relName): ?Association
230
    {
231
        return array_key_exists($relName, $this->associations) ? $this->associations[$relName] : null;
232
    }
233
234
    /**
235
     * @return bool
236
     */
237
    public function isOK(): bool
238
    {
239
        $fieldNames       = $this->getFieldNames();
240
        $associationNames = $this->getAssociationNames();
241
        $intersection     = array_intersect($fieldNames, $associationNames);
242
        return 0 === count($intersection);
243
    }
244
}
245