Completed
Push — develop ( eed049...0ceb6c )
by Nate
01:42
created

UserRelationship::getCollection()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 25

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 25
ccs 0
cts 21
cp 0
rs 9.52
c 0
b 0
f 0
cc 2
nc 2
nop 0
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;
12
use craft\elements\db\UserQuery;
13
use craft\elements\User;
14
use craft\helpers\ArrayHelper;
15
use craft\helpers\Json;
16
use flipbox\craft\ember\helpers\QueryHelper;
17
use flipbox\organizations\behaviors\OrganizationsAssociatedToUserBehavior;
18
use flipbox\organizations\elements\Organization;
19
use flipbox\organizations\Organizations;
20
use flipbox\organizations\queries\UserAssociationQuery;
21
use flipbox\organizations\records\UserAssociation;
22
use Tightenco\Collect\Support\Collection;
23
24
/**
25
 * Manages Users associated to Organizations
26
 *
27
 * @author Flipbox Factory <[email protected]>
28
 * @since 2.0.0
29
 *
30
 * @method UserAssociation findOrCreate($object)
31
 * @method UserAssociation findOne($object = null)
32
 * @method UserAssociation findOrFail($object)
33
 */
34
class UserRelationship implements RelationshipInterface
35
{
36
    use RelationshipTrait;
37
38
    /**
39
     * @var Organization
40
     */
41
    private $organization;
42
43
    /**
44
     * @param Organization $organization
45
     */
46
    public function __construct(Organization $organization)
47
    {
48
        $this->organization = $organization;
49
    }
50
51
52
    /************************************************************
53
     * COLLECTION
54
     ************************************************************/
55
56
    /**
57
     * Get a collection of associated users
58
     *
59
     * @return User[]|Collection
60
     */
61
    public function getCollection(): Collection
62
    {
63
        /** @var UserQuery $query */
64
        /** @noinspection PhpUndefinedMethodInspection */
65
        $query = User::find()
66
            ->organization($this->organization)
67
            ->orderBy([
68
                'userOrder' => SORT_ASC,
69
                'username' => SORT_ASC,
70
            ]);
71
72
        if (null === $this->collection) {
73
            return Collection::make(
74
                $query->all()
75
            );
76
        };
77
78
        return Collection::make(
79
            $query
80
                ->id($this->collection->sortBy('userOrder')->pluck('userId'))
81
                ->fixedOrder(true)
82
                ->limit(null)
83
                ->all()
84
        );
85
    }
86
87
88
    /************************************************************
89
     * QUERY
90
     ************************************************************/
91
92
    /**
93
     * @param array $criteria
94
     * @return UserAssociationQuery
95
     */
96
    protected function query(array $criteria = []): UserAssociationQuery
97
    {
98
        /** @noinspection PhpUndefinedMethodInspection */
99
        $query = UserAssociation::find()
100
            ->setOrganizationId($this->organization->getId() ?: false)
0 ignored issues
show
Security Bug introduced by
It seems like $this->organization->getId() ?: false can also be of type false; however, flipbox\organizations\qu...it::setOrganizationId() does only seem to accept string|array<integer,str...nts\Organization>>|null, did you maybe forget to handle an error condition?
Loading history...
101
            ->orderBy([
102
                'userOrder' => SORT_ASC
103
            ]);
104
105
        if (!empty($criteria)) {
106
            QueryHelper::configure(
107
                $query,
108
                $criteria
109
            );
110
        }
111
112
        return $query;
113
    }
114
115
    /**
116
     * @param $object
117
     * @return UserAssociation
118
     */
119
    protected function create($object): UserAssociation
120
    {
121
        return (new UserAssociation())
122
            ->setOrganization($this->organization)
123
            ->setUser($this->resolveUser($object));
124
    }
125
126
    /**
127
     * @inheritDoc
128
     *
129
     * @param bool $addToUser
130
     */
131
    public function addOne($object, array $attributes = [], bool $addToUser = false): RelationshipInterface
132
    {
133
        if (null === ($association = $this->findOne($object))) {
134
            $association = $this->create($object);
135
            $this->addToCollection($association);
136
        }
137
138
        if (!empty($attributes)) {
139
            Craft::configure(
140
                $association,
141
                $attributes
142
            );
143
        }
144
145
        // Add user to user as well?
146
        if ($addToUser && null !== ($use = $association->getUser())) {
147
            /** @var OrganizationsAssociatedToUserBehavior $use */
148
            $use->getOrganizations()->add($this->organization);
149
        }
150
151
        return $this;
152
    }
153
154
155
    /*******************************************
156
     * SAVE
157
     *******************************************/
158
159
    /**
160
     * @inheritDoc
161
     */
162
    protected function associationDelta(): array
163
    {
164
        $existingAssociations = $this->query()
165
            ->indexBy('userId')
166
            ->all();
167
168
        $associations = [];
169
        $order = 1;
170
        /** @var UserAssociation $newAssociation */
171
        foreach ($this->getRelationships()->sortBy('userOrder') as $newAssociation) {
172
            if (null === ($association = ArrayHelper::remove(
173
                $existingAssociations,
174
                $newAssociation->getUserId()
175
            ))) {
176
                $association = $newAssociation;
177
            } elseif ($newAssociation->getTypes()->isMutated()) {
178
                /** @var UserAssociation $association */
179
                $association->getTypes()->clear()->add(
180
                    $newAssociation->getTypes()->getCollection()
181
                );
182
            }
183
184
            $association->userOrder = $order++;
185
            $association->organizationOrder = $newAssociation->organizationOrder;
186
            $association->state = $newAssociation->state;
187
188
            $associations[] = $association;
189
        }
190
191
        return [$associations, $existingAssociations];
192
    }
193
194
    /**
195
     * @inheritDoc
196
     */
197
    protected function handleAssociationError()
198
    {
199
        $this->organization->addError('users', 'Unable to save user organizations.');
200
    }
201
202
203
    /*******************************************
204
     * UTILS
205
     *******************************************/
206
207
    /**
208
     * @param UserAssociation|User|int|array|null $object
209
     * @return int|null
210
     */
211
    protected function findKey($object = null)
212
    {
213
        if (null === ($element = $this->resolveUser($object))) {
214
            Organizations::info(sprintf(
215
                "Unable to resolve user: %s",
216
                (string)Json::encode($object)
217
            ));
218
            return null;
219
        }
220
221
        foreach ($this->findAll() as $key => $association) {
0 ignored issues
show
Deprecated Code introduced by
The method flipbox\organizations\re...ionshipTrait::findAll() has been deprecated with message: use `getCollection()`

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
222
            if (null !== $association->getUser() && $association->getUser()->email == $element->email) {
223
                return $key;
224
            }
225
        }
226
227
        return null;
228
    }
229
230
    /**
231
     * @param UserAssociation|User|int|array|null $user
232
     * @return User|null
233
     */
234
    protected function resolveUser($user = null)
235
    {
236
        if (null === $user) {
237
            return null;
238
        }
239
240
        if ($user instanceof UserAssociation) {
241
            return $user->getUser();
242
        }
243
244
        if ($user instanceof User) {
245
            return $user;
246
        }
247
248
        if (is_array($user) &&
249
            null !== ($id = ArrayHelper::getValue($user, 'id'))
250
        ) {
251
            $user = ['id' => $id];
252
        }
253
254
        return User::findOne($user);
255
    }
256
}
257