This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | /** |
||
4 | * _ __ __ _____ _____ ___ ____ _____ |
||
5 | * | | / // // ___//_ _// || __||_ _| |
||
6 | * | |/ // /(__ ) / / / /| || | | | |
||
7 | * |___//_//____/ /_/ /_/ |_||_| |_| |
||
8 | * @link https://vistart.me/ |
||
9 | * @copyright Copyright (c) 2016 - 2017 vistart |
||
10 | * @license https://vistart.me/license/ |
||
11 | */ |
||
12 | |||
13 | namespace rhosocial\organization; |
||
14 | |||
15 | use rhosocial\base\models\traits\SelfBlameableTrait; |
||
16 | use rhosocial\base\models\queries\BaseBlameableQuery; |
||
17 | use rhosocial\base\models\queries\BaseUserQuery; |
||
18 | use rhosocial\organization\exceptions\DisallowMemberJoinOtherException; |
||
19 | use rhosocial\organization\exceptions\ExcludeOtherMembersException; |
||
20 | use rhosocial\organization\exceptions\OnlyAcceptCurrentOrgMemberException; |
||
21 | use rhosocial\organization\exceptions\OnlyAcceptSuperiorOrgMemberException; |
||
22 | use rhosocial\organization\rbac\roles\DepartmentAdmin; |
||
23 | use rhosocial\organization\rbac\roles\DepartmentCreator; |
||
24 | use rhosocial\organization\rbac\roles\OrganizationAdmin; |
||
25 | use rhosocial\organization\rbac\roles\OrganizationCreator; |
||
26 | use rhosocial\organization\queries\MemberQuery; |
||
27 | use rhosocial\organization\queries\OrganizationQuery; |
||
28 | use rhosocial\user\User; |
||
29 | use Yii; |
||
30 | use yii\base\Event; |
||
31 | use yii\base\InvalidParamException; |
||
32 | use yii\db\IntegrityException; |
||
33 | |||
34 | /** |
||
35 | * Organization. |
||
36 | * This class is used to describe an organization or department, depending on the type property. |
||
37 | * Organization or department should be created by the user, it is best not to directly implement their own such. |
||
38 | * |
||
39 | * In general, the organization needs to have `setUpOrganization` permission, and the user does not have this permission |
||
40 | * by default. You need to give this permission to the user who created the organization in advance. |
||
41 | * Department, affiliated with the organization or other department, also need the appropriate permission to set up. |
||
42 | * |
||
43 | * While this can work independently, we still strongly recommend that you declare the Organization class yourself and |
||
44 | * inherit this. |
||
45 | * Then you need to specify the Profile and Member class yourself, like following: |
||
46 | ```php |
||
47 | class Organization extends \rhosocial\organization\Organization |
||
48 | { |
||
49 | public $profileClass = Profile::class; |
||
50 | public $memberClass = Member::class; |
||
51 | } |
||
52 | ``` |
||
53 | * If you need to limit the number of subordinates, the number of members, you need to specify the appropriate class |
||
54 | * name. |
||
55 | * If there is no limit, you need to set it to false manually. |
||
56 | * |
||
57 | * @method Member createMember(array $config) Create member who is subordinate to this. |
||
58 | * @property int $type Whether indicate this instance is an organization or a department. |
||
59 | * |
||
60 | * @property bool $isExcludeOtherMembers Determine whether the other organization and its subordinate departments |
||
61 | * members could join in the current organization and its subordinate departments. (Only fit for Organization) |
||
62 | * @property bool $isDisallowMemberJoinOther Determine whether the current organization and its subordinate |
||
63 | * departments members could join in the other organization and its subordinate departments. (Only fit for Organization) |
||
64 | * @property bool $isOnlyAcceptCurrentOrgMember Determine whether the current department only accept the member of |
||
65 | * the top level organization. (Only fit for Department) |
||
66 | * @property bool $isOnlyAcceptSuperiorOrgMember Determine whether the current department only accept the member of |
||
67 | * the superior organization or department. (Only fit for Department) |
||
68 | * @property string $joinPassword |
||
69 | * @property string $joinIpAddress |
||
70 | * @property string $joinEntranceUrl |
||
71 | * @property bool $exitAllowWithdrawActively |
||
72 | * |
||
73 | * @property-read Member[] $members Get all member models of this organization/department. |
||
74 | * @property-read User[] $memberUsers Get all members of this organization/department. |
||
75 | * @property-read User $creator Get creator of this organization/department. |
||
76 | * @property-read User[] $administrators Get administrators of this organization/department. |
||
77 | * @property-read SubordinateLimit subordinateLimit |
||
78 | * @property-read MemberLimit memberLimit |
||
79 | * @property-read static|null $topOrganization The top level organization of current organization or departments. |
||
80 | * @property-read Profile $profile Get profile model. Friendly to IDE. |
||
81 | * @property-read OrganizationSetting[] $settings Get all settings. |
||
82 | * |
||
83 | * @version 1.0 |
||
84 | * @author vistart <[email protected]> |
||
85 | */ |
||
86 | class Organization extends User |
||
87 | { |
||
88 | use SelfBlameableTrait; |
||
89 | |||
90 | const TYPE_ORGANIZATION = 1; |
||
91 | const TYPE_DEPARTMENT = 2; |
||
92 | |||
93 | /** |
||
94 | * @var boolean Organization does not need password and corresponding features. |
||
95 | */ |
||
96 | public $passwordHashAttribute = false; |
||
97 | |||
98 | /** |
||
99 | * @var boolean Organization does not need password and corresponding features. |
||
100 | */ |
||
101 | public $passwordResetTokenAttribute = false; |
||
102 | |||
103 | /** |
||
104 | * @var boolean Organization does not need password and corresponding features. |
||
105 | */ |
||
106 | public $passwordHistoryClass = false; |
||
107 | |||
108 | /** |
||
109 | * @var boolean Organization does not need source. |
||
110 | */ |
||
111 | public $sourceAttribute = false; |
||
112 | |||
113 | /** |
||
114 | * @var boolean Organization does not need auth key. |
||
115 | */ |
||
116 | public $authKeyAttribute = false; |
||
117 | |||
118 | /** |
||
119 | * @var boolean Organization does not need access token. |
||
120 | */ |
||
121 | public $accessTokenAttribute = false; |
||
122 | |||
123 | /** |
||
124 | * @var boolean Organization does not need login log. |
||
125 | */ |
||
126 | public $loginLogClass = false; |
||
127 | |||
128 | /** |
||
129 | * @var string The Organization Profile Class |
||
130 | */ |
||
131 | public $profileClass = Profile::class; |
||
132 | |||
133 | /** |
||
134 | * @var string The Member Class. |
||
135 | */ |
||
136 | public $memberClass = Member::class; |
||
137 | |||
138 | /** |
||
139 | * @var string The Subordinate Limit Class |
||
140 | */ |
||
141 | public $subordinateLimitClass = SubordinateLimit::class; |
||
142 | |||
143 | /** |
||
144 | * @var string The Member Limit Class |
||
145 | */ |
||
146 | public $memberLimitClass = MemberLimit::class; |
||
147 | |||
148 | /** |
||
149 | * @var string The Organization Search Class |
||
150 | */ |
||
151 | public $searchClass = OrganizationSearch::class; |
||
152 | |||
153 | /** |
||
154 | * @var string The Organization Setting Class |
||
155 | */ |
||
156 | public $organizationSettingClass = OrganizationSetting::class; |
||
157 | |||
158 | /** |
||
159 | * @var Member |
||
160 | */ |
||
161 | private $noInitMember; |
||
162 | |||
163 | /** |
||
164 | * @var SubordinateLimit |
||
165 | */ |
||
166 | private $noInitSubordinateLimit; |
||
167 | |||
168 | /** |
||
169 | * @var MemberLimit |
||
170 | */ |
||
171 | private $noInitMemberLimit; |
||
172 | |||
173 | /** |
||
174 | * @var OrganizationSetting |
||
175 | */ |
||
176 | private $noInitOrganizationSetting; |
||
177 | |||
178 | /** |
||
179 | * @var User the creator of current Organization or Department. |
||
180 | * This property is only available after registration. |
||
181 | * Please do not access it at other times. |
||
182 | * If you want to get creator model except registration, please |
||
183 | * access [[$creator]] magic-property instead. |
||
184 | */ |
||
185 | public $creatorModel; |
||
186 | |||
187 | /** |
||
188 | * @var array The configuration array of Organization Profile. |
||
189 | * This property is only available after registration. |
||
190 | * Please do not access it at other times. |
||
191 | * If you want to get profile model except registration, please |
||
192 | * access [[$profile]] magic-property instead. |
||
193 | */ |
||
194 | public $profileConfig; |
||
195 | |||
196 | const EVENT_BEFORE_ADD_MEMBER = 'eventBeforeAddMember'; |
||
197 | const EVENT_AFTER_ADD_MEMBER = 'eventAfterAddMember'; |
||
198 | const EVENT_BEFORE_REMOVE_MEMBER = 'eventBeforeRemoveMember'; |
||
199 | const EVENT_AFTER_REMOVE_MEMBER = 'eventAfterRemoveMember'; |
||
200 | |||
201 | public $cacheTagPrefix = 'tag_organization_'; |
||
202 | |||
203 | /** |
||
204 | * @return Member |
||
205 | */ |
||
206 | 51 | public function getNoInitMember() |
|
207 | { |
||
208 | 51 | if (!$this->noInitMember) { |
|
209 | 51 | $class = $this->memberClass; |
|
210 | 51 | $this->noInitMember = $class::buildNoInitModel(); |
|
211 | } |
||
212 | 51 | return $this->noInitMember; |
|
213 | } |
||
214 | |||
215 | /** |
||
216 | * @return SubordinateLimit |
||
217 | */ |
||
218 | 2 | public function getNoInitSubordinateLimit() |
|
219 | { |
||
220 | 2 | if (!$this->noInitSubordinateLimit) { |
|
221 | 2 | $class = $this->subordinateLimitClass; |
|
222 | 2 | $this->noInitSubordinateLimit = $class::buildNoInitModel(); |
|
223 | } |
||
224 | 2 | return $this->noInitSubordinateLimit; |
|
225 | } |
||
226 | |||
227 | /** |
||
228 | * @return MemberLimit |
||
229 | */ |
||
230 | 1 | public function getNoInitMemberLimit() |
|
231 | { |
||
232 | 1 | if (!$this->noInitMemberLimit) { |
|
233 | 1 | $class = $this->memberLimitClass; |
|
234 | 1 | $this->noInitMemberLimit = $class::buildNoInitModel(); |
|
235 | } |
||
236 | 1 | return $this->noInitMemberLimit; |
|
237 | } |
||
238 | |||
239 | /** |
||
240 | * @return null|OrganizationSetting |
||
241 | */ |
||
242 | 31 | public function getNoInitOrganizationSetting() |
|
243 | { |
||
244 | 31 | if (!$this->noInitOrganizationSetting) { |
|
245 | 31 | $class = $this->organizationSettingClass; |
|
246 | 31 | if (empty($class)) { |
|
247 | return null; |
||
248 | } |
||
249 | 31 | $this->noInitOrganizationSetting = $class::buildNoInitModel(); |
|
250 | } |
||
251 | 31 | return $this->noInitOrganizationSetting; |
|
252 | } |
||
253 | |||
254 | /** |
||
255 | * @return null|OrganizationSearch |
||
256 | */ |
||
257 | public function getSearchModel() |
||
258 | { |
||
259 | $class = $this->searchClass; |
||
260 | if (empty($class) || !class_exists($class)) { |
||
261 | return null; |
||
262 | } |
||
263 | return new $class; |
||
264 | } |
||
265 | |||
266 | /** |
||
267 | * @inheritdoc |
||
268 | */ |
||
269 | 52 | public function init() |
|
270 | { |
||
271 | 52 | $this->parentAttribute = 'parent_guid'; |
|
272 | 52 | if (class_exists($this->memberClass)) { |
|
273 | 52 | $this->addSubsidiaryClass('Member', ['class' => $this->memberClass]); |
|
274 | } |
||
275 | 52 | if ($this->skipInit) { |
|
276 | 52 | return; |
|
277 | } |
||
278 | 52 | $this->on(static::$eventAfterRegister, [$this, 'onAddProfile'], $this->profileConfig); |
|
279 | 52 | $this->on(static::$eventAfterRegister, [$this, 'onAssignCreator'], $this->creatorModel); |
|
280 | 52 | $this->on(static::EVENT_BEFORE_DELETE, [$this, 'onRevokeCreator']); |
|
281 | 52 | $this->on(static::EVENT_BEFORE_DELETE, [$this, 'onRevokeAdministrators']); |
|
282 | 52 | $this->on(static::EVENT_BEFORE_DELETE, [$this, 'onRevokePermissions']); |
|
283 | 52 | $this->initSelfBlameableEvents(); |
|
284 | 52 | parent::init(); |
|
285 | 52 | } |
|
286 | |||
287 | /** |
||
288 | * @inheritdoc |
||
289 | */ |
||
290 | 1 | public function attributeLabels() |
|
291 | { |
||
292 | return [ |
||
293 | 1 | $this->guidAttribute => Yii::t('user', 'GUID'), |
|
294 | 1 | $this->idAttribute => Yii::t('user', 'ID'), |
|
295 | 1 | $this->ipAttribute => Yii::t('user', 'IP Address'), |
|
296 | 1 | $this->ipTypeAttribute => Yii::t('user', 'IP Address Type'), |
|
297 | 1 | $this->parentAttribute => Yii::t('organization', 'Parent'), |
|
298 | 1 | $this->createdAtAttribute => Yii::t('user', 'Creation Time'), |
|
299 | 1 | $this->updatedAtAttribute => Yii::t('user', 'Last Updated Time'), |
|
300 | 1 | $this->statusAttribute => Yii::t('user', 'Status'), |
|
301 | 1 | 'type' => Yii::t('user', 'Type'), |
|
302 | 1 | 'isExcludeOtherMembers' => Yii::t('organization', 'Exclude Other Members'), |
|
303 | 1 | 'isDisallowMemberJoinOther' => Yii::t('organization', 'Disallow Member to Join in Other Organizations'), |
|
304 | 1 | 'isOnlyAcceptCurrentOrgMember' => Yii::t('organization', 'Only Accept Current Organization Members'), |
|
305 | 1 | 'isOnlyAcceptSuperiorOrgMember' => Yii::t('organization', 'Only Accept Superior Organization Members'), |
|
306 | ]; |
||
307 | } |
||
308 | |||
309 | /** |
||
310 | * @inheritdoc |
||
311 | */ |
||
312 | 52 | public static function tableName() |
|
313 | { |
||
314 | 52 | return '{{%organization}}'; |
|
315 | } |
||
316 | |||
317 | /** |
||
318 | * Find. |
||
319 | * Friendly to IDE. |
||
320 | * @return OrganizationQuery |
||
321 | */ |
||
322 | 52 | public static function find() |
|
323 | { |
||
324 | 52 | return parent::find(); |
|
325 | } |
||
326 | |||
327 | /** |
||
328 | * Get rules associated with type attribute. |
||
329 | * @return array |
||
330 | */ |
||
331 | 51 | protected function getTypeRules() |
|
332 | { |
||
333 | return [ |
||
334 | 51 | ['type', 'default', 'value' => static::TYPE_ORGANIZATION], |
|
335 | ['type', 'required'], |
||
336 | 51 | ['type', 'in', 'range' => [static::TYPE_ORGANIZATION, static::TYPE_DEPARTMENT]], |
|
337 | ]; |
||
338 | } |
||
339 | |||
340 | /** |
||
341 | * @inheritdoc |
||
342 | */ |
||
343 | 51 | public function rules() |
|
344 | { |
||
345 | 51 | return array_merge(parent::rules(), $this->getTypeRules(), $this->getSelfBlameableRules()); |
|
346 | } |
||
347 | |||
348 | /** |
||
349 | * Get Member Query. |
||
350 | * @return MemberQuery |
||
351 | */ |
||
352 | 50 | public function getMembers() |
|
353 | { |
||
354 | 50 | return $this->hasMany($this->memberClass, [ |
|
355 | 50 | $this->getNoInitMember()->createdByAttribute => $this->guidAttribute |
|
356 | 50 | ])->inverseOf('organization'); |
|
357 | } |
||
358 | |||
359 | /** |
||
360 | * Get organization member users' query. |
||
361 | * @return BaseUserQuery |
||
362 | */ |
||
363 | 6 | public function getMemberUsers() |
|
364 | { |
||
365 | 6 | $noInit = $this->getNoInitMember(); |
|
366 | 6 | $class = $noInit->memberUserClass; |
|
367 | 6 | $noInitUser = $class::buildNoInitModel(); |
|
368 | 6 | return $this->hasMany($class, [ |
|
369 | 6 | $noInitUser->guidAttribute => $this->getNoInitMember()->memberAttribute |
|
370 | 6 | ])->via('members')->inverseOf('atOrganizations'); |
|
371 | } |
||
372 | |||
373 | /** |
||
374 | * Get subordinate limit query. |
||
375 | * @return null|BaseBlameableQuery |
||
376 | */ |
||
377 | 2 | public function getSubordinateLimit() |
|
378 | { |
||
379 | 2 | if (empty($this->subordinateLimitClass)) { |
|
380 | return null; |
||
381 | } |
||
382 | 2 | return $this->hasOne($this->subordinateLimitClass, [ |
|
383 | 2 | $this->getNoInitSubordinateLimit()->createdByAttribute => $this->guidAttribute |
|
384 | ]); |
||
385 | } |
||
386 | |||
387 | /** |
||
388 | * Get member limit query. |
||
389 | * @return null|BaseBlameableQuery |
||
390 | */ |
||
391 | 1 | public function getMemberLimit() |
|
392 | { |
||
393 | 1 | if (empty($this->memberLimitClass)) { |
|
394 | return null; |
||
395 | } |
||
396 | 1 | return $this->hasOne($this->memberLimitClass, [ |
|
397 | 1 | $this->getNoInitMemberLimit()->createdByAttribute => $this->guidAttribute |
|
398 | ]); |
||
399 | } |
||
400 | |||
401 | /** |
||
402 | * @param string|null $item If you want to get all settings, please set it null. |
||
403 | * @return null |
||
404 | */ |
||
405 | 31 | public function getSettings($item = null) |
|
406 | { |
||
407 | 31 | if (empty($this->organizationSettingClass) || !is_string($this->organizationSettingClass)) { |
|
408 | return null; |
||
409 | } |
||
410 | 31 | $query = $this->hasMany($this->organizationSettingClass, [$this->getNoInitOrganizationSetting()->createdByAttribute => $this->guidAttribute]); |
|
411 | 31 | if (!empty($item)) { |
|
412 | 31 | $query = $query->andWhere([$this->getNoInitOrganizationSetting()->idAttribute => $item]); |
|
413 | } |
||
414 | 31 | return $query; |
|
415 | } |
||
416 | |||
417 | /** |
||
418 | * Set organization setting. |
||
419 | * @param string $item |
||
420 | * @param string $value |
||
421 | * @param bool $unique |
||
422 | * @return bool|null Null if organization setting not enabled. |
||
423 | * @throws IntegrityException throw if "item-value" unique broke. |
||
424 | */ |
||
425 | 31 | public function setSetting($item, $value, $unique = false) |
|
426 | { |
||
427 | 31 | if (empty($this->organizationSettingClass) || !is_string($this->organizationSettingClass)) { |
|
428 | return null; |
||
429 | } |
||
430 | 31 | $setting = $this->getSettings($item)->one(); |
|
431 | /* @var $setting OrganizationSetting */ |
||
432 | 31 | if (!$setting) { |
|
433 | 31 | $setting = $this->create($this->organizationSettingClass, [ |
|
434 | 31 | $this->getNoInitOrganizationSetting()->idAttribute => $item, |
|
435 | ]); |
||
436 | } |
||
437 | 31 | $setting->value = $value; |
|
438 | 31 | if ($unique) { |
|
439 | $class = $this->organizationSettingClass; |
||
440 | if ($class::find()->andWhere([ |
||
441 | $this->getNoInitOrganizationSetting()->idAttribute => $item, |
||
442 | $this->getNoInitOrganizationSetting()->contentAttribute => $value |
||
443 | ])->exists()) { |
||
444 | throw new IntegrityException("`$item` : `$value` existed."); |
||
445 | } |
||
446 | } |
||
447 | 31 | return $setting->save(); |
|
448 | } |
||
449 | |||
450 | /** |
||
451 | * Get member with specified user. |
||
452 | * @param User|string|integer $user |
||
453 | * @return Member Null if `user` is not in this organization. |
||
454 | */ |
||
455 | 50 | public function getMember($user) |
|
456 | { |
||
457 | 50 | return $this->getMembers()->user($user)->one(); |
|
0 ignored issues
–
show
Bug
Compatibility
introduced
by
![]() |
|||
458 | } |
||
459 | |||
460 | /** |
||
461 | * Add member to organization. |
||
462 | * @param Member|User|string|integer $member Member or User model, or User ID or GUID. |
||
463 | * If member is created, it will be re-assigned to this parameter. |
||
464 | * @see createMemberModel |
||
465 | * @see createMemberModelWithUser |
||
466 | * @return boolean |
||
467 | * @throws DisallowMemberJoinOtherException |
||
468 | * @throws ExcludeOtherMembersException |
||
469 | * @throws OnlyAcceptCurrentOrgMemberException |
||
470 | * @throws OnlyAcceptSuperiorOrgMemberException |
||
471 | */ |
||
472 | 50 | public function addMember(&$member) |
|
473 | { |
||
474 | 50 | if ($this->getIsNewRecord()) { |
|
475 | return false; |
||
476 | } |
||
477 | 50 | if ($this->hasReachedMemberLimit()) { |
|
478 | 1 | return false; |
|
479 | } |
||
480 | 50 | $user = null; |
|
481 | 50 | if ($member instanceof Member) { |
|
482 | if ($member->getIsNewRecord()) { |
||
483 | return false; |
||
484 | } |
||
485 | $user = $member->memberUser; |
||
486 | } |
||
487 | 50 | if ($member instanceof User) { |
|
488 | 50 | $user = $member; |
|
489 | } |
||
490 | 50 | if (is_string($member) || is_int($member)) { |
|
491 | $class = Yii::$app->user->identityClass; |
||
492 | $user = $class::find()->guidOrId($member)->one(); |
||
493 | } |
||
494 | 50 | if ($this->hasMember($user)) { |
|
495 | return false; |
||
496 | } |
||
497 | 50 | $orgs = $user->getAtOrganizations()->all(); |
|
498 | /* @var $orgs Organization[] */ |
||
499 | 50 | foreach ($orgs as $org) { |
|
500 | 31 | if ($org->topOrganization->isDisallowMemberJoinOther && !$org->topOrganization->equals($this->topOrganization)) { |
|
0 ignored issues
–
show
It seems like
$this->topOrganization can be null ; however, equals() does not accept null , maybe add an additional type check?
Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code: /** @return stdClass|null */
function mayReturnNull() { }
function doesNotAcceptNull(stdClass $x) { }
// With potential error.
function withoutCheck() {
$x = mayReturnNull();
doesNotAcceptNull($x); // Potential error here.
}
// Safe - Alternative 1
function withCheck1() {
$x = mayReturnNull();
if ( ! $x instanceof stdClass) {
throw new \LogicException('$x must be defined.');
}
doesNotAcceptNull($x);
}
// Safe - Alternative 2
function withCheck2() {
$x = mayReturnNull();
if ($x instanceof stdClass) {
doesNotAcceptNull($x);
}
}
![]() |
|||
501 | 1 | throw new DisallowMemberJoinOtherException(Yii::t('organization', "An organization in which the user is located does not allow its members to join other organizations.")); |
|
502 | } |
||
503 | 31 | if ($this->topOrganization->isExcludeOtherMembers && !$org->topOrganization->equals($this->topOrganization)) { |
|
504 | 31 | throw new ExcludeOtherMembersException(Yii::t('organization', "The organization does not allow users who have joined other organizations to join.")); |
|
505 | } |
||
506 | } |
||
507 | 50 | if ($this->isDepartment() && $this->isOnlyAcceptCurrentOrgMember && !$this->topOrganization->hasMember($user)) { |
|
508 | 1 | throw new OnlyAcceptCurrentOrgMemberException(Yii::t('organization' ,'This department is only accepted by members of the organization.')); |
|
509 | } |
||
510 | 50 | if ($this->isDepartment() && !$this->parent->equals($this->topOrganization) && $this->isOnlyAcceptSuperiorOrgMember && !$this->parent->hasMember($user)) { |
|
0 ignored issues
–
show
It seems like
equals() must be provided by classes using this trait. How about adding it as abstract method to this trait?
This check looks for methods that are used by a trait but not required by it. To illustrate, let’s look at the following code example trait Idable {
public function equalIds(Idable $other) {
return $this->getId() === $other->getId();
}
}
The trait Adding the ![]() It seems like
hasMember() must be provided by classes using this trait. How about adding it as abstract method to this trait?
This check looks for methods that are used by a trait but not required by it. To illustrate, let’s look at the following code example trait Idable {
public function equalIds(Idable $other) {
return $this->getId() === $other->getId();
}
}
The trait Adding the ![]() |
|||
511 | 1 | throw new OnlyAcceptSuperiorOrgMemberException(Yii::t('organization', 'This department only accepts members of the parent organization or department.')); |
|
512 | } |
||
513 | |||
514 | 50 | $this->trigger(self::EVENT_BEFORE_ADD_MEMBER); |
|
515 | 50 | $model = null; |
|
516 | 50 | if ($member instanceof Member) { |
|
517 | $model = $this->createMemberModel($member); |
||
518 | 50 | } elseif (($member instanceof User) || is_string($member) || is_int($member)) { |
|
519 | 50 | $model = $this->createMemberModelWithUser($member); |
|
520 | } |
||
521 | 50 | $member = $model; |
|
522 | 50 | $result = ($member instanceof Member) ? $member->save() : false; |
|
523 | 50 | $this->trigger(self::EVENT_AFTER_ADD_MEMBER); |
|
524 | 50 | return $result; |
|
525 | } |
||
526 | |||
527 | /** |
||
528 | * Create member model, and set organization with this. |
||
529 | * @param Member $member If this parameter is not new record, it's organization |
||
530 | * will be set with this, and return it. Otherwise, it will extract `User` |
||
531 | * model and create new `Member` model. |
||
532 | * @see createMemberModelWithUser |
||
533 | * @return Member |
||
534 | */ |
||
535 | public function createMemberModel($member) |
||
536 | { |
||
537 | if (!$member->getIsNewRecord()) { |
||
538 | $member->setOrganization($this); |
||
0 ignored issues
–
show
$this is of type this<rhosocial\organization\Organization> , but the function expects a object<rhosocial\organization\BaseOrganization> .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
539 | return $member; |
||
540 | } |
||
541 | return $this->createMemberModelWithUser($member->memberUser); |
||
542 | } |
||
543 | |||
544 | /** |
||
545 | * Create member model with user, and set organization with this. |
||
546 | * @param User|string|integer $user |
||
547 | * @return Member |
||
548 | */ |
||
549 | 50 | public function createMemberModelWithUser($user) |
|
550 | { |
||
551 | $config = [ |
||
552 | 50 | 'memberUser' => $user, |
|
553 | 50 | 'organization' => $this, |
|
554 | 50 | 'nickname' => '', |
|
555 | ]; |
||
556 | 50 | $member = $this->createMember($config); |
|
557 | 50 | $member->nickname = $member->memberUser->profile->nickname; |
|
558 | 50 | return $member; |
|
559 | } |
||
560 | |||
561 | /** |
||
562 | * Remove member. |
||
563 | * Note: the creator cannot be removed. |
||
564 | * @param Member|User $member |
||
565 | * @return boolean |
||
566 | */ |
||
567 | 4 | public function removeMember(&$member) |
|
568 | { |
||
569 | 4 | if ($this->getIsNewRecord()) { |
|
570 | return false; |
||
571 | } |
||
572 | 4 | $this->trigger(self::EVENT_BEFORE_REMOVE_MEMBER); |
|
573 | 4 | if ($member instanceof $this->memberClass) { |
|
574 | 4 | $member = $member->{$member->memberAttribute}; |
|
575 | } |
||
576 | 4 | $member = $this->getMember($member); |
|
577 | 4 | if (!$member || $member->isCreator()) { |
|
578 | return false; |
||
579 | } |
||
580 | 4 | $result = $member->delete() > 0; |
|
581 | 4 | $this->trigger(self::EVENT_AFTER_REMOVE_MEMBER); |
|
582 | 4 | return $result; |
|
583 | } |
||
584 | |||
585 | /** |
||
586 | * Remove administrator. |
||
587 | * @param Member|User|integer|string $member Member instance, or User instance or its GUID or ID. |
||
588 | * @param boolean $keep Keep member after administrator being revoked. |
||
589 | * @return boolean |
||
590 | * @throws IntegrityException |
||
591 | */ |
||
592 | public function removeAdministrator(&$member, $keep = true) |
||
593 | { |
||
594 | if ($this->getIsNewRecord()) { |
||
595 | return false; |
||
596 | } |
||
597 | if ($member instanceof $this->memberClass) { |
||
598 | $member = $member->{$member->memberAttribute}; |
||
599 | } |
||
600 | $member = $this->getMember($member); |
||
601 | if ($member && $member->isAdministrator()) { |
||
602 | if ($keep) { |
||
603 | return $member->revokeAdministrator(); |
||
604 | } |
||
605 | return $this->removeMember($member); |
||
606 | } |
||
607 | return false; |
||
608 | } |
||
609 | |||
610 | /** |
||
611 | * |
||
612 | * @param Event $event |
||
613 | * @throws IntegrityException |
||
614 | * @return boolean |
||
615 | */ |
||
616 | 51 | public function onAddProfile($event) |
|
617 | { |
||
618 | 51 | $profile = $event->sender->createProfile($event->data); |
|
619 | 51 | if (!$profile->save()) { |
|
620 | throw new IntegrityException('Profile Save Failed.'); |
||
621 | } |
||
622 | 51 | return true; |
|
623 | } |
||
624 | |||
625 | /** |
||
626 | * |
||
627 | * @param Event $event |
||
628 | */ |
||
629 | 51 | public function onAssignCreator($event) |
|
630 | { |
||
631 | 51 | return $event->sender->addCreator($event->data); |
|
632 | } |
||
633 | |||
634 | /** |
||
635 | * |
||
636 | * @param Event $event |
||
637 | * @return boolean |
||
638 | */ |
||
639 | 20 | public function onRevokeCreator($event) |
|
640 | { |
||
641 | 20 | $sender = $event->sender; |
|
642 | /* @var $sender static */ |
||
643 | 20 | $member = $sender->getMemberCreators()->one(); |
|
644 | /* @var $member Member */ |
||
645 | 20 | $role = $this->isOrganization() ? (new OrganizationCreator)->name : (new DepartmentCreator)->name; |
|
646 | 20 | return $member->revokeRole($role); |
|
0 ignored issues
–
show
$role is of type string , but the function expects a object<rhosocial\user\rbac\Role> .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
647 | } |
||
648 | |||
649 | /** |
||
650 | * |
||
651 | * @param Event $event |
||
652 | * @return boolean |
||
653 | */ |
||
654 | 20 | public function onRevokeAdministrators($event) |
|
655 | { |
||
656 | 20 | $sender = $event->sender; |
|
657 | /* @var $sender static */ |
||
658 | 20 | $members = $sender->getMemberAdministrators()->all(); |
|
659 | /* @var $members Member[] */ |
||
660 | 20 | foreach ($members as $member) |
|
661 | { |
||
662 | 1 | $member->revokeAdministrator(); |
|
663 | } |
||
664 | 20 | return true; |
|
665 | } |
||
666 | |||
667 | /** |
||
668 | * |
||
669 | * @param Event $event |
||
670 | */ |
||
671 | 20 | public function onRevokePermissions($event) |
|
0 ignored issues
–
show
|
|||
672 | { |
||
673 | |||
674 | 20 | } |
|
675 | |||
676 | /** |
||
677 | * Check whether current instance is an organization. |
||
678 | * @return boolean |
||
679 | */ |
||
680 | 50 | public function isOrganization() |
|
681 | { |
||
682 | 50 | return $this->type == static::TYPE_ORGANIZATION; |
|
683 | } |
||
684 | |||
685 | /** |
||
686 | * Check whether current instance if a department. |
||
687 | * @return boolean |
||
688 | */ |
||
689 | 50 | public function isDepartment() |
|
690 | { |
||
691 | 50 | return $this->type == static::TYPE_DEPARTMENT; |
|
692 | } |
||
693 | |||
694 | /** |
||
695 | * Check whether the current organization has a member. |
||
696 | * @param User|string|integer $user User instance, GUID or ID. |
||
697 | * @return boolean |
||
698 | */ |
||
699 | 50 | public function hasMember($user) |
|
700 | { |
||
701 | 50 | return !empty($this->getMember($user)); |
|
702 | } |
||
703 | |||
704 | /** |
||
705 | * Get member query which role is specified `Creator`. |
||
706 | * @return MemberQuery |
||
707 | */ |
||
708 | 24 | public function getMemberCreators() |
|
709 | { |
||
710 | 24 | return $this->getMembers()->andWhere(['role' => [(new DepartmentCreator)->name, (new OrganizationCreator)->name]]); |
|
711 | } |
||
712 | |||
713 | /** |
||
714 | * Get member query which role is specified `Administrator`. |
||
715 | * @return MemberQuery |
||
716 | */ |
||
717 | 22 | public function getMemberAdministrators() |
|
718 | { |
||
719 | 22 | return $this->getMembers()->andWhere(['role' => [(new DepartmentAdmin)->name, (new OrganizationAdmin)->name]]); |
|
720 | } |
||
721 | |||
722 | /** |
||
723 | * Get user query which role is specified `Creator`. |
||
724 | * @return BaseUserQuery |
||
725 | */ |
||
726 | 4 | public function getCreator() |
|
727 | { |
||
728 | 4 | $noInit = $this->getNoInitMember(); |
|
729 | 4 | $class = $noInit->memberUserClass; |
|
730 | 4 | $noInitUser = $class::buildNoInitModel(); |
|
731 | 4 | return $this->hasOne($class, [ |
|
732 | 4 | $noInitUser->guidAttribute => $this->getNoInitMember()->memberAttribute |
|
733 | 4 | ])->via('memberCreators')->inverseOf('creatorsAtOrganizations'); |
|
734 | } |
||
735 | |||
736 | /** |
||
737 | * Get user query which role is specified `Administrator`. |
||
738 | * @return BaseUserQuery |
||
739 | */ |
||
740 | 2 | public function getAdministrators() |
|
741 | { |
||
742 | 2 | $noInit = $this->getNoInitMember(); |
|
743 | 2 | $class = $noInit->memberUserClass; |
|
744 | 2 | $noInitUser = $class::buildNoInitModel(); |
|
745 | 2 | return $this->hasMany($class, [ |
|
746 | 2 | $noInitUser->guidAttribute => $this->getNoInitMember()->memberAttribute |
|
747 | 2 | ])->via('memberAdministrators')->inverseOf('administratorsAtOrganizations'); |
|
748 | } |
||
749 | |||
750 | /** |
||
751 | * |
||
752 | * @param User $user |
||
753 | * @return boolean |
||
754 | * @throws \Exception |
||
755 | * @throws IntegrityException |
||
756 | */ |
||
757 | 51 | protected function addCreator($user) |
|
758 | { |
||
759 | 51 | if (!$user) { |
|
760 | 1 | throw new InvalidParamException('Creator Invalid.'); |
|
761 | } |
||
762 | 50 | $member = $user; |
|
763 | 50 | $transaction = Yii::$app->db->beginTransaction(); |
|
764 | try { |
||
765 | 50 | if (!$this->addMember($member)) { |
|
766 | throw new IntegrityException('Failed to add member.'); |
||
767 | } |
||
768 | 50 | $role = $this->isOrganization() ? (new OrganizationCreator)->name : (new DepartmentCreator)->name; |
|
769 | 50 | $member->assignRole($role); |
|
0 ignored issues
–
show
$role is of type string , but the function expects a object<rhosocial\user\rbac\Role> .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() The method
assignRole does only exist in rhosocial\organization\Member , but not in rhosocial\user\User .
It seems like the method you are trying to call exists only in some of the possible types. Let’s take a look at an example: class A
{
public function foo() { }
}
class B extends A
{
public function bar() { }
}
/**
* @param A|B $x
*/
function someFunction($x)
{
$x->foo(); // This call is fine as the method exists in A and B.
$x->bar(); // This method only exists in B and might cause an error.
}
Available Fixes
![]() |
|||
770 | 50 | if (!$member->save()) { |
|
771 | throw new IntegrityException('Failed to assign creator.'); |
||
772 | } |
||
773 | 50 | $transaction->commit(); |
|
774 | } catch (\Exception $ex) { |
||
775 | $transaction->rollBack(); |
||
776 | Yii::error($ex->getMessage(), __METHOD__); |
||
777 | throw $ex; |
||
778 | } |
||
779 | 50 | return true; |
|
780 | } |
||
781 | |||
782 | /** |
||
783 | * Add administrator. |
||
784 | * @param User|integer|string $user User instance, or its GUID or ID. |
||
785 | * @return boolean |
||
786 | * @throws \Exception |
||
787 | * @throws IntegrityException |
||
788 | */ |
||
789 | 17 | public function addAdministrator($user) |
|
790 | { |
||
791 | 17 | $transaction = Yii::$app->db->beginTransaction(); |
|
792 | try { |
||
793 | 17 | if (!$this->hasMember($user) && !$this->addMember($user)) { |
|
794 | throw new IntegrityException(Yii::t('organization', 'Failed to add member.')); |
||
795 | } |
||
796 | 17 | $member = $this->getMember($user); |
|
797 | 17 | $member->assignAdministrator(); |
|
798 | 17 | $transaction->commit(); |
|
799 | 2 | } catch (\Exception $ex) { |
|
800 | 2 | $transaction->rollBack(); |
|
801 | 2 | Yii::error($ex->getMessage(), __METHOD__); |
|
802 | 2 | throw $ex; |
|
803 | } |
||
804 | 17 | return true; |
|
805 | } |
||
806 | |||
807 | /** |
||
808 | * Check whether the current organization has administrator. |
||
809 | * @param User|integer|string $user |
||
810 | * @return boolean |
||
811 | */ |
||
812 | 2 | public function hasAdministrator($user) |
|
813 | { |
||
814 | 2 | $member = $this->getMember($user); |
|
815 | 2 | if (!$member) { |
|
816 | return false; |
||
817 | } |
||
818 | 2 | return $member->isAdministrator(); |
|
819 | } |
||
820 | |||
821 | /** |
||
822 | * Check whether this organization has reached the upper limit of subordinates. |
||
823 | * @return boolean |
||
824 | */ |
||
825 | 19 | public function hasReachedSubordinateLimit() |
|
826 | { |
||
827 | 19 | $remaining = $this->getRemainingSubordinatePlaces(); |
|
828 | 19 | if ($remaining === false) { |
|
829 | return false; |
||
830 | } |
||
831 | 19 | return $remaining <= 0; |
|
832 | } |
||
833 | |||
834 | /** |
||
835 | * Get the remaining places of subordinates. |
||
836 | * @return bool|int False if no limit |
||
837 | */ |
||
838 | 19 | public function getRemainingSubordinatePlaces() |
|
839 | { |
||
840 | 19 | $class = $this->subordinateLimitClass; |
|
841 | 19 | if (empty($class)) { |
|
842 | return false; |
||
843 | } |
||
844 | 19 | $limit = $class::getLimit($this); |
|
845 | 19 | if ($limit === false) { |
|
846 | return false; |
||
847 | } |
||
848 | 19 | $count = (int)$this->getChildren()->count(); |
|
849 | 19 | return $limit - $count; |
|
850 | } |
||
851 | |||
852 | /** |
||
853 | * Check whether this organization has reached the upper limit of members. |
||
854 | * @return boolean |
||
855 | */ |
||
856 | 50 | public function hasReachedMemberLimit() |
|
857 | { |
||
858 | 50 | $remaining = $this->getRemainingMemberPlaces(); |
|
859 | 50 | if ($remaining === false) { |
|
860 | return false; |
||
861 | } |
||
862 | 50 | return $remaining <= 0; |
|
863 | } |
||
864 | |||
865 | /** |
||
866 | * Get the remaining places of members. |
||
867 | * @return bool|int False if no limit. |
||
868 | */ |
||
869 | 50 | public function getRemainingMemberPlaces() |
|
870 | { |
||
871 | 50 | $class = $this->memberLimitClass; |
|
872 | 50 | if (empty($class)) { |
|
873 | return false; |
||
874 | } |
||
875 | 50 | $limit = $class::getLimit($this); |
|
876 | 50 | if ($limit === false) { |
|
877 | return false; |
||
878 | } |
||
879 | 50 | $count = (int)$this->getMembers()->count(); |
|
880 | 50 | return $limit - $count; |
|
881 | } |
||
882 | |||
883 | const SETTING_ITEM_EXCLUDE_OTHER_MEMBERS = 'exclude_other_members'; |
||
884 | |||
885 | /** |
||
886 | * @return bool |
||
887 | */ |
||
888 | 31 | public function getIsExcludeOtherMembers() |
|
889 | { |
||
890 | 31 | $setting = $this->getSettings(static::SETTING_ITEM_EXCLUDE_OTHER_MEMBERS)->one(); |
|
891 | 31 | if (!$setting) { |
|
892 | 31 | $this->setIsExcludeOtherMembers(false); |
|
893 | 31 | $setting = $this->getSettings(static::SETTING_ITEM_EXCLUDE_OTHER_MEMBERS)->one(); |
|
894 | } |
||
895 | 31 | return $setting->value == '1'; |
|
896 | } |
||
897 | |||
898 | /** |
||
899 | * @param bool $value |
||
900 | * @return bool |
||
901 | */ |
||
902 | 31 | public function setIsExcludeOtherMembers($value = true) |
|
903 | { |
||
904 | 31 | return $this->setSetting(static::SETTING_ITEM_EXCLUDE_OTHER_MEMBERS, $value ? '1' : '0'); |
|
905 | } |
||
906 | |||
907 | const SETTING_ITEM_DISALLOW_MEMBER_JOIN_OTHER = 'disallow_member_join_other'; |
||
908 | |||
909 | /** |
||
910 | * @return bool |
||
911 | */ |
||
912 | 31 | public function getIsDisallowMemberJoinOther() |
|
913 | { |
||
914 | 31 | $setting = $this->getSettings(static::SETTING_ITEM_DISALLOW_MEMBER_JOIN_OTHER)->one(); |
|
915 | 31 | if (!$setting) { |
|
916 | 31 | $this->setIsDisallowMemberJoinOther(false); |
|
917 | 31 | $setting = $this->getSettings(static::SETTING_ITEM_DISALLOW_MEMBER_JOIN_OTHER)->one(); |
|
918 | } |
||
919 | 31 | return $setting->value == '1'; |
|
920 | } |
||
921 | |||
922 | /** |
||
923 | * @param bool $value |
||
924 | * @return bool |
||
925 | */ |
||
926 | 31 | public function setIsDisallowMemberJoinOther($value = true) |
|
927 | { |
||
928 | 31 | return $this->setSetting(static::SETTING_ITEM_DISALLOW_MEMBER_JOIN_OTHER, $value ? '1' : '0'); |
|
929 | } |
||
930 | |||
931 | const SETTING_ITEM_ONLY_ACCEPT_CURRENT_ORG_MEMBER = 'only_accept_current_org_member'; |
||
932 | |||
933 | /** |
||
934 | * @return bool |
||
935 | */ |
||
936 | 18 | public function getIsOnlyAcceptCurrentOrgMember() |
|
937 | { |
||
938 | 18 | $setting = $this->getSettings(static::SETTING_ITEM_ONLY_ACCEPT_CURRENT_ORG_MEMBER)->one(); |
|
939 | 18 | if (!$setting) { |
|
940 | 18 | $this->setIsOnlyAcceptCurrentOrgMember(false); |
|
941 | 18 | $setting = $this->getSettings(static::SETTING_ITEM_ONLY_ACCEPT_CURRENT_ORG_MEMBER)->one(); |
|
942 | } |
||
943 | 18 | return $setting->value == '1'; |
|
944 | } |
||
945 | |||
946 | /** |
||
947 | * @param bool $value |
||
948 | * @return bool |
||
949 | */ |
||
950 | 18 | public function setIsOnlyAcceptCurrentOrgMember($value = true) |
|
951 | { |
||
952 | 18 | return $this->setSetting(static::SETTING_ITEM_ONLY_ACCEPT_CURRENT_ORG_MEMBER, $value ? '1' : '0'); |
|
953 | } |
||
954 | |||
955 | const SETTING_ITEM_ONLY_ACCEPT_SUPERIOR_ORG_MEMBER = 'only_accept_superior_org_member'; |
||
956 | |||
957 | /** |
||
958 | * @return bool |
||
959 | */ |
||
960 | 10 | public function getIsOnlyAcceptSuperiorOrgMember() |
|
961 | { |
||
962 | 10 | if ($this->parent && $this->parent->equals($this->topOrganization)) { |
|
0 ignored issues
–
show
It seems like
equals() must be provided by classes using this trait. How about adding it as abstract method to this trait?
This check looks for methods that are used by a trait but not required by it. To illustrate, let’s look at the following code example trait Idable {
public function equalIds(Idable $other) {
return $this->getId() === $other->getId();
}
}
The trait Adding the ![]() |
|||
963 | return $this->getIsOnlyAcceptCurrentOrgMember(); |
||
964 | } |
||
965 | 10 | $setting = $this->getSettings(static::SETTING_ITEM_ONLY_ACCEPT_SUPERIOR_ORG_MEMBER)->one(); |
|
966 | 10 | if (!$setting) { |
|
967 | 10 | $this->setIsOnlyAcceptSuperiorOrgMember(false); |
|
968 | 10 | $setting = $this->getSettings(static::SETTING_ITEM_ONLY_ACCEPT_SUPERIOR_ORG_MEMBER)->one(); |
|
969 | } |
||
970 | 10 | return $setting->value == '1'; |
|
971 | } |
||
972 | |||
973 | /** |
||
974 | * @param bool $value |
||
975 | * @return bool |
||
976 | */ |
||
977 | 10 | public function setIsOnlyAcceptSuperiorOrgMember($value = true) |
|
978 | { |
||
979 | 10 | if ($this->parent && $this->parent->equals($this->topOrganization)) { |
|
0 ignored issues
–
show
It seems like
equals() must be provided by classes using this trait. How about adding it as abstract method to this trait?
This check looks for methods that are used by a trait but not required by it. To illustrate, let’s look at the following code example trait Idable {
public function equalIds(Idable $other) {
return $this->getId() === $other->getId();
}
}
The trait Adding the ![]() |
|||
980 | return $this->setIsOnlyAcceptCurrentOrgMember($value); |
||
981 | } |
||
982 | 10 | return $this->setSetting(static::SETTING_ITEM_ONLY_ACCEPT_SUPERIOR_ORG_MEMBER, $value ? '1' : '0'); |
|
983 | } |
||
984 | |||
985 | const SETTING_ITEM_JOIN_PASSWORD = 'join_password'; |
||
986 | |||
987 | /** |
||
988 | * Get join password. |
||
989 | * @return mixed |
||
990 | */ |
||
991 | public function getJoinPassword() |
||
992 | { |
||
993 | $setting = $this->getSettings(static::SETTING_ITEM_JOIN_PASSWORD)->one(); |
||
994 | if (!$setting) { |
||
995 | $this->setJoinPassword(); |
||
996 | $setting = $this->getSettings(static::SETTING_ITEM_JOIN_PASSWORD)->one(); |
||
997 | } |
||
998 | return $setting->value; |
||
999 | } |
||
1000 | |||
1001 | /** |
||
1002 | * Set join password. |
||
1003 | * @param string $value |
||
1004 | * @return bool|null |
||
1005 | */ |
||
1006 | public function setJoinPassword($value = '') |
||
1007 | { |
||
1008 | return $this->setSetting(static::SETTING_ITEM_JOIN_PASSWORD, $value); |
||
1009 | } |
||
1010 | |||
1011 | const SETTING_ITEM_JOIN_IP_ADDRESS = 'join_ip_address'; |
||
1012 | |||
1013 | /** |
||
1014 | * Get Join IP address |
||
1015 | * @return mixed |
||
1016 | */ |
||
1017 | public function getJoinIpAddress() |
||
1018 | { |
||
1019 | $setting = $this->getSettings(static::SETTING_ITEM_JOIN_IP_ADDRESS)->one(); |
||
1020 | if (!$setting) { |
||
1021 | $this->setJoinIpAddress(); |
||
1022 | $setting = $this->getSettings(static::SETTING_ITEM_JOIN_IP_ADDRESS)->one(); |
||
1023 | } |
||
1024 | return $setting->value; |
||
1025 | } |
||
1026 | |||
1027 | /** |
||
1028 | * Set join IP address. |
||
1029 | * @param $value |
||
1030 | * @return bool|null |
||
1031 | */ |
||
1032 | public function setJoinIpAddress($value = '') |
||
1033 | { |
||
1034 | return $this->setSetting(static::SETTING_ITEM_JOIN_IP_ADDRESS, $value); |
||
1035 | } |
||
1036 | |||
1037 | const SETTING_ITEM_JOIN_ENTRANCE_URL = 'join_entrance_url'; |
||
1038 | |||
1039 | /** |
||
1040 | * Get join entrance URL. |
||
1041 | * This setting should be confirmed unique. |
||
1042 | * @return string |
||
1043 | */ |
||
1044 | public function getJoinEntranceUrl() |
||
1045 | { |
||
1046 | $setting = $this->getSettings(static::SETTING_ITEM_JOIN_ENTRANCE_URL)->one(); |
||
1047 | if (!$setting) { |
||
1048 | $this->setJoinEntranceUrl(); |
||
1049 | $setting = $this->getSettings(static::SETTING_ITEM_JOIN_ENTRANCE_URL)->one(); |
||
1050 | } |
||
1051 | return $setting->value; |
||
1052 | } |
||
1053 | |||
1054 | /** |
||
1055 | * Set join entrance URL. |
||
1056 | * @param string $value |
||
1057 | * @return bool|null |
||
1058 | */ |
||
1059 | public function setJoinEntranceUrl($value = '') |
||
1060 | { |
||
1061 | return $this->setSetting(static::SETTING_ITEM_JOIN_ENTRANCE_URL, $value, !empty($value)); |
||
1062 | } |
||
1063 | |||
1064 | const SETTING_ITEM_EXIT_ALLOW_WITHDRAW_ACTIVELY = 'exit_allow_withdraw_actively'; |
||
1065 | |||
1066 | /** |
||
1067 | * @return bool |
||
1068 | */ |
||
1069 | public function getExitAllowWithdrawActively() |
||
1070 | { |
||
1071 | $setting = $this->getSettings(static::SETTING_ITEM_EXIT_ALLOW_WITHDRAW_ACTIVELY)->one(); |
||
1072 | if (!$setting) { |
||
1073 | $this->setExitAllowWithdrawActively(); |
||
1074 | $setting = $this->getSettings(static::SETTING_ITEM_EXIT_ALLOW_WITHDRAW_ACTIVELY)->one(); |
||
1075 | } |
||
1076 | return $setting->value == '1'; |
||
1077 | } |
||
1078 | |||
1079 | /** |
||
1080 | * @param bool $value |
||
1081 | * @return bool|null |
||
1082 | */ |
||
1083 | public function setExitAllowWithdrawActively($value = false) |
||
1084 | { |
||
1085 | return $this->setSetting(static::SETTING_ITEM_EXIT_ALLOW_WITHDRAW_ACTIVELY, $value ? '1' : '0'); |
||
1086 | } |
||
1087 | |||
1088 | /** |
||
1089 | * @return $this|null|static |
||
1090 | */ |
||
1091 | 31 | public function getTopOrganization() |
|
1092 | { |
||
1093 | 31 | if ($this->isOrganization()) { |
|
1094 | 31 | return $this; |
|
1095 | } |
||
1096 | 18 | $chain = $this->getAncestorChain(); |
|
1097 | 18 | return static::findOne(end($chain)); |
|
1098 | } |
||
1099 | |||
1100 | /** |
||
1101 | * Check whether the subordinates have the [[$user]] |
||
1102 | * Note, this operation may consume the quantity of database selection. |
||
1103 | * @param User $user |
||
1104 | * @return bool |
||
1105 | */ |
||
1106 | 2 | public function hasMemberInSubordinates($user) |
|
1107 | { |
||
1108 | 2 | if ($this->getChildren()->joinWith(['memberUsers mu_alias']) |
|
1109 | 2 | ->andWhere(['mu_alias.' . $user->guidAttribute => $user->getGUID()])->exists()) { |
|
1110 | 1 | return true; |
|
1111 | } |
||
1112 | 2 | $children = $this->children; |
|
1113 | /* @var $children static[] */ |
||
1114 | 2 | foreach ($children as $child) { |
|
1115 | 2 | if ($child->hasMemberInSubordinates($user)) { |
|
1116 | 2 | return true; |
|
1117 | } |
||
1118 | } |
||
1119 | 2 | return false; |
|
1120 | } |
||
1121 | } |
||
1122 |