See Release Notes
Long Term Support Release
Differences Between: [Versions 39 and 310] [Versions 39 and 311] [Versions 39 and 400] [Versions 39 and 401] [Versions 39 and 402] [Versions 39 and 403]
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 18 /** 19 * External message API 20 * 21 * @package core_message 22 * @category external 23 * @copyright 2011 Jerome Mouneyrac 24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 25 */ 26 27 defined('MOODLE_INTERNAL') || die(); 28 29 require_once("$CFG->libdir/externallib.php"); 30 require_once($CFG->dirroot . "/message/lib.php"); 31 32 /** 33 * Message external functions 34 * 35 * @package core_message 36 * @category external 37 * @copyright 2011 Jerome Mouneyrac 38 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 39 * @since Moodle 2.2 40 */ 41 class core_message_external extends external_api { 42 /** 43 * Returns description of method parameters 44 * 45 * @return external_function_parameters 46 * @since Moodle 3.6 47 */ 48 public static function send_messages_to_conversation_parameters() { 49 return new external_function_parameters( 50 array( 51 'conversationid' => new external_value(PARAM_INT, 'id of the conversation'), 52 'messages' => new external_multiple_structure( 53 new external_single_structure( 54 array( 55 'text' => new external_value(PARAM_RAW, 'the text of the message'), 56 'textformat' => new external_format_value('text', VALUE_DEFAULT, FORMAT_MOODLE), 57 ) 58 ) 59 ) 60 ) 61 ); 62 } 63 64 /** 65 * Send messages from the current USER to a conversation. 66 * 67 * This conversation may be any type of conversation, individual or group. 68 * 69 * @param int $conversationid the id of the conversation to which the messages will be sent. 70 * @param array $messages An array of message to send. 71 * @return array the array of messages which were sent (created). 72 * @since Moodle 3.6 73 */ 74 public static function send_messages_to_conversation(int $conversationid, array $messages = []) { 75 global $CFG, $USER; 76 77 // Check if messaging is enabled. 78 if (empty($CFG->messaging)) { 79 throw new moodle_exception('disabled', 'message'); 80 } 81 82 // Ensure the current user is allowed to run this function. 83 $context = context_system::instance(); 84 self::validate_context($context); 85 86 $params = self::validate_parameters(self::send_messages_to_conversation_parameters(), [ 87 'conversationid' => $conversationid, 88 'messages' => $messages 89 ]); 90 91 // Validate messages content before posting them. 92 foreach ($params['messages'] as $message) { 93 // Check message length. 94 if (strlen($message['text']) > \core_message\api::MESSAGE_MAX_LENGTH) { 95 throw new moodle_exception('errormessagetoolong', 'message'); 96 } 97 } 98 99 $messages = []; 100 foreach ($params['messages'] as $message) { 101 $createdmessage = \core_message\api::send_message_to_conversation($USER->id, $params['conversationid'], $message['text'], 102 $message['textformat']); 103 $createdmessage->text = message_format_message_text((object) [ 104 'smallmessage' => $createdmessage->text, 105 'fullmessageformat' => external_validate_format($message['textformat']), 106 'fullmessagetrust' => $createdmessage->fullmessagetrust 107 ]); 108 $messages[] = $createdmessage; 109 } 110 111 return $messages; 112 } 113 114 /** 115 * Returns description of method result value. 116 * 117 * @return external_description 118 * @since Moodle 3.6 119 */ 120 public static function send_messages_to_conversation_returns() { 121 return new external_multiple_structure( 122 self::get_conversation_message_structure() 123 ); 124 } 125 126 127 /** 128 * Returns description of method parameters 129 * 130 * @return external_function_parameters 131 * @since Moodle 2.2 132 */ 133 public static function send_instant_messages_parameters() { 134 return new external_function_parameters( 135 array( 136 'messages' => new external_multiple_structure( 137 new external_single_structure( 138 array( 139 'touserid' => new external_value(PARAM_INT, 'id of the user to send the private message'), 140 'text' => new external_value(PARAM_RAW, 'the text of the message'), 141 'textformat' => new external_format_value('text', VALUE_DEFAULT, FORMAT_MOODLE), 142 'clientmsgid' => new external_value(PARAM_ALPHANUMEXT, 'your own client id for the message. If this id is provided, the fail message id will be returned to you', VALUE_OPTIONAL), 143 ) 144 ) 145 ) 146 ) 147 ); 148 } 149 150 /** 151 * Send private messages from the current USER to other users 152 * 153 * @param array $messages An array of message to send. 154 * @return array 155 * @since Moodle 2.2 156 */ 157 public static function send_instant_messages($messages = array()) { 158 global $CFG, $USER, $DB; 159 160 // Check if messaging is enabled. 161 if (empty($CFG->messaging)) { 162 throw new moodle_exception('disabled', 'message'); 163 } 164 165 // Ensure the current user is allowed to run this function 166 $context = context_system::instance(); 167 self::validate_context($context); 168 require_capability('moodle/site:sendmessage', $context); 169 170 // Ensure the current user is allowed to delete message for everyone. 171 $candeletemessagesforallusers = has_capability('moodle/site:deleteanymessage', $context); 172 173 $params = self::validate_parameters(self::send_instant_messages_parameters(), array('messages' => $messages)); 174 175 //retrieve all tousers of the messages 176 $receivers = array(); 177 foreach($params['messages'] as $message) { 178 $receivers[] = $message['touserid']; 179 } 180 list($sqluserids, $sqlparams) = $DB->get_in_or_equal($receivers); 181 $tousers = $DB->get_records_select("user", "id " . $sqluserids . " AND deleted = 0", $sqlparams); 182 183 $resultmessages = array(); 184 $messageids = array(); 185 foreach ($params['messages'] as $message) { 186 $resultmsg = array(); //the infos about the success of the operation 187 188 // We are going to do some checking. 189 // Code should match /messages/index.php checks. 190 $success = true; 191 192 // Check the user exists. 193 if (empty($tousers[$message['touserid']])) { 194 $success = false; 195 $errormessage = get_string('touserdoesntexist', 'message', $message['touserid']); 196 } 197 198 // Check message length. 199 if ($success && strlen($message['text']) > \core_message\api::MESSAGE_MAX_LENGTH) { 200 $success = false; 201 $errormessage = get_string('errormessagetoolong', 'message'); 202 } 203 204 // TODO MDL-31118 performance improvement - edit the function so we can pass an array instead userid 205 // Check if the recipient can be messaged by the sender. 206 if ($success && !\core_message\api::can_send_message($tousers[$message['touserid']]->id, $USER->id)) { 207 $success = false; 208 $errormessage = get_string('usercantbemessaged', 'message', fullname(\core_user::get_user($message['touserid']))); 209 } 210 211 // Now we can send the message (at least try). 212 if ($success) { 213 // TODO MDL-31118 performance improvement - edit the function so we can pass an array instead one touser object. 214 $success = message_post_message($USER, $tousers[$message['touserid']], 215 $message['text'], external_validate_format($message['textformat'])); 216 } 217 218 // Build the resultmsg. 219 if (isset($message['clientmsgid'])) { 220 $resultmsg['clientmsgid'] = $message['clientmsgid']; 221 } 222 if ($success) { 223 $resultmsg['msgid'] = $success; 224 $resultmsg['timecreated'] = time(); 225 $resultmsg['candeletemessagesforallusers'] = $candeletemessagesforallusers; 226 $messageids[] = $success; 227 } else { 228 // WARNINGS: for backward compatibility we return this errormessage. 229 // We should have thrown exceptions as these errors prevent results to be returned. 230 // See http://docs.moodle.org/dev/Errors_handling_in_web_services#When_to_send_a_warning_on_the_server_side . 231 $resultmsg['msgid'] = -1; 232 if (!isset($errormessage)) { // Nobody has set a message error or thrown an exception, let's set it. 233 $errormessage = get_string('messageundeliveredbynotificationsettings', 'error'); 234 } 235 $resultmsg['errormessage'] = $errormessage; 236 } 237 238 $resultmessages[] = $resultmsg; 239 } 240 241 if (!empty($messageids)) { 242 $messagerecords = $DB->get_records_list( 243 'messages', 244 'id', 245 $messageids, 246 '', 247 'id, conversationid, smallmessage, fullmessageformat, fullmessagetrust'); 248 $resultmessages = array_map(function($resultmessage) use ($messagerecords, $USER) { 249 $id = $resultmessage['msgid']; 250 $resultmessage['conversationid'] = isset($messagerecords[$id]) ? $messagerecords[$id]->conversationid : null; 251 $resultmessage['useridfrom'] = $USER->id; 252 $resultmessage['text'] = message_format_message_text((object) [ 253 'smallmessage' => $messagerecords[$id]->smallmessage, 254 'fullmessageformat' => external_validate_format($messagerecords[$id]->fullmessageformat), 255 'fullmessagetrust' => $messagerecords[$id]->fullmessagetrust 256 ]); 257 return $resultmessage; 258 }, $resultmessages); 259 } 260 261 return $resultmessages; 262 } 263 264 /** 265 * Returns description of method result value 266 * 267 * @return external_description 268 * @since Moodle 2.2 269 */ 270 public static function send_instant_messages_returns() { 271 return new external_multiple_structure( 272 new external_single_structure( 273 array( 274 'msgid' => new external_value(PARAM_INT, 'test this to know if it succeeds: id of the created message if it succeeded, -1 when failed'), 275 'clientmsgid' => new external_value(PARAM_ALPHANUMEXT, 'your own id for the message', VALUE_OPTIONAL), 276 'errormessage' => new external_value(PARAM_TEXT, 'error message - if it failed', VALUE_OPTIONAL), 277 'text' => new external_value(PARAM_RAW, 'The text of the message', VALUE_OPTIONAL), 278 'timecreated' => new external_value(PARAM_INT, 'The timecreated timestamp for the message', VALUE_OPTIONAL), 279 'conversationid' => new external_value(PARAM_INT, 'The conversation id for this message', VALUE_OPTIONAL), 280 'useridfrom' => new external_value(PARAM_INT, 'The user id who sent the message', VALUE_OPTIONAL), 281 'candeletemessagesforallusers' => new external_value(PARAM_BOOL, 282 'If the user can delete messages in the conversation for all users', VALUE_DEFAULT, false), 283 ) 284 ) 285 ); 286 } 287 288 /** 289 * Create contacts parameters description. 290 * 291 * @deprecated since Moodle 3.6 292 * @return external_function_parameters 293 * @since Moodle 2.5 294 */ 295 public static function create_contacts_parameters() { 296 return new external_function_parameters( 297 array( 298 'userids' => new external_multiple_structure( 299 new external_value(PARAM_INT, 'User ID'), 300 'List of user IDs' 301 ), 302 'userid' => new external_value(PARAM_INT, 'The id of the user we are creating the contacts for, 0 for the 303 current user', VALUE_DEFAULT, 0) 304 ) 305 ); 306 } 307 308 /** 309 * Create contacts. 310 * 311 * @deprecated since Moodle 3.6 312 * @param array $userids array of user IDs. 313 * @param int $userid The id of the user we are creating the contacts for 314 * @return external_description 315 * @since Moodle 2.5 316 */ 317 public static function create_contacts($userids, $userid = 0) { 318 global $CFG, $USER; 319 320 // Check if messaging is enabled. 321 if (empty($CFG->messaging)) { 322 throw new moodle_exception('disabled', 'message'); 323 } 324 325 if (empty($userid)) { 326 $userid = $USER->id; 327 } 328 329 // Validate context. 330 $context = context_system::instance(); 331 self::validate_context($context); 332 333 $params = array('userids' => $userids, 'userid' => $userid); 334 $params = self::validate_parameters(self::create_contacts_parameters(), $params); 335 336 $capability = 'moodle/site:manageallmessaging'; 337 if (($USER->id != $params['userid']) && !has_capability($capability, $context)) { 338 throw new required_capability_exception($context, $capability, 'nopermissions', ''); 339 } 340 341 $warnings = array(); 342 foreach ($params['userids'] as $id) { 343 if (!message_add_contact($id, 0, $params['userid'])) { 344 $warnings[] = array( 345 'item' => 'user', 346 'itemid' => $id, 347 'warningcode' => 'contactnotcreated', 348 'message' => 'The contact could not be created' 349 ); 350 } 351 } 352 return $warnings; 353 } 354 355 /** 356 * Create contacts return description. 357 * 358 * @deprecated since Moodle 3.6 359 * @return external_description 360 * @since Moodle 2.5 361 */ 362 public static function create_contacts_returns() { 363 return new external_warnings(); 364 } 365 366 /** 367 * Marking the method as deprecated. 368 * 369 * @return bool 370 */ 371 public static function create_contacts_is_deprecated() { 372 return true; 373 } 374 375 /** 376 * Delete contacts parameters description. 377 * 378 * @return external_function_parameters 379 * @since Moodle 2.5 380 */ 381 public static function delete_contacts_parameters() { 382 return new external_function_parameters( 383 array( 384 'userids' => new external_multiple_structure( 385 new external_value(PARAM_INT, 'User ID'), 386 'List of user IDs' 387 ), 388 'userid' => new external_value(PARAM_INT, 'The id of the user we are deleting the contacts for, 0 for the 389 current user', VALUE_DEFAULT, 0) 390 ) 391 ); 392 } 393 394 /** 395 * Delete contacts. 396 * 397 * @param array $userids array of user IDs. 398 * @param int $userid The id of the user we are deleting the contacts for 399 * @return null 400 * @since Moodle 2.5 401 */ 402 public static function delete_contacts($userids, $userid = 0) { 403 global $CFG, $USER; 404 405 // Check if messaging is enabled. 406 if (empty($CFG->messaging)) { 407 throw new moodle_exception('disabled', 'message'); 408 } 409 410 if (empty($userid)) { 411 $userid = $USER->id; 412 } 413 414 // Validate context. 415 $context = context_system::instance(); 416 self::validate_context($context); 417 418 $params = array('userids' => $userids, 'userid' => $userid); 419 $params = self::validate_parameters(self::delete_contacts_parameters(), $params); 420 421 $capability = 'moodle/site:manageallmessaging'; 422 if (($USER->id != $params['userid']) && !has_capability($capability, $context)) { 423 throw new required_capability_exception($context, $capability, 'nopermissions', ''); 424 } 425 426 foreach ($params['userids'] as $id) { 427 \core_message\api::remove_contact($params['userid'], $id); 428 } 429 430 return null; 431 } 432 433 /** 434 * Delete contacts return description. 435 * 436 * @return external_description 437 * @since Moodle 2.5 438 */ 439 public static function delete_contacts_returns() { 440 return null; 441 } 442 443 /** 444 * Mute conversations parameters description. 445 * 446 * @return external_function_parameters 447 */ 448 public static function mute_conversations_parameters() { 449 return new external_function_parameters( 450 [ 451 'userid' => new external_value(PARAM_INT, 'The id of the user who is blocking'), 452 'conversationids' => new external_multiple_structure( 453 new external_value(PARAM_INT, 'id of the conversation', VALUE_REQUIRED) 454 ), 455 ] 456 ); 457 } 458 459 /** 460 * Mutes conversations. 461 * 462 * @param int $userid The id of the user who is blocking 463 * @param array $conversationids The list of conversations being muted 464 * @return external_description 465 */ 466 public static function mute_conversations(int $userid, array $conversationids) { 467 global $CFG, $USER; 468 469 // Check if messaging is enabled. 470 if (empty($CFG->messaging)) { 471 throw new moodle_exception('disabled', 'message'); 472 } 473 474 // Validate context. 475 $context = context_system::instance(); 476 self::validate_context($context); 477 478 $params = ['userid' => $userid, 'conversationids' => $conversationids]; 479 $params = self::validate_parameters(self::mute_conversations_parameters(), $params); 480 481 $capability = 'moodle/site:manageallmessaging'; 482 if (($USER->id != $params['userid']) && !has_capability($capability, $context)) { 483 throw new required_capability_exception($context, $capability, 'nopermissions', ''); 484 } 485 486 foreach ($params['conversationids'] as $conversationid) { 487 if (!\core_message\api::is_conversation_muted($params['userid'], $conversationid)) { 488 \core_message\api::mute_conversation($params['userid'], $conversationid); 489 } 490 } 491 492 return []; 493 } 494 495 /** 496 * Mute conversations return description. 497 * 498 * @return external_description 499 */ 500 public static function mute_conversations_returns() { 501 return new external_warnings(); 502 } 503 504 /** 505 * Unmute conversations parameters description. 506 * 507 * @return external_function_parameters 508 */ 509 public static function unmute_conversations_parameters() { 510 return new external_function_parameters( 511 [ 512 'userid' => new external_value(PARAM_INT, 'The id of the user who is unblocking'), 513 'conversationids' => new external_multiple_structure( 514 new external_value(PARAM_INT, 'id of the conversation', VALUE_REQUIRED) 515 ), 516 ] 517 ); 518 } 519 520 /** 521 * Unmute conversations. 522 * 523 * @param int $userid The id of the user who is unblocking 524 * @param array $conversationids The list of conversations being muted 525 */ 526 public static function unmute_conversations(int $userid, array $conversationids) { 527 global $CFG, $USER; 528 529 // Check if messaging is enabled. 530 if (empty($CFG->messaging)) { 531 throw new moodle_exception('disabled', 'message'); 532 } 533 534 // Validate context. 535 $context = context_system::instance(); 536 self::validate_context($context); 537 538 $params = ['userid' => $userid, 'conversationids' => $conversationids]; 539 $params = self::validate_parameters(self::unmute_conversations_parameters(), $params); 540 541 $capability = 'moodle/site:manageallmessaging'; 542 if (($USER->id != $params['userid']) && !has_capability($capability, $context)) { 543 throw new required_capability_exception($context, $capability, 'nopermissions', ''); 544 } 545 546 foreach ($params['conversationids'] as $conversationid) { 547 \core_message\api::unmute_conversation($params['userid'], $conversationid); 548 } 549 550 return []; 551 } 552 553 /** 554 * Unmute conversations return description. 555 * 556 * @return external_description 557 */ 558 public static function unmute_conversations_returns() { 559 return new external_warnings(); 560 } 561 562 /** 563 * Block user parameters description. 564 * 565 * @return external_function_parameters 566 */ 567 public static function block_user_parameters() { 568 return new external_function_parameters( 569 [ 570 'userid' => new external_value(PARAM_INT, 'The id of the user who is blocking'), 571 'blockeduserid' => new external_value(PARAM_INT, 'The id of the user being blocked'), 572 ] 573 ); 574 } 575 576 /** 577 * Blocks a user. 578 * 579 * @param int $userid The id of the user who is blocking 580 * @param int $blockeduserid The id of the user being blocked 581 * @return external_description 582 */ 583 public static function block_user(int $userid, int $blockeduserid) { 584 global $CFG, $USER; 585 586 // Check if messaging is enabled. 587 if (empty($CFG->messaging)) { 588 throw new moodle_exception('disabled', 'message'); 589 } 590 591 // Validate context. 592 $context = context_system::instance(); 593 self::validate_context($context); 594 595 $params = ['userid' => $userid, 'blockeduserid' => $blockeduserid]; 596 $params = self::validate_parameters(self::block_user_parameters(), $params); 597 598 $capability = 'moodle/site:manageallmessaging'; 599 if (($USER->id != $params['userid']) && !has_capability($capability, $context)) { 600 throw new required_capability_exception($context, $capability, 'nopermissions', ''); 601 } 602 603 // If the blocking is going to be useless then don't do it. 604 if (\core_message\api::can_send_message($userid, $blockeduserid, true)) { 605 return []; 606 } 607 608 if (!\core_message\api::is_blocked($params['userid'], $params['blockeduserid'])) { 609 \core_message\api::block_user($params['userid'], $params['blockeduserid']); 610 } 611 612 return []; 613 } 614 615 /** 616 * Block user return description. 617 * 618 * @return external_description 619 */ 620 public static function block_user_returns() { 621 return new external_warnings(); 622 } 623 624 /** 625 * Unblock user parameters description. 626 * 627 * @return external_function_parameters 628 */ 629 public static function unblock_user_parameters() { 630 return new external_function_parameters( 631 [ 632 'userid' => new external_value(PARAM_INT, 'The id of the user who is unblocking'), 633 'unblockeduserid' => new external_value(PARAM_INT, 'The id of the user being unblocked'), 634 ] 635 ); 636 } 637 638 /** 639 * Unblock user. 640 * 641 * @param int $userid The id of the user who is unblocking 642 * @param int $unblockeduserid The id of the user being unblocked 643 */ 644 public static function unblock_user(int $userid, int $unblockeduserid) { 645 global $CFG, $USER; 646 647 // Check if messaging is enabled. 648 if (empty($CFG->messaging)) { 649 throw new moodle_exception('disabled', 'message'); 650 } 651 652 // Validate context. 653 $context = context_system::instance(); 654 self::validate_context($context); 655 656 $params = ['userid' => $userid, 'unblockeduserid' => $unblockeduserid]; 657 $params = self::validate_parameters(self::unblock_user_parameters(), $params); 658 659 $capability = 'moodle/site:manageallmessaging'; 660 if (($USER->id != $params['userid']) && !has_capability($capability, $context)) { 661 throw new required_capability_exception($context, $capability, 'nopermissions', ''); 662 } 663 664 \core_message\api::unblock_user($params['userid'], $params['unblockeduserid']); 665 666 return []; 667 } 668 669 /** 670 * Unblock user return description. 671 * 672 * @return external_description 673 */ 674 public static function unblock_user_returns() { 675 return new external_warnings(); 676 } 677 678 /** 679 * Block contacts parameters description. 680 * 681 * @deprecated since Moodle 3.6 682 * @return external_function_parameters 683 * @since Moodle 2.5 684 */ 685 public static function block_contacts_parameters() { 686 return new external_function_parameters( 687 array( 688 'userids' => new external_multiple_structure( 689 new external_value(PARAM_INT, 'User ID'), 690 'List of user IDs' 691 ), 692 'userid' => new external_value(PARAM_INT, 'The id of the user we are blocking the contacts for, 0 for the 693 current user', VALUE_DEFAULT, 0) 694 ) 695 ); 696 } 697 698 /** 699 * Block contacts. 700 * 701 * @deprecated since Moodle 3.6 702 * @param array $userids array of user IDs. 703 * @param int $userid The id of the user we are blocking the contacts for 704 * @return external_description 705 * @since Moodle 2.5 706 */ 707 public static function block_contacts($userids, $userid = 0) { 708 global $CFG, $USER; 709 710 // Check if messaging is enabled. 711 if (empty($CFG->messaging)) { 712 throw new moodle_exception('disabled', 'message'); 713 } 714 715 if (empty($userid)) { 716 $userid = $USER->id; 717 } 718 719 // Validate context. 720 $context = context_system::instance(); 721 self::validate_context($context); 722 723 $params = array('userids' => $userids, 'userid' => $userid); 724 $params = self::validate_parameters(self::block_contacts_parameters(), $params); 725 726 $capability = 'moodle/site:manageallmessaging'; 727 if (($USER->id != $params['userid']) && !has_capability($capability, $context)) { 728 throw new required_capability_exception($context, $capability, 'nopermissions', ''); 729 } 730 731 $warnings = array(); 732 foreach ($params['userids'] as $id) { 733 if (!message_block_contact($id, $params['userid'])) { 734 $warnings[] = array( 735 'item' => 'user', 736 'itemid' => $id, 737 'warningcode' => 'contactnotblocked', 738 'message' => 'The contact could not be blocked' 739 ); 740 } 741 } 742 return $warnings; 743 } 744 745 /** 746 * Block contacts return description. 747 * 748 * @deprecated since Moodle 3.6 749 * @return external_description 750 * @since Moodle 2.5 751 */ 752 public static function block_contacts_returns() { 753 return new external_warnings(); 754 } 755 756 /** 757 * Marking the method as deprecated. 758 * 759 * @return bool 760 */ 761 public static function block_contacts_is_deprecated() { 762 return true; 763 } 764 765 /** 766 * Unblock contacts parameters description. 767 * 768 * @deprecated since Moodle 3.6 769 * @return external_function_parameters 770 * @since Moodle 2.5 771 */ 772 public static function unblock_contacts_parameters() { 773 return new external_function_parameters( 774 array( 775 'userids' => new external_multiple_structure( 776 new external_value(PARAM_INT, 'User ID'), 777 'List of user IDs' 778 ), 779 'userid' => new external_value(PARAM_INT, 'The id of the user we are unblocking the contacts for, 0 for the 780 current user', VALUE_DEFAULT, 0) 781 ) 782 ); 783 } 784 785 /** 786 * Unblock contacts. 787 * 788 * @param array $userids array of user IDs. 789 * @param int $userid The id of the user we are unblocking the contacts for 790 * @return null 791 * @since Moodle 2.5 792 */ 793 public static function unblock_contacts($userids, $userid = 0) { 794 global $CFG, $USER; 795 796 // Check if messaging is enabled. 797 if (empty($CFG->messaging)) { 798 throw new moodle_exception('disabled', 'message'); 799 } 800 801 if (empty($userid)) { 802 $userid = $USER->id; 803 } 804 805 // Validate context. 806 $context = context_system::instance(); 807 self::validate_context($context); 808 809 $params = array('userids' => $userids, 'userid' => $userid); 810 $params = self::validate_parameters(self::unblock_contacts_parameters(), $params); 811 812 $capability = 'moodle/site:manageallmessaging'; 813 if (($USER->id != $params['userid']) && !has_capability($capability, $context)) { 814 throw new required_capability_exception($context, $capability, 'nopermissions', ''); 815 } 816 817 foreach ($params['userids'] as $id) { 818 message_unblock_contact($id, $params['userid']); 819 } 820 821 return null; 822 } 823 824 /** 825 * Unblock contacts return description. 826 * 827 * @deprecated since Moodle 3.6 828 * @return external_description 829 * @since Moodle 2.5 830 */ 831 public static function unblock_contacts_returns() { 832 return null; 833 } 834 835 /** 836 * Marking the method as deprecated. 837 * 838 * @return bool 839 */ 840 public static function unblock_contacts_is_deprecated() { 841 return true; 842 } 843 844 /** 845 * Returns contact requests parameters description. 846 * 847 * @return external_function_parameters 848 */ 849 public static function get_contact_requests_parameters() { 850 return new external_function_parameters( 851 [ 852 'userid' => new external_value(PARAM_INT, 'The id of the user we want the requests for'), 853 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0), 854 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0) 855 ] 856 ); 857 } 858 859 /** 860 * Handles returning the contact requests for a user. 861 * 862 * This also includes the user data necessary to display information 863 * about the user. 864 * 865 * It will not include blocked users. 866 * 867 * @param int $userid The id of the user we want to get the contact requests for 868 * @param int $limitfrom 869 * @param int $limitnum 870 */ 871 public static function get_contact_requests(int $userid, int $limitfrom = 0, int $limitnum = 0) { 872 global $CFG, $USER; 873 874 // Check if messaging is enabled. 875 if (empty($CFG->messaging)) { 876 throw new moodle_exception('disabled', 'message'); 877 } 878 879 // Validate context. 880 $context = context_system::instance(); 881 self::validate_context($context); 882 883 $params = [ 884 'userid' => $userid, 885 'limitfrom' => $limitfrom, 886 'limitnum' => $limitnum 887 ]; 888 $params = self::validate_parameters(self::get_contact_requests_parameters(), $params); 889 890 $capability = 'moodle/site:manageallmessaging'; 891 if (($USER->id != $params['userid']) && !has_capability($capability, $context)) { 892 throw new required_capability_exception($context, $capability, 'nopermissions', ''); 893 } 894 895 return \core_message\api::get_contact_requests($params['userid'], $params['limitfrom'], $params['limitnum']); 896 } 897 898 /** 899 * Returns the contact requests return description. 900 * 901 * @return external_description 902 */ 903 public static function get_contact_requests_returns() { 904 return new external_multiple_structure( 905 self::get_conversation_member_structure() 906 ); 907 } 908 909 /** 910 * Returns the number of contact requests the user has received parameters description. 911 * 912 * @return external_function_parameters 913 */ 914 public static function get_received_contact_requests_count_parameters() { 915 return new external_function_parameters( 916 array( 917 'userid' => new external_value(PARAM_INT, 'The id of the user we want to return the number of ' . 918 'received contact requests for', VALUE_REQUIRED), 919 ) 920 ); 921 } 922 923 /** 924 * Returns the number of contact requests the user has received. 925 * 926 * @param int $userid The ID of the user we want to return the number of received contact requests for 927 * @return external_value 928 */ 929 public static function get_received_contact_requests_count(int $userid) { 930 global $CFG, $USER; 931 932 // Check if messaging is enabled. 933 if (empty($CFG->messaging)) { 934 throw new moodle_exception('disabled', 'message'); 935 } 936 937 // Validate context. 938 $context = context_system::instance(); 939 self::validate_context($context); 940 941 $params = [ 942 'userid' => $userid, 943 ]; 944 $params = self::validate_parameters(self::get_received_contact_requests_count_parameters(), $params); 945 946 $capability = 'moodle/site:manageallmessaging'; 947 if (($USER->id != $params['userid']) && !has_capability($capability, $context)) { 948 throw new required_capability_exception($context, $capability, 'nopermissions', ''); 949 } 950 951 return \core_message\api::get_received_contact_requests_count($params['userid']); 952 } 953 954 /** 955 * Returns the number of contact requests the user has received return description. 956 * 957 * @return external_value 958 */ 959 public static function get_received_contact_requests_count_returns() { 960 return new external_value(PARAM_INT, 'The number of received contact requests'); 961 } 962 963 /** 964 * Returns get conversation members parameters description. 965 * 966 * @return external_function_parameters 967 */ 968 public static function get_conversation_members_parameters() { 969 return new external_function_parameters( 970 [ 971 'userid' => new external_value(PARAM_INT, 'The id of the user we are performing this action on behalf of'), 972 'conversationid' => new external_value(PARAM_INT, 'The id of the conversation'), 973 'includecontactrequests' => new external_value(PARAM_BOOL, 'Do we want to include contact requests?', 974 VALUE_DEFAULT, false), 975 'includeprivacyinfo' => new external_value(PARAM_BOOL, 'Do we want to include privacy info?', 976 VALUE_DEFAULT, false), 977 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0), 978 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0) 979 ] 980 ); 981 } 982 983 /** 984 * Returns a list of conversation members. 985 * 986 * @param int $userid The user we are returning the conversation members for, used by helper::get_member_info. 987 * @param int $conversationid The id of the conversation 988 * @param bool $includecontactrequests Do we want to include contact requests with this data? 989 * @param bool $includeprivacyinfo Do we want to include privacy info? 990 * @param int $limitfrom 991 * @param int $limitnum 992 * @return array 993 */ 994 public static function get_conversation_members(int $userid, int $conversationid, bool $includecontactrequests = false, 995 bool $includeprivacyinfo = false, int $limitfrom = 0, int $limitnum = 0) { 996 global $CFG, $USER; 997 998 // Check if messaging is enabled. 999 if (empty($CFG->messaging)) { 1000 throw new moodle_exception('disabled', 'message'); 1001 } 1002 1003 // Validate context. 1004 $context = context_system::instance(); 1005 self::validate_context($context); 1006 1007 $params = [ 1008 'userid' => $userid, 1009 'conversationid' => $conversationid, 1010 'includecontactrequests' => $includecontactrequests, 1011 'includeprivacyinfo' => $includeprivacyinfo, 1012 'limitfrom' => $limitfrom, 1013 'limitnum' => $limitnum 1014 ]; 1015 $params = self::validate_parameters(self::get_conversation_members_parameters(), $params); 1016 1017 $capability = 'moodle/site:manageallmessaging'; 1018 if (($USER->id != $params['userid']) && !has_capability($capability, $context)) { 1019 throw new required_capability_exception($context, $capability, 'nopermissions', ''); 1020 } 1021 1022 // The user needs to be a part of the conversation before querying who the members are. 1023 if (!\core_message\api::is_user_in_conversation($params['userid'], $params['conversationid'])) { 1024 throw new moodle_exception('You are not a member of this conversation.'); 1025 } 1026 1027 return \core_message\api::get_conversation_members($params['userid'], $params['conversationid'], $params['includecontactrequests'], 1028 $params['includeprivacyinfo'], $params['limitfrom'], $params['limitnum']); 1029 } 1030 1031 /** 1032 * Returns the get conversation members return description. 1033 * 1034 * @return external_description 1035 */ 1036 public static function get_conversation_members_returns() { 1037 return new external_multiple_structure( 1038 self::get_conversation_member_structure() 1039 ); 1040 } 1041 1042 /** 1043 * Creates a contact request parameters description. 1044 * 1045 * @return external_function_parameters 1046 */ 1047 public static function create_contact_request_parameters() { 1048 return new external_function_parameters( 1049 [ 1050 'userid' => new external_value(PARAM_INT, 'The id of the user making the request'), 1051 'requesteduserid' => new external_value(PARAM_INT, 'The id of the user being requested') 1052 ] 1053 ); 1054 } 1055 1056 /** 1057 * Creates a contact request. 1058 * 1059 * @param int $userid The id of the user who is creating the contact request 1060 * @param int $requesteduserid The id of the user being requested 1061 */ 1062 public static function create_contact_request(int $userid, int $requesteduserid) { 1063 global $CFG, $USER; 1064 1065 // Check if messaging is enabled. 1066 if (empty($CFG->messaging)) { 1067 throw new moodle_exception('disabled', 'message'); 1068 } 1069 1070 // Validate context. 1071 $context = context_system::instance(); 1072 self::validate_context($context); 1073 1074 $params = ['userid' => $userid, 'requesteduserid' => $requesteduserid]; 1075 $params = self::validate_parameters(self::create_contact_request_parameters(), $params); 1076 1077 $capability = 'moodle/site:manageallmessaging'; 1078 if (($USER->id != $params['userid']) && !has_capability($capability, $context)) { 1079 throw new required_capability_exception($context, $capability, 'nopermissions', ''); 1080 } 1081 1082 $result = [ 1083 'warnings' => [] 1084 ]; 1085 1086 if (!\core_message\api::can_create_contact($params['userid'], $params['requesteduserid'])) { 1087 $result['warnings'][] = [ 1088 'item' => 'user', 1089 'itemid' => $params['requesteduserid'], 1090 'warningcode' => 'cannotcreatecontactrequest', 1091 'message' => 'You are unable to create a contact request for this user' 1092 ]; 1093 } else { 1094 if ($requests = \core_message\api::get_contact_requests_between_users($params['userid'], $params['requesteduserid'])) { 1095 // There should only ever be one but just in case there are multiple then we can return the first. 1096 $result['request'] = array_shift($requests); 1097 } else { 1098 $result['request'] = \core_message\api::create_contact_request($params['userid'], $params['requesteduserid']); 1099 } 1100 } 1101 1102 return $result; 1103 } 1104 1105 /** 1106 * Creates a contact request return description. 1107 * 1108 * @return external_description 1109 */ 1110 public static function create_contact_request_returns() { 1111 return new external_single_structure( 1112 array( 1113 'request' => new external_single_structure( 1114 array( 1115 'id' => new external_value(PARAM_INT, 'Message id'), 1116 'userid' => new external_value(PARAM_INT, 'User from id'), 1117 'requesteduserid' => new external_value(PARAM_INT, 'User to id'), 1118 'timecreated' => new external_value(PARAM_INT, 'Time created'), 1119 ), 1120 'request record', 1121 VALUE_OPTIONAL 1122 ), 1123 'warnings' => new external_warnings() 1124 ) 1125 ); 1126 } 1127 1128 /** 1129 * Confirm a contact request parameters description. 1130 * 1131 * @return external_function_parameters 1132 */ 1133 public static function confirm_contact_request_parameters() { 1134 return new external_function_parameters( 1135 [ 1136 'userid' => new external_value(PARAM_INT, 'The id of the user making the request'), 1137 'requesteduserid' => new external_value(PARAM_INT, 'The id of the user being requested') 1138 ] 1139 ); 1140 } 1141 1142 /** 1143 * Confirm a contact request. 1144 * 1145 * @param int $userid The id of the user who is creating the contact request 1146 * @param int $requesteduserid The id of the user being requested 1147 */ 1148 public static function confirm_contact_request(int $userid, int $requesteduserid) { 1149 global $CFG, $USER; 1150 1151 // Check if messaging is enabled. 1152 if (empty($CFG->messaging)) { 1153 throw new moodle_exception('disabled', 'message'); 1154 } 1155 1156 // Validate context. 1157 $context = context_system::instance(); 1158 self::validate_context($context); 1159 1160 $params = ['userid' => $userid, 'requesteduserid' => $requesteduserid]; 1161 $params = self::validate_parameters(self::confirm_contact_request_parameters(), $params); 1162 1163 $capability = 'moodle/site:manageallmessaging'; 1164 if (($USER->id != $params['requesteduserid']) && !has_capability($capability, $context)) { 1165 throw new required_capability_exception($context, $capability, 'nopermissions', ''); 1166 } 1167 1168 \core_message\api::confirm_contact_request($params['userid'], $params['requesteduserid']); 1169 1170 return []; 1171 } 1172 1173 /** 1174 * Confirm a contact request return description. 1175 * 1176 * @return external_description 1177 */ 1178 public static function confirm_contact_request_returns() { 1179 return new external_warnings(); 1180 } 1181 1182 /** 1183 * Declines a contact request parameters description. 1184 * 1185 * @return external_function_parameters 1186 */ 1187 public static function decline_contact_request_parameters() { 1188 return new external_function_parameters( 1189 [ 1190 'userid' => new external_value(PARAM_INT, 'The id of the user making the request'), 1191 'requesteduserid' => new external_value(PARAM_INT, 'The id of the user being requested') 1192 ] 1193 ); 1194 } 1195 1196 /** 1197 * Declines a contact request. 1198 * 1199 * @param int $userid The id of the user who is creating the contact request 1200 * @param int $requesteduserid The id of the user being requested 1201 */ 1202 public static function decline_contact_request(int $userid, int $requesteduserid) { 1203 global $CFG, $USER; 1204 1205 // Check if messaging is enabled. 1206 if (empty($CFG->messaging)) { 1207 throw new moodle_exception('disabled', 'message'); 1208 } 1209 1210 // Validate context. 1211 $context = context_system::instance(); 1212 self::validate_context($context); 1213 1214 $params = ['userid' => $userid, 'requesteduserid' => $requesteduserid]; 1215 $params = self::validate_parameters(self::decline_contact_request_parameters(), $params); 1216 1217 $capability = 'moodle/site:manageallmessaging'; 1218 if (($USER->id != $params['requesteduserid']) && !has_capability($capability, $context)) { 1219 throw new required_capability_exception($context, $capability, 'nopermissions', ''); 1220 } 1221 1222 \core_message\api::decline_contact_request($params['userid'], $params['requesteduserid']); 1223 1224 return []; 1225 } 1226 1227 /** 1228 * Declines a contact request return description. 1229 * 1230 * @return external_description 1231 */ 1232 public static function decline_contact_request_returns() { 1233 return new external_warnings(); 1234 } 1235 1236 /** 1237 * Return the structure of a message area contact. 1238 * 1239 * @return external_single_structure 1240 * @since Moodle 3.2 1241 */ 1242 private static function get_messagearea_contact_structure() { 1243 return new external_single_structure( 1244 array( 1245 'userid' => new external_value(PARAM_INT, 'The user\'s id'), 1246 'fullname' => new external_value(PARAM_NOTAGS, 'The user\'s name'), 1247 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL'), 1248 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL'), 1249 'ismessaging' => new external_value(PARAM_BOOL, 'If we are messaging the user'), 1250 'sentfromcurrentuser' => new external_value(PARAM_BOOL, 'Was the last message sent from the current user?'), 1251 'lastmessage' => new external_value(PARAM_NOTAGS, 'The user\'s last message'), 1252 'lastmessagedate' => new external_value(PARAM_INT, 'Timestamp for last message', VALUE_DEFAULT, null), 1253 'messageid' => new external_value(PARAM_INT, 'The unique search message id', VALUE_DEFAULT, null), 1254 'showonlinestatus' => new external_value(PARAM_BOOL, 'Show the user\'s online status?'), 1255 'isonline' => new external_value(PARAM_BOOL, 'The user\'s online status'), 1256 'isread' => new external_value(PARAM_BOOL, 'If the user has read the message'), 1257 'isblocked' => new external_value(PARAM_BOOL, 'If the user has been blocked'), 1258 'unreadcount' => new external_value(PARAM_INT, 'The number of unread messages in this conversation', 1259 VALUE_DEFAULT, null), 1260 'conversationid' => new external_value(PARAM_INT, 'The id of the conversation', VALUE_DEFAULT, null), 1261 ) 1262 ); 1263 } 1264 1265 /** 1266 * Return the structure of a conversation. 1267 * 1268 * @return external_single_structure 1269 * @since Moodle 3.6 1270 */ 1271 private static function get_conversation_structure() { 1272 return new external_single_structure( 1273 array( 1274 'id' => new external_value(PARAM_INT, 'The conversation id'), 1275 'name' => new external_value(PARAM_RAW, 'The conversation name, if set', VALUE_DEFAULT, null), 1276 'subname' => new external_value(PARAM_RAW, 'A subtitle for the conversation name, if set', VALUE_DEFAULT, null), 1277 'imageurl' => new external_value(PARAM_URL, 'A link to the conversation picture, if set', VALUE_DEFAULT, null), 1278 'type' => new external_value(PARAM_INT, 'The type of the conversation (1=individual,2=group,3=self)'), 1279 'membercount' => new external_value(PARAM_INT, 'Total number of conversation members'), 1280 'ismuted' => new external_value(PARAM_BOOL, 'If the user muted this conversation'), 1281 'isfavourite' => new external_value(PARAM_BOOL, 'If the user marked this conversation as a favourite'), 1282 'isread' => new external_value(PARAM_BOOL, 'If the user has read all messages in the conversation'), 1283 'unreadcount' => new external_value(PARAM_INT, 'The number of unread messages in this conversation', 1284 VALUE_DEFAULT, null), 1285 'members' => new external_multiple_structure( 1286 self::get_conversation_member_structure() 1287 ), 1288 'messages' => new external_multiple_structure( 1289 self::get_conversation_message_structure() 1290 ), 1291 'candeletemessagesforallusers' => new external_value(PARAM_BOOL, 1292 'If the user can delete messages in the conversation for all users', VALUE_DEFAULT, false), 1293 ) 1294 ); 1295 } 1296 1297 /** 1298 * Return the structure of a conversation member. 1299 * 1300 * @return external_single_structure 1301 * @since Moodle 3.6 1302 */ 1303 private static function get_conversation_member_structure() { 1304 $result = [ 1305 'id' => new external_value(PARAM_INT, 'The user id'), 1306 'fullname' => new external_value(PARAM_NOTAGS, 'The user\'s name'), 1307 'profileurl' => new external_value(PARAM_URL, 'The link to the user\'s profile page'), 1308 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL'), 1309 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL'), 1310 'isonline' => new external_value(PARAM_BOOL, 'The user\'s online status'), 1311 'showonlinestatus' => new external_value(PARAM_BOOL, 'Show the user\'s online status?'), 1312 'isblocked' => new external_value(PARAM_BOOL, 'If the user has been blocked'), 1313 'iscontact' => new external_value(PARAM_BOOL, 'Is the user a contact?'), 1314 'isdeleted' => new external_value(PARAM_BOOL, 'Is the user deleted?'), 1315 'canmessageevenifblocked' => new external_value(PARAM_BOOL, 1316 'If the user can still message even if they get blocked'), 1317 'canmessage' => new external_value(PARAM_BOOL, 'If the user can be messaged'), 1318 'requirescontact' => new external_value(PARAM_BOOL, 'If the user requires to be contacts'), 1319 ]; 1320 1321 $result['contactrequests'] = new external_multiple_structure( 1322 new external_single_structure( 1323 [ 1324 'id' => new external_value(PARAM_INT, 'The id of the contact request'), 1325 'userid' => new external_value(PARAM_INT, 'The id of the user who created the contact request'), 1326 'requesteduserid' => new external_value(PARAM_INT, 'The id of the user confirming the request'), 1327 'timecreated' => new external_value(PARAM_INT, 'The timecreated timestamp for the contact request'), 1328 ] 1329 ), 'The contact requests', VALUE_OPTIONAL 1330 ); 1331 1332 $result['conversations'] = new external_multiple_structure(new external_single_structure( 1333 array( 1334 'id' => new external_value(PARAM_INT, 'Conversations id'), 1335 'type' => new external_value(PARAM_INT, 'Conversation type: private or public'), 1336 'name' => new external_value(PARAM_RAW, 'Multilang compatible conversation name'. VALUE_OPTIONAL), 1337 'timecreated' => new external_value(PARAM_INT, 'The timecreated timestamp for the conversation'), 1338 ), 'information about conversation', VALUE_OPTIONAL), 1339 'Conversations between users', VALUE_OPTIONAL 1340 ); 1341 1342 return new external_single_structure( 1343 $result 1344 ); 1345 } 1346 1347 /** 1348 * Return the structure of a message area message. 1349 * 1350 * @return external_single_structure 1351 * @since Moodle 3.6 1352 */ 1353 private static function get_conversation_message_structure() { 1354 return new external_single_structure( 1355 array( 1356 'id' => new external_value(PARAM_INT, 'The id of the message'), 1357 'useridfrom' => new external_value(PARAM_INT, 'The id of the user who sent the message'), 1358 'text' => new external_value(PARAM_RAW, 'The text of the message'), 1359 'timecreated' => new external_value(PARAM_INT, 'The timecreated timestamp for the message'), 1360 ) 1361 ); 1362 } 1363 1364 /** 1365 * Return the structure of a message area message. 1366 * 1367 * @return external_single_structure 1368 * @since Moodle 3.2 1369 */ 1370 private static function get_messagearea_message_structure() { 1371 return new external_single_structure( 1372 array( 1373 'id' => new external_value(PARAM_INT, 'The id of the message'), 1374 'useridfrom' => new external_value(PARAM_INT, 'The id of the user who sent the message'), 1375 'useridto' => new external_value(PARAM_INT, 'The id of the user who received the message'), 1376 'text' => new external_value(PARAM_RAW, 'The text of the message'), 1377 'displayblocktime' => new external_value(PARAM_BOOL, 'Should we display the block time?'), 1378 'blocktime' => new external_value(PARAM_NOTAGS, 'The time to display above the message'), 1379 'position' => new external_value(PARAM_ALPHA, 'The position of the text'), 1380 'timesent' => new external_value(PARAM_NOTAGS, 'The time the message was sent'), 1381 'timecreated' => new external_value(PARAM_INT, 'The timecreated timestamp for the message'), 1382 'isread' => new external_value(PARAM_INT, 'Determines if the message was read or not'), 1383 ) 1384 ); 1385 } 1386 1387 /** 1388 * Get messagearea search users in course parameters. 1389 * 1390 * @deprecated since 3.6 1391 * 1392 * @return external_function_parameters 1393 * @since 3.2 1394 */ 1395 public static function data_for_messagearea_search_users_in_course_parameters() { 1396 return new external_function_parameters( 1397 array( 1398 'userid' => new external_value(PARAM_INT, 'The id of the user who is performing the search'), 1399 'courseid' => new external_value(PARAM_INT, 'The id of the course'), 1400 'search' => new external_value(PARAM_RAW, 'The string being searched'), 1401 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0), 1402 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0) 1403 ) 1404 ); 1405 } 1406 1407 /** 1408 * Get messagearea search users in course results. 1409 * 1410 * @deprecated since 3.6 1411 * 1412 * @param int $userid The id of the user who is performing the search 1413 * @param int $courseid The id of the course 1414 * @param string $search The string being searched 1415 * @param int $limitfrom 1416 * @param int $limitnum 1417 * @return stdClass 1418 * @throws moodle_exception 1419 * @since 3.2 1420 */ 1421 public static function data_for_messagearea_search_users_in_course($userid, $courseid, $search, $limitfrom = 0, 1422 $limitnum = 0) { 1423 global $CFG, $PAGE, $USER; 1424 1425 // Check if messaging is enabled. 1426 if (empty($CFG->messaging)) { 1427 throw new moodle_exception('disabled', 'message'); 1428 } 1429 1430 $systemcontext = context_system::instance(); 1431 1432 $params = array( 1433 'userid' => $userid, 1434 'courseid' => $courseid, 1435 'search' => $search, 1436 'limitfrom' => $limitfrom, 1437 'limitnum' => $limitnum 1438 ); 1439 $params = self::validate_parameters(self::data_for_messagearea_search_users_in_course_parameters(), $params); 1440 self::validate_context($systemcontext); 1441 1442 if (($USER->id != $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) { 1443 throw new moodle_exception('You do not have permission to perform this action.'); 1444 } 1445 1446 $users = \core_message\api::search_users_in_course( 1447 $params['userid'], 1448 $params['courseid'], 1449 $params['search'], 1450 $params['limitfrom'], 1451 $params['limitnum'] 1452 ); 1453 $results = new \core_message\output\messagearea\user_search_results($users); 1454 1455 $renderer = $PAGE->get_renderer('core_message'); 1456 return $results->export_for_template($renderer); 1457 } 1458 1459 /** 1460 * Get messagearea search users in course returns. 1461 * 1462 * @deprecated since 3.6 1463 * 1464 * @return external_single_structure 1465 * @since 3.2 1466 */ 1467 public static function data_for_messagearea_search_users_in_course_returns() { 1468 return new external_single_structure( 1469 array( 1470 'contacts' => new external_multiple_structure( 1471 self::get_messagearea_contact_structure() 1472 ), 1473 ) 1474 ); 1475 } 1476 1477 /** 1478 * Marking the method as deprecated. 1479 * 1480 * @return bool 1481 */ 1482 public static function data_for_messagearea_search_users_in_course_is_deprecated() { 1483 return true; 1484 } 1485 1486 /** 1487 * Get messagearea search users parameters. 1488 * 1489 * @deprecated since 3.6 1490 * 1491 * @return external_function_parameters 1492 * @since 3.2 1493 */ 1494 public static function data_for_messagearea_search_users_parameters() { 1495 return new external_function_parameters( 1496 array( 1497 'userid' => new external_value(PARAM_INT, 'The id of the user who is performing the search'), 1498 'search' => new external_value(PARAM_RAW, 'The string being searched'), 1499 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0) 1500 ) 1501 ); 1502 } 1503 1504 /** 1505 * Get messagearea search users results. 1506 * 1507 * @deprecated since 3.6 1508 * 1509 * @param int $userid The id of the user who is performing the search 1510 * @param string $search The string being searched 1511 * @param int $limitnum 1512 * @return stdClass 1513 * @throws moodle_exception 1514 * @since 3.2 1515 */ 1516 public static function data_for_messagearea_search_users($userid, $search, $limitnum = 0) { 1517 global $CFG, $PAGE, $USER; 1518 1519 // Check if messaging is enabled. 1520 if (empty($CFG->messaging)) { 1521 throw new moodle_exception('disabled', 'message'); 1522 } 1523 1524 $systemcontext = context_system::instance(); 1525 1526 $params = array( 1527 'userid' => $userid, 1528 'search' => $search, 1529 'limitnum' => $limitnum 1530 ); 1531 $params = self::validate_parameters(self::data_for_messagearea_search_users_parameters(), $params); 1532 self::validate_context($systemcontext); 1533 1534 if (($USER->id != $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) { 1535 throw new moodle_exception('You do not have permission to perform this action.'); 1536 } 1537 1538 list($contacts, $courses, $noncontacts) = \core_message\api::search_users( 1539 $params['userid'], 1540 $params['search'], 1541 $params['limitnum'] 1542 ); 1543 1544 $search = new \core_message\output\messagearea\user_search_results($contacts, $courses, $noncontacts); 1545 1546 $renderer = $PAGE->get_renderer('core_message'); 1547 return $search->export_for_template($renderer); 1548 } 1549 1550 /** 1551 * Get messagearea search users returns. 1552 * 1553 * @deprecated since 3.6 1554 * 1555 * @return external_single_structure 1556 * @since 3.2 1557 */ 1558 public static function data_for_messagearea_search_users_returns() { 1559 return new external_single_structure( 1560 array( 1561 'contacts' => new external_multiple_structure( 1562 self::get_messagearea_contact_structure() 1563 ), 1564 'courses' => new external_multiple_structure( 1565 new external_single_structure( 1566 array( 1567 'id' => new external_value(PARAM_INT, 'The course id'), 1568 'shortname' => new external_value(PARAM_TEXT, 'The course shortname'), 1569 'fullname' => new external_value(PARAM_TEXT, 'The course fullname'), 1570 ) 1571 ) 1572 ), 1573 'noncontacts' => new external_multiple_structure( 1574 self::get_messagearea_contact_structure() 1575 ) 1576 ) 1577 ); 1578 } 1579 1580 /** 1581 * Marking the method as deprecated. 1582 * 1583 * @return bool 1584 */ 1585 public static function data_for_messagearea_search_users_is_deprecated() { 1586 return true; 1587 } 1588 1589 /** 1590 * Get messagearea message search users parameters. 1591 * 1592 * @return external_function_parameters 1593 * @since 3.6 1594 */ 1595 public static function message_search_users_parameters() { 1596 return new external_function_parameters( 1597 array( 1598 'userid' => new external_value(PARAM_INT, 'The id of the user who is performing the search'), 1599 'search' => new external_value(PARAM_RAW, 'The string being searched'), 1600 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0), 1601 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0), 1602 ) 1603 ); 1604 } 1605 1606 /** 1607 * Get search users results. 1608 * 1609 * @param int $userid The id of the user who is performing the search 1610 * @param string $search The string being searched 1611 * @param int $limitfrom 1612 * @param int $limitnum 1613 * @return array 1614 * @throws moodle_exception 1615 * @since 3.6 1616 */ 1617 public static function message_search_users($userid, $search, $limitfrom = 0, $limitnum = 0) { 1618 global $USER; 1619 1620 $systemcontext = context_system::instance(); 1621 1622 $params = array( 1623 'userid' => $userid, 1624 'search' => $search, 1625 'limitfrom' => $limitfrom, 1626 'limitnum' => $limitnum 1627 ); 1628 $params = self::validate_parameters(self::message_search_users_parameters(), $params); 1629 self::validate_context($systemcontext); 1630 1631 if (($USER->id != $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) { 1632 throw new moodle_exception('You do not have permission to perform this action.'); 1633 } 1634 1635 list($contacts, $noncontacts) = \core_message\api::message_search_users( 1636 $params['userid'], 1637 $params['search'], 1638 $params['limitfrom'], 1639 $params['limitnum']); 1640 1641 return array('contacts' => $contacts, 'noncontacts' => $noncontacts); 1642 } 1643 1644 /** 1645 * Get messagearea message search users returns. 1646 * 1647 * @return external_single_structure 1648 * @since 3.2 1649 */ 1650 public static function message_search_users_returns() { 1651 return new external_single_structure( 1652 array( 1653 'contacts' => new external_multiple_structure( 1654 self::get_conversation_member_structure() 1655 ), 1656 'noncontacts' => new external_multiple_structure( 1657 self::get_conversation_member_structure() 1658 ) 1659 ) 1660 ); 1661 } 1662 1663 /** 1664 * Get messagearea search messages parameters. 1665 * 1666 * @return external_function_parameters 1667 * @since 3.2 1668 */ 1669 public static function data_for_messagearea_search_messages_parameters() { 1670 return new external_function_parameters( 1671 array( 1672 'userid' => new external_value(PARAM_INT, 'The id of the user who is performing the search'), 1673 'search' => new external_value(PARAM_RAW, 'The string being searched'), 1674 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0), 1675 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0) 1676 ) 1677 ); 1678 } 1679 1680 /** 1681 * Get messagearea search messages results. 1682 * 1683 * @param int $userid The id of the user who is performing the search 1684 * @param string $search The string being searched 1685 * @param int $limitfrom 1686 * @param int $limitnum 1687 * @return stdClass 1688 * @throws moodle_exception 1689 * @since 3.2 1690 */ 1691 public static function data_for_messagearea_search_messages($userid, $search, $limitfrom = 0, $limitnum = 0) { 1692 global $CFG, $USER; 1693 1694 // Check if messaging is enabled. 1695 if (empty($CFG->messaging)) { 1696 throw new moodle_exception('disabled', 'message'); 1697 } 1698 1699 $systemcontext = context_system::instance(); 1700 1701 $params = array( 1702 'userid' => $userid, 1703 'search' => $search, 1704 'limitfrom' => $limitfrom, 1705 'limitnum' => $limitnum 1706 1707 ); 1708 $params = self::validate_parameters(self::data_for_messagearea_search_messages_parameters(), $params); 1709 self::validate_context($systemcontext); 1710 1711 if (($USER->id != $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) { 1712 throw new moodle_exception('You do not have permission to perform this action.'); 1713 } 1714 1715 $messages = \core_message\api::search_messages( 1716 $params['userid'], 1717 $params['search'], 1718 $params['limitfrom'], 1719 $params['limitnum'] 1720 ); 1721 1722 $data = new \stdClass(); 1723 $data->contacts = []; 1724 foreach ($messages as $message) { 1725 $contact = new \stdClass(); 1726 $contact->userid = $message->userid; 1727 $contact->fullname = $message->fullname; 1728 $contact->profileimageurl = $message->profileimageurl; 1729 $contact->profileimageurlsmall = $message->profileimageurlsmall; 1730 $contact->messageid = $message->messageid; 1731 $contact->ismessaging = $message->ismessaging; 1732 $contact->sentfromcurrentuser = false; 1733 if ($message->lastmessage) { 1734 if ($message->userid !== $message->useridfrom) { 1735 $contact->sentfromcurrentuser = true; 1736 } 1737 $contact->lastmessage = shorten_text($message->lastmessage, 60); 1738 } else { 1739 $contact->lastmessage = null; 1740 } 1741 $contact->lastmessagedate = $message->lastmessagedate; 1742 $contact->showonlinestatus = is_null($message->isonline) ? false : true; 1743 $contact->isonline = $message->isonline; 1744 $contact->isblocked = $message->isblocked; 1745 $contact->isread = $message->isread; 1746 $contact->unreadcount = $message->unreadcount; 1747 $contact->conversationid = $message->conversationid; 1748 1749 $data->contacts[] = $contact; 1750 } 1751 1752 return $data; 1753 } 1754 1755 /** 1756 * Get messagearea search messages returns. 1757 * 1758 * @return external_single_structure 1759 * @since 3.2 1760 */ 1761 public static function data_for_messagearea_search_messages_returns() { 1762 return new external_single_structure( 1763 array( 1764 'contacts' => new external_multiple_structure( 1765 self::get_messagearea_contact_structure() 1766 ) 1767 ) 1768 ); 1769 } 1770 1771 /** 1772 * Get conversations parameters. 1773 * 1774 * @return external_function_parameters 1775 * @since 3.6 1776 */ 1777 public static function get_conversations_parameters() { 1778 return new external_function_parameters( 1779 array( 1780 'userid' => new external_value(PARAM_INT, 'The id of the user who we are viewing conversations for'), 1781 'limitfrom' => new external_value(PARAM_INT, 'The offset to start at', VALUE_DEFAULT, 0), 1782 'limitnum' => new external_value(PARAM_INT, 'Limit number of conversations to this', VALUE_DEFAULT, 0), 1783 'type' => new external_value(PARAM_INT, 'Filter by type', VALUE_DEFAULT, null), 1784 'favourites' => new external_value(PARAM_BOOL, 'Whether to restrict the results to contain NO favourite 1785 conversations (false), ONLY favourite conversation (true), or ignore any restriction altogether (null)', 1786 VALUE_DEFAULT, null), 1787 'mergeself' => new external_value(PARAM_BOOL, 'Whether to include self-conversations (true) or ONLY private 1788 conversations (false) when private conversations are requested.', 1789 VALUE_DEFAULT, false), 1790 ) 1791 ); 1792 } 1793 1794 /** 1795 * Get the list of conversations for the user. 1796 * 1797 * @param int $userid The id of the user who is performing the search 1798 * @param int $limitfrom 1799 * @param int $limitnum 1800 * @param int|null $type 1801 * @param bool|null $favourites 1802 * @param bool $mergeself whether to include self-conversations (true) or ONLY private conversations (false) 1803 * when private conversations are requested. 1804 * @return stdClass 1805 * @throws \moodle_exception if the messaging feature is disabled on the site. 1806 * @since 3.2 1807 */ 1808 public static function get_conversations($userid, $limitfrom = 0, $limitnum = 0, int $type = null, bool $favourites = null, 1809 bool $mergeself = false) { 1810 global $CFG, $USER; 1811 1812 // All the standard BL checks. 1813 if (empty($CFG->messaging)) { 1814 throw new moodle_exception('disabled', 'message'); 1815 } 1816 1817 $params = array( 1818 'userid' => $userid, 1819 'limitfrom' => $limitfrom, 1820 'limitnum' => $limitnum, 1821 'type' => $type, 1822 'favourites' => $favourites, 1823 'mergeself' => $mergeself 1824 ); 1825 $params = self::validate_parameters(self::get_conversations_parameters(), $params); 1826 1827 $systemcontext = context_system::instance(); 1828 self::validate_context($systemcontext); 1829 1830 if (($USER->id != $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) { 1831 throw new moodle_exception('You do not have permission to perform this action.'); 1832 } 1833 1834 $conversations = \core_message\api::get_conversations( 1835 $params['userid'], 1836 $params['limitfrom'], 1837 $params['limitnum'], 1838 $params['type'], 1839 $params['favourites'], 1840 $params['mergeself'] 1841 ); 1842 1843 return (object) ['conversations' => $conversations]; 1844 } 1845 1846 /** 1847 * Get conversations returns. 1848 * 1849 * @return external_single_structure 1850 * @since 3.6 1851 */ 1852 public static function get_conversations_returns() { 1853 return new external_single_structure( 1854 [ 1855 'conversations' => new external_multiple_structure( 1856 self::get_conversation_structure(true) 1857 ) 1858 ] 1859 ); 1860 } 1861 1862 /** 1863 * Get conversation parameters. 1864 * 1865 * @return external_function_parameters 1866 */ 1867 public static function get_conversation_parameters() { 1868 return new external_function_parameters( 1869 array( 1870 'userid' => new external_value(PARAM_INT, 'The id of the user who we are viewing conversations for'), 1871 'conversationid' => new external_value(PARAM_INT, 'The id of the conversation to fetch'), 1872 'includecontactrequests' => new external_value(PARAM_BOOL, 'Include contact requests in the members'), 1873 'includeprivacyinfo' => new external_value(PARAM_BOOL, 'Include privacy info in the members'), 1874 'memberlimit' => new external_value(PARAM_INT, 'Limit for number of members', VALUE_DEFAULT, 0), 1875 'memberoffset' => new external_value(PARAM_INT, 'Offset for member list', VALUE_DEFAULT, 0), 1876 'messagelimit' => new external_value(PARAM_INT, 'Limit for number of messages', VALUE_DEFAULT, 100), 1877 'messageoffset' => new external_value(PARAM_INT, 'Offset for messages list', VALUE_DEFAULT, 0), 1878 'newestmessagesfirst' => new external_value(PARAM_BOOL, 'Order messages by newest first', VALUE_DEFAULT, true) 1879 ) 1880 ); 1881 } 1882 1883 /** 1884 * Get a single conversation. 1885 * 1886 * @param int $userid The user id to get the conversation for 1887 * @param int $conversationid The id of the conversation to fetch 1888 * @param bool $includecontactrequests Should contact requests be included between members 1889 * @param bool $includeprivacyinfo Should privacy info be included between members 1890 * @param int $memberlimit Limit number of members to load 1891 * @param int $memberoffset Offset members by this amount 1892 * @param int $messagelimit Limit number of messages to load 1893 * @param int $messageoffset Offset the messages 1894 * @param bool $newestmessagesfirst Order messages by newest first 1895 * @return stdClass 1896 * @throws \moodle_exception if the messaging feature is disabled on the site. 1897 */ 1898 public static function get_conversation( 1899 int $userid, 1900 int $conversationid, 1901 bool $includecontactrequests = false, 1902 bool $includeprivacyinfo = false, 1903 int $memberlimit = 0, 1904 int $memberoffset = 0, 1905 int $messagelimit = 0, 1906 int $messageoffset = 0, 1907 bool $newestmessagesfirst = true 1908 ) { 1909 global $CFG, $DB, $USER; 1910 1911 // All the standard BL checks. 1912 if (empty($CFG->messaging)) { 1913 throw new moodle_exception('disabled', 'message'); 1914 } 1915 1916 $params = [ 1917 'userid' => $userid, 1918 'conversationid' => $conversationid, 1919 'includecontactrequests' => $includecontactrequests, 1920 'includeprivacyinfo' => $includeprivacyinfo, 1921 'memberlimit' => $memberlimit, 1922 'memberoffset' => $memberoffset, 1923 'messagelimit' => $messagelimit, 1924 'messageoffset' => $messageoffset, 1925 'newestmessagesfirst' => $newestmessagesfirst 1926 ]; 1927 self::validate_parameters(self::get_conversation_parameters(), $params); 1928 1929 $systemcontext = context_system::instance(); 1930 self::validate_context($systemcontext); 1931 1932 $conversation = \core_message\api::get_conversation( 1933 $params['userid'], 1934 $params['conversationid'], 1935 $params['includecontactrequests'], 1936 $params['includeprivacyinfo'], 1937 $params['memberlimit'], 1938 $params['memberoffset'], 1939 $params['messagelimit'], 1940 $params['messageoffset'], 1941 $params['newestmessagesfirst'] 1942 ); 1943 1944 if ($conversation) { 1945 return $conversation; 1946 } else { 1947 // We have to throw an exception here because the external functions annoyingly 1948 // don't accept null to be returned for a single structure. 1949 throw new \moodle_exception('errorconversationdoesnotexist', 'message'); 1950 } 1951 } 1952 1953 /** 1954 * Get conversation returns. 1955 * 1956 * @return external_single_structure 1957 */ 1958 public static function get_conversation_returns() { 1959 return self::get_conversation_structure(); 1960 } 1961 1962 /** 1963 * Get conversation parameters. 1964 * 1965 * @return external_function_parameters 1966 */ 1967 public static function get_conversation_between_users_parameters() { 1968 return new external_function_parameters( 1969 array( 1970 'userid' => new external_value(PARAM_INT, 'The id of the user who we are viewing conversations for'), 1971 'otheruserid' => new external_value(PARAM_INT, 'The other user id'), 1972 'includecontactrequests' => new external_value(PARAM_BOOL, 'Include contact requests in the members'), 1973 'includeprivacyinfo' => new external_value(PARAM_BOOL, 'Include privacy info in the members'), 1974 'memberlimit' => new external_value(PARAM_INT, 'Limit for number of members', VALUE_DEFAULT, 0), 1975 'memberoffset' => new external_value(PARAM_INT, 'Offset for member list', VALUE_DEFAULT, 0), 1976 'messagelimit' => new external_value(PARAM_INT, 'Limit for number of messages', VALUE_DEFAULT, 100), 1977 'messageoffset' => new external_value(PARAM_INT, 'Offset for messages list', VALUE_DEFAULT, 0), 1978 'newestmessagesfirst' => new external_value(PARAM_BOOL, 'Order messages by newest first', VALUE_DEFAULT, true) 1979 ) 1980 ); 1981 } 1982 1983 /** 1984 * Get a single conversation between users. 1985 * 1986 * @param int $userid The user id to get the conversation for 1987 * @param int $otheruserid The other user id 1988 * @param bool $includecontactrequests Should contact requests be included between members 1989 * @param bool $includeprivacyinfo Should privacy info be included between members 1990 * @param int $memberlimit Limit number of members to load 1991 * @param int $memberoffset Offset members by this amount 1992 * @param int $messagelimit Limit number of messages to load 1993 * @param int $messageoffset Offset the messages 1994 * @param bool $newestmessagesfirst Order messages by newest first 1995 * @return stdClass 1996 * @throws \moodle_exception if the messaging feature is disabled on the site. 1997 */ 1998 public static function get_conversation_between_users( 1999 int $userid, 2000 int $otheruserid, 2001 bool $includecontactrequests = false, 2002 bool $includeprivacyinfo = false, 2003 int $memberlimit = 0, 2004 int $memberoffset = 0, 2005 int $messagelimit = 0, 2006 int $messageoffset = 0, 2007 bool $newestmessagesfirst = true 2008 ) { 2009 global $CFG, $DB, $USER; 2010 2011 // All the standard BL checks. 2012 if (empty($CFG->messaging)) { 2013 throw new moodle_exception('disabled', 'message'); 2014 } 2015 2016 $params = [ 2017 'userid' => $userid, 2018 'otheruserid' => $otheruserid, 2019 'includecontactrequests' => $includecontactrequests, 2020 'includeprivacyinfo' => $includeprivacyinfo, 2021 'memberlimit' => $memberlimit, 2022 'memberoffset' => $memberoffset, 2023 'messagelimit' => $messagelimit, 2024 'messageoffset' => $messageoffset, 2025 'newestmessagesfirst' => $newestmessagesfirst 2026 ]; 2027 self::validate_parameters(self::get_conversation_between_users_parameters(), $params); 2028 2029 $systemcontext = context_system::instance(); 2030 self::validate_context($systemcontext); 2031 2032 $conversationid = \core_message\api::get_conversation_between_users([$params['userid'], $params['otheruserid']]); 2033 $conversation = null; 2034 2035 if ($conversationid) { 2036 $conversation = \core_message\api::get_conversation( 2037 $params['userid'], 2038 $conversationid, 2039 $params['includecontactrequests'], 2040 $params['includeprivacyinfo'], 2041 $params['memberlimit'], 2042 $params['memberoffset'], 2043 $params['messagelimit'], 2044 $params['messageoffset'], 2045 $params['newestmessagesfirst'] 2046 ); 2047 } 2048 2049 if ($conversation) { 2050 return $conversation; 2051 } else { 2052 // We have to throw an exception here because the external functions annoyingly 2053 // don't accept null to be returned for a single structure. 2054 throw new \moodle_exception('errorconversationdoesnotexist', 'message'); 2055 } 2056 } 2057 2058 /** 2059 * Get conversation returns. 2060 * 2061 * @return external_single_structure 2062 */ 2063 public static function get_conversation_between_users_returns() { 2064 return self::get_conversation_structure(true); 2065 } 2066 2067 /** 2068 * Get self-conversation parameters. 2069 * 2070 * @return external_function_parameters 2071 */ 2072 public static function get_self_conversation_parameters() { 2073 return new external_function_parameters( 2074 array( 2075 'userid' => new external_value(PARAM_INT, 'The id of the user who we are viewing self-conversations for'), 2076 'messagelimit' => new external_value(PARAM_INT, 'Limit for number of messages', VALUE_DEFAULT, 100), 2077 'messageoffset' => new external_value(PARAM_INT, 'Offset for messages list', VALUE_DEFAULT, 0), 2078 'newestmessagesfirst' => new external_value(PARAM_BOOL, 'Order messages by newest first', VALUE_DEFAULT, true) 2079 ) 2080 ); 2081 } 2082 2083 /** 2084 * Get a single self-conversation. 2085 * 2086 * @param int $userid The user id to get the self-conversation for 2087 * @param int $messagelimit Limit number of messages to load 2088 * @param int $messageoffset Offset the messages 2089 * @param bool $newestmessagesfirst Order messages by newest first 2090 * @return stdClass 2091 * @throws \moodle_exception if the messaging feature is disabled on the site. 2092 * @since Moodle 3.7 2093 */ 2094 public static function get_self_conversation( 2095 int $userid, 2096 int $messagelimit = 0, 2097 int $messageoffset = 0, 2098 bool $newestmessagesfirst = true 2099 ) { 2100 global $CFG; 2101 2102 // All the standard BL checks. 2103 if (empty($CFG->messaging)) { 2104 throw new moodle_exception('disabled', 'message'); 2105 } 2106 2107 $params = [ 2108 'userid' => $userid, 2109 'messagelimit' => $messagelimit, 2110 'messageoffset' => $messageoffset, 2111 'newestmessagesfirst' => $newestmessagesfirst 2112 ]; 2113 self::validate_parameters(self::get_self_conversation_parameters(), $params); 2114 2115 $systemcontext = context_system::instance(); 2116 self::validate_context($systemcontext); 2117 2118 $conversation = \core_message\api::get_self_conversation($params['userid']); 2119 2120 if ($conversation) { 2121 $conversation = \core_message\api::get_conversation( 2122 $params['userid'], 2123 $conversation->id, 2124 false, 2125 false, 2126 0, 2127 0, 2128 $params['messagelimit'], 2129 $params['messageoffset'], 2130 $params['newestmessagesfirst'] 2131 ); 2132 } 2133 2134 if ($conversation) { 2135 return $conversation; 2136 } else { 2137 // We have to throw an exception here because the external functions annoyingly 2138 // don't accept null to be returned for a single structure. 2139 throw new \moodle_exception('errorconversationdoesnotexist', 'message'); 2140 } 2141 } 2142 2143 /** 2144 * Get conversation returns. 2145 * 2146 * @return external_single_structure 2147 */ 2148 public static function get_self_conversation_returns() { 2149 return self::get_conversation_structure(); 2150 } 2151 2152 /** 2153 * The messagearea conversations parameters. 2154 * 2155 * @deprecated since 3.6 2156 * @return external_function_parameters 2157 * @since 3.2 2158 */ 2159 public static function data_for_messagearea_conversations_parameters() { 2160 return new external_function_parameters( 2161 array( 2162 'userid' => new external_value(PARAM_INT, 'The id of the user who we are viewing conversations for'), 2163 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0), 2164 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0) 2165 ) 2166 ); 2167 } 2168 2169 /** 2170 * Get messagearea conversations. 2171 * 2172 * NOTE FOR FINAL DEPRECATION: 2173 * When removing this method, please also consider removal of get_conversations_legacy_formatter() 2174 * from the \core_message\helper class. This helper method was used solely to format the new get_conversations() return data 2175 * into the old format used here, and in message/index.php. If we no longer need either of these, then that method can be 2176 * removed. 2177 * 2178 * @deprecated since 3.6 2179 * @param int $userid The id of the user who we are viewing conversations for 2180 * @param int $limitfrom 2181 * @param int $limitnum 2182 * @return stdClass 2183 * @throws moodle_exception 2184 * @since 3.2 2185 */ 2186 public static function data_for_messagearea_conversations($userid, $limitfrom = 0, $limitnum = 0) { 2187 global $CFG, $PAGE, $USER; 2188 2189 // Check if messaging is enabled. 2190 if (empty($CFG->messaging)) { 2191 throw new moodle_exception('disabled', 'message'); 2192 } 2193 2194 $systemcontext = context_system::instance(); 2195 2196 $params = array( 2197 'userid' => $userid, 2198 'limitfrom' => $limitfrom, 2199 'limitnum' => $limitnum 2200 ); 2201 $params = self::validate_parameters(self::data_for_messagearea_conversations_parameters(), $params); 2202 self::validate_context($systemcontext); 2203 2204 if (($USER->id != $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) { 2205 throw new moodle_exception('You do not have permission to perform this action.'); 2206 } 2207 2208 $conversations = \core_message\api::get_conversations($params['userid'], $params['limitfrom'], $params['limitnum']); 2209 2210 // Format the conversations in the legacy style, as the get_conversations method has since been changed. 2211 $conversations = \core_message\helper::get_conversations_legacy_formatter($conversations); 2212 2213 $conversations = new \core_message\output\messagearea\contacts(null, $conversations); 2214 2215 $renderer = $PAGE->get_renderer('core_message'); 2216 return $conversations->export_for_template($renderer); 2217 } 2218 2219 /** 2220 * The messagearea conversations return structure. 2221 * 2222 * @deprecated since 3.6 2223 * @return external_single_structure 2224 * @since 3.2 2225 */ 2226 public static function data_for_messagearea_conversations_returns() { 2227 return new external_single_structure( 2228 array( 2229 'contacts' => new external_multiple_structure( 2230 self::get_messagearea_contact_structure() 2231 ) 2232 ) 2233 ); 2234 } 2235 2236 /** 2237 * Marking the method as deprecated. 2238 * 2239 * @return bool 2240 */ 2241 public static function data_for_messagearea_conversations_is_deprecated() { 2242 return true; 2243 } 2244 2245 /** 2246 * The messagearea contacts return parameters. 2247 * 2248 * @deprecated since 3.6 2249 * @return external_function_parameters 2250 * @since 3.2 2251 */ 2252 public static function data_for_messagearea_contacts_parameters() { 2253 return self::data_for_messagearea_conversations_parameters(); 2254 } 2255 2256 /** 2257 * Get messagearea contacts parameters. 2258 * 2259 * @deprecated since 3.6 2260 * @param int $userid The id of the user who we are viewing conversations for 2261 * @param int $limitfrom 2262 * @param int $limitnum 2263 * @return stdClass 2264 * @throws moodle_exception 2265 * @since 3.2 2266 */ 2267 public static function data_for_messagearea_contacts($userid, $limitfrom = 0, $limitnum = 0) { 2268 global $CFG, $PAGE, $USER; 2269 2270 // Check if messaging is enabled. 2271 if (empty($CFG->messaging)) { 2272 throw new moodle_exception('disabled', 'message'); 2273 } 2274 2275 $systemcontext = context_system::instance(); 2276 2277 $params = array( 2278 'userid' => $userid, 2279 'limitfrom' => $limitfrom, 2280 'limitnum' => $limitnum 2281 ); 2282 $params = self::validate_parameters(self::data_for_messagearea_contacts_parameters(), $params); 2283 self::validate_context($systemcontext); 2284 2285 if (($USER->id != $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) { 2286 throw new moodle_exception('You do not have permission to perform this action.'); 2287 } 2288 2289 $contacts = \core_message\api::get_contacts($params['userid'], $params['limitfrom'], $params['limitnum']); 2290 $contacts = new \core_message\output\messagearea\contacts(null, $contacts); 2291 2292 $renderer = $PAGE->get_renderer('core_message'); 2293 return $contacts->export_for_template($renderer); 2294 } 2295 2296 /** 2297 * The messagearea contacts return structure. 2298 * 2299 * @deprecated since 3.6 2300 * @return external_single_structure 2301 * @since 3.2 2302 */ 2303 public static function data_for_messagearea_contacts_returns() { 2304 return self::data_for_messagearea_conversations_returns(); 2305 } 2306 2307 /** 2308 * Marking the method as deprecated. 2309 * 2310 * @return bool 2311 */ 2312 public static function data_for_messagearea_contacts_is_deprecated() { 2313 return true; 2314 } 2315 2316 /** 2317 * The messagearea messages parameters. 2318 * 2319 * @deprecated since 3.6 2320 * @return external_function_parameters 2321 * @since 3.2 2322 */ 2323 public static function data_for_messagearea_messages_parameters() { 2324 return new external_function_parameters( 2325 array( 2326 'currentuserid' => new external_value(PARAM_INT, 'The current user\'s id'), 2327 'otheruserid' => new external_value(PARAM_INT, 'The other user\'s id'), 2328 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0), 2329 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0), 2330 'newest' => new external_value(PARAM_BOOL, 'Newest first?', VALUE_DEFAULT, false), 2331 'timefrom' => new external_value(PARAM_INT, 2332 'The timestamp from which the messages were created', VALUE_DEFAULT, 0), 2333 ) 2334 ); 2335 } 2336 2337 /** 2338 * Get messagearea messages. 2339 * 2340 * @deprecated since 3.6 2341 * @param int $currentuserid The current user's id 2342 * @param int $otheruserid The other user's id 2343 * @param int $limitfrom 2344 * @param int $limitnum 2345 * @param boolean $newest 2346 * @return stdClass 2347 * @throws moodle_exception 2348 * @since 3.2 2349 */ 2350 public static function data_for_messagearea_messages($currentuserid, $otheruserid, $limitfrom = 0, $limitnum = 0, 2351 $newest = false, $timefrom = 0) { 2352 global $CFG, $PAGE, $USER; 2353 2354 // Check if messaging is enabled. 2355 if (empty($CFG->messaging)) { 2356 throw new moodle_exception('disabled', 'message'); 2357 } 2358 2359 $systemcontext = context_system::instance(); 2360 2361 $params = array( 2362 'currentuserid' => $currentuserid, 2363 'otheruserid' => $otheruserid, 2364 'limitfrom' => $limitfrom, 2365 'limitnum' => $limitnum, 2366 'newest' => $newest, 2367 'timefrom' => $timefrom, 2368 ); 2369 $params = self::validate_parameters(self::data_for_messagearea_messages_parameters(), $params); 2370 self::validate_context($systemcontext); 2371 2372 if (($USER->id != $params['currentuserid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) { 2373 throw new moodle_exception('You do not have permission to perform this action.'); 2374 } 2375 2376 if ($params['newest']) { 2377 $sort = 'timecreated DESC'; 2378 } else { 2379 $sort = 'timecreated ASC'; 2380 } 2381 2382 // We need to enforce a one second delay on messages to avoid race conditions of current 2383 // messages still being sent. 2384 // 2385 // There is a chance that we could request messages before the current time's 2386 // second has elapsed and while other messages are being sent in that same second. In which 2387 // case those messages will be lost. 2388 // 2389 // Instead we ignore the current time in the result set to ensure that second is allowed to finish. 2390 if (!empty($params['timefrom'])) { 2391 $timeto = time() - 1; 2392 } else { 2393 $timeto = 0; 2394 } 2395 2396 // No requesting messages from the current time, as stated above. 2397 if ($params['timefrom'] == time()) { 2398 $messages = []; 2399 } else { 2400 $messages = \core_message\api::get_messages($params['currentuserid'], $params['otheruserid'], $params['limitfrom'], 2401 $params['limitnum'], $sort, $params['timefrom'], $timeto); 2402 } 2403 2404 $messages = new \core_message\output\messagearea\messages($params['currentuserid'], $params['otheruserid'], $messages); 2405 2406 $renderer = $PAGE->get_renderer('core_message'); 2407 return $messages->export_for_template($renderer); 2408 } 2409 2410 /** 2411 * The messagearea messages return structure. 2412 * 2413 * @deprecated since 3.6 2414 * @return external_single_structure 2415 * @since 3.2 2416 */ 2417 public static function data_for_messagearea_messages_returns() { 2418 return new external_single_structure( 2419 array( 2420 'iscurrentuser' => new external_value(PARAM_BOOL, 'Is the currently logged in user the user we are viewing 2421 the messages on behalf of?'), 2422 'currentuserid' => new external_value(PARAM_INT, 'The current user\'s id'), 2423 'otheruserid' => new external_value(PARAM_INT, 'The other user\'s id'), 2424 'otheruserfullname' => new external_value(PARAM_NOTAGS, 'The other user\'s fullname'), 2425 'showonlinestatus' => new external_value(PARAM_BOOL, 'Show the user\'s online status?'), 2426 'isonline' => new external_value(PARAM_BOOL, 'The user\'s online status'), 2427 'messages' => new external_multiple_structure( 2428 self::get_messagearea_message_structure() 2429 ), 2430 'isblocked' => new external_value(PARAM_BOOL, 'Is this user blocked by the current user?', VALUE_DEFAULT, false), 2431 ) 2432 ); 2433 } 2434 2435 /** 2436 * Marking the method as deprecated. 2437 * 2438 * @return bool 2439 */ 2440 public static function data_for_messagearea_messages_is_deprecated() { 2441 return true; 2442 } 2443 2444 /** 2445 * The conversation messages parameters. 2446 * 2447 * @return external_function_parameters 2448 * @since 3.6 2449 */ 2450 public static function get_conversation_messages_parameters() { 2451 return new external_function_parameters( 2452 array( 2453 'currentuserid' => new external_value(PARAM_INT, 'The current user\'s id'), 2454 'convid' => new external_value(PARAM_INT, 'The conversation id'), 2455 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0), 2456 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0), 2457 'newest' => new external_value(PARAM_BOOL, 'Newest first?', VALUE_DEFAULT, false), 2458 'timefrom' => new external_value(PARAM_INT, 2459 'The timestamp from which the messages were created', VALUE_DEFAULT, 0), 2460 ) 2461 ); 2462 } 2463 2464 /** 2465 * Get conversation messages. 2466 * 2467 * @param int $currentuserid The current user's id. 2468 * @param int $convid The conversation id. 2469 * @param int $limitfrom Return a subset of records, starting at this point (optional). 2470 * @param int $limitnum Return a subset comprising this many records in total (optional, required if $limitfrom is set). 2471 * @param bool $newest True for getting first newest messages, false otherwise. 2472 * @param int $timefrom The time from the conversation messages to get. 2473 * @return array The messages and members who have sent some of these messages. 2474 * @throws moodle_exception 2475 * @since 3.6 2476 */ 2477 public static function get_conversation_messages(int $currentuserid, int $convid, int $limitfrom = 0, int $limitnum = 0, 2478 bool $newest = false, int $timefrom = 0) { 2479 global $CFG, $USER; 2480 2481 // Check if messaging is enabled. 2482 if (empty($CFG->messaging)) { 2483 throw new moodle_exception('disabled', 'message'); 2484 } 2485 2486 $systemcontext = context_system::instance(); 2487 2488 $params = array( 2489 'currentuserid' => $currentuserid, 2490 'convid' => $convid, 2491 'limitfrom' => $limitfrom, 2492 'limitnum' => $limitnum, 2493 'newest' => $newest, 2494 'timefrom' => $timefrom, 2495 ); 2496 $params = self::validate_parameters(self::get_conversation_messages_parameters(), $params); 2497 self::validate_context($systemcontext); 2498 2499 if (($USER->id != $params['currentuserid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) { 2500 throw new moodle_exception('You do not have permission to perform this action.'); 2501 } 2502 2503 // Check that the user belongs to the conversation. 2504 if (!\core_message\api::is_user_in_conversation($params['currentuserid'], $params['convid'])) { 2505 throw new moodle_exception('User is not part of conversation.'); 2506 } 2507 2508 $sort = $newest ? 'timecreated DESC' : 'timecreated ASC'; 2509 2510 // We need to enforce a one second delay on messages to avoid race conditions of current 2511 // messages still being sent. 2512 // 2513 // There is a chance that we could request messages before the current time's 2514 // second has elapsed and while other messages are being sent in that same second. In which 2515 // case those messages will be lost. 2516 // 2517 // Instead we ignore the current time in the result set to ensure that second is allowed to finish. 2518 $timeto = empty($params['timefrom']) ? 0 : time() - 1; 2519 2520 // No requesting messages from the current time, as stated above. 2521 if ($params['timefrom'] == time()) { 2522 $messages = []; 2523 } else { 2524 $messages = \core_message\api::get_conversation_messages( 2525 $params['currentuserid'], 2526 $params['convid'], 2527 $params['limitfrom'], 2528 $params['limitnum'], 2529 $sort, 2530 $params['timefrom'], 2531 $timeto); 2532 } 2533 2534 return $messages; 2535 } 2536 2537 /** 2538 * The messagearea messages return structure. 2539 * 2540 * @return external_single_structure 2541 * @since 3.6 2542 */ 2543 public static function get_conversation_messages_returns() { 2544 return new external_single_structure( 2545 array( 2546 'id' => new external_value(PARAM_INT, 'The conversation id'), 2547 'members' => new external_multiple_structure( 2548 self::get_conversation_member_structure() 2549 ), 2550 'messages' => new external_multiple_structure( 2551 self::get_conversation_message_structure() 2552 ), 2553 ) 2554 ); 2555 } 2556 2557 /** 2558 * The user contacts return parameters. 2559 * 2560 * @return external_function_parameters 2561 */ 2562 public static function get_user_contacts_parameters() { 2563 return new external_function_parameters( 2564 array( 2565 'userid' => new external_value(PARAM_INT, 'The id of the user who we retrieving the contacts for'), 2566 'limitfrom' => new external_value(PARAM_INT, 'Limit from', VALUE_DEFAULT, 0), 2567 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 0) 2568 ) 2569 ); 2570 } 2571 2572 /** 2573 * Get user contacts. 2574 * 2575 * @param int $userid The id of the user who we are viewing conversations for 2576 * @param int $limitfrom 2577 * @param int $limitnum 2578 * @return array 2579 * @throws moodle_exception 2580 */ 2581 public static function get_user_contacts(int $userid, int $limitfrom = 0, int $limitnum = 0) { 2582 global $CFG, $USER; 2583 2584 // Check if messaging is enabled. 2585 if (empty($CFG->messaging)) { 2586 throw new moodle_exception('disabled', 'message'); 2587 } 2588 2589 $systemcontext = context_system::instance(); 2590 2591 $params = array( 2592 'userid' => $userid, 2593 'limitfrom' => $limitfrom, 2594 'limitnum' => $limitnum 2595 ); 2596 $params = self::validate_parameters(self::get_user_contacts_parameters(), $params); 2597 self::validate_context($systemcontext); 2598 2599 if (($USER->id != $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) { 2600 throw new moodle_exception('You do not have permission to perform this action.'); 2601 } 2602 2603 return \core_message\api::get_user_contacts($params['userid'], $params['limitfrom'], $params['limitnum']); 2604 } 2605 2606 /** 2607 * The user contacts return structure. 2608 * 2609 * @return external_multiple_structure 2610 */ 2611 public static function get_user_contacts_returns() { 2612 return new external_multiple_structure( 2613 self::get_conversation_member_structure() 2614 ); 2615 } 2616 2617 /** 2618 * The get most recent message return parameters. 2619 * 2620 * @deprecated since 3.6 2621 * @return external_function_parameters 2622 * @since 3.2 2623 */ 2624 public static function data_for_messagearea_get_most_recent_message_parameters() { 2625 return new external_function_parameters( 2626 array( 2627 'currentuserid' => new external_value(PARAM_INT, 'The current user\'s id'), 2628 'otheruserid' => new external_value(PARAM_INT, 'The other user\'s id'), 2629 ) 2630 ); 2631 } 2632 2633 /** 2634 * Get the most recent message in a conversation. 2635 * 2636 * @deprecated since 3.6 2637 * @param int $currentuserid The current user's id 2638 * @param int $otheruserid The other user's id 2639 * @return stdClass 2640 * @throws moodle_exception 2641 * @since 3.2 2642 */ 2643 public static function data_for_messagearea_get_most_recent_message($currentuserid, $otheruserid) { 2644 global $CFG, $PAGE, $USER; 2645 2646 // Check if messaging is enabled. 2647 if (empty($CFG->messaging)) { 2648 throw new moodle_exception('disabled', 'message'); 2649 } 2650 2651 $systemcontext = context_system::instance(); 2652 2653 $params = array( 2654 'currentuserid' => $currentuserid, 2655 'otheruserid' => $otheruserid 2656 ); 2657 $params = self::validate_parameters(self::data_for_messagearea_get_most_recent_message_parameters(), $params); 2658 self::validate_context($systemcontext); 2659 2660 if (($USER->id != $params['currentuserid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) { 2661 throw new moodle_exception('You do not have permission to perform this action.'); 2662 } 2663 2664 $message = \core_message\api::get_most_recent_message($params['currentuserid'], $params['otheruserid']); 2665 $message = new \core_message\output\messagearea\message($message); 2666 2667 $renderer = $PAGE->get_renderer('core_message'); 2668 return $message->export_for_template($renderer); 2669 } 2670 2671 /** 2672 * The get most recent message return structure. 2673 * 2674 * @deprecated since 3.6 2675 * @return external_single_structure 2676 * @since 3.2 2677 */ 2678 public static function data_for_messagearea_get_most_recent_message_returns() { 2679 return self::get_messagearea_message_structure(); 2680 } 2681 2682 /** 2683 * Marking the method as deprecated. 2684 * 2685 * @return bool 2686 */ 2687 public static function data_for_messagearea_get_most_recent_message_is_deprecated() { 2688 return true; 2689 } 2690 2691 /** 2692 * The get profile parameters. 2693 * 2694 * @deprecated since 3.6 2695 * @return external_function_parameters 2696 * @since 3.2 2697 */ 2698 public static function data_for_messagearea_get_profile_parameters() { 2699 return new external_function_parameters( 2700 array( 2701 'currentuserid' => new external_value(PARAM_INT, 'The current user\'s id'), 2702 'otheruserid' => new external_value(PARAM_INT, 'The id of the user whose profile we want to view'), 2703 ) 2704 ); 2705 } 2706 2707 /** 2708 * Get the profile information for a contact. 2709 * 2710 * @deprecated since 3.6 2711 * @param int $currentuserid The current user's id 2712 * @param int $otheruserid The id of the user whose profile we are viewing 2713 * @return stdClass 2714 * @throws moodle_exception 2715 * @since 3.2 2716 */ 2717 public static function data_for_messagearea_get_profile($currentuserid, $otheruserid) { 2718 global $CFG, $PAGE, $USER; 2719 2720 // Check if messaging is enabled. 2721 if (empty($CFG->messaging)) { 2722 throw new moodle_exception('disabled', 'message'); 2723 } 2724 2725 $systemcontext = context_system::instance(); 2726 2727 $params = array( 2728 'currentuserid' => $currentuserid, 2729 'otheruserid' => $otheruserid 2730 ); 2731 $params = self::validate_parameters(self::data_for_messagearea_get_profile_parameters(), $params); 2732 self::validate_context($systemcontext); 2733 2734 if (($USER->id != $params['currentuserid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) { 2735 throw new moodle_exception('You do not have permission to perform this action.'); 2736 } 2737 2738 $profile = \core_message\api::get_profile($params['currentuserid'], $params['otheruserid']); 2739 $profile = new \core_message\output\messagearea\profile($profile); 2740 2741 $renderer = $PAGE->get_renderer('core_message'); 2742 return $profile->export_for_template($renderer); 2743 } 2744 2745 /** 2746 * The get profile return structure. 2747 * 2748 * @deprecated since 3.6 2749 * @return external_single_structure 2750 * @since 3.2 2751 */ 2752 public static function data_for_messagearea_get_profile_returns() { 2753 return new external_single_structure( 2754 array( 2755 'userid' => new external_value(PARAM_INT, 'The id of the user whose profile we are viewing'), 2756 'email' => new external_value(core_user::get_property_type('email'), 'An email address'), 2757 'country' => new external_value(PARAM_TEXT, 'Home country of the user'), 2758 'city' => new external_value(core_user::get_property_type('city'), 'Home city of the user'), 2759 'fullname' => new external_value(PARAM_NOTAGS, 'The user\'s name'), 2760 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL'), 2761 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL'), 2762 'showonlinestatus' => new external_value(PARAM_BOOL, 'Show the user\'s online status?'), 2763 'isonline' => new external_value(PARAM_BOOL, 'The user\'s online status'), 2764 'isblocked' => new external_value(PARAM_BOOL, 'Is the user blocked?'), 2765 'iscontact' => new external_value(PARAM_BOOL, 'Is the user a contact?') 2766 ) 2767 ); 2768 } 2769 2770 /** 2771 * Marking the method as deprecated. 2772 * 2773 * @return bool 2774 */ 2775 public static function data_for_messagearea_get_profile_is_deprecated() { 2776 return true; 2777 } 2778 2779 /** 2780 * Get contacts parameters description. 2781 * 2782 * @deprecated since 3.6 2783 * @return external_function_parameters 2784 * @since Moodle 2.5 2785 */ 2786 public static function get_contacts_parameters() { 2787 return new external_function_parameters(array()); 2788 } 2789 2790 /** 2791 * Get contacts. 2792 * 2793 * @deprecated since 3.6 2794 * @return external_description 2795 * @since Moodle 2.5 2796 */ 2797 public static function get_contacts() { 2798 global $CFG, $PAGE, $USER; 2799 2800 // Check if messaging is enabled. 2801 if (empty($CFG->messaging)) { 2802 throw new moodle_exception('disabled', 'message'); 2803 } 2804 2805 require_once($CFG->dirroot . '/user/lib.php'); 2806 2807 $allcontacts = array('online' => [], 'offline' => [], 'strangers' => []); 2808 $contacts = \core_message\api::get_contacts_with_unread_message_count($USER->id); 2809 foreach ($contacts as $contact) { 2810 // Set the mode. 2811 $mode = 'offline'; 2812 if (\core_message\helper::is_online($contact->lastaccess)) { 2813 $mode = 'online'; 2814 } 2815 2816 $newcontact = array( 2817 'id' => $contact->id, 2818 'fullname' => fullname($contact), 2819 'unread' => $contact->messagecount 2820 ); 2821 2822 $userpicture = new user_picture($contact); 2823 $userpicture->size = 1; // Size f1. 2824 $newcontact['profileimageurl'] = $userpicture->get_url($PAGE)->out(false); 2825 $userpicture->size = 0; // Size f2. 2826 $newcontact['profileimageurlsmall'] = $userpicture->get_url($PAGE)->out(false); 2827 2828 $allcontacts[$mode][$contact->id] = $newcontact; 2829 } 2830 2831 $strangers = \core_message\api::get_non_contacts_with_unread_message_count($USER->id); 2832 foreach ($strangers as $contact) { 2833 $newcontact = array( 2834 'id' => $contact->id, 2835 'fullname' => fullname($contact), 2836 'unread' => $contact->messagecount 2837 ); 2838 2839 $userpicture = new user_picture($contact); 2840 $userpicture->size = 1; // Size f1. 2841 $newcontact['profileimageurl'] = $userpicture->get_url($PAGE)->out(false); 2842 $userpicture->size = 0; // Size f2. 2843 $newcontact['profileimageurlsmall'] = $userpicture->get_url($PAGE)->out(false); 2844 2845 $allcontacts['strangers'][$contact->id] = $newcontact; 2846 } 2847 2848 // Add noreply user and support user to the list, if they don't exist. 2849 $supportuser = core_user::get_support_user(); 2850 if (!isset($strangers[$supportuser->id]) && !$supportuser->deleted) { 2851 $supportuser->messagecount = message_count_unread_messages($USER, $supportuser); 2852 if ($supportuser->messagecount > 0) { 2853 $supportuser->fullname = fullname($supportuser); 2854 $supportuser->unread = $supportuser->messagecount; 2855 $allcontacts['strangers'][$supportuser->id] = $supportuser; 2856 } 2857 } 2858 2859 $noreplyuser = core_user::get_noreply_user(); 2860 if (!isset($strangers[$noreplyuser->id]) && !$noreplyuser->deleted) { 2861 $noreplyuser->messagecount = message_count_unread_messages($USER, $noreplyuser); 2862 if ($noreplyuser->messagecount > 0) { 2863 $noreplyuser->fullname = fullname($noreplyuser); 2864 $noreplyuser->unread = $noreplyuser->messagecount; 2865 $allcontacts['strangers'][$noreplyuser->id] = $noreplyuser; 2866 } 2867 } 2868 2869 return $allcontacts; 2870 } 2871 2872 /** 2873 * Get contacts return description. 2874 * 2875 * @deprecated since 3.6 2876 * @return external_description 2877 * @since Moodle 2.5 2878 */ 2879 public static function get_contacts_returns() { 2880 return new external_single_structure( 2881 array( 2882 'online' => new external_multiple_structure( 2883 new external_single_structure( 2884 array( 2885 'id' => new external_value(PARAM_INT, 'User ID'), 2886 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'), 2887 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL), 2888 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL', VALUE_OPTIONAL), 2889 'unread' => new external_value(PARAM_INT, 'Unread message count') 2890 ) 2891 ), 2892 'List of online contacts' 2893 ), 2894 'offline' => new external_multiple_structure( 2895 new external_single_structure( 2896 array( 2897 'id' => new external_value(PARAM_INT, 'User ID'), 2898 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'), 2899 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL), 2900 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL', VALUE_OPTIONAL), 2901 'unread' => new external_value(PARAM_INT, 'Unread message count') 2902 ) 2903 ), 2904 'List of offline contacts' 2905 ), 2906 'strangers' => new external_multiple_structure( 2907 new external_single_structure( 2908 array( 2909 'id' => new external_value(PARAM_INT, 'User ID'), 2910 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'), 2911 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL), 2912 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL', VALUE_OPTIONAL), 2913 'unread' => new external_value(PARAM_INT, 'Unread message count') 2914 ) 2915 ), 2916 'List of users that are not in the user\'s contact list but have sent a message' 2917 ) 2918 ) 2919 ); 2920 } 2921 2922 /** 2923 * Marking the method as deprecated. 2924 * 2925 * @return bool 2926 */ 2927 public static function get_contacts_is_deprecated() { 2928 return true; 2929 } 2930 2931 /** 2932 * Search contacts parameters description. 2933 * 2934 * @return external_function_parameters 2935 * @since Moodle 2.5 2936 */ 2937 public static function search_contacts_parameters() { 2938 return new external_function_parameters( 2939 array( 2940 'searchtext' => new external_value(PARAM_CLEAN, 'String the user\'s fullname has to match to be found'), 2941 'onlymycourses' => new external_value(PARAM_BOOL, 'Limit search to the user\'s courses', 2942 VALUE_DEFAULT, false) 2943 ) 2944 ); 2945 } 2946 2947 /** 2948 * Search contacts. 2949 * 2950 * @param string $searchtext query string. 2951 * @param bool $onlymycourses limit the search to the user's courses only. 2952 * @return external_description 2953 * @since Moodle 2.5 2954 */ 2955 public static function search_contacts($searchtext, $onlymycourses = false) { 2956 global $CFG, $USER, $PAGE; 2957 require_once($CFG->dirroot . '/user/lib.php'); 2958 2959 // Check if messaging is enabled. 2960 if (empty($CFG->messaging)) { 2961 throw new moodle_exception('disabled', 'message'); 2962 } 2963 2964 require_once($CFG->libdir . '/enrollib.php'); 2965 2966 $params = array('searchtext' => $searchtext, 'onlymycourses' => $onlymycourses); 2967 $params = self::validate_parameters(self::search_contacts_parameters(), $params); 2968 2969 // Extra validation, we do not allow empty queries. 2970 if ($params['searchtext'] === '') { 2971 throw new moodle_exception('querystringcannotbeempty'); 2972 } 2973 2974 $courseids = array(); 2975 if ($params['onlymycourses']) { 2976 $mycourses = enrol_get_my_courses(array('id')); 2977 foreach ($mycourses as $mycourse) { 2978 $courseids[] = $mycourse->id; 2979 } 2980 } else { 2981 $courseids[] = SITEID; 2982 } 2983 2984 // Retrieving the users matching the query. 2985 $users = message_search_users($courseids, $params['searchtext']); 2986 $results = array(); 2987 foreach ($users as $user) { 2988 $results[$user->id] = $user; 2989 } 2990 2991 // Reorganising information. 2992 foreach ($results as &$user) { 2993 $newuser = array( 2994 'id' => $user->id, 2995 'fullname' => fullname($user) 2996 ); 2997 2998 // Avoid undefined property notice as phone not specified. 2999 $user->phone1 = null; 3000 $user->phone2 = null; 3001 3002 $userpicture = new user_picture($user); 3003 $userpicture->size = 1; // Size f1. 3004 $newuser['profileimageurl'] = $userpicture->get_url($PAGE)->out(false); 3005 $userpicture->size = 0; // Size f2. 3006 $newuser['profileimageurlsmall'] = $userpicture->get_url($PAGE)->out(false); 3007 3008 $user = $newuser; 3009 } 3010 3011 return $results; 3012 } 3013 3014 /** 3015 * Search contacts return description. 3016 * 3017 * @return external_description 3018 * @since Moodle 2.5 3019 */ 3020 public static function search_contacts_returns() { 3021 return new external_multiple_structure( 3022 new external_single_structure( 3023 array( 3024 'id' => new external_value(PARAM_INT, 'User ID'), 3025 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'), 3026 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL), 3027 'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL', VALUE_OPTIONAL) 3028 ) 3029 ), 3030 'List of contacts' 3031 ); 3032 } 3033 3034 /** 3035 * Get messages parameters description. 3036 * 3037 * @return external_function_parameters 3038 * @since 2.8 3039 */ 3040 public static function get_messages_parameters() { 3041 return new external_function_parameters( 3042 array( 3043 'useridto' => new external_value(PARAM_INT, 'the user id who received the message, 0 for any user', VALUE_REQUIRED), 3044 'useridfrom' => new external_value( 3045 PARAM_INT, 'the user id who send the message, 0 for any user. -10 or -20 for no-reply or support user', 3046 VALUE_DEFAULT, 0), 3047 'type' => new external_value( 3048 PARAM_ALPHA, 'type of message to return, expected values are: notifications, conversations and both', 3049 VALUE_DEFAULT, 'both'), 3050 'read' => new external_value(PARAM_BOOL, 'true for getting read messages, false for unread', VALUE_DEFAULT, true), 3051 'newestfirst' => new external_value( 3052 PARAM_BOOL, 'true for ordering by newest first, false for oldest first', 3053 VALUE_DEFAULT, true), 3054 'limitfrom' => new external_value(PARAM_INT, 'limit from', VALUE_DEFAULT, 0), 3055 'limitnum' => new external_value(PARAM_INT, 'limit number', VALUE_DEFAULT, 0) 3056 ) 3057 ); 3058 } 3059 3060 /** 3061 * Get messages function implementation. 3062 * 3063 * @since 2.8 3064 * @throws invalid_parameter_exception 3065 * @throws moodle_exception 3066 * @param int $useridto the user id who received the message 3067 * @param int $useridfrom the user id who send the message. -10 or -20 for no-reply or support user 3068 * @param string $type type of message to return, expected values: notifications, conversations and both 3069 * @param bool $read true for retreiving read messages, false for unread 3070 * @param bool $newestfirst true for ordering by newest first, false for oldest first 3071 * @param int $limitfrom limit from 3072 * @param int $limitnum limit num 3073 * @return external_description 3074 */ 3075 public static function get_messages($useridto, $useridfrom = 0, $type = 'both', $read = true, 3076 $newestfirst = true, $limitfrom = 0, $limitnum = 0) { 3077 global $CFG, $USER; 3078 3079 $warnings = array(); 3080 3081 $params = array( 3082 'useridto' => $useridto, 3083 'useridfrom' => $useridfrom, 3084 'type' => $type, 3085 'read' => $read, 3086 'newestfirst' => $newestfirst, 3087 'limitfrom' => $limitfrom, 3088 'limitnum' => $limitnum 3089 ); 3090 3091 $params = self::validate_parameters(self::get_messages_parameters(), $params); 3092 3093 $context = context_system::instance(); 3094 self::validate_context($context); 3095 3096 $useridto = $params['useridto']; 3097 $useridfrom = $params['useridfrom']; 3098 $type = $params['type']; 3099 $read = $params['read']; 3100 $newestfirst = $params['newestfirst']; 3101 $limitfrom = $params['limitfrom']; 3102 $limitnum = $params['limitnum']; 3103 3104 $allowedvalues = array('notifications', 'conversations', 'both'); 3105 if (!in_array($type, $allowedvalues)) { 3106 throw new invalid_parameter_exception('Invalid value for type parameter (value: ' . $type . '),' . 3107 'allowed values are: ' . implode(',', $allowedvalues)); 3108 } 3109 3110 // Check if private messaging between users is allowed. 3111 if (empty($CFG->messaging)) { 3112 // If we are retreiving only conversations, and messaging is disabled, throw an exception. 3113 if ($type == "conversations") { 3114 throw new moodle_exception('disabled', 'message'); 3115 } 3116 if ($type == "both") { 3117 $warning = array(); 3118 $warning['item'] = 'message'; 3119 $warning['itemid'] = $USER->id; 3120 $warning['warningcode'] = '1'; 3121 $warning['message'] = 'Private messages (conversations) are not enabled in this site. 3122 Only notifications will be returned'; 3123 $warnings[] = $warning; 3124 } 3125 } 3126 3127 if (!empty($useridto)) { 3128 if (core_user::is_real_user($useridto)) { 3129 $userto = core_user::get_user($useridto, '*', MUST_EXIST); 3130 } else { 3131 throw new moodle_exception('invaliduser'); 3132 } 3133 } 3134 3135 if (!empty($useridfrom)) { 3136 // We use get_user here because the from user can be the noreply or support user. 3137 $userfrom = core_user::get_user($useridfrom, '*', MUST_EXIST); 3138 } 3139 3140 // Check if the current user is the sender/receiver or just a privileged user. 3141 if ($useridto != $USER->id and $useridfrom != $USER->id and 3142 !has_capability('moodle/site:readallmessages', $context)) { 3143 throw new moodle_exception('accessdenied', 'admin'); 3144 } 3145 3146 // Which type of messages to retrieve. 3147 $notifications = -1; 3148 if ($type != 'both') { 3149 $notifications = ($type == 'notifications') ? 1 : 0; 3150 } 3151 3152 $orderdirection = $newestfirst ? 'DESC' : 'ASC'; 3153 $sort = "mr.timecreated $orderdirection"; 3154 3155 if ($messages = message_get_messages($useridto, $useridfrom, $notifications, $read, $sort, $limitfrom, $limitnum)) { 3156 $canviewfullname = has_capability('moodle/site:viewfullnames', $context); 3157 3158 // In some cases, we don't need to get the to/from user objects from the sql query. 3159 $userfromfullname = ''; 3160 $usertofullname = ''; 3161 3162 // In this case, the useridto field is not empty, so we can get the user destinatary fullname from there. 3163 if (!empty($useridto)) { 3164 $usertofullname = fullname($userto, $canviewfullname); 3165 // The user from may or may not be filled. 3166 if (!empty($useridfrom)) { 3167 $userfromfullname = fullname($userfrom, $canviewfullname); 3168 } 3169 } else { 3170 // If the useridto field is empty, the useridfrom must be filled. 3171 $userfromfullname = fullname($userfrom, $canviewfullname); 3172 } 3173 foreach ($messages as $mid => $message) { 3174 3175 // Do not return deleted messages. 3176 if (!$message->notification) { 3177 if (($useridto == $USER->id and $message->timeusertodeleted) or 3178 ($useridfrom == $USER->id and $message->timeuserfromdeleted)) { 3179 unset($messages[$mid]); 3180 continue; 3181 } 3182 } 3183 3184 // We need to get the user from the query. 3185 if (empty($userfromfullname)) { 3186 // Check for non-reply and support users. 3187 if (core_user::is_real_user($message->useridfrom)) { 3188 $user = new stdClass(); 3189 $user = username_load_fields_from_object($user, $message, 'userfrom'); 3190 $message->userfromfullname = fullname($user, $canviewfullname); 3191 } else { 3192 $user = core_user::get_user($message->useridfrom); 3193 $message->userfromfullname = fullname($user, $canviewfullname); 3194 } 3195 } else { 3196 $message->userfromfullname = $userfromfullname; 3197 } 3198 3199 // We need to get the user from the query. 3200 if (empty($usertofullname)) { 3201 $user = new stdClass(); 3202 $user = username_load_fields_from_object($user, $message, 'userto'); 3203 $message->usertofullname = fullname($user, $canviewfullname); 3204 } else { 3205 $message->usertofullname = $usertofullname; 3206 } 3207 3208 $message->text = message_format_message_text($message); 3209 $messages[$mid] = (array) $message; 3210 } 3211 } 3212 3213 $results = array( 3214 'messages' => $messages, 3215 'warnings' => $warnings 3216 ); 3217 3218 return $results; 3219 } 3220 3221 /** 3222 * Get messages return description. 3223 * 3224 * @return external_single_structure 3225 * @since 2.8 3226 */ 3227 public static function get_messages_returns() { 3228 return new external_single_structure( 3229 array( 3230 'messages' => new external_multiple_structure( 3231 new external_single_structure( 3232 array( 3233 'id' => new external_value(PARAM_INT, 'Message id'), 3234 'useridfrom' => new external_value(PARAM_INT, 'User from id'), 3235 'useridto' => new external_value(PARAM_INT, 'User to id'), 3236 'subject' => new external_value(PARAM_TEXT, 'The message subject'), 3237 'text' => new external_value(PARAM_RAW, 'The message text formated'), 3238 'fullmessage' => new external_value(PARAM_RAW, 'The message'), 3239 'fullmessageformat' => new external_format_value('fullmessage'), 3240 'fullmessagehtml' => new external_value(PARAM_RAW, 'The message in html'), 3241 'smallmessage' => new external_value(PARAM_RAW, 'The shorten message'), 3242 'notification' => new external_value(PARAM_INT, 'Is a notification?'), 3243 'contexturl' => new external_value(PARAM_RAW, 'Context URL'), 3244 'contexturlname' => new external_value(PARAM_TEXT, 'Context URL link name'), 3245 'timecreated' => new external_value(PARAM_INT, 'Time created'), 3246 'timeread' => new external_value(PARAM_INT, 'Time read'), 3247 'usertofullname' => new external_value(PARAM_TEXT, 'User to full name'), 3248 'userfromfullname' => new external_value(PARAM_TEXT, 'User from full name'), 3249 'component' => new external_value(PARAM_TEXT, 'The component that generated the notification', 3250 VALUE_OPTIONAL), 3251 'eventtype' => new external_value(PARAM_TEXT, 'The type of notification', VALUE_OPTIONAL), 3252 'customdata' => new external_value(PARAM_RAW, 'Custom data to be passed to the message processor. 3253 The data here is serialised using json_encode().', VALUE_OPTIONAL), 3254 ), 'message' 3255 ) 3256 ), 3257 'warnings' => new external_warnings() 3258 ) 3259 ); 3260 } 3261 3262 /** 3263 * Mark all notifications as read parameters description. 3264 * 3265 * @return external_function_parameters 3266 * @since 3.2 3267 */ 3268 public static function mark_all_notifications_as_read_parameters() { 3269 return new external_function_parameters( 3270 array( 3271 'useridto' => new external_value(PARAM_INT, 'the user id who received the message, 0 for any user', VALUE_REQUIRED), 3272 'useridfrom' => new external_value( 3273 PARAM_INT, 'the user id who send the message, 0 for any user. -10 or -20 for no-reply or support user', 3274 VALUE_DEFAULT, 0), 3275 'timecreatedto' => new external_value( 3276 PARAM_INT, 'mark messages created before this time as read, 0 for all messages', 3277 VALUE_DEFAULT, 0), 3278 ) 3279 ); 3280 } 3281 3282 /** 3283 * Mark all notifications as read function. 3284 * 3285 * @since 3.2 3286 * @throws invalid_parameter_exception 3287 * @throws moodle_exception 3288 * @param int $useridto the user id who received the message 3289 * @param int $useridfrom the user id who send the message. -10 or -20 for no-reply or support user 3290 * @param int $timecreatedto mark message created before this time as read, 0 for all messages 3291 * @return external_description 3292 */ 3293 public static function mark_all_notifications_as_read($useridto, $useridfrom, $timecreatedto = 0) { 3294 global $USER; 3295 3296 $params = self::validate_parameters( 3297 self::mark_all_notifications_as_read_parameters(), 3298 array( 3299 'useridto' => $useridto, 3300 'useridfrom' => $useridfrom, 3301 'timecreatedto' => $timecreatedto, 3302 ) 3303 ); 3304 3305 $context = context_system::instance(); 3306 self::validate_context($context); 3307 3308 $useridto = $params['useridto']; 3309 $useridfrom = $params['useridfrom']; 3310 $timecreatedto = $params['timecreatedto']; 3311 3312 if (!empty($useridto)) { 3313 if (core_user::is_real_user($useridto)) { 3314 $userto = core_user::get_user($useridto, '*', MUST_EXIST); 3315 } else { 3316 throw new moodle_exception('invaliduser'); 3317 } 3318 } 3319 3320 if (!empty($useridfrom)) { 3321 // We use get_user here because the from user can be the noreply or support user. 3322 $userfrom = core_user::get_user($useridfrom, '*', MUST_EXIST); 3323 } 3324 3325 // Check if the current user is the sender/receiver or just a privileged user. 3326 if ($useridto != $USER->id and $useridfrom != $USER->id and 3327 // The deleteanymessage cap seems more reasonable here than readallmessages. 3328 !has_capability('moodle/site:deleteanymessage', $context)) { 3329 throw new moodle_exception('accessdenied', 'admin'); 3330 } 3331 3332 \core_message\api::mark_all_notifications_as_read($useridto, $useridfrom, $timecreatedto); 3333 3334 return true; 3335 } 3336 3337 /** 3338 * Mark all notifications as read return description. 3339 * 3340 * @return external_single_structure 3341 * @since 3.2 3342 */ 3343 public static function mark_all_notifications_as_read_returns() { 3344 return new external_value(PARAM_BOOL, 'True if the messages were marked read, false otherwise'); 3345 } 3346 3347 /** 3348 * Get unread conversations count parameters description. 3349 * 3350 * @return external_function_parameters 3351 * @since 3.2 3352 */ 3353 public static function get_unread_conversations_count_parameters() { 3354 return new external_function_parameters( 3355 array( 3356 'useridto' => new external_value(PARAM_INT, 'the user id who received the message, 0 for any user', VALUE_REQUIRED), 3357 ) 3358 ); 3359 } 3360 3361 /** 3362 * Get unread messages count function. 3363 * 3364 * @since 3.2 3365 * @throws invalid_parameter_exception 3366 * @throws moodle_exception 3367 * @param int $useridto the user id who received the message 3368 * @return external_description 3369 */ 3370 public static function get_unread_conversations_count($useridto) { 3371 global $USER, $CFG; 3372 3373 // Check if messaging is enabled. 3374 if (empty($CFG->messaging)) { 3375 throw new moodle_exception('disabled', 'message'); 3376 } 3377 3378 $params = self::validate_parameters( 3379 self::get_unread_conversations_count_parameters(), 3380 array('useridto' => $useridto) 3381 ); 3382 3383 $context = context_system::instance(); 3384 self::validate_context($context); 3385 3386 $useridto = $params['useridto']; 3387 3388 if (!empty($useridto)) { 3389 if (core_user::is_real_user($useridto)) { 3390 $userto = core_user::get_user($useridto, '*', MUST_EXIST); 3391 } else { 3392 throw new moodle_exception('invaliduser'); 3393 } 3394 } else { 3395 $useridto = $USER->id; 3396 } 3397 3398 // Check if the current user is the receiver or just a privileged user. 3399 if ($useridto != $USER->id and !has_capability('moodle/site:readallmessages', $context)) { 3400 throw new moodle_exception('accessdenied', 'admin'); 3401 } 3402 3403 return \core_message\api::count_unread_conversations($userto); 3404 } 3405 3406 /** 3407 * Get unread conversations count return description. 3408 * 3409 * @return external_single_structure 3410 * @since 3.2 3411 */ 3412 public static function get_unread_conversations_count_returns() { 3413 return new external_value(PARAM_INT, 'The count of unread messages for the user'); 3414 } 3415 3416 /** 3417 * Get blocked users parameters description. 3418 * 3419 * @return external_function_parameters 3420 * @since 2.9 3421 */ 3422 public static function get_blocked_users_parameters() { 3423 return new external_function_parameters( 3424 array( 3425 'userid' => new external_value(PARAM_INT, 3426 'the user whose blocked users we want to retrieve', 3427 VALUE_REQUIRED), 3428 ) 3429 ); 3430 } 3431 3432 /** 3433 * Retrieve a list of users blocked 3434 * 3435 * @param int $userid the user whose blocked users we want to retrieve 3436 * @return external_description 3437 * @since 2.9 3438 */ 3439 public static function get_blocked_users($userid) { 3440 global $CFG, $USER, $PAGE; 3441 3442 // Warnings array, it can be empty at the end but is mandatory. 3443 $warnings = array(); 3444 3445 // Validate params. 3446 $params = array( 3447 'userid' => $userid 3448 ); 3449 $params = self::validate_parameters(self::get_blocked_users_parameters(), $params); 3450 $userid = $params['userid']; 3451 3452 // Validate context. 3453 $context = context_system::instance(); 3454 self::validate_context($context); 3455 3456 // Check if private messaging between users is allowed. 3457 if (empty($CFG->messaging)) { 3458 throw new moodle_exception('disabled', 'message'); 3459 } 3460 3461 $user = core_user::get_user($userid, '*', MUST_EXIST); 3462 core_user::require_active_user($user); 3463 3464 // Check if we have permissions for retrieve the information. 3465 $capability = 'moodle/site:manageallmessaging'; 3466 if (($USER->id != $userid) && !has_capability($capability, $context)) { 3467 throw new required_capability_exception($context, $capability, 'nopermissions', ''); 3468 } 3469 3470 // Now, we can get safely all the blocked users. 3471 $users = \core_message\api::get_blocked_users($user->id); 3472 3473 $blockedusers = array(); 3474 foreach ($users as $user) { 3475 $newuser = array( 3476 'id' => $user->id, 3477 'fullname' => fullname($user), 3478 ); 3479 3480 $userpicture = new user_picture($user); 3481 $userpicture->size = 1; // Size f1. 3482 $newuser['profileimageurl'] = $userpicture->get_url($PAGE)->out(false); 3483 3484 $blockedusers[] = $newuser; 3485 } 3486 3487 $results = array( 3488 'users' => $blockedusers, 3489 'warnings' => $warnings 3490 ); 3491 return $results; 3492 } 3493 3494 /** 3495 * Get blocked users return description. 3496 * 3497 * @return external_single_structure 3498 * @since 2.9 3499 */ 3500 public static function get_blocked_users_returns() { 3501 return new external_single_structure( 3502 array( 3503 'users' => new external_multiple_structure( 3504 new external_single_structure( 3505 array( 3506 'id' => new external_value(PARAM_INT, 'User ID'), 3507 'fullname' => new external_value(PARAM_NOTAGS, 'User full name'), 3508 'profileimageurl' => new external_value(PARAM_URL, 'User picture URL', VALUE_OPTIONAL) 3509 ) 3510 ), 3511 'List of blocked users' 3512 ), 3513 'warnings' => new external_warnings() 3514 ) 3515 ); 3516 } 3517 3518 /** 3519 * Returns description of method parameters 3520 * 3521 * @return external_function_parameters 3522 * @since 2.9 3523 */ 3524 public static function mark_message_read_parameters() { 3525 return new external_function_parameters( 3526 array( 3527 'messageid' => new external_value(PARAM_INT, 'id of the message in the messages table'), 3528 'timeread' => new external_value(PARAM_INT, 'timestamp for when the message should be marked read', 3529 VALUE_DEFAULT, 0) 3530 ) 3531 ); 3532 } 3533 3534 /** 3535 * Mark a single message as read, trigger message_viewed event 3536 * 3537 * @param int $messageid id of the message (in the message table) 3538 * @param int $timeread timestamp for when the message should be marked read 3539 * @return external_description 3540 * @throws invalid_parameter_exception 3541 * @throws moodle_exception 3542 * @since 2.9 3543 */ 3544 public static function mark_message_read($messageid, $timeread) { 3545 global $CFG, $DB, $USER; 3546 3547 // Check if private messaging between users is allowed. 3548 if (empty($CFG->messaging)) { 3549 throw new moodle_exception('disabled', 'message'); 3550 } 3551 3552 // Warnings array, it can be empty at the end but is mandatory. 3553 $warnings = array(); 3554 3555 // Validate params. 3556 $params = array( 3557 'messageid' => $messageid, 3558 'timeread' => $timeread 3559 ); 3560 $params = self::validate_parameters(self::mark_message_read_parameters(), $params); 3561 3562 if (empty($params['timeread'])) { 3563 $timeread = time(); 3564 } else { 3565 $timeread = $params['timeread']; 3566 } 3567 3568 // Validate context. 3569 $context = context_system::instance(); 3570 self::validate_context($context); 3571 3572 $sql = "SELECT m.*, mcm.userid as useridto 3573 FROM {messages} m 3574 INNER JOIN {message_conversations} mc 3575 ON m.conversationid = mc.id 3576 INNER JOIN {message_conversation_members} mcm 3577 ON mcm.conversationid = mc.id 3578 LEFT JOIN {message_user_actions} mua 3579 ON (mua.messageid = m.id AND mua.userid = ? AND mua.action = ?) 3580 WHERE mua.id is NULL 3581 AND mcm.userid != m.useridfrom 3582 AND m.id = ?"; 3583 $messageparams = []; 3584 $messageparams[] = $USER->id; 3585 $messageparams[] = \core_message\api::MESSAGE_ACTION_READ; 3586 $messageparams[] = $params['messageid']; 3587 $message = $DB->get_record_sql($sql, $messageparams, MUST_EXIST); 3588 3589 if ($message->useridto != $USER->id) { 3590 throw new invalid_parameter_exception('Invalid messageid, you don\'t have permissions to mark this message as read'); 3591 } 3592 3593 \core_message\api::mark_message_as_read($USER->id, $message, $timeread); 3594 3595 $results = array( 3596 'messageid' => $message->id, 3597 'warnings' => $warnings 3598 ); 3599 return $results; 3600 } 3601 3602 /** 3603 * Returns description of method result value 3604 * 3605 * @return external_description 3606 * @since 2.9 3607 */ 3608 public static function mark_message_read_returns() { 3609 return new external_single_structure( 3610 array( 3611 'messageid' => new external_value(PARAM_INT, 'the id of the message in the messages table'), 3612 'warnings' => new external_warnings() 3613 ) 3614 ); 3615 } 3616 3617 /** 3618 * Returns description of method parameters 3619 * 3620 * @return external_function_parameters 3621 */ 3622 public static function mark_notification_read_parameters() { 3623 return new external_function_parameters( 3624 array( 3625 'notificationid' => new external_value(PARAM_INT, 'id of the notification'), 3626 'timeread' => new external_value(PARAM_INT, 'timestamp for when the notification should be marked read', 3627 VALUE_DEFAULT, 0) 3628 ) 3629 ); 3630 } 3631 3632 /** 3633 * Mark a single notification as read. 3634 * 3635 * This will trigger a 'notification_viewed' event. 3636 * 3637 * @param int $notificationid id of the notification 3638 * @param int $timeread timestamp for when the notification should be marked read 3639 * @return external_description 3640 * @throws invalid_parameter_exception 3641 * @throws moodle_exception 3642 */ 3643 public static function mark_notification_read($notificationid, $timeread) { 3644 global $CFG, $DB, $USER; 3645 3646 // Warnings array, it can be empty at the end but is mandatory. 3647 $warnings = array(); 3648 3649 // Validate params. 3650 $params = array( 3651 'notificationid' => $notificationid, 3652 'timeread' => $timeread 3653 ); 3654 $params = self::validate_parameters(self::mark_notification_read_parameters(), $params); 3655 3656 if (empty($params['timeread'])) { 3657 $timeread = time(); 3658 } else { 3659 $timeread = $params['timeread']; 3660 } 3661 3662 // Validate context. 3663 $context = context_system::instance(); 3664 self::validate_context($context); 3665 3666 $notification = $DB->get_record('notifications', ['id' => $params['notificationid']], '*', MUST_EXIST); 3667 3668 if ($notification->useridto != $USER->id) { 3669 throw new invalid_parameter_exception('Invalid notificationid, you don\'t have permissions to mark this ' . 3670 'notification as read'); 3671 } 3672 3673 \core_message\api::mark_notification_as_read($notification, $timeread); 3674 3675 $results = array( 3676 'notificationid' => $notification->id, 3677 'warnings' => $warnings 3678 ); 3679 3680 return $results; 3681 } 3682 3683 /** 3684 * Returns description of method result value 3685 * 3686 * @return external_description 3687 */ 3688 public static function mark_notification_read_returns() { 3689 return new external_single_structure( 3690 array( 3691 'notificationid' => new external_value(PARAM_INT, 'id of the notification'), 3692 'warnings' => new external_warnings() 3693 ) 3694 ); 3695 } 3696 3697 /** 3698 * Mark all messages as read parameters description. 3699 * 3700 * @deprecated since 3.6 3701 * @return external_function_parameters 3702 * @since 3.2 3703 */ 3704 public static function mark_all_messages_as_read_parameters() { 3705 return new external_function_parameters( 3706 array( 3707 'useridto' => new external_value(PARAM_INT, 'the user id who received the message, 0 for any user', VALUE_REQUIRED), 3708 'useridfrom' => new external_value( 3709 PARAM_INT, 'the user id who send the message, 0 for any user. -10 or -20 for no-reply or support user', 3710 VALUE_DEFAULT, 0), 3711 ) 3712 ); 3713 } 3714 3715 /** 3716 * Mark all messages as read function. 3717 * 3718 * @deprecated since 3.6 3719 * @throws invalid_parameter_exception 3720 * @throws moodle_exception 3721 * @param int $useridto the user id who received the message 3722 * @param int $useridfrom the user id who send the message. -10 or -20 for no-reply or support user 3723 * @return external_description 3724 * @since 3.2 3725 */ 3726 public static function mark_all_messages_as_read($useridto, $useridfrom) { 3727 global $USER, $CFG; 3728 3729 // Check if messaging is enabled. 3730 if (empty($CFG->messaging)) { 3731 throw new moodle_exception('disabled', 'message'); 3732 } 3733 3734 $params = self::validate_parameters( 3735 self::mark_all_messages_as_read_parameters(), 3736 array( 3737 'useridto' => $useridto, 3738 'useridfrom' => $useridfrom, 3739 ) 3740 ); 3741 3742 $context = context_system::instance(); 3743 self::validate_context($context); 3744 3745 $useridto = $params['useridto']; 3746 $useridfrom = $params['useridfrom']; 3747 3748 if (!empty($useridto)) { 3749 if (core_user::is_real_user($useridto)) { 3750 $userto = core_user::get_user($useridto, '*', MUST_EXIST); 3751 } else { 3752 throw new moodle_exception('invaliduser'); 3753 } 3754 } 3755 3756 if (!empty($useridfrom)) { 3757 // We use get_user here because the from user can be the noreply or support user. 3758 $userfrom = core_user::get_user($useridfrom, '*', MUST_EXIST); 3759 } 3760 3761 // Check if the current user is the sender/receiver or just a privileged user. 3762 if ($useridto != $USER->id and $useridfrom != $USER->id and 3763 // The deleteanymessage cap seems more reasonable here than readallmessages. 3764 !has_capability('moodle/site:deleteanymessage', $context)) { 3765 throw new moodle_exception('accessdenied', 'admin'); 3766 } 3767 3768 if ($useridfrom) { 3769 if ($conversationid = \core_message\api::get_conversation_between_users([$useridto, $useridfrom])) { 3770 \core_message\api::mark_all_messages_as_read($useridto, $conversationid); 3771 } 3772 } else { 3773 \core_message\api::mark_all_messages_as_read($useridto); 3774 } 3775 3776 return true; 3777 } 3778 3779 /** 3780 * Mark all messages as read return description. 3781 * 3782 * @deprecated since 3.6 3783 * @return external_single_structure 3784 * @since 3.2 3785 */ 3786 public static function mark_all_messages_as_read_returns() { 3787 return new external_value(PARAM_BOOL, 'True if the messages were marked read, false otherwise'); 3788 } 3789 3790 /** 3791 * Marking the method as deprecated. 3792 * 3793 * @return bool 3794 */ 3795 public static function mark_all_messages_as_read_is_deprecated() { 3796 return true; 3797 } 3798 3799 /** 3800 * Mark all conversation messages as read parameters description. 3801 * 3802 * @return external_function_parameters 3803 * @since 3.6 3804 */ 3805 public static function mark_all_conversation_messages_as_read_parameters() { 3806 return new external_function_parameters( 3807 array( 3808 'userid' => new external_value(PARAM_INT, 'The user id who who we are marking the messages as read for'), 3809 'conversationid' => 3810 new external_value(PARAM_INT, 'The conversation id who who we are marking the messages as read for') 3811 ) 3812 ); 3813 } 3814 3815 /** 3816 * Mark all conversation messages as read function. 3817 * 3818 * @param int $userid The user id of who we want to delete the conversation for 3819 * @param int $conversationid The id of the conversations 3820 * @since 3.6 3821 */ 3822 public static function mark_all_conversation_messages_as_read(int $userid, int $conversationid) { 3823 global $CFG; 3824 3825 // Check if messaging is enabled. 3826 if (empty($CFG->messaging)) { 3827 throw new moodle_exception('disabled', 'message'); 3828 } 3829 3830 $params = array( 3831 'userid' => $userid, 3832 'conversationid' => $conversationid, 3833 ); 3834 $params = self::validate_parameters(self::mark_all_conversation_messages_as_read_parameters(), $params); 3835 3836 $context = context_system::instance(); 3837 self::validate_context($context); 3838 3839 $user = core_user::get_user($params['userid'], '*', MUST_EXIST); 3840 core_user::require_active_user($user); 3841 3842 if (\core_message\api::can_mark_all_messages_as_read($params['userid'], $params['conversationid'])) { 3843 \core_message\api::mark_all_messages_as_read($params['userid'], $params['conversationid']); 3844 } else { 3845 throw new moodle_exception('accessdenied', 'admin'); 3846 } 3847 } 3848 3849 /** 3850 * Mark all conversation messages as read return description. 3851 * 3852 * @return external_warnings 3853 * @since 3.6 3854 */ 3855 public static function mark_all_conversation_messages_as_read_returns() { 3856 return null; 3857 } 3858 3859 /** 3860 * Returns description of method parameters. 3861 * 3862 * @deprecated since 3.6 3863 * @return external_function_parameters 3864 * @since 3.2 3865 */ 3866 public static function delete_conversation_parameters() { 3867 return new external_function_parameters( 3868 array( 3869 'userid' => new external_value(PARAM_INT, 'The user id of who we want to delete the conversation for'), 3870 'otheruserid' => new external_value(PARAM_INT, 'The user id of the other user in the conversation'), 3871 ) 3872 ); 3873 } 3874 3875 /** 3876 * Deletes a conversation. 3877 * 3878 * @deprecated since 3.6 3879 * @param int $userid The user id of who we want to delete the conversation for 3880 * @param int $otheruserid The user id of the other user in the conversation 3881 * @return array 3882 * @throws moodle_exception 3883 * @since 3.2 3884 */ 3885 public static function delete_conversation($userid, $otheruserid) { 3886 global $CFG; 3887 3888 // Check if private messaging between users is allowed. 3889 if (empty($CFG->messaging)) { 3890 throw new moodle_exception('disabled', 'message'); 3891 } 3892 3893 // Warnings array, it can be empty at the end but is mandatory. 3894 $warnings = array(); 3895 3896 // Validate params. 3897 $params = array( 3898 'userid' => $userid, 3899 'otheruserid' => $otheruserid, 3900 ); 3901 $params = self::validate_parameters(self::delete_conversation_parameters(), $params); 3902 3903 // Validate context. 3904 $context = context_system::instance(); 3905 self::validate_context($context); 3906 3907 $user = core_user::get_user($params['userid'], '*', MUST_EXIST); 3908 core_user::require_active_user($user); 3909 3910 if (!$conversationid = \core_message\api::get_conversation_between_users([$params['userid'], $params['otheruserid']])) { 3911 return []; 3912 } 3913 3914 if (\core_message\api::can_delete_conversation($user->id, $conversationid)) { 3915 \core_message\api::delete_conversation_by_id($user->id, $conversationid); 3916 $status = true; 3917 } else { 3918 throw new moodle_exception('You do not have permission to delete messages'); 3919 } 3920 3921 $results = array( 3922 'status' => $status, 3923 'warnings' => $warnings 3924 ); 3925 3926 return $results; 3927 } 3928 3929 /** 3930 * Returns description of method result value. 3931 * 3932 * @deprecated since 3.6 3933 * @return external_description 3934 * @since 3.2 3935 */ 3936 public static function delete_conversation_returns() { 3937 return new external_single_structure( 3938 array( 3939 'status' => new external_value(PARAM_BOOL, 'True if the conversation was deleted, false otherwise'), 3940 'warnings' => new external_warnings() 3941 ) 3942 ); 3943 } 3944 3945 /** 3946 * Marking the method as deprecated. 3947 * 3948 * @return bool 3949 */ 3950 public static function delete_conversation_is_deprecated() { 3951 return true; 3952 } 3953 3954 /** 3955 * Returns description of method parameters. 3956 * 3957 * @return external_function_parameters 3958 * @since 3.6 3959 */ 3960 public static function delete_conversations_by_id_parameters() { 3961 return new external_function_parameters( 3962 array( 3963 'userid' => new external_value(PARAM_INT, 'The user id of who we want to delete the conversation for'), 3964 'conversationids' => new external_multiple_structure( 3965 new external_value(PARAM_INT, 'The id of the conversation'), 3966 'List of conversation IDs' 3967 ), 3968 ) 3969 ); 3970 } 3971 3972 /** 3973 * Deletes a conversation. 3974 * 3975 * @param int $userid The user id of who we want to delete the conversation for 3976 * @param int[] $conversationids The ids of the conversations 3977 * @return array 3978 * @throws moodle_exception 3979 * @since 3.6 3980 */ 3981 public static function delete_conversations_by_id($userid, array $conversationids) { 3982 global $CFG; 3983 3984 // Check if private messaging between users is allowed. 3985 if (empty($CFG->messaging)) { 3986 throw new moodle_exception('disabled', 'message'); 3987 } 3988 3989 // Validate params. 3990 $params = [ 3991 'userid' => $userid, 3992 'conversationids' => $conversationids, 3993 ]; 3994 $params = self::validate_parameters(self::delete_conversations_by_id_parameters(), $params); 3995 3996 // Validate context. 3997 $context = context_system::instance(); 3998 self::validate_context($context); 3999 4000 $user = core_user::get_user($params['userid'], '*', MUST_EXIST); 4001 core_user::require_active_user($user); 4002 4003 foreach ($params['conversationids'] as $conversationid) { 4004 if (\core_message\api::can_delete_conversation($user->id, $conversationid)) { 4005 \core_message\api::delete_conversation_by_id($user->id, $conversationid); 4006 } else { 4007 throw new moodle_exception("You do not have permission to delete the conversation '$conversationid'"); 4008 } 4009 } 4010 4011 return []; 4012 } 4013 4014 /** 4015 * Returns description of method result value. 4016 * 4017 * @return external_description 4018 * @since 3.6 4019 */ 4020 public static function delete_conversations_by_id_returns() { 4021 return new external_warnings(); 4022 } 4023 4024 /** 4025 * Returns description of method parameters 4026 * 4027 * @return external_function_parameters 4028 * @since 3.1 4029 */ 4030 public static function delete_message_parameters() { 4031 return new external_function_parameters( 4032 array( 4033 'messageid' => new external_value(PARAM_INT, 'The message id'), 4034 'userid' => new external_value(PARAM_INT, 'The user id of who we want to delete the message for'), 4035 'read' => new external_value(PARAM_BOOL, 'If is a message read', VALUE_DEFAULT, true) 4036 ) 4037 ); 4038 } 4039 4040 /** 4041 * Deletes a message 4042 * 4043 * @param int $messageid the message id 4044 * @param int $userid the user id of who we want to delete the message for 4045 * @param bool $read if is a message read (default to true) 4046 * @return external_description 4047 * @throws moodle_exception 4048 * @since 3.1 4049 */ 4050 public static function delete_message($messageid, $userid, $read = true) { 4051 global $CFG; 4052 4053 // Check if private messaging between users is allowed. 4054 if (empty($CFG->messaging)) { 4055 throw new moodle_exception('disabled', 'message'); 4056 } 4057 4058 // Warnings array, it can be empty at the end but is mandatory. 4059 $warnings = array(); 4060 4061 // Validate params. 4062 $params = array( 4063 'messageid' => $messageid, 4064 'userid' => $userid, 4065 'read' => $read 4066 ); 4067 $params = self::validate_parameters(self::delete_message_parameters(), $params); 4068 4069 // Validate context. 4070 $context = context_system::instance(); 4071 self::validate_context($context); 4072 4073 $user = core_user::get_user($params['userid'], '*', MUST_EXIST); 4074 core_user::require_active_user($user); 4075 4076 if (\core_message\api::can_delete_message($user->id, $params['messageid'])) { 4077 $status = \core_message\api::delete_message($user->id, $params['messageid']); 4078 } else { 4079 throw new moodle_exception('You do not have permission to delete this message'); 4080 } 4081 4082 $results = array( 4083 'status' => $status, 4084 'warnings' => $warnings 4085 ); 4086 return $results; 4087 } 4088 4089 /** 4090 * Returns description of method result value 4091 * 4092 * @return external_description 4093 * @since 3.1 4094 */ 4095 public static function delete_message_returns() { 4096 return new external_single_structure( 4097 array( 4098 'status' => new external_value(PARAM_BOOL, 'True if the message was deleted, false otherwise'), 4099 'warnings' => new external_warnings() 4100 ) 4101 ); 4102 } 4103 4104 /** 4105 * Returns description of method parameters 4106 * 4107 * @return external_function_parameters 4108 * @since 3.2 4109 */ 4110 public static function message_processor_config_form_parameters() { 4111 return new external_function_parameters( 4112 array( 4113 'userid' => new external_value(PARAM_INT, 'id of the user, 0 for current user', VALUE_REQUIRED), 4114 'name' => new external_value(PARAM_SAFEDIR, 'The name of the message processor'), 4115 'formvalues' => new external_multiple_structure( 4116 new external_single_structure( 4117 array( 4118 'name' => new external_value(PARAM_TEXT, 'name of the form element', VALUE_REQUIRED), 4119 'value' => new external_value(PARAM_RAW, 'value of the form element', VALUE_REQUIRED), 4120 ) 4121 ), 4122 'Config form values', 4123 VALUE_REQUIRED 4124 ), 4125 ) 4126 ); 4127 } 4128 4129 /** 4130 * Processes a message processor config form. 4131 * 4132 * @param int $userid the user id 4133 * @param string $name the name of the processor 4134 * @param array $formvalues the form values 4135 * @return external_description 4136 * @throws moodle_exception 4137 * @since 3.2 4138 */ 4139 public static function message_processor_config_form($userid, $name, $formvalues) { 4140 global $USER, $CFG; 4141 4142 $params = self::validate_parameters( 4143 self::message_processor_config_form_parameters(), 4144 array( 4145 'userid' => $userid, 4146 'name' => $name, 4147 'formvalues' => $formvalues, 4148 ) 4149 ); 4150 4151 $user = self::validate_preferences_permissions($params['userid']); 4152 4153 $processor = get_message_processor($params['name']); 4154 $preferences = []; 4155 $form = new stdClass(); 4156 4157 foreach ($params['formvalues'] as $formvalue) { 4158 // Curly braces to ensure interpretation is consistent between 4159 // php 5 and php 7. 4160 $form->{$formvalue['name']} = $formvalue['value']; 4161 } 4162 4163 $processor->process_form($form, $preferences); 4164 4165 if (!empty($preferences)) { 4166 set_user_preferences($preferences, $params['userid']); 4167 } 4168 } 4169 4170 /** 4171 * Returns description of method result value 4172 * 4173 * @return external_description 4174 * @since 3.2 4175 */ 4176 public static function message_processor_config_form_returns() { 4177 return null; 4178 } 4179 4180 /** 4181 * Returns description of method parameters 4182 * 4183 * @return external_function_parameters 4184 * @since 3.2 4185 */ 4186 public static function get_message_processor_parameters() { 4187 return new external_function_parameters( 4188 array( 4189 'userid' => new external_value(PARAM_INT, 'id of the user, 0 for current user'), 4190 'name' => new external_value(PARAM_SAFEDIR, 'The name of the message processor', VALUE_REQUIRED), 4191 ) 4192 ); 4193 } 4194 4195 /** 4196 * Get a message processor. 4197 * 4198 * @param int $userid 4199 * @param string $name the name of the processor 4200 * @return external_description 4201 * @throws moodle_exception 4202 * @since 3.2 4203 */ 4204 public static function get_message_processor($userid = 0, $name) { 4205 global $USER, $PAGE, $CFG; 4206 4207 // Check if messaging is enabled. 4208 if (empty($CFG->messaging)) { 4209 throw new moodle_exception('disabled', 'message'); 4210 } 4211 4212 $params = self::validate_parameters( 4213 self::get_message_processor_parameters(), 4214 array( 4215 'userid' => $userid, 4216 'name' => $name, 4217 ) 4218 ); 4219 4220 if (empty($params['userid'])) { 4221 $params['userid'] = $USER->id; 4222 } 4223 4224 $user = core_user::get_user($params['userid'], '*', MUST_EXIST); 4225 core_user::require_active_user($user); 4226 self::validate_context(context_user::instance($params['userid'])); 4227 4228 $processor = get_message_processor($params['name']); 4229 4230 $processoroutput = new \core_message\output\processor($processor, $user); 4231 $renderer = $PAGE->get_renderer('core_message'); 4232 4233 return $processoroutput->export_for_template($renderer); 4234 } 4235 4236 /** 4237 * Returns description of method result value 4238 * 4239 * @return external_description 4240 * @since 3.2 4241 */ 4242 public static function get_message_processor_returns() { 4243 return new external_function_parameters( 4244 array( 4245 'systemconfigured' => new external_value(PARAM_BOOL, 'Site configuration status'), 4246 'userconfigured' => new external_value(PARAM_BOOL, 'The user configuration status'), 4247 ) 4248 ); 4249 } 4250 4251 /** 4252 * Check that the user has enough permission to retrieve message or notifications preferences. 4253 * 4254 * @param int $userid the user id requesting the preferences 4255 * @return stdClass full user object 4256 * @throws moodle_exception 4257 * @since Moodle 3.2 4258 */ 4259 protected static function validate_preferences_permissions($userid) { 4260 global $USER; 4261 4262 if (empty($userid)) { 4263 $user = $USER; 4264 } else { 4265 $user = core_user::get_user($userid, '*', MUST_EXIST); 4266 core_user::require_active_user($user); 4267 } 4268 4269 $systemcontext = context_system::instance(); 4270 self::validate_context($systemcontext); 4271 4272 // Check access control. 4273 if ($user->id == $USER->id) { 4274 // Editing own message profile. 4275 require_capability('moodle/user:editownmessageprofile', $systemcontext); 4276 } else { 4277 // Teachers, parents, etc. 4278 $personalcontext = context_user::instance($user->id); 4279 require_capability('moodle/user:editmessageprofile', $personalcontext); 4280 } 4281 return $user; 4282 } 4283 4284 /** 4285 * Returns a notification or message preference structure. 4286 * 4287 * @return external_single_structure the structure 4288 * @since Moodle 3.2 4289 */ 4290 protected static function get_preferences_structure() { 4291 return new external_single_structure( 4292 array( 4293 'userid' => new external_value(PARAM_INT, 'User id'), 4294 'disableall' => new external_value(PARAM_INT, 'Whether all the preferences are disabled'), 4295 'processors' => new external_multiple_structure( 4296 new external_single_structure( 4297 array( 4298 'displayname' => new external_value(PARAM_TEXT, 'Display name'), 4299 'name' => new external_value(PARAM_PLUGIN, 'Processor name'), 4300 'hassettings' => new external_value(PARAM_BOOL, 'Whether has settings'), 4301 'contextid' => new external_value(PARAM_INT, 'Context id'), 4302 'userconfigured' => new external_value(PARAM_INT, 'Whether is configured by the user'), 4303 ) 4304 ), 4305 'Config form values' 4306 ), 4307 'components' => new external_multiple_structure( 4308 new external_single_structure( 4309 array( 4310 'displayname' => new external_value(PARAM_TEXT, 'Display name'), 4311 'notifications' => new external_multiple_structure( 4312 new external_single_structure( 4313 array( 4314 'displayname' => new external_value(PARAM_TEXT, 'Display name'), 4315 'preferencekey' => new external_value(PARAM_ALPHANUMEXT, 'Preference key'), 4316 'processors' => new external_multiple_structure( 4317 new external_single_structure( 4318 array( 4319 'displayname' => new external_value(PARAM_TEXT, 'Display name'), 4320 'name' => new external_value(PARAM_PLUGIN, 'Processor name'), 4321 'locked' => new external_value(PARAM_BOOL, 'Is locked by admin?'), 4322 'lockedmessage' => new external_value(PARAM_TEXT, 4323 'Text to display if locked', VALUE_OPTIONAL), 4324 'userconfigured' => new external_value(PARAM_INT, 'Is configured?'), 4325 'loggedin' => new external_single_structure( 4326 array( 4327 'name' => new external_value(PARAM_NOTAGS, 'Name'), 4328 'displayname' => new external_value(PARAM_TEXT, 'Display name'), 4329 'checked' => new external_value(PARAM_BOOL, 'Is checked?'), 4330 ) 4331 ), 4332 'loggedoff' => new external_single_structure( 4333 array( 4334 'name' => new external_value(PARAM_NOTAGS, 'Name'), 4335 'displayname' => new external_value(PARAM_TEXT, 'Display name'), 4336 'checked' => new external_value(PARAM_BOOL, 'Is checked?'), 4337 ) 4338 ), 4339 ) 4340 ), 4341 'Processors values for this notification' 4342 ), 4343 ) 4344 ), 4345 'List of notificaitons for the component' 4346 ), 4347 ) 4348 ), 4349 'Available components' 4350 ), 4351 ) 4352 ); 4353 } 4354 4355 /** 4356 * Returns description of method parameters 4357 * 4358 * @return external_function_parameters 4359 * @since 3.2 4360 */ 4361 public static function get_user_notification_preferences_parameters() { 4362 return new external_function_parameters( 4363 array( 4364 'userid' => new external_value(PARAM_INT, 'id of the user, 0 for current user', VALUE_DEFAULT, 0) 4365 ) 4366 ); 4367 } 4368 4369 /** 4370 * Get the notification preferences for a given user. 4371 * 4372 * @param int $userid id of the user, 0 for current user 4373 * @return external_description 4374 * @throws moodle_exception 4375 * @since 3.2 4376 */ 4377 public static function get_user_notification_preferences($userid = 0) { 4378 global $PAGE; 4379 4380 $params = self::validate_parameters( 4381 self::get_user_notification_preferences_parameters(), 4382 array( 4383 'userid' => $userid, 4384 ) 4385 ); 4386 $user = self::validate_preferences_permissions($params['userid']); 4387 4388 $processors = get_message_processors(); 4389 $providers = message_get_providers_for_user($user->id); 4390 $preferences = \core_message\api::get_all_message_preferences($processors, $providers, $user); 4391 $notificationlist = new \core_message\output\preferences\notification_list($processors, $providers, $preferences, $user); 4392 4393 $renderer = $PAGE->get_renderer('core_message'); 4394 4395 $result = array( 4396 'warnings' => array(), 4397 'preferences' => $notificationlist->export_for_template($renderer) 4398 ); 4399 return $result; 4400 } 4401 4402 /** 4403 * Returns description of method result value 4404 * 4405 * @return external_description 4406 * @since 3.2 4407 */ 4408 public static function get_user_notification_preferences_returns() { 4409 return new external_function_parameters( 4410 array( 4411 'preferences' => self::get_preferences_structure(), 4412 'warnings' => new external_warnings(), 4413 ) 4414 ); 4415 } 4416 4417 /** 4418 * Returns description of method parameters 4419 * 4420 * @return external_function_parameters 4421 * @since 3.2 4422 */ 4423 public static function get_user_message_preferences_parameters() { 4424 return new external_function_parameters( 4425 array( 4426 'userid' => new external_value(PARAM_INT, 'id of the user, 0 for current user', VALUE_DEFAULT, 0) 4427 ) 4428 ); 4429 } 4430 4431 /** 4432 * Get the notification preferences for a given user. 4433 * 4434 * @param int $userid id of the user, 0 for current user 4435 * @return external_description 4436 * @throws moodle_exception 4437 * @since 3.2 4438 */ 4439 public static function get_user_message_preferences($userid = 0) { 4440 global $CFG, $PAGE; 4441 4442 $params = self::validate_parameters( 4443 self::get_user_message_preferences_parameters(), 4444 array( 4445 'userid' => $userid, 4446 ) 4447 ); 4448 4449 $user = self::validate_preferences_permissions($params['userid']); 4450 4451 // Filter out enabled, available system_configured and user_configured processors only. 4452 $readyprocessors = array_filter(get_message_processors(), function($processor) { 4453 return $processor->enabled && 4454 $processor->configured && 4455 $processor->object->is_user_configured() && 4456 // Filter out processors that don't have and message preferences to configure. 4457 $processor->object->has_message_preferences(); 4458 }); 4459 4460 $providers = array_filter(message_get_providers_for_user($user->id), function($provider) { 4461 return $provider->component === 'moodle'; 4462 }); 4463 $preferences = \core_message\api::get_all_message_preferences($readyprocessors, $providers, $user); 4464 $notificationlistoutput = new \core_message\output\preferences\message_notification_list($readyprocessors, 4465 $providers, $preferences, $user); 4466 4467 $renderer = $PAGE->get_renderer('core_message'); 4468 4469 $entertosend = get_user_preferences('message_entertosend', $CFG->messagingdefaultpressenter, $user); 4470 4471 $result = array( 4472 'warnings' => array(), 4473 'preferences' => $notificationlistoutput->export_for_template($renderer), 4474 'blocknoncontacts' => \core_message\api::get_user_privacy_messaging_preference($user->id), 4475 'entertosend' => $entertosend 4476 ); 4477 return $result; 4478 } 4479 4480 /** 4481 * Returns description of method result value 4482 * 4483 * @return external_description 4484 * @since 3.2 4485 */ 4486 public static function get_user_message_preferences_returns() { 4487 return new external_function_parameters( 4488 array( 4489 'preferences' => self::get_preferences_structure(), 4490 'blocknoncontacts' => new external_value(PARAM_INT, 'Privacy messaging setting to define who can message you'), 4491 'entertosend' => new external_value(PARAM_BOOL, 'User preference for using enter to send messages'), 4492 'warnings' => new external_warnings(), 4493 ) 4494 ); 4495 } 4496 4497 /** 4498 * Returns description of method parameters for the favourite_conversations() method. 4499 * 4500 * @return external_function_parameters 4501 */ 4502 public static function set_favourite_conversations_parameters() { 4503 return new external_function_parameters( 4504 array( 4505 'userid' => new external_value(PARAM_INT, 'id of the user, 0 for current user', VALUE_DEFAULT, 0), 4506 'conversations' => new external_multiple_structure( 4507 new external_value(PARAM_INT, 'id of the conversation', VALUE_DEFAULT, 0) 4508 ) 4509 ) 4510 ); 4511 } 4512 4513 /** 4514 * Favourite a conversation, or list of conversations for a user. 4515 * 4516 * @param int $userid the id of the user, or 0 for the current user. 4517 * @param array $conversationids the list of conversations ids to favourite. 4518 * @return array 4519 * @throws moodle_exception if messaging is disabled or if the user cannot perform the action. 4520 */ 4521 public static function set_favourite_conversations(int $userid, array $conversationids) { 4522 global $CFG, $USER; 4523 4524 // All the business logic checks that really shouldn't be in here. 4525 if (empty($CFG->messaging)) { 4526 throw new moodle_exception('disabled', 'message'); 4527 } 4528 $params = [ 4529 'userid' => $userid, 4530 'conversations' => $conversationids 4531 ]; 4532 $params = self::validate_parameters(self::set_favourite_conversations_parameters(), $params); 4533 $systemcontext = context_system::instance(); 4534 self::validate_context($systemcontext); 4535 4536 if (($USER->id != $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) { 4537 throw new moodle_exception('You do not have permission to perform this action.'); 4538 } 4539 4540 foreach ($params['conversations'] as $conversationid) { 4541 \core_message\api::set_favourite_conversation($conversationid, $params['userid']); 4542 } 4543 4544 return []; 4545 } 4546 4547 /** 4548 * Return a description of the returns for the create_user_favourite_conversations() method. 4549 * 4550 * @return external_description 4551 */ 4552 public static function set_favourite_conversations_returns() { 4553 return new external_warnings(); 4554 } 4555 4556 /** 4557 * Returns description of method parameters for unfavourite_conversations() method. 4558 * 4559 * @return external_function_parameters 4560 */ 4561 public static function unset_favourite_conversations_parameters() { 4562 return new external_function_parameters( 4563 array( 4564 'userid' => new external_value(PARAM_INT, 'id of the user, 0 for current user', VALUE_DEFAULT, 0), 4565 'conversations' => new external_multiple_structure( 4566 new external_value(PARAM_INT, 'id of the conversation', VALUE_DEFAULT, 0) 4567 ) 4568 ) 4569 ); 4570 } 4571 4572 /** 4573 * Unfavourite a conversation, or list of conversations for a user. 4574 * 4575 * @param int $userid the id of the user, or 0 for the current user. 4576 * @param array $conversationids the list of conversations ids unset as favourites. 4577 * @return array 4578 * @throws moodle_exception if messaging is disabled or if the user cannot perform the action. 4579 */ 4580 public static function unset_favourite_conversations(int $userid, array $conversationids) { 4581 global $CFG, $USER; 4582 4583 // All the business logic checks that really shouldn't be in here. 4584 if (empty($CFG->messaging)) { 4585 throw new moodle_exception('disabled', 'message'); 4586 } 4587 $params = [ 4588 'userid' => $userid, 4589 'conversations' => $conversationids 4590 ]; 4591 $params = self::validate_parameters(self::unset_favourite_conversations_parameters(), $params); 4592 $systemcontext = context_system::instance(); 4593 self::validate_context($systemcontext); 4594 4595 if (($USER->id != $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) { 4596 throw new moodle_exception('You do not have permission to perform this action.'); 4597 } 4598 4599 foreach ($params['conversations'] as $conversationid) { 4600 \core_message\api::unset_favourite_conversation($conversationid, $params['userid']); 4601 } 4602 4603 return []; 4604 } 4605 4606 /** 4607 * Unset favourite conversations return description. 4608 * 4609 * @return external_description 4610 */ 4611 public static function unset_favourite_conversations_returns() { 4612 return new external_warnings(); 4613 } 4614 4615 /** 4616 * Returns description of method parameters for get_member_info() method. 4617 * 4618 * @return external_function_parameters 4619 */ 4620 public static function get_member_info_parameters() { 4621 return new external_function_parameters( 4622 array( 4623 'referenceuserid' => new external_value(PARAM_INT, 'id of the user'), 4624 'userids' => new external_multiple_structure( 4625 new external_value(PARAM_INT, 'id of members to get') 4626 ), 4627 'includecontactrequests' => new external_value(PARAM_BOOL, 'include contact requests in response', VALUE_DEFAULT, false), 4628 'includeprivacyinfo' => new external_value(PARAM_BOOL, 'include privacy info in response', VALUE_DEFAULT, false) 4629 ) 4630 ); 4631 } 4632 4633 /** 4634 * Returns conversation member info for the supplied users, relative to the supplied referenceuserid. 4635 * 4636 * This is the basic structure used when returning members, and includes information about the relationship between each member 4637 * and the referenceuser, such as a whether the referenceuser has marked the member as a contact, or has blocked them. 4638 * 4639 * @param int $referenceuserid the id of the user which check contact and blocked status. 4640 * @param array $userids 4641 * @return array the array of objects containing member info. 4642 * @throws moodle_exception if messaging is disabled or if the user cannot perform the action. 4643 */ 4644 public static function get_member_info( 4645 int $referenceuserid, 4646 array $userids, 4647 bool $includecontactrequests = false, 4648 bool $includeprivacyinfo = false 4649 ) { 4650 global $CFG, $USER; 4651 4652 // All the business logic checks that really shouldn't be in here. 4653 if (empty($CFG->messaging)) { 4654 throw new moodle_exception('disabled', 'message'); 4655 } 4656 $params = [ 4657 'referenceuserid' => $referenceuserid, 4658 'userids' => $userids, 4659 'includecontactrequests' => $includecontactrequests, 4660 'includeprivacyinfo' => $includeprivacyinfo 4661 ]; 4662 $params = self::validate_parameters(self::get_member_info_parameters(), $params); 4663 $systemcontext = context_system::instance(); 4664 self::validate_context($systemcontext); 4665 4666 if (($USER->id != $referenceuserid) && !has_capability('moodle/site:readallmessages', $systemcontext)) { 4667 throw new moodle_exception('You do not have permission to perform this action.'); 4668 } 4669 4670 return \core_message\helper::get_member_info( 4671 $params['referenceuserid'], 4672 $params['userids'], 4673 $params['includecontactrequests'], 4674 $params['includeprivacyinfo'] 4675 ); 4676 } 4677 4678 /** 4679 * Get member info return description. 4680 * 4681 * @return external_description 4682 */ 4683 public static function get_member_info_returns() { 4684 return new external_multiple_structure( 4685 self::get_conversation_member_structure() 4686 ); 4687 } 4688 4689 /** 4690 * Returns description of method parameters for get_conversation_counts() method. 4691 * 4692 * @return external_function_parameters 4693 */ 4694 public static function get_conversation_counts_parameters() { 4695 return new external_function_parameters( 4696 [ 4697 'userid' => new external_value(PARAM_INT, 'id of the user, 0 for current user', VALUE_DEFAULT, 0) 4698 ] 4699 ); 4700 } 4701 4702 /** 4703 * Returns an array of conversation counts for the various types of conversations, including favourites. 4704 * 4705 * Return format: 4706 * [ 4707 * 'favourites' => 0, 4708 * 'types' => [ 4709 * \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0, 4710 * \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 0 4711 * ] 4712 * ] 4713 * 4714 * @param int $userid the id of the user whose counts we are fetching. 4715 * @return array the array of conversation counts, indexed by type. 4716 * @throws moodle_exception if the current user cannot perform this action. 4717 */ 4718 public static function get_conversation_counts(int $userid) { 4719 global $CFG, $USER; 4720 4721 // All the business logic checks that really shouldn't be in here. 4722 if (empty($CFG->messaging)) { 4723 throw new moodle_exception('disabled', 'message'); 4724 } 4725 4726 if (empty($userid)) { 4727 $userid = $USER->id; 4728 } 4729 4730 $params = ['userid' => $userid]; 4731 $params = self::validate_parameters(self::get_conversation_counts_parameters(), $params); 4732 4733 $systemcontext = context_system::instance(); 4734 self::validate_context($systemcontext); 4735 4736 if (($USER->id != $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) { 4737 throw new moodle_exception('You do not have permission to perform this action.'); 4738 } 4739 4740 return \core_message\api::get_conversation_counts($params['userid']); 4741 } 4742 4743 /** 4744 * Get conversation counts return description. 4745 * 4746 * @return external_description 4747 */ 4748 public static function get_conversation_counts_returns() { 4749 return new external_single_structure( 4750 [ 4751 'favourites' => new external_value(PARAM_INT, 'Total number of favourite conversations'), 4752 'types' => new external_single_structure( 4753 [ 4754 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => new external_value(PARAM_INT, 4755 'Total number of individual conversations'), 4756 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => new external_value(PARAM_INT, 4757 'Total number of group conversations'), 4758 \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF => new external_value(PARAM_INT, 4759 'Total number of self conversations'), 4760 ] 4761 ), 4762 ] 4763 ); 4764 } 4765 4766 /** 4767 * Returns description of method parameters for get_unread_conversation_counts() method. 4768 * 4769 * @return external_function_parameters 4770 */ 4771 public static function get_unread_conversation_counts_parameters() { 4772 return new external_function_parameters( 4773 [ 4774 'userid' => new external_value(PARAM_INT, 'id of the user, 0 for current user', VALUE_DEFAULT, 0) 4775 ] 4776 ); 4777 } 4778 4779 /** 4780 * Returns an array of unread conversation counts for the various types of conversations, including favourites. 4781 * 4782 * Return format: 4783 * [ 4784 * 'favourites' => 0, 4785 * 'types' => [ 4786 * \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => 0, 4787 * \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => 0 4788 * ] 4789 * ] 4790 * 4791 * @param int $userid the id of the user whose counts we are fetching. 4792 * @return array the array of unread conversation counts, indexed by type. 4793 * @throws moodle_exception if the current user cannot perform this action. 4794 */ 4795 public static function get_unread_conversation_counts(int $userid) { 4796 global $CFG, $USER; 4797 4798 // All the business logic checks that really shouldn't be in here. 4799 if (empty($CFG->messaging)) { 4800 throw new moodle_exception('disabled', 'message'); 4801 } 4802 4803 if (empty($userid)) { 4804 $userid = $USER->id; 4805 } 4806 4807 $params = ['userid' => $userid]; 4808 $params = self::validate_parameters(self::get_unread_conversation_counts_parameters(), $params); 4809 4810 $systemcontext = context_system::instance(); 4811 self::validate_context($systemcontext); 4812 4813 if (($USER->id != $params['userid']) && !has_capability('moodle/site:readallmessages', $systemcontext)) { 4814 throw new moodle_exception('You do not have permission to perform this action.'); 4815 } 4816 4817 return \core_message\api::get_unread_conversation_counts($params['userid']); 4818 } 4819 4820 /** 4821 * Get unread conversation counts return description. 4822 * 4823 * @return external_description 4824 */ 4825 public static function get_unread_conversation_counts_returns() { 4826 return new external_single_structure( 4827 [ 4828 'favourites' => new external_value(PARAM_INT, 'Total number of unread favourite conversations'), 4829 'types' => new external_single_structure( 4830 [ 4831 \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL => new external_value(PARAM_INT, 4832 'Total number of unread individual conversations'), 4833 \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP => new external_value(PARAM_INT, 4834 'Total number of unread group conversations'), 4835 \core_message\api::MESSAGE_CONVERSATION_TYPE_SELF => new external_value(PARAM_INT, 4836 'Total number of unread self conversations'), 4837 ] 4838 ), 4839 ] 4840 ); 4841 } 4842 4843 /** 4844 * Returns description of method parameters 4845 * 4846 * @return external_function_parameters 4847 * @since 3.7 4848 */ 4849 public static function delete_message_for_all_users_parameters() { 4850 return new external_function_parameters( 4851 array( 4852 'messageid' => new external_value(PARAM_INT, 'The message id'), 4853 'userid' => new external_value(PARAM_INT, 'The user id of who we want to delete the message for all users') 4854 ) 4855 ); 4856 } 4857 /** 4858 * Deletes a message for all users 4859 * 4860 * @param int $messageid the message id 4861 * @param int $userid the user id of who we want to delete the message for all users, is no longer used. 4862 * @return external_description 4863 * @throws moodle_exception 4864 * @since 3.7 4865 */ 4866 public static function delete_message_for_all_users(int $messageid, int $userid) { 4867 global $CFG, $USER; 4868 4869 // Check if private messaging between users is allowed. 4870 if (empty($CFG->messaging)) { 4871 throw new moodle_exception('disabled', 'message'); 4872 } 4873 4874 // Validate params. 4875 $params = array( 4876 'messageid' => $messageid, 4877 'userid' => $userid 4878 ); 4879 $params = self::validate_parameters(self::delete_message_for_all_users_parameters(), $params); 4880 4881 // Validate context. 4882 $context = context_system::instance(); 4883 self::validate_context($context); 4884 4885 core_user::require_active_user($USER); 4886 4887 // Checks if a user can delete a message for all users. 4888 if (core_message\api::can_delete_message_for_all_users($USER->id, $params['messageid'])) { 4889 \core_message\api::delete_message_for_all_users($params['messageid']); 4890 } else { 4891 throw new moodle_exception('You do not have permission to delete this message for everyone.'); 4892 } 4893 4894 return []; 4895 } 4896 /** 4897 * Returns description of method result value 4898 * 4899 * @return external_description 4900 * @since 3.7 4901 */ 4902 public static function delete_message_for_all_users_returns() { 4903 return new external_warnings(); 4904 } 4905 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body