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 | * This file contains functionality to keep track of notifications for players and communicate with external push services |
||
4 | * |
||
5 | * @package BZiON\Models |
||
6 | * @license https://github.com/allejo/bzion/blob/master/LICENSE.md GNU General Public License Version 3 |
||
7 | */ |
||
8 | |||
9 | use BZIon\Event\Event; |
||
10 | use BZIon\Event\Events; |
||
11 | use BZIon\Model\Column\Timestamp; |
||
12 | use BZIon\NotificationAdapter\NotificationAdapter; |
||
13 | |||
14 | /** |
||
15 | * A notification to a player |
||
16 | * @package BZiON\Models |
||
17 | */ |
||
18 | class Notification extends Model |
||
19 | { |
||
20 | use Timestamp; |
||
21 | |||
22 | /** |
||
23 | * The id of the notified player |
||
24 | * @var int |
||
25 | */ |
||
26 | protected $receiver; |
||
27 | |||
28 | /** |
||
29 | * The type of the notification |
||
30 | * |
||
31 | * Can be one of the constants in BZIon\Event\Events |
||
32 | * |
||
33 | * @var int |
||
34 | */ |
||
35 | protected $type; |
||
36 | |||
37 | /** |
||
38 | * The event of the notification |
||
39 | * @var Event |
||
40 | */ |
||
41 | protected $event; |
||
42 | |||
43 | /** |
||
44 | * Services that will be notified when a new notification is created |
||
45 | * @var NotificationAdapter[] |
||
46 | */ |
||
47 | private static $adapters = array(); |
||
48 | |||
49 | const DEFAULT_STATUS = 'read'; |
||
50 | |||
51 | /** |
||
52 | * The name of the database table used for queries |
||
53 | */ |
||
54 | const TABLE = "notifications"; |
||
55 | |||
56 | /** |
||
57 | * {@inheritdoc} |
||
58 | */ |
||
59 | View Code Duplication | protected function assignResult($notification) |
|
60 | { |
||
61 | $this->receiver = $notification['receiver']; |
||
62 | $this->type = $notification['type']; |
||
63 | $this->event = unserialize($notification['event']); |
||
64 | $this->status = $notification['status']; |
||
65 | $this->timestamp = TimeDate::fromMysql($notification['timestamp']); |
||
66 | } |
||
67 | |||
68 | 2 | /** |
|
69 | * Enter a new notification into the database |
||
70 | 2 | * @param int $receiver The receiver's ID |
|
71 | 2 | * @param string $type The type of the notification |
|
72 | 2 | * @param Event $event The event of the notification |
|
73 | 2 | * @param string $timestamp The timestamp of the notification |
|
74 | 2 | * @param string $status The status of the notification (unread, read, deleted) |
|
75 | 2 | * @return Notification An object representing the notification that was just entered |
|
76 | */ |
||
77 | View Code Duplication | public static function newNotification($receiver, $type, $event, $timestamp = "now", $status = "unread") |
|
78 | { |
||
79 | $notification = self::create(array( |
||
80 | "receiver" => $receiver, |
||
81 | "type" => $type, |
||
82 | "event" => serialize($event), |
||
83 | "timestamp" => TimeDate::from($timestamp)->toMysql(), |
||
84 | "status" => $status |
||
85 | )); |
||
86 | 2 | ||
87 | return $notification; |
||
88 | 2 | } |
|
89 | 2 | ||
90 | 2 | /** |
|
91 | 2 | * Show a list of notifications for a specific user |
|
92 | 2 | * @param int $receiver The ID of the recipient of the notifications |
|
93 | 2 | * @param bool $onlyUnread False to show both unread & read notifications |
|
94 | * @return Notification[] |
||
95 | */ |
||
96 | 2 | public static function getNotifications($receiver, $onlyUnread = false) |
|
97 | { |
||
98 | $statuses = array('unread'); |
||
99 | if (!$onlyUnread) { |
||
100 | $statuses[] = 'read'; |
||
101 | } |
||
102 | |||
103 | return self::getQueryBuilder() |
||
104 | ->where('status')->isOneOf($statuses) |
||
105 | ->where('receiver')->is($receiver) |
||
106 | ->getModels(); |
||
107 | } |
||
108 | |||
109 | /** |
||
110 | * Show the number of notifications the user hasn't read yet |
||
111 | * @param int $receiver |
||
112 | * @return int |
||
113 | */ |
||
114 | public static function countUnreadNotifications($receiver) |
||
115 | { |
||
116 | return self::fetchCount("WHERE receiver = ? AND status = 'unread'", |
||
117 | $receiver |
||
118 | ); |
||
119 | } |
||
120 | |||
121 | /** |
||
122 | * Get the receiving player of the notification |
||
123 | 1 | * @return Player |
|
124 | */ |
||
125 | 1 | public function getReceiver() |
|
126 | 1 | { |
|
127 | return Player::get($this->receiver); |
||
128 | } |
||
129 | |||
130 | /** |
||
131 | * Get the type of the notification |
||
132 | * |
||
133 | * Do not use Notification::getType(), as it returns the name of the class |
||
134 | 2 | * (i.e. notification) |
|
135 | * |
||
136 | 2 | * @return int |
|
137 | */ |
||
138 | public function getCategory() |
||
139 | { |
||
140 | return $this->type; |
||
141 | } |
||
142 | |||
143 | /** |
||
144 | * Get the event of the notification |
||
145 | * @return Event |
||
146 | 1 | */ |
|
147 | public function getEvent() |
||
148 | 1 | { |
|
149 | return $this->event; |
||
150 | } |
||
151 | |||
152 | /** |
||
153 | * Finds if the notification has been read by the user |
||
154 | * |
||
155 | 1 | * This returns true even if the notification is deleted |
|
156 | * @return bool |
||
157 | 1 | */ |
|
158 | public function isRead() |
||
159 | { |
||
160 | return $this->status != "unread"; |
||
161 | } |
||
162 | |||
163 | /** |
||
164 | * Mark the notification as read by the user |
||
165 | * @return void |
||
166 | 1 | */ |
|
167 | public function markAsRead() |
||
168 | 1 | { |
|
169 | if ($this->status == "deleted") { |
||
170 | return; |
||
171 | } |
||
172 | |||
173 | $this->update('status', $this->status = "read"); |
||
174 | } |
||
175 | 1 | ||
176 | /** |
||
177 | 1 | * Make sure that the user is shown the notification immediately if they are |
|
178 | * browsing |
||
179 | */ |
||
180 | public function push() |
||
181 | 1 | { |
|
182 | 1 | self::pushEvent('notification', $this); |
|
183 | } |
||
184 | |||
185 | /** |
||
186 | * Get the available actions for the notification |
||
187 | * |
||
188 | 1 | * @param bool $email Whether actions should be formatted for e-mails |
|
189 | * @return array |
||
190 | 1 | */ |
|
191 | 1 | public function getActions($email = false) |
|
192 | { |
||
193 | switch ($this->type) { |
||
194 | case Events::TEAM_INVITE: |
||
195 | return array( |
||
196 | ($email) ? 'Accept invitation' : 'Accept' => $this->event->getInvitation()->getUrl('accept', $email) |
||
197 | ); |
||
198 | default: |
||
199 | return array(); |
||
200 | } |
||
201 | } |
||
202 | |||
203 | /** |
||
204 | * Push an event to the event adapters |
||
205 | * @param string $type The type of the event |
||
206 | * @param mixed $data The data for the event |
||
207 | * @return void |
||
208 | */ |
||
209 | public static function pushEvent($type, $data = null) |
||
210 | { |
||
211 | switch ($type) { |
||
212 | case 'message': |
||
213 | $message = array( |
||
214 | 'conversation' => $data['message']->getConversation()->getId(), |
||
215 | 'message' => $data['message']->getId(), |
||
216 | 'author' => $data['message']->getAuthor()->getId(), |
||
217 | 1 | 'recipients' => $data['recipients'] |
|
218 | ); |
||
219 | break; |
||
220 | 1 | case 'notification': |
|
221 | $message = array( |
||
222 | 1 | 'type' => $data->getType(), |
|
223 | 1 | 'receiver' => $data->getReceiver()->getId(), |
|
224 | 1 | 'notification' => $data->getId() |
|
225 | 1 | ); |
|
226 | break; |
||
227 | 1 | case 'blank': |
|
228 | 1 | $message = null; |
|
229 | break; |
||
230 | 1 | default: |
|
231 | 1 | $message = $data; |
|
232 | 1 | } |
|
233 | |||
234 | 1 | foreach (self::$adapters as $adapter) { |
|
235 | $adapter->trigger($type, $message); |
||
236 | } |
||
237 | } |
||
238 | |||
239 | /** |
||
240 | * Initialize the external push adapters |
||
241 | * @return void |
||
242 | 1 | */ |
|
243 | public static function initializeAdapters() |
||
244 | { |
||
245 | 1 | if (self::$adapters) { |
|
0 ignored issues
–
show
|
|||
246 | // The adapters have already been initialized, no need to do anything! |
||
247 | return; |
||
248 | } |
||
249 | |||
250 | $adapters = array( |
||
251 | 1 | 'BZIon\NotificationAdapter\WebSocketAdapter' |
|
252 | ); |
||
253 | 1 | ||
254 | foreach ($adapters as $adapter) { |
||
255 | if ($adapter::isEnabled()) { |
||
256 | self::$adapters[] = new $adapter(); |
||
257 | } |
||
258 | } |
||
259 | 1 | } |
|
260 | |||
261 | /** |
||
262 | 1 | * {@inheritdoc} |
|
263 | 1 | */ |
|
264 | 1 | public static function getActiveStatuses() |
|
265 | { |
||
266 | return array('read', 'unread'); |
||
267 | 1 | } |
|
268 | |||
269 | /** |
||
270 | * Get a query builder for notifications |
||
271 | * @return NotificationQueryBuilder |
||
272 | */ |
||
273 | public static function getQueryBuilder() |
||
274 | { |
||
275 | return new NotificationQueryBuilder('Notification', array( |
||
276 | 'columns' => array( |
||
277 | 'receiver' => 'receiver', |
||
278 | 'timestamp' => 'timestamp', |
||
279 | 'status' => 'status' |
||
280 | ) |
||
281 | )); |
||
282 | } |
||
283 | } |
||
284 |
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.