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 |
|
|
|
|
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
|
|
|
|
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.