These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | /** |
||
3 | * Elgg internal messages plugin |
||
4 | * This plugin lets users send messages to each other. |
||
5 | */ |
||
6 | |||
7 | elgg_register_event_handler('init', 'system', 'messages_init'); |
||
8 | |||
9 | function messages_init() { |
||
10 | |||
11 | // add page menu items |
||
12 | if (elgg_is_logged_in()) { |
||
13 | elgg_register_menu_item('page', [ |
||
14 | 'name' => 'messages:inbox', |
||
15 | 'text' => elgg_echo('messages:inbox'), |
||
16 | 'href' => "messages/inbox/" . elgg_get_logged_in_user_entity()->username, |
||
17 | 'context' => 'messages', |
||
18 | ]); |
||
19 | |||
20 | elgg_register_menu_item('page', [ |
||
21 | 'name' => 'messages:sentmessages', |
||
22 | 'text' => elgg_echo('messages:sentmessages'), |
||
23 | 'href' => "messages/sent/" . elgg_get_logged_in_user_entity()->username, |
||
24 | 'context' => 'messages', |
||
25 | ]); |
||
26 | } |
||
27 | |||
28 | // Extend system CSS with our own styles, which are defined in the messages/css view |
||
29 | elgg_extend_view('elgg.css', 'messages/css'); |
||
30 | elgg_extend_view('elgg.js', 'messages/js'); |
||
31 | |||
32 | // Register a page handler, so we can have nice URLs |
||
33 | elgg_register_page_handler('messages', 'messages_page_handler'); |
||
34 | |||
35 | // Register a URL handler |
||
36 | elgg_register_plugin_hook_handler('entity:url', 'object', 'messages_set_url'); |
||
37 | |||
38 | // Extend avatar hover menu |
||
39 | elgg_register_plugin_hook_handler('register', 'menu:user_hover', 'messages_user_hover_menu'); |
||
40 | |||
41 | // delete messages sent by a user when user is deleted |
||
42 | elgg_register_event_handler('delete', 'user', 'messages_purge'); |
||
43 | |||
44 | // ecml |
||
45 | elgg_register_plugin_hook_handler('get_views', 'ecml', 'messages_ecml_views_hook'); |
||
46 | |||
47 | // permission overrides |
||
48 | elgg_register_plugin_hook_handler('permissions_check:metadata', 'object', 'messages_can_edit_metadata'); |
||
49 | elgg_register_plugin_hook_handler('permissions_check', 'object', 'messages_can_edit'); |
||
50 | elgg_register_plugin_hook_handler('container_permissions_check', 'object', 'messages_can_edit_container'); |
||
51 | |||
52 | // Topbar menu. We assume this menu will render *after* a message is rendered. If a refactor/plugin |
||
53 | // causes it to render first, the unread count notification will not update until the next page. |
||
54 | elgg_register_plugin_hook_handler('register', 'menu:topbar', 'messages_register_topbar'); |
||
55 | } |
||
56 | |||
57 | /** |
||
58 | * Messages page handler |
||
59 | * |
||
60 | * @param array $page Array of URL components for routing |
||
61 | * @return bool |
||
62 | */ |
||
63 | function messages_page_handler($page) { |
||
64 | |||
65 | elgg_gatekeeper(); |
||
66 | |||
67 | elgg_push_breadcrumb(elgg_echo('messages'), 'messages/inbox/' . $current_user->username); |
||
68 | |||
69 | if (!isset($page[0])) { |
||
70 | $page[0] = 'inbox'; |
||
71 | } |
||
72 | |||
73 | // Support the old inbox url /messages/<username>, but only if it matches the logged in user. |
||
74 | // Otherwise having a username like "read" on the system could confuse this function. |
||
75 | if ($current_user->username === $page[0]) { |
||
76 | $page[1] = $page[0]; |
||
77 | $page[0] = 'inbox'; |
||
78 | } |
||
79 | |||
80 | if (!isset($page[1])) { |
||
81 | $page[1] = $current_user->username; |
||
82 | } |
||
83 | |||
84 | switch ($page[0]) { |
||
85 | case 'inbox': |
||
86 | echo elgg_view_resource('messages/inbox', [ |
||
87 | 'username' => $page[1], |
||
88 | ]); |
||
89 | break; |
||
90 | case 'sent': |
||
91 | echo elgg_view_resource('messages/sent', [ |
||
92 | 'username' => $page[1], |
||
93 | ]); |
||
94 | break; |
||
95 | case 'read': |
||
96 | echo elgg_view_resource('messages/read', [ |
||
97 | 'guid' => $page[1], |
||
98 | ]); |
||
99 | break; |
||
100 | case 'compose': |
||
101 | case 'add': |
||
102 | echo elgg_view_resource('messages/send'); |
||
103 | break; |
||
104 | default: |
||
105 | return false; |
||
106 | } |
||
107 | return true; |
||
108 | } |
||
109 | |||
110 | /** |
||
111 | * Add inbox link to topbar |
||
112 | * |
||
113 | * @param string $hook "register" |
||
114 | * @param string $type "menu:topbar" |
||
115 | * @param array $items Menu items |
||
116 | * @param array $params Hook params |
||
117 | * @return array |
||
118 | */ |
||
119 | function messages_register_topbar($hook, $type, $items, $params) { |
||
120 | if (!elgg_is_logged_in()) { |
||
121 | return; |
||
122 | } |
||
123 | |||
124 | $user = elgg_get_logged_in_user_entity(); |
||
125 | |||
126 | $text = elgg_echo('messages'); |
||
127 | $title = $text; |
||
128 | |||
129 | $num_messages = (int) messages_count_unread(); |
||
130 | if ($num_messages) { |
||
131 | $title .= " (" . elgg_echo("messages:unreadcount", [$num_messages]) . ")"; |
||
132 | } |
||
133 | |||
134 | $items[] = ElggMenuItem::factory([ |
||
135 | 'name' => 'messages', |
||
136 | 'href' => "messages/inbox/$user->username", |
||
137 | 'text' => $text, |
||
138 | 'priority' => 600, |
||
139 | 'title' => $title, |
||
140 | 'icon' => 'mail', |
||
141 | 'badge' => $num_messages ? $num_messages : null, |
||
142 | ]); |
||
143 | |||
144 | return $items; |
||
145 | } |
||
146 | |||
147 | /** |
||
148 | * Override the canEditMetadata function to return true for messages |
||
149 | * |
||
150 | */ |
||
151 | View Code Duplication | function messages_can_edit_metadata($hook_name, $entity_type, $return_value, $parameters) { |
|
152 | |||
153 | global $messagesendflag; |
||
154 | |||
155 | if ($messagesendflag !== 1) { |
||
156 | return; |
||
157 | } |
||
158 | |||
159 | $entity = elgg_extract('entity', $parameters); |
||
160 | if ($entity->getSubtype() == 'messages') { |
||
161 | return true; |
||
162 | } |
||
163 | } |
||
164 | |||
165 | /** |
||
166 | * Override the canEdit function to return true for messages within a particular context. |
||
167 | * |
||
168 | */ |
||
169 | View Code Duplication | function messages_can_edit($hook_name, $entity_type, $return_value, $parameters) { |
|
170 | |||
171 | global $messagesendflag; |
||
172 | |||
173 | if ($messagesendflag !== 1) { |
||
174 | return; |
||
175 | } |
||
176 | |||
177 | $entity = elgg_extract('entity', $parameters); |
||
178 | if ($entity->getSubtype() == 'messages') { |
||
179 | return true; |
||
180 | } |
||
181 | } |
||
182 | |||
183 | /** |
||
184 | * Prevent messages from generating a notification |
||
185 | */ |
||
186 | function messages_notification_msg($hook_name, $entity_type, $return_value, $params) { |
||
187 | $entity = elgg_extract('entity', $params); |
||
188 | if (!$entity instanceof ElggEntity) { |
||
189 | return; |
||
190 | } |
||
191 | |||
192 | if ($entity->getSubtype() == 'messages') { |
||
193 | return false; |
||
194 | } |
||
195 | } |
||
196 | |||
197 | /** |
||
198 | * Override the canEdit function to return true for messages within a particular context. |
||
199 | * |
||
200 | */ |
||
201 | function messages_can_edit_container($hook_name, $entity_type, $return_value, $parameters) { |
||
202 | |||
203 | global $messagesendflag; |
||
204 | |||
205 | if ($messagesendflag == 1) { |
||
206 | return true; |
||
207 | } |
||
208 | } |
||
209 | |||
210 | /** |
||
211 | * Send an internal message |
||
212 | * |
||
213 | * @param string $subject The subject line of the message |
||
214 | * @param string $body The body of the mesage |
||
215 | * @param int $recipient_guid The GUID of the user to send to |
||
216 | * @param int $sender_guid Optionally, the GUID of the user to send from |
||
217 | * @param int $original_msg_guid The GUID of the message to reply from (default: none) |
||
218 | * @param bool $notify Send a notification (default: true) |
||
219 | * @param bool $add_to_sent If true (default), will add a message to the sender's 'sent' tray |
||
220 | * @return bool |
||
221 | */ |
||
222 | function messages_send($subject, $body, $recipient_guid, $sender_guid = 0, $original_msg_guid = 0, $notify = true, $add_to_sent = true) { |
||
223 | |||
224 | // @todo remove globals |
||
225 | global $messagesendflag; |
||
226 | $messagesendflag = 1; |
||
227 | |||
228 | // @todo remove globals |
||
229 | global $messages_pm; |
||
230 | if ($notify) { |
||
231 | $messages_pm = 1; |
||
232 | } else { |
||
233 | $messages_pm = 0; |
||
234 | } |
||
235 | |||
236 | // If $sender_guid == 0, set to current user |
||
237 | if ($sender_guid == 0) { |
||
238 | $sender_guid = (int) elgg_get_logged_in_user_guid(); |
||
239 | } |
||
240 | |||
241 | // Initialise 2 new ElggObject |
||
242 | $message_to = new ElggObject(); |
||
243 | $message_sent = new ElggObject(); |
||
244 | |||
245 | $message_to->subtype = "messages"; |
||
246 | $message_sent->subtype = "messages"; |
||
247 | |||
248 | $message_to->owner_guid = $recipient_guid; |
||
249 | $message_to->container_guid = $recipient_guid; |
||
250 | $message_sent->owner_guid = $sender_guid; |
||
251 | $message_sent->container_guid = $sender_guid; |
||
252 | |||
253 | $message_to->access_id = ACCESS_PUBLIC; |
||
254 | $message_sent->access_id = ACCESS_PUBLIC; |
||
255 | |||
256 | $message_to->title = $subject; |
||
257 | $message_to->description = $body; |
||
258 | |||
259 | $message_sent->title = $subject; |
||
260 | $message_sent->description = $body; |
||
261 | |||
262 | $message_to->toId = $recipient_guid; // the user receiving the message |
||
263 | $message_to->fromId = $sender_guid; // the user receiving the message |
||
264 | $message_to->readYet = 0; // this is a toggle between 0 / 1 (1 = read) |
||
265 | $message_to->hiddenFrom = 0; // this is used when a user deletes a message in their sentbox, it is a flag |
||
266 | $message_to->hiddenTo = 0; // this is used when a user deletes a message in their inbox |
||
267 | |||
268 | $message_sent->toId = $recipient_guid; // the user receiving the message |
||
269 | $message_sent->fromId = $sender_guid; // the user receiving the message |
||
270 | $message_sent->readYet = 0; // this is a toggle between 0 / 1 (1 = read) |
||
271 | $message_sent->hiddenFrom = 0; // this is used when a user deletes a message in their sentbox, it is a flag |
||
272 | $message_sent->hiddenTo = 0; // this is used when a user deletes a message in their inbox |
||
273 | |||
274 | // Save the copy of the message that goes to the recipient |
||
275 | $success = $message_to->save(); |
||
276 | |||
277 | // Save the copy of the message that goes to the sender |
||
278 | if ($add_to_sent) { |
||
279 | $message_sent->save(); |
||
280 | } |
||
281 | |||
282 | $message_to->access_id = ACCESS_PRIVATE; |
||
283 | $message_to->save(); |
||
284 | |||
285 | if ($add_to_sent) { |
||
286 | $message_sent->access_id = ACCESS_PRIVATE; |
||
287 | $message_sent->save(); |
||
288 | } |
||
289 | |||
290 | // if the new message is a reply then create a relationship link between the new message |
||
291 | // and the message it is in reply to |
||
292 | if ($original_msg_guid && $success) { |
||
293 | add_entity_relationship($message_sent->guid, "reply", $original_msg_guid); |
||
294 | } |
||
295 | |||
296 | $message_contents = strip_tags($body); |
||
297 | if (($recipient_guid != elgg_get_logged_in_user_guid()) && $notify) { |
||
298 | $recipient = get_user($recipient_guid); |
||
299 | $sender = get_user($sender_guid); |
||
300 | |||
301 | $subject = elgg_echo('messages:email:subject', [], $recipient->language); |
||
302 | $body = elgg_echo('messages:email:body', [ |
||
303 | $sender->name, |
||
304 | $message_contents, |
||
305 | elgg_get_site_url() . "messages/inbox/" . $recipient->username, |
||
306 | $sender->name, |
||
307 | elgg_get_site_url() . "messages/compose?send_to=" . $sender_guid |
||
308 | ], |
||
309 | $recipient->language |
||
310 | ); |
||
311 | |||
312 | $params = [ |
||
313 | 'object' => $message_to, |
||
314 | 'action' => 'send', |
||
315 | 'url' => $message_to->getURL(), |
||
316 | ]; |
||
317 | notify_user($recipient_guid, $sender_guid, $subject, $body, $params); |
||
318 | } |
||
319 | |||
320 | $messagesendflag = 0; |
||
321 | return $success; |
||
322 | } |
||
323 | |||
324 | /** |
||
325 | * Message URL override |
||
326 | * |
||
327 | * @param string $hook |
||
328 | * @param string $type |
||
329 | * @param string $url |
||
330 | * @param array $params |
||
331 | * @return string |
||
332 | */ |
||
333 | function messages_set_url($hook, $type, $url, $params) { |
||
334 | $entity = $params['entity']; |
||
335 | if (elgg_instanceof($entity, 'object', 'messages')) { |
||
336 | return 'messages/read/' . $entity->getGUID(); |
||
337 | } |
||
338 | } |
||
339 | |||
340 | /** |
||
341 | * Returns the unread messages in a user's inbox |
||
342 | * |
||
343 | * @param int $user_guid GUID of user whose inbox we're counting (0 for logged in user) |
||
344 | * @param int $limit Number of unread messages to return (default from settings) |
||
345 | * @param int $offset Start at a defined offset (for listings) |
||
346 | * @param bool $count Switch between entities array or count mode |
||
347 | * |
||
348 | * @return array, int (if $count = true) |
||
349 | * @since 1.9 |
||
350 | */ |
||
351 | function messages_get_unread($user_guid = 0, $limit = null, $offset = 0, $count = false) { |
||
352 | return elgg_get_entities_from_metadata([ |
||
353 | 'metadata_name_value_pairs' => [ |
||
354 | 'toId' => $user_guid, |
||
355 | 'readYet' => 0, |
||
356 | 'msg' => 1, |
||
357 | ], |
||
358 | 'owner_guid' => $user_guid ?: elgg_get_logged_in_user_guid(), |
||
359 | 'limit' => $limit ?: elgg_get_config('default_limit'), |
||
360 | 'offset' => $offset, |
||
361 | 'count' => $count, |
||
362 | 'distinct' => false, |
||
363 | ]); |
||
364 | } |
||
365 | |||
366 | /** |
||
367 | * Count the unread messages in a user's inbox |
||
368 | * |
||
369 | * @param int $user_guid GUID of user whose inbox we're counting (0 for logged in user) |
||
370 | * |
||
371 | * @return int |
||
372 | */ |
||
373 | function messages_count_unread($user_guid = 0) { |
||
374 | return messages_get_unread($user_guid, 10, 0, true); |
||
375 | } |
||
376 | |||
377 | /** |
||
378 | * Prepare the compose form variables |
||
379 | * |
||
380 | * @return array |
||
381 | */ |
||
382 | function messages_prepare_form_vars($recipient_guid = 0) { |
||
383 | |||
384 | $recipients = []; |
||
385 | $recipient = get_user($recipient_guid); |
||
386 | if (!empty($recipient)) { |
||
387 | $recipients[] = $recipient->getGUID(); |
||
388 | } |
||
389 | |||
390 | // input names => defaults |
||
391 | $values = [ |
||
392 | 'subject' => elgg_get_sticky_value('messages', 'subject', ''), |
||
393 | 'body' => elgg_get_sticky_value('messages', 'body', ''), |
||
394 | 'recipients' => elgg_get_sticky_value('messages', 'recipients', $recipients), |
||
395 | ]; |
||
396 | |||
397 | elgg_clear_sticky_form('messages'); |
||
398 | |||
399 | return $values; |
||
400 | } |
||
401 | |||
402 | /** |
||
403 | * Add to the user hover menu |
||
404 | */ |
||
405 | View Code Duplication | function messages_user_hover_menu($hook, $type, $return, $params) { |
|
0 ignored issues
–
show
|
|||
406 | $user = $params['entity']; |
||
407 | |||
408 | if (!elgg_is_logged_in()) { |
||
409 | return; |
||
410 | } |
||
411 | |||
412 | if (elgg_get_logged_in_user_guid() == $user->guid) { |
||
413 | return; |
||
414 | } |
||
415 | |||
416 | $return[] = ElggMenuItem::factory([ |
||
417 | 'name' => 'send', |
||
418 | 'text' => elgg_echo('messages:sendmessage'), |
||
419 | 'icon' => 'mail', |
||
420 | 'href' => "messages/compose?send_to={$user->guid}", |
||
421 | 'section' => 'action', |
||
422 | ]); |
||
423 | |||
424 | return $return; |
||
425 | } |
||
426 | |||
427 | /** |
||
428 | * Delete messages from a user who is being deleted |
||
429 | * |
||
430 | * @param string $event Event name |
||
431 | * @param string $type Event type |
||
432 | * @param ElggUser $user User being deleted |
||
433 | */ |
||
434 | function messages_purge($event, $type, $user) { |
||
435 | |||
436 | if (!$user->getGUID()) { |
||
437 | return; |
||
438 | } |
||
439 | |||
440 | // make sure we delete them all |
||
441 | $entity_disable_override = access_show_hidden_entities(true); |
||
442 | $ia = elgg_set_ignore_access(true); |
||
443 | |||
444 | $options = [ |
||
445 | 'type' => 'object', |
||
446 | 'subtype' => 'messages', |
||
447 | 'metadata_name' => 'fromId', |
||
448 | 'metadata_value' => $user->getGUID(), |
||
449 | 'limit' => 0, |
||
450 | ]; |
||
451 | $batch = new ElggBatch('elgg_get_entities_from_metadata', $options); |
||
452 | foreach ($batch as $e) { |
||
453 | $e->delete(); |
||
454 | } |
||
455 | |||
456 | elgg_set_ignore_access($ia); |
||
457 | access_show_hidden_entities($entity_disable_override); |
||
458 | } |
||
459 | |||
460 | /** |
||
461 | * Register messages with ECML. |
||
462 | * |
||
463 | * @param string $hook |
||
464 | * @param string $entity_type |
||
465 | * @param string $return_value |
||
466 | * @param array $params |
||
467 | * |
||
468 | * @return array |
||
469 | */ |
||
470 | function messages_ecml_views_hook($hook, $entity_type, $return_value, $params) { |
||
471 | $return_value['messages/messages'] = elgg_echo('messages'); |
||
472 | |||
473 | return $return_value; |
||
474 | } |
||
475 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.