Passed
Pull Request — master (#226)
by Christopher
03:55
created

AssociationStubBase::setForeignFieldName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 1
1
<?php declare(strict_types=1);
2
3
namespace AlgoWeb\PODataLaravel\Models\ObjectMap\Entities\Associations;
4
5
use AlgoWeb\PODataLaravel\Models\ObjectMap\Entities\EntityField;
6
use AlgoWeb\PODataLaravel\Models\ObjectMap\Entities\EntityGubbins;
7
8
abstract class AssociationStubBase
9
{
10
    /**
11
     * @var AssociationStubRelationType
12
     */
13
    protected $multiplicity;
14
15
    /**
16
     * Foreign key field of this end of relation.
17
     *
18
     * @var string|null
19
     */
20
    protected $keyFieldName;
21
22
    /**
23
     * A list of fields to Traverse between Keyfield and foreignField.
24
     *
25
     * @var string[]
26
     */
27
    protected $throughFieldChain;
28
29
    /**
30
     * Foreign key field of other end of relation.
31
     *
32
     * @var string|null
33
     */
34
    protected $foreignFieldName;
35
36
    /**
37
     * @var string|null
38
     */
39
    protected $relationName;
40
41
    /**
42
     * Target type this relation points to, if known.  Is null for known-side polymorphic relations.
43
     *
44
     * @var string|null
45
     */
46
    protected $targType;
47
48
    /**
49
     * Base type this relation is attached to.
50
     *
51
     * @var string|null
52
     */
53
    protected $baseType;
54
55
    /**
56
     * Any assocations this stub is a member of.
57
     *
58
     * @var Association[]
59
     */
60
    protected $associations = [];
61
62
    /**
63
     * @var EntityGubbins the entity this stub lives on
64
     */
65
    protected $entity;
66
67
    /**
68
     * Sets the entity owning this AssocationStub.
69
     *
70
     * @param EntityGubbins $entity
71
     */
72
    public function setEntity(EntityGubbins $entity): void
73
    {
74
        $this->entity = $entity;
75
    }
76
77
    /**
78
     * Gets the entity owning this AssocationStub.
79
     *
80
     * @return EntityGubbins
81
     */
82
    public function getEntity(): EntityGubbins
83
    {
84
        return $this->entity;
85
    }
86
    /**
87
     * Adds this stub as a member of an assocation.
88
     *
89
     * @param Association $newAssocation the new assocation to be a member of
90
     */
91
    public function addAssociation(Association $newAssocation): void
92
    {
93
        $this->associations[spl_object_hash($newAssocation)] = $newAssocation;
94
    }
95
96
    /**
97
     * Gets all assocations assigned to this stub.
98
     *
99
     * @return Association[] All assocations this stub is a member of
100
     */
101
    public function getAssociations(): array
102
    {
103
        return array_values($this->associations);
104
    }
105
106
    /**
107
     * @return string
108
     */
109
    public function getRelationName()
110
    {
111
        return $this->relationName;
112
    }
113
114
    /**
115
     * @param string $relationName
116
     */
117
    public function setRelationName($relationName)
118
    {
119
        $this->relationName = $this->checkStringInput($relationName) ? $relationName : $this->relationName;
120
    }
121
122
    /**
123
     * @return AssociationStubRelationType
124
     */
125
    public function getMultiplicity()
126
    {
127
        return $this->multiplicity;
128
    }
129
130
    /**
131
     * @param AssociationStubRelationType $multiplicity
132
     */
133
    public function setMultiplicity(AssociationStubRelationType $multiplicity)
134
    {
135
        $this->multiplicity = $multiplicity;
136
    }
137
138
    /**
139
     * @return string
140
     */
141
    public function getKeyFieldName(): string
142
    {
143
        return $this->keyFieldName ?? '';
144
    }
145
146
    public function getKeyField() : ?EntityField
147
    {
148
        return $this->entity->getFields()[$this->getKeyFieldName()];
149
    }
150
151
    /**
152
     * @param string $keyFieldName
153
     */
154
    public function setKeyFieldName($keyFieldName)
155
    {
156
        $this->keyFieldName = $this->checkStringInput($keyFieldName) ? $keyFieldName : $this->keyFieldName;
157
    }
158
159
    public function isCompatible(AssociationStubBase $otherStub)
160
    {
161
        if ($this->morphicType() != $otherStub->morphicType()) {
162
            return false;
163
        }
164
165
        if (!$this->isOk()) {
166
            return false;
167
        }
168
        if (!$otherStub->isOk()) {
169
            return false;
170
        }
171
        return count($this->getThroughFieldChain()) === count($otherStub->getThroughFieldChain());
172
    }
173
174
    /**
175
     * Is this AssociationStub sane?
176
     */
177
    public function isOk()
178
    {
179
        if (null === $this->multiplicity) {
180
            return false;
181
        }
182
        if (null === $this->relationName) {
183
            return false;
184
        }
185
        if (null === $this->keyFieldName) {
186
            return false;
187
        }
188
        if (null === $this->baseType) {
189
            return false;
190
        }
191
        $targType = $this->targType;
192
        if ($this instanceof AssociationStubMonomorphic && null === $targType) {
193
            return false;
194
        }
195
        $foreignField = $this->foreignFieldName;
196
        if (null !== $targType) {
197
            if (!$this->checkStringInput($targType)) {
198
                return false;
199
            }
200
            if (!$this->checkStringInput($foreignField)) {
201
                return false;
202
            }
203
        }
204
205
        if (null === $this->throughFieldChain) {
206
            return false;
207
        }
208
        return (null === $targType) === (null === $foreignField);
209
    }
210
211
    /**
212
     * @return string
213
     */
214
    public function getTargType()
215
    {
216
        return $this->targType;
217
    }
218
219
    /**
220
     * @param string $targType
221
     */
222
    public function setTargType($targType)
223
    {
224
        $this->targType = $targType;
225
    }
226
227
    /**
228
     * @return string
229
     */
230
    public function getBaseType()
231
    {
232
        return $this->baseType;
233
    }
234
235
    /**
236
     * @param string $baseType
237
     */
238
    public function setBaseType($baseType)
239
    {
240
        $this->baseType = $this->checkStringInput($baseType) ? $baseType : $this->baseType;
241
    }
242
243
    /**
244
     * @return string
245
     */
246
    public function getForeignFieldName()
247
    {
248
        return $this->foreignFieldName;
249
    }
250
251
    /**
252
     * @param string $foreignFieldName
253
     */
254
    public function setForeignFieldName($foreignFieldName)
255
    {
256
        $this->foreignFieldName = $foreignFieldName;
257
    }
258
259
    /**
260
     * @return string[]|null
261
     */
262
    public function getThroughFieldChain(): array
263
    {
264
        return $this->throughFieldChain;
265
    }
266
267
    /**
268
     * @param string[]|null $keyChain
269
     */
270
    public function setThroughFieldChain(?array $keyChain)
271
    {
272
        $this->throughFieldChain = $keyChain;
273
    }
274
    /**
275
     * Supply a canonical sort ordering to determine order in associations.
276
     *
277
     * @param AssociationStubBase $other
278
     *
279
     * @return int
280
     */
281
    public function compare(AssociationStubBase $other)
282
    {
283
        $thisFirst  = $this->getKeyFieldName() === '' ? false : $this->getKeyField()->getIsKeyField();
284
        $otherFirst = $other->getKeyFieldName() === '' ? false : $other->getKeyField()->getIsKeyField();
285
        if (
286
            ($thisFirst || $otherFirst) &&
287
            !($thisFirst && $otherFirst)
288
            ) {
289
            return $thisFirst ? -1 : 1;
290
        }
291
        $cmps = [
292
            [get_class($this), get_class($other)],
293
            [$this->getBaseType() ?? '', $other->getBaseType() ?? ''],
294
            [$this->getRelationName() ?? '', $other->getRelationName() ?? ''],
295
        ];
296
        foreach($cmps as $cmpvals){
297
            $cmp = strcmp($cmpvals[0], $cmpvals[1]);
298
            if(0 !== $cmp){
299
                return $cmp / abs($cmp);
300
            }
301
        }
302
        return 0;
303
    }
304
305
    /**
306
     * Return what type of stub this is - polymorphic, monomorphic, or something else.
307
     *
308
     * @return string
309
     */
310
    abstract public function morphicType();
311
312
    /**
313
     * @param $input
314
     * @return bool
315
     */
316
    private function checkStringInput($input)
317
    {
318
        if (null === $input || !is_string($input) || empty($input)) {
319
            return false;
320
        }
321
        return true;
322
    }
323
}
324