Completed
Push — master ( 5d951f...f67c03 )
by Nate
13:58 queued 11:06
created

Users::init()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 8
ccs 0
cts 7
cp 0
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 5
nc 1
nop 0
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\services;
10
11
use Craft;
12
use craft\elements\User as UserElement;
13
use craft\helpers\ArrayHelper;
14
use flipbox\ember\services\traits\elements\Accessor;
15
use flipbox\organizations\db\OrganizationQuery;
16
use flipbox\organizations\elements\Organization as OrganizationElement;
17
use flipbox\organizations\Organizations as OrganizationPlugin;
18
use flipbox\organizations\records\UserAssociation;
19
use yii\base\Component;
20
use yii\base\InvalidConfigException;
21
22
/**
23
 * @author Flipbox Factory <[email protected]>
24
 * @since 1.0.0
25
 *
26
 * @method UserElement parentFind($identifier)
27
 */
28
class Users extends Component
29
{
30
    use Accessor {
31
        find as parentFind;
32
    }
33
34
    /**
35
     * @inheritdoc
36
     */
37
    public function init()
38
    {
39
        $settings = OrganizationPlugin::getInstance()->getSettings();
40
        $this->cacheDuration = $settings->usersCacheDuration;
41
        $this->cacheDependency = $settings->usersCacheDependency;
42
43
        parent::init();
44
    }
45
46
    /**
47
     * @inheritdoc
48
     */
49
    public static function elementClass(): string
50
    {
51
        return UserElement::class;
52
    }
53
54
    /**
55
     * @param $identifier
56
     * @return array
57
     */
58
    protected function identifierCondition($identifier): array
59
    {
60
        $base = [
61
            'status' => null
62
        ];
63
64
        if (is_array($identifier)) {
65
            return array_merge($base, $identifier);
66
        }
67
68
        if (!is_numeric($identifier) && is_string($identifier)) {
69
            $base['where'] = [
70
                'or',
71
                ['username' => $identifier],
72
                ['email' => $identifier]
73
            ];
74
        } else {
75
            $base['id'] = $identifier;
76
        }
77
78
        return $base;
79
    }
80
81
    /**
82
     * @param mixed $user
83
     * @return UserElement
84
     * @throws InvalidConfigException
85
     */
86
    public function resolve($user = 'CURRENT_USER')
87
    {
88
        if (is_array($user) &&
89
            null !== ($id = ArrayHelper::getValue($user, 'id'))
90
        ) {
91
            return Craft::$app->getUsers()->getUserById($id);
92
        }
93
94
        if ($object = $this->find($user)) {
95
            return $object;
96
        }
97
98
        return $this->create($user);
99
    }
100
101
    /*******************************************
102
     * FIND
103
     *******************************************/
104
105
    /**
106
     * @param mixed $identifier
107
     * @return UserElement|null
108
     */
109
    public function find($identifier = 'CURRENT_USER')
110
    {
111
        if ('CURRENT_USER' === $identifier) {
112
            return Craft::$app->getUser()->getIdentity();
113
        }
114
115
        return $this->parentFind($identifier);
116
    }
117
118
    /**
119
     * @param OrganizationQuery $query
120
     * @param UserElement $user
121
     * @return bool
122
     * @throws \Exception
123
     */
124
    public function saveAssociations(
125
        OrganizationQuery $query,
126
        UserElement $user
127
    ): bool {
128
        /** @var UserElement[] $models */
129
        if (null === ($models = $query->getCachedResult())) {
130
            return true;
131
        }
132
133
        $models = $query->all();
134
135
        $associationService = OrganizationPlugin::getInstance()->getUserOrganizationAssociations();
136
137
        $query = $associationService->getQuery([
138
            $associationService::SOURCE_ATTRIBUTE => $user->getId() ?: false
139
        ]);
140
141
        $query->setCachedResult(
142
            $this->toAssociations($models, $user->getId())
143
        );
144
145
        return $associationService->save($query);
146
    }
147
148
    /**
149
     * @param OrganizationQuery $query
150
     * @param UserElement $user
151
     * @return bool
152
     * @throws \Exception
153
     */
154
    public function dissociate(
155
        OrganizationQuery $query,
156
        UserElement $user
157
    ): bool {
158
        return $this->associations(
159
            $query,
160
            $user,
161
            [
162
                OrganizationPlugin::getInstance()->getUserOrganizationAssociations(),
163
                'dissociate'
164
            ]
165
        );
166
    }
167
168
    /**
169
     * @param OrganizationQuery $query
170
     * @param UserElement $user
171
     * @return bool
172
     * @throws \Exception
173
     */
174
    public function associate(
175
        OrganizationQuery $query,
176
        UserElement $user
177
    ): bool {
178
        return $this->associations(
179
            $query,
180
            $user,
181
            [
182
                OrganizationPlugin::getInstance()->getUserOrganizationAssociations(),
183
                'associate'
184
            ]
185
        );
186
    }
187
188
    /**
189
     * @param OrganizationQuery $query
190
     * @param UserElement $user
191
     * @param callable $callable
192
     * @return bool
193
     */
194
    protected function associations(
195
        OrganizationQuery $query,
196
        UserElement $user,
197
        callable $callable
198
    ) {
199
        /** @var UserElement[] $models */
200
        if (null === ($models = $query->getCachedResult())) {
201
            return true;
202
        }
203
204
        $models = ArrayHelper::index($models, 'id');
205
206
        $success = true;
207
        $ids = [];
208
        $count = count($models);
209
        $i = 0;
210
        foreach ($this->toAssociations($models, $user->getId()) as $association) {
211
            if (true === call_user_func_array($callable, [$association, ++$i === $count])) {
212
                ArrayHelper::remove($models, $association->userId);
213
                $ids[] = $association->userId;
214
                continue;
215
            }
216
217
            $success = false;
218
        }
219
220
        $query->id($ids);
221
222
        if ($success === false) {
223
            $query->setCachedResult($models);
224
        }
225
226
        return $success;
227
    }
228
229
    /**
230
     * @param OrganizationElement[] $organizations
231
     * @param int $userId
232
     * @return UserAssociation[]
233
     */
234
    private function toAssociations(
235
        array $organizations,
236
        int $userId
237
    ) {
238
        $associations = [];
239
        $sortOrder = 1;
240
241
        $associationService = OrganizationPlugin::getInstance()->getUserOrganizationAssociations();
242
        $sortOrderAttribute = $associationService::SORT_ORDER_ATTRIBUTE;
243
244
        $existingAssociations = $associationService->findAllByCriteria([
245
            'where' => [
246
                $associationService::SOURCE_ATTRIBUTE => ArrayHelper::getColumn($organizations, 'id'),
247
                $associationService::TARGET_ATTRIBUTE => $userId,
248
            ],
249
            'indexBy' => $associationService::SOURCE_ATTRIBUTE
250
        ]);
251
252
        foreach ($organizations as $organization) {
253
            if (null === ($association = ArrayHelper::remove($existingAssociations, $organization->getId()))) {
254
                $association = $associationService->create([
255
                    'userId' => (int)$userId,
256
                    'organizationId' => (int)$organization->getId()
257
                ]);
258
            }
259
260
            $association->{$sortOrderAttribute} = $sortOrder++;
261
            $associations[] = $association;
262
        }
263
264
        return $associations;
265
    }
266
}
267