UserAssociation::afterSave()   B
last analyzed

Complexity

Conditions 6
Paths 20

Size

Total Lines 46

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

Changes 0
Metric Value
dl 0
loc 46
ccs 0
cts 27
cp 0
rs 8.5559
c 0
b 0
f 0
cc 6
nc 20
nop 2
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\records;
10
11
use Craft;
12
use flipbox\craft\ember\helpers\ModelHelper;
13
use flipbox\craft\ember\records\ActiveRecord;
14
use flipbox\craft\ember\records\IdAttributeTrait;
15
use flipbox\craft\ember\records\SortableTrait;
16
use flipbox\craft\ember\records\UserAttributeTrait;
17
use flipbox\organizations\relationships\RelationshipInterface;
18
use flipbox\organizations\relationships\UserTypeRelationship;
19
use flipbox\organizations\Organizations;
20
use flipbox\organizations\queries\UserAssociationQuery;
21
use yii\db\ActiveQueryInterface;
22
use yii\helpers\Json;
23
24
/**
25
 * @author Flipbox Factory <[email protected]>
26
 * @since 1.0.0
27
 *
28
 * @property int $organizationId
29
 * @property int $organizationOrder The order which an organization lists its users
30
 * @property int $userOrder The order which a user lists its organizations
31
 * @property string $state The user state
32
 * @property Organization $organization
33
 * @property UserType[] $typeRecords
34
 */
35
class UserAssociation extends ActiveRecord
36
{
37
38
    const STATE_ACTIVE = 'active';
39
    const STATE_PENDING = 'pending';
40
    const STATE_INACTIVE = 'inactive';
41
    const STATE_INVITED = 'invited';
42
43
    use SortableTrait,
44
        UserAttributeTrait,
45
        IdAttributeTrait,
46
        OrganizationAttributeTrait;
47
48
    /**
49
     * The table name
50
     */
51
    const TABLE_ALIAS = Organization::TABLE_ALIAS . '_user_associations';
52
53
    /**
54
     * Whether associated types should be saved
55
     *
56
     * @var bool
57
     */
58
    private $saveTypes = true;
59
60
    /**
61
     * @inheritdoc
62
     */
63
    protected $getterPriorityAttributes = ['userId', 'organizationId'];
64
65
    /**
66
     * @var RelationshipInterface
67
     */
68
    private $manager;
69
70
    /**
71
     * @return static
72
     */
73
    public function withTypes(): self
74
    {
75
        $this->saveTypes = true;
76
        return $this;
77
    }
78
79
    /**
80
     * @return static
81
     */
82
    public function withoutTypes(): self
83
    {
84
        $this->saveTypes = false;
85
        return $this;
86
    }
87
88
    /**
89
     * @inheritdoc
90
     */
91
    public function init()
92
    {
93
        parent::init();
94
95
        // Default state
96
        if (empty($this->state)) {
97
            $this->state = Organizations::getInstance()->getSettings()->getDefaultUserState();
98
        }
99
    }
100
101
    /**
102
     * @noinspection PhpDocMissingThrowsInspection
103
     *
104
     * @inheritdoc
105
     * @return UserAssociationQuery
106
     */
107
    public static function find()
108
    {
109
        /** @noinspection PhpUnhandledExceptionInspection */
110
        /** @noinspection PhpIncompatibleReturnTypeInspection */
111
        return Craft::createObject(UserAssociationQuery::class, [get_called_class()]);
112
    }
113
114
    /**
115
     * @return array
116
     */
117
    public function rules()
118
    {
119
        return array_merge(
120
            parent::rules(),
121
            $this->idRules(),
122
            $this->userRules(),
123
            $this->organizationRules(),
124
            [
125
                [
126
                    [
127
                        'userId',
128
                        'organizationId',
129
                        'state'
130
                    ],
131
                    'required'
132
                ],
133
                [
134
                    [
135
                        'state'
136
                    ],
137
                    'in',
138
                    'range' => array_keys(Organizations::getInstance()->getSettings()->getUserStates())
139
                ],
140
                [
141
                    [
142
                        'state'
143
                    ],
144
                    'default',
145
                    'value' => Organizations::getInstance()->getSettings()->getDefaultUserState()
146
                ],
147
                [
148
                    [
149
                        'userOrder',
150
                        'organizationOrder'
151
                    ],
152
                    'number',
153
                    'integerOnly' => true
154
                ],
155
                [
156
                    [
157
                        'userId',
158
                        'organizationId'
159
                    ],
160
                    'safe',
161
                    'on' => [
162
                        ModelHelper::SCENARIO_DEFAULT
0 ignored issues
show
Deprecated Code introduced by
The constant flipbox\craft\ember\help...elper::SCENARIO_DEFAULT has been deprecated with message: Use `yii\base\Model::SCENARIO_DEFAULT`

This class constant 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 constant will be removed from the class and what other constant to use instead.

Loading history...
163
                    ]
164
                ]
165
            ]
166
        );
167
    }
168
169
    /**
170
     * @inheritdoc
171
     */
172
    public function beforeSave($insert)
173
    {
174
        if (Organizations::getInstance()->getSettings()->getEnforceUserSortOrder()) {
175
            $this->ensureSortOrder(
176
                [
177
                    'userId' => $this->userId
178
                ],
179
                'organizationOrder'
180
            );
181
        }
182
183
        if (Organizations::getInstance()->getSettings()->getEnforceOrganizationSortOrder()) {
184
            $this->ensureSortOrder(
185
                [
186
                    'organizationId' => $this->organizationId
187
                ],
188
                'userOrder'
189
            );
190
        }
191
192
        return parent::beforeSave($insert);
193
    }
194
195
    /**
196
     * @inheritdoc
197
     * @throws \yii\db\Exception
198
     */
199
    public function afterSave($insert, $changedAttributes)
200
    {
201
        try {
202
            if (Organizations::getInstance()->getSettings()->getEnforceUserSortOrder()) {
203
                $this->autoReOrder(
204
                    'userId',
205
                    [
206
                        'organizationId' => $this->organizationId
207
                    ],
208
                    'userOrder'
209
                );
210
            }
211
212
            if (Organizations::getInstance()->getSettings()->getEnforceOrganizationSortOrder()) {
213
                $this->autoReOrder(
214
                    'organizationId',
215
                    [
216
                        'userId' => $this->userId
217
                    ],
218
                    'organizationOrder'
219
                );
220
            }
221
        } catch (\Exception $e) {
222
            Organizations::error(
223
                sprintf(
224
                    "Exception caught while trying to reorder '%s'. Exception: [%s].",
225
                    (string)get_class($this),
226
                    (string)Json::encode([
227
                        'Trace' => $e->getTraceAsString(),
228
                        'File' => $e->getFile(),
229
                        'Line' => $e->getLine(),
230
                        'Code' => $e->getCode(),
231
                        'Message' => $e->getMessage()
232
                    ])
233
                ),
234
                __METHOD__
235
            );
236
        }
237
238
        // Save types if they've also been altered
239
        if (true === $this->saveTypes && $this->getTypes()->isMutated()) {
240
            $this->getTypes()->save();
241
        }
242
243
        parent::afterSave($insert, $changedAttributes);
244
    }
245
246
    /**
247
     * @inheritdoc
248
     * @throws \yii\db\Exception
249
     */
250
    public function afterDelete()
251
    {
252
        if (Organizations::getInstance()->getSettings()->getEnforceOrganizationSortOrder()) {
253
            $this->sequentialOrder(
254
                'organizationId',
255
                [
256
                    'userId' => $this->userId
257
                ],
258
                'organizationOrder'
259
            );
260
        }
261
262
        if (Organizations::getInstance()->getSettings()->getEnforceUserSortOrder()) {
263
            $this->sequentialOrder(
264
                'userId',
265
                [
266
                    'organizationId' => $this->organizationId
267
                ],
268
                'userOrder'
269
            );
270
        }
271
272
        parent::afterDelete();
273
    }
274
275
    /**
276
     * @return ActiveQueryInterface
277
     */
278
    public function getTypeRecords(): ActiveQueryInterface
279
    {
280
        /** @noinspection PhpUndefinedMethodInspection */
281
        return $this->hasMany(UserType::class, ['id' => 'typeId'])
282
            ->viaTable(
283
                UserTypeAssociation::tableName(),
284
                ['userId' => 'id']
285
            );
286
    }
287
288
    /**
289
     * @return UserTypeRelationship|RelationshipInterface
290
     */
291
    public function getTypes(): RelationshipInterface
292
    {
293
        if (null === $this->manager) {
294
            $this->manager = new UserTypeRelationship($this);
295
        }
296
297
        return $this->manager;
298
    }
299
300
301
    /************************************************************
302
     * RELATIONS
303
     ************************************************************/
304
305
    /**
306
     * We're using an alias so 'types' can be used to retrieve relations
307
     *
308
     * @inheritDoc
309
     */
310
    public function getRelation($name, $throwException = true)
311
    {
312
        if ($name === 'types') {
313
            $name = 'typeRecords';
314
        }
315
316
        return parent::getRelation($name);
317
    }
318
319
    /**
320
     * We're using an alias so 'types' is converted to 'typeRecords'
321
     *
322
     * @inheritDoc
323
     */
324
    public function populateRelation($name, $records)
325
    {
326
        if ($name === 'types') {
327
            $name = 'typeRecords';
328
        }
329
330
        parent::populateRelation($name, $records);
331
    }
332
}
333