Completed
Push — master ( 9e4a5a...eed049 )
by Nate
09:38 queued 08:13
created

UserAssociation::afterSave()   B

Complexity

Conditions 5
Paths 20

Size

Total Lines 46

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 0
Metric Value
dl 0
loc 46
ccs 0
cts 27
cp 0
rs 8.867
c 0
b 0
f 0
cc 5
nc 20
nop 2
crap 30
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\managers\RelationshipManagerInterface;
18
use flipbox\organizations\managers\UserTypeRelationshipManager;
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[] $types
34
 */
35
class UserAssociation extends ActiveRecord
36
{
37
    const STATE_ACTIVE = 'active';
38
    const STATE_PENDING = 'pending';
39
    const STATE_INACTIVE = 'inactive';
40
41
    use SortableTrait,
42
        UserAttributeTrait,
43
        IdAttributeTrait,
44
        OrganizationAttributeTrait;
45
46
    /**
47
     * The table name
48
     */
49
    const TABLE_ALIAS = Organization::TABLE_ALIAS . '_user_associations';
50
51
    /**
52
     * Whether associated types should be saved
53
     *
54
     * @var bool
55
     */
56
    private $saveTypes = true;
57
58
    /**
59
     * @inheritdoc
60
     */
61
    protected $getterPriorityAttributes = ['userId', 'organizationId'];
62
63
    /**
64
     * @var RelationshipManagerInterface
65
     */
66
    private $manager;
67
68
    /**
69
     * @return RelationshipManagerInterface
70
     */
71
    public function getTypeManager(): RelationshipManagerInterface
72
    {
73
        if (null === $this->manager) {
74
            $this->manager = new UserTypeRelationshipManager($this);
75
        }
76
77
        return $this->manager;
78
    }
79
80
    /**
81
     * @return static
82
     */
83
    public function withTypes(): self
84
    {
85
        $this->saveTypes = false;
86
        return $this;
87
    }
88
89
    /**
90
     * @return static
91
     */
92
    public function withoutTypes(): self
93
    {
94
        $this->saveTypes = true;
95
        return $this;
96
    }
97
98
    /**
99
     * @inheritdoc
100
     */
101
    public function init()
102
    {
103
        parent::init();
104
105
        // Default state
106
        if (empty($this->state)) {
107
            $this->state = Organizations::getInstance()->getSettings()->getDefaultUserState();
108
        }
109
    }
110
111
    /**
112
     * @noinspection PhpDocMissingThrowsInspection
113
     *
114
     * @inheritdoc
115
     * @return UserAssociationQuery
116
     */
117
    public static function find()
118
    {
119
        /** @noinspection PhpUnhandledExceptionInspection */
120
        /** @noinspection PhpIncompatibleReturnTypeInspection */
121
        return Craft::createObject(UserAssociationQuery::class, [get_called_class()]);
122
    }
123
124
    /**
125
     * @return array
126
     */
127
    public function rules()
128
    {
129
        return array_merge(
130
            parent::rules(),
131
            $this->idRules(),
132
            $this->userRules(),
133
            $this->organizationRules(),
134
            [
135
                [
136
                    [
137
                        'userId',
138
                        'organizationId',
139
                        'state'
140
                    ],
141
                    'required'
142
                ],
143
                [
144
                    [
145
                        'state'
146
                    ],
147
                    'in',
148
                    'range' => array_keys(Organizations::getInstance()->getSettings()->getUserStates())
149
                ],
150
                [
151
                    [
152
                        'state'
153
                    ],
154
                    'default',
155
                    'value' => Organizations::getInstance()->getSettings()->getDefaultUserState()
156
                ],
157
                [
158
                    [
159
                        'userOrder',
160
                        'organizationOrder'
161
                    ],
162
                    'number',
163
                    'integerOnly' => true
164
                ],
165
                [
166
                    [
167
                        'userId',
168
                        'organizationId'
169
                    ],
170
                    'safe',
171
                    'on' => [
172
                        ModelHelper::SCENARIO_DEFAULT
173
                    ]
174
                ]
175
            ]
176
        );
177
    }
178
179
    /**
180
     * @inheritdoc
181
     */
182
    public function beforeSave($insert)
183
    {
184
        if (Organizations::getInstance()->getSettings()->getEnforceUserSortOrder()) {
185
            $this->ensureSortOrder(
186
                [
187
                    'userId' => $this->userId
188
                ],
189
                'organizationOrder'
190
            );
191
        }
192
193
        if (Organizations::getInstance()->getSettings()->getEnforceOrganizationSortOrder()) {
194
            $this->ensureSortOrder(
195
                [
196
                    'organizationId' => $this->organizationId
197
                ],
198
                'userOrder'
199
            );
200
        }
201
202
        return parent::beforeSave($insert);
203
    }
204
205
    /**
206
     * @inheritdoc
207
     * @throws \yii\db\Exception
208
     */
209
    public function afterSave($insert, $changedAttributes)
210
    {
211
        try {
212
            if (Organizations::getInstance()->getSettings()->getEnforceUserSortOrder()) {
213
                $this->autoReOrder(
214
                    'userId',
215
                    [
216
                        'organizationId' => $this->organizationId
217
                    ],
218
                    'userOrder'
219
                );
220
            }
221
222
            if (Organizations::getInstance()->getSettings()->getEnforceOrganizationSortOrder()) {
223
                $this->autoReOrder(
224
                    'organizationId',
225
                    [
226
                        'userId' => $this->userId
227
                    ],
228
                    'organizationOrder'
229
                );
230
            }
231
        } catch (\Exception $e) {
232
            Organizations::error(
233
                sprintf(
234
                    "Exception caught while trying to reorder '%s'. Exception: [%s].",
235
                    (string)get_class($this),
236
                    (string)Json::encode([
237
                        'Trace' => $e->getTraceAsString(),
238
                        'File' => $e->getFile(),
239
                        'Line' => $e->getLine(),
240
                        'Code' => $e->getCode(),
241
                        'Message' => $e->getMessage()
242
                    ])
243
                ),
244
                __METHOD__
245
            );
246
        }
247
248
        // Save types if they've also been altered
249
        if ($this->getTypeManager()->isMutated()) {
250
            $this->getTypeManager()->save();
251
        }
252
253
        parent::afterSave($insert, $changedAttributes);
254
    }
255
256
    /**
257
     * @inheritdoc
258
     * @throws \yii\db\Exception
259
     */
260
    public function afterDelete()
261
    {
262
        if (Organizations::getInstance()->getSettings()->getEnforceOrganizationSortOrder()) {
263
            $this->sequentialOrder(
264
                'organizationId',
265
                [
266
                    'userId' => $this->userId
267
                ],
268
                'organizationOrder'
269
            );
270
        }
271
272
        if (Organizations::getInstance()->getSettings()->getEnforceUserSortOrder()) {
273
            $this->sequentialOrder(
274
                'userId',
275
                [
276
                    'organizationId' => $this->organizationId
277
                ],
278
                'userOrder'
279
            );
280
        }
281
282
        parent::afterDelete();
283
    }
284
285
    /**
286
     * @return ActiveQueryInterface
287
     */
288
    public function getTypes(): ActiveQueryInterface
289
    {
290
        // Todo - order this by the sortOrder
291
        /** @noinspection PhpUndefinedMethodInspection */
292
        return $this->hasMany(UserType::class, ['id' => 'typeId'])
293
            ->viaTable(
294
                UserTypeAssociation::tableName(),
295
                ['userId' => 'id']
296
            );
297
    }
298
}
299