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.name/ |
||
9 | * @copyright Copyright (c) 2016 vistart |
||
10 | * @license https://vistart.name/license/ |
||
11 | */ |
||
12 | |||
13 | namespace vistart\Models\traits; |
||
14 | |||
15 | use yii\base\ModelEvent; |
||
16 | use yii\db\AfterSaveEvent; |
||
17 | |||
18 | /** |
||
19 | * This trait should be used in models extended from models used BlameableTrait. |
||
20 | * Notice: The models used BlameableTrait are also models used EntityTrait. |
||
21 | * |
||
22 | * @property $recipient |
||
23 | * @version 2.0 |
||
24 | * @author vistart <[email protected]> |
||
25 | */ |
||
26 | trait MessageTrait |
||
27 | { |
||
28 | use MutualTrait; |
||
29 | |||
30 | public $attachmentAttribute = 'attachment'; |
||
31 | public $receivedAtAttribute = 'received_at'; |
||
32 | public $readAtAttribute = 'read_at'; |
||
33 | public static $eventMessageReceived = 'messageReceived'; |
||
34 | public static $eventMessageRead = 'messageRead'; |
||
35 | public $permitChangeContent = false; |
||
36 | public $permitChangeReceivedAt = false; |
||
37 | public $permitChangeReadAt = false; |
||
38 | |||
39 | 4 | public function hasBeenReceived() |
|
40 | { |
||
41 | 4 | return is_string($this->receivedAtAttribute) ? !$this->isInitDatetime($this->getReceivedAt()) : false; |
|
0 ignored issues
–
show
|
|||
42 | } |
||
43 | |||
44 | 4 | public function hasBeenRead() |
|
45 | { |
||
46 | 4 | return is_string($this->readAtAttribute) ? !$this->isInitDatetime($this->getReadAt()) : false; |
|
0 ignored issues
–
show
It seems like
isInitDatetime() 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 ![]() |
|||
47 | } |
||
48 | |||
49 | 2 | public function touchReceived() |
|
50 | { |
||
51 | 2 | return $this->setReceivedAt(static::currentDatetime()); |
|
52 | } |
||
53 | |||
54 | 2 | public function touchRead() |
|
55 | { |
||
56 | 2 | return $this->setReadAt(static::currentDatetime()); |
|
57 | } |
||
58 | |||
59 | 4 | public function getReceivedAt() |
|
60 | { |
||
61 | 4 | if (is_string($this->receivedAtAttribute)) { |
|
62 | 4 | $raAttribute = $this->receivedAtAttribute; |
|
63 | 4 | return $this->$raAttribute; |
|
64 | } |
||
65 | return null; |
||
66 | } |
||
67 | |||
68 | 8 | public function setReceivedAt($receivedAt) |
|
69 | { |
||
70 | 8 | if (is_string($this->receivedAtAttribute)) { |
|
71 | 8 | $raAttribute = $this->receivedAtAttribute; |
|
72 | 8 | return $this->$raAttribute = $receivedAt; |
|
73 | } |
||
74 | return null; |
||
75 | } |
||
76 | |||
77 | 4 | public function getReadAt() |
|
78 | { |
||
79 | 4 | if (is_string($this->readAtAttribute)) { |
|
80 | 4 | $raAttribute = $this->readAtAttribute; |
|
81 | 4 | return $this->$raAttribute; |
|
82 | } |
||
83 | return null; |
||
84 | } |
||
85 | |||
86 | 8 | public function setReadAt($readAt) |
|
87 | { |
||
88 | 8 | if (is_string($this->readAtAttribute)) { |
|
89 | 8 | $raAttribute = $this->readAtAttribute; |
|
90 | 8 | return $this->$raAttribute = $readAt; |
|
91 | } |
||
92 | return null; |
||
93 | } |
||
94 | |||
95 | /** |
||
96 | * @param ModelEvent $event |
||
97 | */ |
||
98 | 8 | public function onInitReceivedAtAttribute($event) |
|
99 | { |
||
100 | 8 | $sender = $event->sender; |
|
101 | /* @var $sender static */ |
||
102 | 8 | $sender->setReceivedAt(static::getInitDatetime($event)); |
|
103 | 8 | } |
|
104 | |||
105 | /** |
||
106 | * @param ModelEvent $event |
||
107 | */ |
||
108 | 8 | public function onInitReadAtAttribute($event) |
|
109 | { |
||
110 | 8 | $sender = $event->sender; |
|
111 | /* @var $sender static */ |
||
112 | 8 | $sender->setReadAt(static::getInitDatetime($event)); |
|
113 | 8 | } |
|
114 | |||
115 | /** |
||
116 | * We consider you have received the message if you read it. |
||
117 | * @param ModelEvent $event |
||
118 | */ |
||
119 | 4 | public function onReadAtChanged($event) |
|
120 | { |
||
121 | 4 | $sender = $event->sender; |
|
122 | 4 | $raAttribute = $sender->readAtAttribute; |
|
123 | 4 | if (!is_string($raAttribute)) { |
|
124 | return; |
||
125 | } |
||
126 | 4 | $reaAttribute = $sender->receivedAtAttribute; |
|
127 | 4 | if (is_string($reaAttribute) && !$sender->isInitDatetime($sender->$raAttribute) && $sender->isInitDatetime($sender->$reaAttribute)) { |
|
128 | 2 | $sender->$reaAttribute = $sender->currentDatetime(); |
|
129 | 2 | } |
|
130 | 4 | if ($sender->permitChangeReadAt) { |
|
131 | return; |
||
132 | } |
||
133 | 4 | $oldRa = $sender->getOldAttribute($raAttribute); |
|
134 | 4 | if ($oldRa != null && !$sender->isInitDatetime($oldRa) && $sender->$raAttribute != $oldRa) { |
|
135 | $sender->$raAttribute = $oldRa; |
||
136 | return; |
||
137 | } |
||
138 | 4 | } |
|
139 | |||
140 | /** |
||
141 | * You are not allowed to change receive time if you have received it. |
||
142 | * @param ModelEvent $event |
||
143 | */ |
||
144 | 4 | public function onReceivedAtChanged($event) |
|
145 | { |
||
146 | 4 | $sender = $event->sender; |
|
147 | 4 | $raAttribute = $sender->receivedAtAttribute; |
|
148 | 4 | if (!is_string($raAttribute)) { |
|
149 | return; |
||
150 | } |
||
151 | 4 | if ($sender->permitChangeReceivedAt) { |
|
152 | return; |
||
153 | } |
||
154 | 4 | $oldRa = $sender->getOldAttribute($raAttribute); |
|
155 | 4 | if ($oldRa != null && !$sender->isInitDatetime($oldRa) && $sender->$raAttribute != $oldRa) { |
|
156 | $sender->$raAttribute = $oldRa; |
||
157 | return; |
||
158 | } |
||
159 | 4 | } |
|
160 | |||
161 | /** |
||
162 | * You are not allowed to change the content if it is not new message. |
||
163 | * @param ModelEvent $event |
||
164 | */ |
||
165 | 4 | public function onContentChanged($event) |
|
166 | { |
||
167 | 4 | $sender = $event->sender; |
|
168 | 4 | if ($sender->permitChangeContent) { |
|
169 | return; |
||
170 | } |
||
171 | 4 | $cAttribute = $sender->contentAttribute; |
|
172 | 4 | $oldContent = $sender->getOldAttribute($cAttribute); |
|
173 | 4 | if ($oldContent != $sender->$cAttribute) { |
|
174 | 2 | $sender->$cAttribute = $oldContent; |
|
175 | 2 | } |
|
176 | 4 | } |
|
177 | |||
178 | /** |
||
179 | * Trigger message received or read events. |
||
180 | * @param AfterSaveEvent $event |
||
181 | */ |
||
182 | 4 | public function onMessageUpdated($event) |
|
183 | { |
||
184 | 4 | $sender = $event->sender; |
|
185 | 4 | $reaAttribute = $sender->receivedAtAttribute; |
|
186 | 4 | if (isset($event->changedAttributes[$reaAttribute]) && $event->changedAttributes[$reaAttribute] != $sender->$reaAttribute) { |
|
187 | 4 | $sender->trigger(static::$eventMessageReceived); |
|
188 | 4 | } |
|
189 | 4 | $raAttribute = $sender->readAtAttribute; |
|
190 | 4 | if (isset($event->changedAttributes[$raAttribute]) && $event->changedAttributes[$raAttribute] != $sender->$raAttribute) { |
|
191 | 2 | $sender->trigger(static::$eventMessageRead); |
|
192 | 2 | } |
|
193 | 4 | } |
|
194 | |||
195 | 8 | public function initMessageEvents() |
|
196 | { |
||
197 | 8 | $this->on(static::EVENT_BEFORE_INSERT, [$this, 'onInitReceivedAtAttribute']); |
|
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 ![]() |
|||
198 | 8 | $this->on(static::EVENT_BEFORE_INSERT, [$this, 'onInitReadAtAttribute']); |
|
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 ![]() |
|||
199 | 8 | $this->on(static::EVENT_BEFORE_UPDATE, [$this, 'onReceivedAtChanged']); |
|
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 ![]() |
|||
200 | 8 | $this->on(static::EVENT_BEFORE_UPDATE, [$this, 'onReadAtChanged']); |
|
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 ![]() |
|||
201 | 8 | $this->on(static::EVENT_BEFORE_UPDATE, [$this, 'onContentChanged']); |
|
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 ![]() |
|||
202 | 8 | $this->on(static::EVENT_AFTER_UPDATE, [$this, 'onMessageUpdated']); |
|
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 ![]() |
|||
203 | 8 | } |
|
204 | |||
205 | 8 | public function getMessageRules() |
|
206 | { |
||
207 | 8 | $rules = []; |
|
208 | 8 | $rules = array_merge($rules, $this->getMutualRules()); |
|
209 | 8 | if (is_string($this->attachmentAttribute)) { |
|
210 | 8 | $rules[] = [$this->attachmentAttribute, 'safe']; |
|
211 | 8 | } |
|
212 | 8 | if (is_string($this->receivedAtAttribute)) { |
|
213 | 8 | $rules[] = [$this->receivedAtAttribute, 'safe']; |
|
214 | 8 | } |
|
215 | 8 | if (is_string($this->readAtAttribute)) { |
|
216 | 8 | $rules[] = [$this->readAtAttribute, 'safe']; |
|
217 | 8 | } |
|
218 | 8 | return $rules; |
|
219 | } |
||
220 | |||
221 | 8 | public function rules() |
|
222 | { |
||
223 | 8 | return array_merge(parent::rules(), $this->getMessageRules()); |
|
224 | } |
||
225 | |||
226 | 8 | public function enabledFields() |
|
227 | { |
||
228 | 8 | $fields = parent::enabledFields(); |
|
229 | 8 | if (is_string($this->otherGuidAttribute)) { |
|
230 | 8 | $fields[] = $this->otherGuidAttribute; |
|
231 | 8 | } |
|
232 | 8 | if (is_string($this->attachmentAttribute)) { |
|
233 | 8 | $fields[] = $this->attachmentAttribute; |
|
234 | 8 | } |
|
235 | 8 | if (is_string($this->receivedAtAttribute)) { |
|
236 | 8 | $fields[] = $this->receivedAtAttribute; |
|
237 | 8 | } |
|
238 | 8 | if (is_string($this->readAtAttribute)) { |
|
239 | 8 | $fields[] = $this->readAtAttribute; |
|
240 | 8 | } |
|
241 | 8 | return $fields; |
|
242 | } |
||
243 | } |
||
244 |
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
The trait
Idable
provides a methodequalsId
that in turn relies on the methodgetId()
. If this method does not exist on a class mixing in this trait, the method will fail.Adding the
getId()
as an abstract method to the trait will make sure it is available.