Completed
Push — develop ( bcbf28...a87a8b )
by Nate
03:33
created

UserTypeRelationship::insertCollection()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 9
ccs 0
cts 8
cp 0
rs 9.9666
c 0
b 0
f 0
cc 2
nc 2
nop 2
crap 6
1
<?php
2
3
/**
4
 * @copyright  Copyright (c) Flipbox Digital Limited
5
 * @license    https://flipboxfactory.com/software/organization/license
6
 * @link       https://www.flipboxfactory.com/software/organization/
7
 */
8
9
namespace flipbox\organizations\relationships;
10
11
use craft\helpers\ArrayHelper;
12
use craft\helpers\Json;
13
use flipbox\craft\ember\helpers\QueryHelper;
14
use flipbox\organizations\Organizations;
15
use flipbox\organizations\queries\UserTypeAssociationQuery;
16
use flipbox\organizations\records\OrganizationType;
17
use flipbox\organizations\records\OrganizationTypeAssociation;
18
use flipbox\organizations\records\UserAssociation;
19
use flipbox\organizations\records\UserType;
20
use flipbox\organizations\records\UserTypeAssociation;
21
use Tightenco\Collect\Support\Collection;
22
23
/**
24
 * Manages User Types associated to Organization/User associations
25
 *
26
 * @author Flipbox Factory <[email protected]>
27
 * @since 2.0.0
28
 *
29
 * @property UserTypeAssociation[] $associations
30
 *
31
 * @method UserTypeAssociation findOrCreate($object)
32
 * @method UserTypeAssociation findOne($object = null)
33
 * @method UserTypeAssociation findOrFail($object)
34
 */
35
class UserTypeRelationship implements RelationshipInterface
36
{
37
    use RelationshipTrait {
38
        reset as parentReset;
39
        newRelations as parentSetCache;
40
        addToRelations as parentAddToCache;
41
        removeFromRelations as parentRemoveFromCache;
42
    }
43
44
    /**
45
     * @var UserAssociation
46
     */
47
    private $association;
48
49
    /**
50
     * @param UserAssociation $association
51
     */
52
    public function __construct(UserAssociation $association)
53
    {
54
        $this->association = $association;
55
    }
56
57
58
    /************************************************************
59
     * COLLECTION
60
     ************************************************************/
61
62
    /**
63
     * Get a collection of associated organizations
64
     *
65
     * @return Collection
66
     */
67
    public function getCollection(): Collection
68
    {
69
        return $this->getRelationships()
70
            ->sortBy('sortOrder')
71
            ->pluck('type');
72
    }
73
74
    /**
75
     * @return Collection
76
     */
77
    protected function existingRelationships(): Collection
78
    {
79
        return new Collection(
80
            $this->query()
81
                ->with('typeRecord')
82
                ->all()
83
        );
84
    }
85
86
    /************************************************************
87
     * QUERY
88
     ************************************************************/
89
90
    /**
91
     * @inheritDoc
92
     * @return UserTypeAssociationQuery
93
     */
94
    protected function query(): UserTypeAssociationQuery
95
    {
96
        return UserTypeAssociation::find()
97
            ->setUserId($this->association->getId() ?: false)
98
            ->orderBy([
99
                'sortOrder' => SORT_ASC
100
            ])
101
            ->limit(null);
102
    }
103
104
    /**
105
     * @param UserTypeAssociation|UserType|int|string $type
106
     * @return UserTypeAssociation
107
     */
108
    protected function create($type): UserTypeAssociation
109
    {
110
        if ($type instanceof UserTypeAssociation) {
111
            return $type;
112
        }
113
114
        $association = (new UserTypeAssociation())
115
            ->setType($this->resolveObject($type));
116
117
        $association->userId = $this->association->id;
118
119
        return $association;
120
    }
121
122
    /**
123
     * Reset associations
124
     */
125
    public function reset(): RelationshipInterface
126
    {
127
        unset($this->association->typeRecords);
128
        return $this->parentReset();
129
    }
130
131
132
    /*******************************************
133
     * SAVE
134
     *******************************************/
135
136
    /**
137
     * @inheritDoc
138
     */
139
    protected function delta(): array
140
    {
141
        $existingAssociations = $this->query()
142
            ->indexBy('typeId')
143
            ->all();
144
145
        $associations = [];
146
        $order = 1;
147
        foreach ($this->getRelationships() as $newAssociation) {
148
            if (null === ($association = ArrayHelper::remove(
149
                $existingAssociations,
150
                $newAssociation->typeId
151
            ))) {
152
                $association = $newAssociation;
153
            }
154
155
            $association->sortOrder = $order++;
156
157
            $association->ignoreSortOrder();
158
159
            $associations[] = $association;
160
        }
161
162
        return [$associations, $existingAssociations];
163
    }
164
165
166
    /*******************************************
167
     * COLLECTION UTILS
168
     *******************************************/
169
170
    /**
171
     * @inheritDoc
172
     */
173
    protected function insertCollection(Collection $collection, UserTypeAssociation $association)
174
    {
175
        if ($association->sortOrder > 0) {
176
            $collection->splice($association->sortOrder - 1, 0, [$association]);
177
            return;
178
        }
179
180
        $collection->push($association);
181
    }
182
183
    /**
184
     * @inheritDoc
185
     */
186
    protected function updateCollection(Collection $collection, UserTypeAssociation $association)
187
    {
188
        if ($key = $this->findKey($association)) {
189
            $collection->offsetUnset($key);
190
        }
191
192
        $this->insertCollection($collection, $association);
193
    }
194
195
196
    /*******************************************
197
     * CACHE
198
     *******************************************/
199
200
    /**
201
     * @param array $associations
202
     * @return static
203
     */
204
    protected function newRelations(array $associations): self
205
    {
206
        $this->parentSetCache($associations);
207
        $this->syncToRelations();
208
209
        return $this;
210
    }
211
212
    /**
213
     * @param $association
214
     * @return static
215
     */
216
    protected function addToRelations($association): self
217
    {
218
        $this->parentAddToCache($association);
219
        $this->syncToRelations();
220
221
        return $this;
222
    }
223
224
    /**
225
     * @param int $key
226
     * @return static
227
     */
228
    protected function removeFromRelations(int $key): self
229
    {
230
        $this->parentRemoveFromCache($key);
231
        $this->syncToRelations();
232
233
        return $this;
234
    }
235
236
    /*******************************************
237
     * UTILS
238
     *******************************************/
239
240
    /**
241
     * @return $this
242
     */
243
    protected function syncToRelations()
244
    {
245
        $this->association->populateRelation(
246
            'typeRecords',
247
            $this->getRelationships()->pluck('type')->all()
248
        );
249
        return $this;
250
    }
251
252
    /**
253
     * @param UserTypeAssociation|UserType|int|array|null $object
254
     * @return int|null
255
     */
256
    protected function findKey($object = null)
257
    {
258
        if ($object instanceof OrganizationTypeAssociation) {
259
            return $this->findRelationshipKey($object->getTypeId());
260
        }
261
262
        if (null === ($type = $this->resolveObject($object))) {
263
            return null;
264
        }
265
266
        return $this->findRelationshipKey($type->id);
267
    }
268
269
    /**
270
     * @param $identifier
271
     * @return int|string|null
272
     */
273
    protected function findRelationshipKey($identifier)
274
    {
275
        /** @var UserTypeAssociation $association */
276
        foreach ($this->getRelationships()->all() as $key => $association) {
277
            if ($association->getTypeId() == $identifier) {
278
                return $key;
279
            }
280
        }
281
282
        return null;
283
    }
284
285
    /**
286
     * @param UserTypeAssociation|UserType|int|array|null $type
287
     * @return UserType|null
288
     */
289
    protected function resolveObjectInternal($type)
290
    {
291
        if ($type instanceof UserTypeAssociation) {
292
            return $type->getType();
293
        }
294
295
        if ($type instanceof UserType) {
296
            return $type;
297
        }
298
299
        return UserType::findOne($type);
300
    }
301
}
302