Completed
Push — develop ( e9f396...2b8a13 )
by Nate
04:23
created

dissociateMany()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
dl 0
loc 14
ccs 0
cts 11
cp 0
rs 9.7998
c 0
b 0
f 0
cc 3
nc 4
nop 1
crap 12
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\objects;
10
11
use craft\elements\User;
12
use craft\helpers\ArrayHelper;
13
use craft\helpers\Json;
14
use flipbox\craft\ember\helpers\QueryHelper;
15
use flipbox\organizations\elements\Organization;
16
use flipbox\organizations\Organizations;
17
use flipbox\organizations\queries\UserAssociationQuery;
18
use flipbox\organizations\records\UserAssociation;
19
use yii\db\QueryInterface;
20
21
/**
22
 * @author Flipbox Factory <[email protected]>
23
 * @since 1.0.0
24
 */
25
class OrganizationsAssociatedToUserManager
26
{
27
    use UserAssociationManagerTrait;
28
29
    /**
30
     * @var User
31
     */
32
    private $user;
33
34
    /**
35
     * @param User $user
36
     */
37
    public function __construct(User $user)
38
    {
39
        $this->user = $user;
40
    }
41
42
    /**
43
     * @param array $criteria
44
     * @return UserAssociationQuery
45
     */
46
    public function query(array $criteria = []): UserAssociationQuery
47
    {
48
        /** @noinspection PhpUndefinedMethodInspection */
49
        $query = UserAssociation::find()
50
            ->setUserId($this->user->getId() ?: false)
0 ignored issues
show
Security Bug introduced by
It seems like $this->user->getId() ?: false can also be of type false; however, flipbox\craft\ember\quer...ibuteTrait::setUserId() does only seem to accept string|array<integer,str...ft\elements\User>>|null, did you maybe forget to handle an error condition?
Loading history...
51
            ->orderBy([
52
                'organizationOrder' => SORT_ASC
53
            ]);
54
55
        if (!empty($criteria)) {
56
            QueryHelper::configure(
57
                $query,
58
                $criteria
59
            );
60
        }
61
62
        return $query;
63
    }
64
65
    /**
66
     * @param $object
67
     * @return UserAssociation
68
     */
69
    public function create($object): UserAssociation
70
    {
71
        return (new UserAssociation())
72
            ->setOrganization($this->resolveOrganization($object))
73
            ->setUser($this->user);
74
    }
75
76
77
    /*******************************************
78
     * ASSOCIATE and/or DISASSOCIATE
79
     *******************************************/
80
81
    /**
82
     * @return bool
83
     * @throws \Throwable
84
     * @throws \yii\db\StaleObjectException
85
     */
86
    public function save(): bool
87
    {
88
        // No changes?
89
        if (!$this->isMutated()) {
90
            return true;
91
        }
92
93
        $success = true;
94
95
        $existingAssociations = $this->query()
96
            ->indexBy('organizationId')
97
            ->all();
98
99
        $associations = [];
100
        foreach ($this->findAll() as $newAssociation) {
101
            if (null === ($association = ArrayHelper::remove(
102
                $existingAssociations,
103
                $newAssociation->getOrganizationId()
104
            ))) {
105
                $association = $newAssociation;
106
            }
107
108
            $association->userOrder = $newAssociation->userOrder;
109
            $association->organizationOrder = $newAssociation->organizationOrder;
110
111
            $associations[] = $association;
112
        }
113
114
        // Delete those removed
115
        foreach ($existingAssociations as $existingAssociation) {
116
            if (!$existingAssociation->delete()) {
117
                $success = false;
118
            }
119
        }
120
121
        $order = 1;
122
        foreach ($associations as $association) {
123
            $association->organizationOrder = $order++;
124
125
            if (!$association->save()) {
126
                $success = false;
127
            }
128
        }
129
130
        $this->associations = $associations;
131
132
        if (!$success) {
133
            $this->user->addError('organizations', 'Unable to save user organizations.');
134
        }
135
136
        return $success;
137
    }
138
139
    /*******************************************
140
     * ASSOCIATE
141
     *******************************************/
142
143
    /**
144
     * @param $object
145
     * @param int|null $sortOrder
146
     * @return bool
147
     */
148
    public function associateOne($object, int $sortOrder = null): bool
149
    {
150
        $association = $this->findOrCreate($object);
151
152
        if (null !== $sortOrder) {
153
            $association->organizationOrder = $sortOrder;
154
        }
155
156
        if (!$association->save()) {
157
            $this->user->addError('organizations', 'Unable to associate organization.');
158
159
            return false;
160
        }
161
162
        $this->reset();
163
164
        return true;
165
    }
166
167
    /**
168
     * @param QueryInterface|Organization[] $objects
169
     * @return bool
170
     * @throws \Throwable
171
     */
172
    public function associateMany($objects): bool
173
    {
174
        if ($objects instanceof QueryInterface) {
175
            $objects = $objects->all();
176
        }
177
178
        if (empty($objects)) {
179
            return true;
180
        }
181
182
        $this->addMany($objects);
183
184
        return $this->save();
185
    }
186
187
188
    /*******************************************
189
     * DISSOCIATE
190
     *******************************************/
191
192
    /**
193
     * @param $object
194
     * @return bool
195
     * @throws \Throwable
196
     * @throws \yii\db\StaleObjectException
197
     */
198
    public function dissociateOne($object): bool
199
    {
200
        if (null === ($association = $this->findOne($object))) {
201
            return true;
202
        }
203
204
        if (!$association->delete()) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $association->delete() of type false|integer is loosely compared to false; this is ambiguous if the integer can be zero. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
205
            $this->user->addError('organizations', 'Unable to dissociate organization.');
206
207
            return false;
208
        }
209
210
        $this->removeOne($association);
211
212
        return true;
213
    }
214
215
    /**
216
     * @param QueryInterface|Organization[] $objects
217
     * @return bool
218
     * @throws \Throwable
219
     */
220
    public function dissociateMany($objects): bool
221
    {
222
        if ($objects instanceof QueryInterface) {
223
            $objects = $objects->all();
224
        }
225
226
        if (empty($objects)) {
227
            return true;
228
        }
229
230
        $this->removeMany($objects);
231
232
        return $this->save();
233
    }
234
235
    /**
236
     * @param UserAssociation|Organization|int|array|null $object
237
     * @return int|null
238
     */
239
    protected function findKey($object = null)
240
    {
241
        if (null === ($element = $this->resolveOrganization($object))) {
242
            Organizations::info(sprintf(
243
                "Unable to resolve organization: %s",
244
                (string)Json::encode($object)
245
            ));
246
            return null;
247
        }
248
249
        foreach ($this->findAll() as $key => $association) {
250
            if ($association->getOrganizationId() === $element->getId()) {
251
                return $key;
252
            }
253
        }
254
255
        return null;
256
    }
257
258
    /**
259
     * @param UserAssociation|Organization|int|array|null $organization
260
     * @return Organization|null
261
     */
262
    protected function resolveOrganization($organization = null)
263
    {
264
        if (null === $organization) {
265
            return null;
266
        }
267
268
        if ($organization instanceof UserAssociation) {
269
            return $organization->getOrganization();
270
        }
271
272
        if ($organization instanceof Organization) {
273
            return $organization;
274
        }
275
276
        if (is_array($organization) &&
277
            null !== ($id = ArrayHelper::getValue($organization, 'id'))
278
        ) {
279
            $organization = ['id' => $id];
280
        }
281
282
        return Organization::findOne($organization);
283
    }
284
}
285