Completed
Push — develop ( e5b284...0f5a88 )
by Nate
05:39
created

UserTypeRelationship::removeFromRelations()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 7
ccs 0
cts 6
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 2
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\UserAssociation;
17
use flipbox\organizations\records\UserType;
18
use flipbox\organizations\records\UserTypeAssociation;
19
use Tightenco\Collect\Support\Collection;
20
21
/**
22
 * Manages User Types associated to Organization/User associations
23
 *
24
 * @author Flipbox Factory <[email protected]>
25
 * @since 2.0.0
26
 *
27
 * @property UserTypeAssociation[] $associations
28
 *
29
 * @method UserTypeAssociation findOrCreate($object)
30
 * @method UserTypeAssociation findOne($object = null)
31
 * @method UserTypeAssociation findOrFail($object)
32
 */
33
class UserTypeRelationship implements RelationshipInterface
34
{
35
    use RelationshipTrait {
36
        reset as parentReset;
37
        newRelations as parentSetCache;
38
        addToRelations as parentAddToCache;
39
        removeFromRelations as parentRemoveFromCache;
40
    }
41
42
    /**
43
     * @var UserAssociation
44
     */
45
    private $association;
46
47
    /**
48
     * @param UserAssociation $association
49
     */
50
    public function __construct(UserAssociation $association)
51
    {
52
        $this->association = $association;
53
    }
54
55
56
    /************************************************************
57
     * COLLECTION
58
     ************************************************************/
59
60
    /**
61
     * Get a collection of associated organizations
62
     *
63
     * @return Collection
64
     */
65
    public function getCollection(): Collection
66
    {
67
        return Collection::make(
68
            $this->association->typeRecords
69
        );
70
    }
71
72
73
    /************************************************************
74
     * QUERY
75
     ************************************************************/
76
77
    /**
78
     * @inheritDoc
79
     * @return UserTypeAssociationQuery
80
     */
81
    protected function query(array $criteria = []): UserTypeAssociationQuery
82
    {
83
        $query = UserTypeAssociation::find()
84
            ->setUserId($this->association->getId() ?: false)
85
            ->orderBy([
86
                'sortOrder' => SORT_ASC
87
            ]);
88
89
        if (!empty($criteria)) {
90
            QueryHelper::configure(
91
                $query,
92
                $criteria
93
            );
94
        }
95
96
        return $query;
97
    }
98
99
    /**
100
     * @param UserTypeAssociation|UserType|int|string $type
101
     * @return UserTypeAssociation
102
     */
103
    protected function create($type): UserTypeAssociation
104
    {
105
        $association = (new UserTypeAssociation())
106
            ->setType($this->resolveType($type));
107
108
        $association->userId = $this->association->id;
109
110
        return $association;
111
    }
112
113
    /**
114
     * Reset associations
115
     */
116
    public function reset(): RelationshipInterface
117
    {
118
        unset($this->association->typeRecords);
119
        return $this->parentReset();
120
    }
121
122
123
    /*******************************************
124
     * SAVE
125
     *******************************************/
126
127
    /**
128
     * @inheritDoc
129
     */
130
    protected function associationDelta(): array
131
    {
132
        $existingAssociations = $this->query()
133
            ->indexBy('typeId')
134
            ->all();
135
136
        $associations = [];
137
        $order = 1;
138
        foreach ($this->getRelationships() as $newAssociation) {
139
            if (null === ($association = ArrayHelper::remove(
140
                    $existingAssociations,
141
                    $newAssociation->typeId
142
                ))) {
143
                $association = $newAssociation;
144
            }
145
146
            $association->sortOrder = $order++;
147
148
            $associations[] = $association;
149
        }
150
151
        return [$associations, $existingAssociations];
152
    }
153
154
    /**
155
     * @inheritDoc
156
     */
157
    protected function handleAssociationError()
158
    {
159
        $this->association->addError('types', 'Unable to save organization types.');
160
    }
161
162
163
    /*******************************************
164
     * CACHE
165
     *******************************************/
166
167
    /**
168
     * @param array $associations
169
     * @return static
170
     */
171
    protected function newRelations(array $associations): self
172
    {
173
        $this->parentSetCache($associations);
174
        $this->syncToRelations();
175
176
        return $this;
177
    }
178
179
    /**
180
     * @param $association
181
     * @return static
182
     */
183
    protected function addToRelations($association): self
184
    {
185
        $this->parentAddToCache($association);
186
        $this->syncToRelations();
187
188
        return $this;
189
    }
190
191
    /**
192
     * @param int $key
193
     * @return static
194
     */
195
    protected function removeFromRelations(int $key): self
196
    {
197
        $this->parentRemoveFromCache($key);
198
        $this->syncToRelations();
199
200
        return $this;
201
    }
202
203
    /*******************************************
204
     * UTILS
205
     *******************************************/
206
207
    /**
208
     * @return $this
209
     */
210
    protected function syncToRelations()
211
    {
212
        $this->association->populateRelation(
213
            'typeRecords',
214
            $this->getRelationships()->pluck('type')->all()
215
        );
216
        return $this;
217
    }
218
219
    /**
220
     * @param UserTypeAssociation|UserType|int|array|null $type
221
     * @return int|null
222
     */
223
    protected function findKey($type = null)
224
    {
225
        if (null === ($record = $this->resolveType($type))) {
226
            Organizations::info(sprintf(
227
                "Unable to resolve user association type: %s",
228
                (string)Json::encode($type)
229
            ));
230
            return null;
231
        }
232
233
        foreach ($this->getRelationships() as $key => $association) {
234
            if ($association->getTypeId() == $record->id) {
235
                return $key;
236
            }
237
        }
238
239
        return null;
240
    }
241
242
    /**
243
     * @param UserTypeAssociation|UserType|int|array|null $type
244
     * @return UserType|null
245
     */
246
    protected function resolveType($type = null)
247
    {
248
249
        if (null === $type) {
250
            return null;
251
        }
252
253
        if ($type instanceof UserTypeAssociation) {
254
            return $type->getType();
255
        }
256
257
        if ($type instanceof UserType) {
258
            return $type;
259
        }
260
261
        if (is_array($type) &&
262
            null !== ($id = ArrayHelper::getValue($type, 'id'))
263
        ) {
264
            $type = ['id' => $id];
265
        }
266
267
        return UserType::findOne($type);
268
    }
269
}
270