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\base\models\traits; |
||
14 | |||
15 | use rhosocial\base\models\models\BaseUserModel; |
||
16 | use rhosocial\base\models\traits\MultipleBlameableTrait as mb; |
||
17 | use yii\base\ModelEvent; |
||
18 | use yii\base\InvalidConfigException; |
||
19 | use yii\base\InvalidValueException; |
||
20 | use yii\db\Connection; |
||
21 | use yii\db\IntegrityException; |
||
22 | |||
23 | /** |
||
24 | * Relation features. |
||
25 | * This trait should be used in user relation model which is extended from |
||
26 | * [[BaseBlameableModel]], and is specified `$hostClass` property. And the user |
||
27 | * class should be extended from [[BaseUserModel]], or any other classes used |
||
28 | * [[UserTrait]]. |
||
29 | * Notice: Several methods associated with "inserting", "updating" and "removing" may |
||
30 | * involve more DB operations, I strongly recommend those methods to be placed in |
||
31 | * transaction execution, in order to ensure data consistency. |
||
32 | * If you want to use group feature, the class used [[UserRelationGroupTrait]] |
||
33 | * must be used coordinately. |
||
34 | * @property array $groupGuids the guid array of all groups which owned by current relation. |
||
35 | * @property-read array $favoriteRules |
||
36 | * @property boolean $isFavorite |
||
37 | * @property-read static $opposite |
||
38 | * @property-read array $otherGuidRules |
||
39 | * @property string $remark |
||
40 | * @property-read array $remarkRules |
||
41 | * @property-read array $userRelationRules |
||
42 | * @property-read mixed $group |
||
43 | * @property-read array $groupMembers |
||
44 | * @property array $groupGuids |
||
45 | * @property-read array $allGroups |
||
46 | * @property-read array $nonGroupMembers |
||
47 | * @property-read integer $groupsCount |
||
48 | * @property-read array $groupsRules |
||
49 | * |
||
50 | * @method {$this->multiBlamesClass} createGroup(BaseUserModel $user, array $config = []) |
||
51 | * @method array|false addGroup({$this->multiBlamesClass} $blame) |
||
52 | * @method array|false addOrCreateGroup(){$this->multiBlamesClass}|array &$blame = null, BaseUserModel $user = null) |
||
53 | * @method array|false removeGroup({$this->multiBlamesClass}|string $blame) |
||
54 | * @method array|false removeAllGroups() |
||
55 | * @method {$this->multiBlamesClass} getGroup(string $blameGuid) |
||
56 | * @method {$this->multiBlamesClass} getOrCreateGroup(string $blameGuid, BaseUserModel $user = null)) |
||
57 | * @method array getGroupMembers({$this->multiBlamesClass} $blame) Get all members that belongs to |
||
58 | * @method array getGroupGuids(bool $checkValid = false) |
||
59 | * @method array|false setGroupGuids(array $guids = [], bool $checkValid = false) |
||
60 | * @method array getOwnGroups() Get all groups that owned this relation. |
||
61 | * @method array setOwnGroups(array $blames) |
||
62 | * @method array isGroupContained({$this->multiBlamesClass} $blame) |
||
63 | * @method array getAllGroups() Get all groups created by whom created this relation. |
||
64 | * @method array getNonGroupMembers(BaseUserModel $user) Get members that do not belong to any group. |
||
65 | * @method integer getGroupsCount() Get the count of groups of this relation. |
||
66 | * @method array getEmptyGroups() Get the groups which does not contain any relations. |
||
67 | * @method array getGroupsRules() Get rules associated with group attribute. |
||
68 | * |
||
69 | * @version 1.0 |
||
70 | * @author vistart <[email protected]> |
||
71 | */ |
||
72 | trait UserRelationTrait |
||
73 | { |
||
74 | use mb, |
||
75 | MutualTrait { |
||
76 | mb::addBlame as addGroup; |
||
77 | mb::createBlame as createGroup; |
||
78 | mb::addOrCreateBlame as addOrCreateGroup; |
||
79 | mb::removeBlame as removeGroup; |
||
80 | mb::removeAllBlames as removeAllGroups; |
||
81 | mb::getBlame as getGroup; |
||
82 | mb::getOrCreateBlame as getOrCreateGroup; |
||
83 | mb::getBlameds as getGroupMembers; |
||
84 | mb::getBlameGuids as getGroupGuids; |
||
85 | mb::setBlameGuids as setGroupGuids; |
||
86 | mb::getOwnBlames as getOwnGroups; |
||
87 | mb::setOwnBlames as setOwnGroups; |
||
88 | mb::isBlameOwned as isGroupContained; |
||
89 | mb::getAllBlames as getAllGroups; |
||
90 | mb::getNonBlameds as getNonGroupMembers; |
||
91 | mb::getBlamesCount as getGroupsCount; |
||
92 | mb::getEmptyBlames as getEmptyGroups; |
||
93 | mb::getMultipleBlameableAttributeRules as getGroupsRules; |
||
94 | } |
||
95 | |||
96 | /** |
||
97 | * @var string |
||
98 | */ |
||
99 | public $remarkAttribute = 'remark'; |
||
100 | public static $relationSingle = 0; |
||
101 | public static $relationMutual = 1; |
||
102 | public $relationType = 1; |
||
103 | public static $relationTypes = [ |
||
104 | 0 => 'Single', |
||
105 | 1 => 'Mutual', |
||
106 | ]; |
||
107 | |||
108 | /** |
||
109 | * @var string the attribute name of which determines the relation type. |
||
110 | */ |
||
111 | public $mutualTypeAttribute = 'type'; |
||
112 | public static $mutualTypeNormal = 0x00; |
||
113 | public static $mutualTypeSuspend = 0x01; |
||
114 | |||
115 | /** |
||
116 | * @var array Mutual types. |
||
117 | */ |
||
118 | public static $mutualTypes = [ |
||
119 | 0x00 => 'Normal', |
||
120 | 0x01 => 'Suspend', |
||
121 | ]; |
||
122 | |||
123 | /** |
||
124 | * @var string the attribute name of which determines the `favorite` field. |
||
125 | */ |
||
126 | public $favoriteAttribute = 'favorite'; |
||
127 | |||
128 | /** |
||
129 | * Permit to build self relation. |
||
130 | * @var boolean |
||
131 | */ |
||
132 | public $relationSelf = false; |
||
133 | |||
134 | /** |
||
135 | * Get whether this relation is favorite or not. |
||
136 | * @return boolean |
||
137 | */ |
||
138 | 1 | public function getIsFavorite() |
|
139 | { |
||
140 | 1 | $favoriteAttribute = $this->favoriteAttribute; |
|
141 | 1 | return (is_string($favoriteAttribute) && !empty($favoriteAttribute)) ? |
|
142 | 1 | (int) $this->$favoriteAttribute > 0 : null; |
|
143 | } |
||
144 | |||
145 | /** |
||
146 | * Set favorite. |
||
147 | * @param boolean $fav |
||
148 | */ |
||
149 | 1 | public function setIsFavorite($fav) |
|
150 | { |
||
151 | 1 | $favoriteAttribute = $this->favoriteAttribute; |
|
152 | 1 | return (is_string($favoriteAttribute) && !empty($favoriteAttribute)) ? |
|
153 | 1 | $this->$favoriteAttribute = ($fav ? 1 : 0) : null; |
|
154 | } |
||
155 | |||
156 | /** |
||
157 | * @inheritdoc |
||
158 | */ |
||
159 | 46 | public function rules() |
|
160 | { |
||
161 | 46 | return array_merge(parent::rules(), $this->getUserRelationRules()); |
|
162 | } |
||
163 | |||
164 | /** |
||
165 | * Validation rules associated with user relation. |
||
166 | * @return array rules. |
||
167 | */ |
||
168 | 46 | public function getUserRelationRules() |
|
169 | { |
||
170 | 46 | $rules = []; |
|
171 | 46 | if ($this->relationType == static::$relationMutual) { |
|
172 | $rules = [ |
||
173 | 12 | [[$this->mutualTypeAttribute], 'in', 'range' => array_keys(static::$mutualTypes)], |
|
174 | 12 | [[$this->mutualTypeAttribute], 'default', 'value' => static::$mutualTypeNormal], |
|
175 | ]; |
||
176 | } |
||
177 | 46 | return array_merge($rules, $this->getRemarkRules(), |
|
178 | 46 | $this->getFavoriteRules(), |
|
179 | 46 | $this->getGroupsRules(), |
|
180 | 46 | $this->getOtherGuidRules()); |
|
181 | } |
||
182 | |||
183 | /** |
||
184 | * Get remark. |
||
185 | * @return string remark. |
||
186 | */ |
||
187 | 1 | public function getRemark() |
|
188 | { |
||
189 | 1 | $remarkAttribute = $this->remarkAttribute; |
|
190 | 1 | return (is_string($remarkAttribute) && !empty($remarkAttribute)) ? $this->$remarkAttribute : null; |
|
191 | } |
||
192 | |||
193 | /** |
||
194 | * Set remark. |
||
195 | * @param string $remark |
||
196 | * @return string remark. |
||
197 | */ |
||
198 | 49 | public function setRemark($remark) |
|
199 | { |
||
200 | 49 | $remarkAttribute = $this->remarkAttribute; |
|
201 | 49 | return (is_string($remarkAttribute) && !empty($remarkAttribute)) ? $this->$remarkAttribute = $remark : null; |
|
202 | } |
||
203 | |||
204 | /** |
||
205 | * Validation rules associated with remark attribute. |
||
206 | * @return array rules. |
||
207 | */ |
||
208 | 46 | public function getRemarkRules() |
|
209 | { |
||
210 | 46 | return is_string($this->remarkAttribute) ? [ |
|
211 | 46 | [[$this->remarkAttribute], 'string'], |
|
212 | 46 | [[$this->remarkAttribute], 'default', 'value' => ''], |
|
213 | 46 | ] : []; |
|
214 | } |
||
215 | |||
216 | /** |
||
217 | * Validation rules associated with favorites attribute. |
||
218 | * @return array rules. |
||
219 | */ |
||
220 | 46 | public function getFavoriteRules() |
|
221 | { |
||
222 | 46 | return is_string($this->favoriteAttribute) ? [ |
|
223 | 46 | [[$this->favoriteAttribute], 'boolean'], |
|
224 | 46 | [[$this->favoriteAttribute], 'default', 'value' => 0], |
|
225 | 46 | ] : []; |
|
226 | } |
||
227 | |||
228 | /** |
||
229 | * Validation rules associated with other guid attribute. |
||
230 | * @return array rules. |
||
231 | */ |
||
232 | 46 | public function getOtherGuidRules() |
|
233 | { |
||
234 | 46 | $rules = array_merge($this->getMutualRules(), [ |
|
235 | 46 | [[$this->otherGuidAttribute, |
|
236 | 46 | $this->createdByAttribute], |
|
0 ignored issues
–
show
|
|||
237 | 46 | 'unique', |
|
238 | 46 | 'targetAttribute' => [$this->otherGuidAttribute, $this->createdByAttribute]], |
|
239 | ]); |
||
240 | 46 | return $rules; |
|
241 | } |
||
242 | |||
243 | /** |
||
244 | * Attach events associated with user relation. |
||
245 | */ |
||
246 | 49 | public function initUserRelationEvents() |
|
247 | { |
||
248 | 49 | $this->on(static::EVENT_INIT, [$this, 'onInitBlamesLimit']); |
|
0 ignored issues
–
show
It seems like
on() 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 ![]() |
|||
249 | 49 | $this->on(static::$eventNewRecordCreated, [$this, 'onInitGroups']); |
|
0 ignored issues
–
show
It seems like
on() 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 ![]() |
|||
250 | 49 | $this->on(static::$eventNewRecordCreated, [$this, 'onInitRemark']); |
|
0 ignored issues
–
show
It seems like
on() 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 ![]() |
|||
251 | 49 | $this->on(static::$eventMultipleBlamesChanged, [$this, 'onBlamesChanged']); |
|
0 ignored issues
–
show
It seems like
on() 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 ![]() |
|||
252 | 49 | $this->on(static::EVENT_AFTER_INSERT, [$this, 'onInsertRelation']); |
|
0 ignored issues
–
show
It seems like
on() 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 ![]() |
|||
253 | 49 | $this->on(static::EVENT_AFTER_UPDATE, [$this, 'onUpdateRelation']); |
|
0 ignored issues
–
show
It seems like
on() 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 ![]() |
|||
254 | 49 | $this->on(static::EVENT_AFTER_DELETE, [$this, 'onDeleteRelation']); |
|
0 ignored issues
–
show
It seems like
on() 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 ![]() |
|||
255 | 49 | } |
|
256 | |||
257 | /** |
||
258 | * Get opposite relation against self. |
||
259 | * @return static |
||
260 | */ |
||
261 | 1 | public function getOpposite() |
|
262 | { |
||
263 | 1 | if ($this->isNewRecord) { |
|
0 ignored issues
–
show
The property
isNewRecord does not exist. Did you maybe forget to declare it?
In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code: class MyClass { }
$x = new MyClass();
$x->foo = true;
Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion: class MyClass {
public $foo;
}
$x = new MyClass();
$x->foo = true;
![]() |
|||
264 | 1 | return null; |
|
265 | } |
||
266 | 1 | return static::find()->opposite($this->initiator, $this->recipient); |
|
267 | } |
||
268 | |||
269 | /** |
||
270 | * Check whether the initiator is followed by recipient. |
||
271 | * @param BaseUserModel $initiator |
||
272 | * @param BaseUserModel $recipient |
||
273 | * @return boolean |
||
274 | */ |
||
275 | 6 | public static function isFollowed($initiator, $recipient) |
|
276 | { |
||
277 | 6 | return static::find()->initiators($recipient)->recipients($initiator)->exists(); |
|
278 | } |
||
279 | |||
280 | /** |
||
281 | * Check whether the initiator is following recipient. |
||
282 | * @param BaseUserModel $initiator |
||
283 | * @param BaseUserModel $recipient |
||
284 | * @return boolean |
||
285 | */ |
||
286 | 6 | public static function isFollowing($initiator, $recipient) |
|
287 | { |
||
288 | 6 | return static::find()->initiators($initiator)->recipients($recipient)->exists(); |
|
289 | } |
||
290 | |||
291 | /** |
||
292 | * Check whether the initiator is following and followed by recipient mutually (Single Relation). |
||
293 | * Or check whether the initiator and recipient are friend whatever the mutual type is normal or suspend. |
||
294 | * @param BaseUserModel $initiator |
||
295 | * @param BaseUserModel $recipient |
||
296 | * @return boolean |
||
297 | */ |
||
298 | 3 | public static function isMutual($initiator, $recipient) |
|
299 | { |
||
300 | 3 | return static::isFollowed($initiator, $recipient) && static::isFollowing($initiator, $recipient); |
|
301 | } |
||
302 | |||
303 | /** |
||
304 | * Check whether the initiator is following and followed by recipient mutually (Single Relation). |
||
305 | * Or check whether the initiator and recipient are friend if the mutual type is normal. |
||
306 | * @param BaseUserModel $initiator |
||
307 | * @param BaseUserModel $recipient |
||
308 | * @return boolean |
||
309 | */ |
||
310 | 6 | public static function isFriend($initiator, $recipient) |
|
311 | { |
||
312 | 6 | $query = static::find(); |
|
313 | 6 | $model = $query->noInitModel; |
|
314 | /* @var $model static */ |
||
315 | 6 | if ($model->relationType == static::$relationSingle) { |
|
316 | 2 | return static::isMutual($initiator, $recipient); |
|
317 | } |
||
318 | 4 | if ($model->relationType == static::$relationMutual) { |
|
319 | 4 | $relation = static::find()->initiators($initiator)->recipients($recipient)-> |
|
320 | 4 | andWhere([$model->mutualTypeAttribute => static::$mutualTypeNormal])->exists(); |
|
321 | 4 | $inverse = static::find()->recipients($initiator)->initiators($recipient)-> |
|
322 | 4 | andWhere([$model->mutualTypeAttribute => static::$mutualTypeNormal])->exists(); |
|
323 | 4 | return $relation && $inverse; |
|
324 | } |
||
325 | return false; |
||
326 | } |
||
327 | |||
328 | /** |
||
329 | * Build new or return existed suspend mutual relation, or return null if |
||
330 | * current type is not mutual. |
||
331 | * @see buildRelation() |
||
332 | * @param BaseUserModel|string $user Initiator or its GUID. |
||
333 | * @param BaseUserModel|string $other Recipient or its GUID. |
||
334 | * @return static The relation will be |
||
335 | * given if exists, or return a new relation. |
||
336 | */ |
||
337 | 15 | public static function buildSuspendRelation($user, $other) |
|
338 | { |
||
339 | 15 | $relation = static::buildRelation($user, $other); |
|
340 | 15 | if (!$relation || $relation->relationType != static::$relationMutual) { |
|
341 | 1 | return null; |
|
342 | } |
||
343 | 14 | $relation->setMutualType(static::$mutualTypeSuspend); |
|
344 | 14 | return $relation; |
|
345 | } |
||
346 | |||
347 | /** |
||
348 | * Build new or return existed normal relation. |
||
349 | * The status of mutual relation will be changed to normal if it is not. |
||
350 | * @see buildRelation() |
||
351 | * @param BaseUserModel|string $user Initiator or its GUID. |
||
352 | * @param BaseUserModel|string $other Recipient or its GUID. |
||
353 | * @return static The relation will be |
||
354 | * given if exists, or return a new relation. |
||
355 | */ |
||
356 | 49 | public static function buildNormalRelation($user, $other) |
|
357 | { |
||
358 | 49 | $relation = static::buildRelation($user, $other); |
|
359 | 49 | if (!$relation) { |
|
360 | 1 | return null; |
|
361 | } |
||
362 | 49 | if ($relation->relationType == static::$relationMutual) { |
|
363 | 14 | $relation->setMutualType(static::$mutualTypeNormal); |
|
364 | } |
||
365 | 49 | return $relation; |
|
366 | } |
||
367 | |||
368 | /** |
||
369 | * Transform relation from suspend to normal. |
||
370 | * Note: You should ensure the relation model is not new one. |
||
371 | * @param static $relation |
||
0 ignored issues
–
show
|
|||
372 | * @return boolean |
||
373 | */ |
||
374 | 2 | public static function transformSuspendToNormal($relation) |
|
375 | { |
||
376 | 2 | if (!($relation instanceof static) || $relation->getIsNewRecord() || |
|
0 ignored issues
–
show
It seems like
getIsNewRecord() 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 ![]() |
|||
377 | 1 | $relation->relationType != static::$relationMutual) { |
|
378 | 1 | return false; |
|
379 | } |
||
380 | 1 | $new = static::buildNormalRelation($relation->initiator, $relation->recipient); |
|
381 | 1 | return $new->save() && $relation->refresh(); |
|
0 ignored issues
–
show
It seems like
save() 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
refresh() 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 ![]() |
|||
382 | } |
||
383 | |||
384 | /** |
||
385 | * Revert relation from normal to suspend. |
||
386 | * Note: You should ensure the relation model is not new one. |
||
387 | * @param static $relation |
||
0 ignored issues
–
show
|
|||
388 | * @return boolean |
||
389 | */ |
||
390 | 2 | public static function revertNormalToSuspend($relation) |
|
391 | { |
||
392 | 2 | if (!($relation instanceof static) || $relation->getIsNewRecord() || |
|
0 ignored issues
–
show
It seems like
getIsNewRecord() 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 ![]() |
|||
393 | 1 | $relation->relationType != static::$relationMutual) { |
|
394 | 1 | return false; |
|
395 | } |
||
396 | 1 | $new = static::buildSuspendRelation($relation->initiator, $relation->recipient); |
|
397 | 1 | return $new->save() && $relation->refresh(); |
|
0 ignored issues
–
show
It seems like
save() 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
refresh() 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 ![]() |
|||
398 | } |
||
399 | |||
400 | /** |
||
401 | * Build new or return existed relation between initiator and recipient. |
||
402 | * If relation between initiator and recipient is not found, new relation will |
||
403 | * be built. If initiator and recipient are the same one and it is not allowed |
||
404 | * to build self relation, null will be given. |
||
405 | * If you want to know whether the relation exists, you can check the return |
||
406 | * value of `getIsNewRecord()` method. |
||
407 | * @param BaseUserModel|string $user Initiator or its GUID. |
||
408 | * @param BaseUserModel|string $other Recipient or its GUID. |
||
409 | * @return static The relation will be |
||
410 | * given if exists, or return a new relation. Or return null if not allowed |
||
411 | * to build self relation, |
||
412 | */ |
||
413 | 49 | protected static function buildRelation($user, $other) |
|
414 | { |
||
415 | 49 | $relationQuery = static::find()->initiators($user)->recipients($other); |
|
416 | 49 | $noInit = $relationQuery->noInitModel; |
|
417 | 49 | $relation = $relationQuery->one(); |
|
418 | 49 | if (!$relation) { |
|
419 | 49 | $hostClass = $noInit->hostClass; |
|
420 | 49 | if ($user instanceof BaseUserModel) { |
|
421 | 49 | $hostClass = $hostClass ? : $user->className(); |
|
0 ignored issues
–
show
$hostClass is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
422 | 49 | $user = $user->getGUID(); |
|
423 | } |
||
424 | 49 | if ($other instanceof BaseUserModel) { |
|
425 | 49 | $other = $other->getGUID(); |
|
426 | } |
||
427 | 49 | if (!$noInit->relationSelf && $user == $other) { |
|
428 | 1 | return null; |
|
429 | } |
||
430 | 49 | $relation = new static(['host' => $user, 'recipient' => $other]); |
|
0 ignored issues
–
show
The call to
UserRelationTrait::__construct() has too many arguments starting with array('host' => $user, 'recipient' => $other) .
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue. If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. In this case you can add the ![]() |
|||
431 | } |
||
432 | 49 | return $relation; |
|
433 | } |
||
434 | |||
435 | /** |
||
436 | * Build opposite relation throughout the current relation. The opposite |
||
437 | * relation will be given if existed. |
||
438 | * @param static $relation |
||
0 ignored issues
–
show
|
|||
439 | * @return static |
||
440 | */ |
||
441 | 12 | protected static function buildOppositeRelation($relation) |
|
442 | { |
||
443 | 12 | if (!$relation) { |
|
444 | return null; |
||
445 | } |
||
446 | 12 | $opposite = static::buildRelation($relation->recipient, $relation->initiator); |
|
447 | 12 | if ($relation->relationType == static::$relationSingle) { |
|
448 | $opposite->relationType = static::$relationSingle; |
||
449 | 12 | } elseif ($relation->relationType == static::$relationMutual) { |
|
450 | 12 | $opposite->setMutualType($relation->getMutualType()); |
|
451 | } |
||
452 | 12 | return $opposite; |
|
453 | } |
||
454 | |||
455 | /** |
||
456 | * Get mutual type. |
||
457 | * @return integer |
||
458 | */ |
||
459 | 12 | public function getMutualType() |
|
460 | { |
||
461 | 12 | $btAttribute = $this->mutualTypeAttribute; |
|
462 | 12 | if (is_string($btAttribute) && !empty($btAttribute)) { |
|
463 | 12 | return $this->$btAttribute; |
|
464 | } |
||
465 | return static::$mutualTypeNormal; |
||
466 | } |
||
467 | |||
468 | /** |
||
469 | * Set mutual type. |
||
470 | * @param integer $type |
||
471 | * @return integer |
||
472 | */ |
||
473 | 14 | protected function setMutualType($type) |
|
474 | { |
||
475 | 14 | if (!array_key_exists($type, static::$mutualTypes)) { |
|
476 | $type = static::$mutualTypeNormal; |
||
477 | } |
||
478 | 14 | $btAttribute = $this->mutualTypeAttribute; |
|
479 | 14 | if (is_string($btAttribute) && !empty($btAttribute)) { |
|
480 | 14 | return $this->$btAttribute = $type; |
|
481 | } |
||
482 | return static::$mutualTypeNormal; |
||
483 | } |
||
484 | |||
485 | /** |
||
486 | * Insert relation, the process is placed in a transaction. |
||
487 | * Note: This feature only support relational databases and skip all errors. |
||
488 | * If you don't want to use transaction or database doesn't support it, |
||
489 | * please use `save()` directly. |
||
490 | * @param static $relation |
||
0 ignored issues
–
show
|
|||
491 | * @param Connection $connection |
||
492 | * @return boolean |
||
493 | * @throws InvalidValueException |
||
494 | * @throws InvalidConfigException |
||
495 | * @throws IntegrityException |
||
496 | */ |
||
497 | 1 | public static function insertRelation($relation, Connection $connection = null) |
|
498 | { |
||
499 | 1 | if (!($relation instanceof static)) { |
|
500 | 1 | return false; |
|
501 | } |
||
502 | 1 | if (!$relation->getIsNewRecord()) { |
|
0 ignored issues
–
show
It seems like
getIsNewRecord() 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 ![]() |
|||
503 | 1 | throw new InvalidValueException('This relation is not new one.'); |
|
504 | } |
||
505 | 1 | if (!$connection && isset(\Yii::$app->db) && \Yii::$app->db instanceof Connection) { |
|
506 | 1 | $connection = \Yii::$app->db; |
|
507 | } |
||
508 | 1 | if (!$connection) { |
|
509 | throw new InvalidConfigException('Invalid database connection.'); |
||
510 | } |
||
511 | /* @var $db Connection */ |
||
512 | 1 | $transaction = $connection->beginTransaction(); |
|
513 | try { |
||
514 | 1 | if (!$relation->save()) { |
|
0 ignored issues
–
show
It seems like
save() 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 ![]() |
|||
515 | throw new IntegrityException('Relation insert failed.'); |
||
516 | } |
||
517 | 1 | $transaction->commit(); |
|
518 | } catch (\Exception $ex) { |
||
519 | $transaction->rollBack(); |
||
520 | return false; |
||
521 | } |
||
522 | 1 | return true; |
|
523 | } |
||
524 | |||
525 | /** |
||
526 | * Remove relation, the process is placed in transaction. |
||
527 | * Note: This feature only support relational databases and skip all errors. |
||
528 | * If you don't want to use transaction or database doesn't support it, |
||
529 | * please use `remove()` directly. |
||
530 | * @param static $relation |
||
0 ignored issues
–
show
|
|||
531 | * @param Connection $connection |
||
532 | * @return boolean|integer |
||
533 | * @throws InvalidConfigException |
||
534 | */ |
||
535 | 1 | public static function removeRelation($relation, Connection $connection = null) |
|
536 | { |
||
537 | 1 | if (!($relation instanceof static) || $relation->getIsNewRecord()) { |
|
0 ignored issues
–
show
It seems like
getIsNewRecord() 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 ![]() |
|||
538 | 1 | return false; |
|
539 | } |
||
540 | |||
541 | 1 | if (!$connection && isset(\Yii::$app->db) && \Yii::$app->db instanceof Connection) { |
|
542 | 1 | $connection = \Yii::$app->db; |
|
543 | } |
||
544 | 1 | if (!$connection) { |
|
545 | throw new InvalidConfigException('Invalid database connection.'); |
||
546 | } |
||
547 | /* @var $db Connection */ |
||
548 | 1 | $transaction = $connection->beginTransaction(); |
|
549 | try { |
||
550 | 1 | $result = $relation->remove(); |
|
551 | 1 | $transaction->commit(); |
|
552 | } catch (\Exception $ex) { |
||
553 | $transaction->rollBack(); |
||
554 | return false; |
||
555 | } |
||
556 | 1 | return $result; |
|
557 | } |
||
558 | |||
559 | /** |
||
560 | * Remove myself. |
||
561 | * @return integer|false The number of relations removed, or false if the remove |
||
562 | * is unsuccessful for some reason. Note that it is possible the number of relations |
||
563 | * removed is 0, even though the remove execution is successful. |
||
564 | */ |
||
565 | 49 | public function remove() |
|
566 | { |
||
567 | 49 | return $this->delete(); |
|
0 ignored issues
–
show
The method
delete() does not exist on rhosocial\base\models\traits\UserRelationTrait . Did you maybe mean onDeleteRelation() ?
This check marks calls to methods that do not seem to exist on an object. This is most likely the result of a method being renamed without all references to it being renamed likewise. ![]() |
|||
568 | } |
||
569 | |||
570 | /** |
||
571 | * Remove first relation between initiator(s) and recipient(s). |
||
572 | * @param BaseUserModel|string|array $user Initiator or its guid, or array of them. |
||
573 | * @param BaseUserModel|string|array $other Recipient or its guid, or array of them. |
||
574 | * @return integer|false The number of relations removed. |
||
575 | */ |
||
576 | 1 | public static function removeOneRelation($user, $other) |
|
577 | { |
||
578 | 1 | $model = static::find()->initiators($user)->recipients($other)->one(); |
|
579 | 1 | if ($model instanceof static) { |
|
580 | 1 | return $model->remove(); |
|
581 | } |
||
582 | return false; |
||
583 | } |
||
584 | |||
585 | /** |
||
586 | * Remove all relations between initiator(s) and recipient(s). |
||
587 | * @param BaseUserModel|string|array $user Initiator or its guid, or array of them. |
||
588 | * @param BaseUserModel|string|array $other Recipient or its guid, or array of them. |
||
589 | * @return integer The number of relations removed. |
||
590 | */ |
||
591 | 15 | public static function removeAllRelations($user, $other) |
|
592 | { |
||
593 | 15 | $rni = static::buildNoInitModel(); |
|
594 | 15 | return static::deleteAll([$rni->createdByAttribute => BaseUserModel::compositeGUIDs($user), |
|
595 | 15 | $rni->otherGuidAttribute => BaseUserModel::compositeGUIDs($other)]); |
|
596 | } |
||
597 | |||
598 | /** |
||
599 | * Get first relation between initiator(s) and recipient(s). |
||
600 | * @param BaseUserModel|string|array $user Initiator or its guid, or array of them. |
||
601 | * @param BaseUserModel|string|array $other Recipient or its guid, or array of them. |
||
602 | * @return static |
||
603 | */ |
||
604 | 4 | public static function findOneRelation($user, $other) |
|
605 | { |
||
606 | 4 | return static::find()->initiators($user)->recipients($other)->one(); |
|
607 | } |
||
608 | |||
609 | /** |
||
610 | * Get first opposite relation between initiator(s) and recipient(s). |
||
611 | * @param BaseUserModel|string $user Initiator or its guid, or array of them. |
||
612 | * @param BaseUserModel|string $other Recipient or its guid, or array of them. |
||
613 | * @return static |
||
614 | */ |
||
615 | 1 | public static function findOneOppositeRelation($user, $other) |
|
616 | { |
||
617 | 1 | return static::find()->initiators($other)->recipients($user)->one(); |
|
618 | } |
||
619 | |||
620 | /** |
||
621 | * Get user's or users' all relations, or by specified groups. |
||
622 | * @param BaseUserModel|string|array $user Initiator or its GUID, or Initiators or their GUIDs. |
||
623 | * @param BaseUserRelationGroupModel|string|array|null $groups UserRelationGroup |
||
624 | * or its guid, or array of them. If you do not want to delimit the groups, please assign null. |
||
625 | * @return array all eligible relations |
||
626 | */ |
||
627 | 1 | public static function findOnesAllRelations($user, $groups = null) |
|
628 | { |
||
629 | 1 | return static::find()->initiators($user)->groups($groups)->all(); |
|
630 | } |
||
631 | |||
632 | /** |
||
633 | * Initialize groups attribute. |
||
634 | * @param ModelEvent $event |
||
635 | */ |
||
636 | 49 | public function onInitGroups($event) |
|
637 | { |
||
638 | 49 | $sender = $event->sender; |
|
639 | /* @var $sender static */ |
||
640 | 49 | $sender->removeAllGroups(); |
|
641 | 49 | } |
|
642 | |||
643 | /** |
||
644 | * Initialize remark attribute. |
||
645 | * @param ModelEvent $event |
||
646 | */ |
||
647 | 49 | public function onInitRemark($event) |
|
648 | { |
||
649 | 49 | $sender = $event->sender; |
|
650 | /* @var $sender static */ |
||
651 | 49 | $sender->setRemark(''); |
|
652 | 49 | } |
|
653 | |||
654 | /** |
||
655 | * The event triggered after insert new relation. |
||
656 | * The opposite relation should be inserted without triggering events |
||
657 | * simultaneously after new relation inserted, |
||
658 | * @param ModelEvent $event |
||
659 | * @throws IntegrityException throw if insert failed. |
||
660 | */ |
||
661 | 46 | public function onInsertRelation($event) |
|
662 | { |
||
663 | 46 | $sender = $event->sender; |
|
664 | /* @var $sender static */ |
||
665 | 46 | if ($sender->relationType == static::$relationMutual) { |
|
666 | 12 | $opposite = static::buildOppositeRelation($sender); |
|
667 | 12 | $opposite->off(static::EVENT_AFTER_INSERT, [$opposite, 'onInsertRelation']); |
|
0 ignored issues
–
show
It seems like
off() 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 ![]() |
|||
668 | 12 | if (!$opposite->save()) { |
|
0 ignored issues
–
show
It seems like
save() 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 ![]() |
|||
669 | $opposite->recordWarnings(); |
||
0 ignored issues
–
show
It seems like
recordWarnings() 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 ![]() |
|||
670 | throw new IntegrityException('Reverse relation insert failed.'); |
||
671 | } |
||
672 | 12 | $opposite->on(static::EVENT_AFTER_INSERT, [$opposite, 'onInsertRelation']); |
|
0 ignored issues
–
show
It seems like
on() 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 ![]() |
|||
673 | } |
||
674 | 46 | } |
|
675 | |||
676 | /** |
||
677 | * The event triggered after update relation. |
||
678 | * The opposite relation should be updated without triggering events |
||
679 | * simultaneously after existed relation removed. |
||
680 | * @param ModelEvent $event |
||
681 | * @throw IntegrityException throw if update failed. |
||
682 | */ |
||
683 | 11 | public function onUpdateRelation($event) |
|
684 | { |
||
685 | 11 | $sender = $event->sender; |
|
686 | /* @var $sender static */ |
||
687 | 11 | if ($sender->relationType == static::$relationMutual) { |
|
688 | 2 | $opposite = static::buildOppositeRelation($sender); |
|
689 | 2 | $opposite->off(static::EVENT_AFTER_UPDATE, [$opposite, 'onUpdateRelation']); |
|
0 ignored issues
–
show
It seems like
off() 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 ![]() |
|||
690 | 2 | if (!$opposite->save()) { |
|
0 ignored issues
–
show
It seems like
save() 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 ![]() |
|||
691 | $opposite->recordWarnings(); |
||
0 ignored issues
–
show
It seems like
recordWarnings() 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 ![]() |
|||
692 | throw new IntegrityException('Reverse relation update failed.'); |
||
693 | } |
||
694 | 2 | $opposite->on(static::EVENT_AFTER_UPDATE, [$opposite, 'onUpdateRelation']); |
|
0 ignored issues
–
show
It seems like
on() 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 ![]() |
|||
695 | } |
||
696 | 11 | } |
|
697 | |||
698 | /** |
||
699 | * The event triggered after delete relation. |
||
700 | * The opposite relation should be deleted without triggering events |
||
701 | * simultaneously after existed relation removed. |
||
702 | * @param ModelEvent $event |
||
703 | */ |
||
704 | 49 | public function onDeleteRelation($event) |
|
705 | { |
||
706 | 49 | $sender = $event->sender; |
|
707 | /* @var $sender static */ |
||
708 | 49 | if ($sender->relationType == static::$relationMutual) { |
|
709 | 14 | $sender->off(static::EVENT_AFTER_DELETE, [$sender, 'onDeleteRelation']); |
|
0 ignored issues
–
show
It seems like
off() 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 ![]() |
|||
710 | 14 | static::removeAllRelations($sender->recipient, $sender->initiator); |
|
711 | 14 | $sender->on(static::EVENT_AFTER_DELETE, [$sender, 'onDeleteRelation']); |
|
0 ignored issues
–
show
It seems like
on() 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 ![]() |
|||
712 | } |
||
713 | 49 | } |
|
714 | } |
||
715 |
In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:
Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion: