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

UserRelationship::resolveUser()   B

Complexity

Conditions 6
Paths 5

Size

Total Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

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