/** * Test delete_message. */ public function test_delete_message() { global $DB; $this->resetAfterTest(true); $user1 = self::getDataGenerator()->create_user(); $user2 = self::getDataGenerator()->create_user(); $user3 = self::getDataGenerator()->create_user(); $user4 = self::getDataGenerator()->create_user(); // Login as user1. $this->setUser($user1); $this->assertEquals(array(), core_message_external::create_contacts(array($user2->id, $user3->id))); // User user1 does not interchange messages with user3. $m1to2 = message_post_message($user1, $user2, 'some random text 1', FORMAT_MOODLE); $m2to3 = message_post_message($user2, $user3, 'some random text 3', FORMAT_MOODLE); $m3to2 = message_post_message($user3, $user2, 'some random text 4', FORMAT_MOODLE); $m3to4 = message_post_message($user3, $user4, 'some random text 4', FORMAT_MOODLE); // Retrieve all messages sent by user2 (they are currently unread). $lastmessages = message_get_messages($user1->id, $user2->id, 0, false); // Delete a message not read, as a user from. $result = core_message_external::delete_message($m1to2, $user1->id, false); $result = external_api::clean_returnvalue(core_message_external::delete_message_returns(), $result); $this->assertTrue($result['status']); $this->assertCount(0, $result['warnings']); $deletedmessage = $DB->get_record('message', array('id' => $m1to2)); $this->assertNotEquals(0, $deletedmessage->timeuserfromdeleted); // Try to delete the same message again. $result = core_message_external::delete_message($m1to2, $user1->id, false); $result = external_api::clean_returnvalue(core_message_external::delete_message_returns(), $result); $this->assertFalse($result['status']); // Try to delete a message that does not belong to me. try { $messageid = core_message_external::delete_message($m2to3, $user3->id, false); $this->fail('Exception expected due invalid messageid.'); } catch (moodle_exception $e) { $this->assertEquals('You do not have permission to delete this message', $e->errorcode); } $this->setUser($user3); // Delete a message not read, as a user to. $result = core_message_external::delete_message($m2to3, $user3->id, false); $result = external_api::clean_returnvalue(core_message_external::delete_message_returns(), $result); $this->assertTrue($result['status']); $this->assertCount(0, $result['warnings']); $deletedmessage = $DB->get_record('message', array('id' => $m2to3)); $this->assertNotEquals(0, $deletedmessage->timeusertodeleted); // Delete a message read. $message = $DB->get_record('message', array('id' => $m3to2)); $messageid = message_mark_message_read($message, time()); $result = core_message_external::delete_message($messageid, $user3->id); $result = external_api::clean_returnvalue(core_message_external::delete_message_returns(), $result); $this->assertTrue($result['status']); $this->assertCount(0, $result['warnings']); $deletedmessage = $DB->get_record('message_read', array('id' => $messageid)); $this->assertNotEquals(0, $deletedmessage->timeuserfromdeleted); // Invalid message ids. try { $result = core_message_external::delete_message(-1, $user1->id); $this->fail('Exception expected due invalid messageid.'); } catch (dml_missing_record_exception $e) { $this->assertEquals('invalidrecord', $e->errorcode); } // Invalid user. try { $result = core_message_external::delete_message($m1to2, -1, false); $this->fail('Exception expected due invalid user.'); } catch (moodle_exception $e) { $this->assertEquals('invaliduser', $e->errorcode); } // Not active user. delete_user($user2); try { $result = core_message_external::delete_message($m1to2, $user2->id, false); $this->fail('Exception expected due invalid user.'); } catch (moodle_exception $e) { $this->assertEquals('userdeleted', $e->errorcode); } // Now, as an admin, try to delete any message. $this->setAdminUser(); $result = core_message_external::delete_message($m3to4, $user4->id, false); $result = external_api::clean_returnvalue(core_message_external::delete_message_returns(), $result); $this->assertTrue($result['status']); $this->assertCount(0, $result['warnings']); $deletedmessage = $DB->get_record('message', array('id' => $m3to4)); $this->assertNotEquals(0, $deletedmessage->timeusertodeleted); }
/** * Get messages function implementation. * * @since 2.8 * @throws invalid_parameter_exception * @throws moodle_exception * @param int $useridto the user id who received the message * @param int $useridfrom the user id who send the message. -10 or -20 for no-reply or support user * @param string $type type of message to return, expected values: notifications, conversations and both * @param bool $read true for retreiving read messages, false for unread * @param bool $newestfirst true for ordering by newest first, false for oldest first * @param int $limitfrom limit from * @param int $limitnum limit num * @return external_description */ public static function get_messages($useridto, $useridfrom = 0, $type = 'both', $read = true, $newestfirst = true, $limitfrom = 0, $limitnum = 0) { global $CFG, $USER; $warnings = array(); $params = array('useridto' => $useridto, 'useridfrom' => $useridfrom, 'type' => $type, 'read' => $read, 'newestfirst' => $newestfirst, 'limitfrom' => $limitfrom, 'limitnum' => $limitnum); $params = self::validate_parameters(self::get_messages_parameters(), $params); $context = context_system::instance(); self::validate_context($context); $useridto = $params['useridto']; $useridfrom = $params['useridfrom']; $type = $params['type']; $read = $params['read']; $newestfirst = $params['newestfirst']; $limitfrom = $params['limitfrom']; $limitnum = $params['limitnum']; $allowedvalues = array('notifications', 'conversations', 'both'); if (!in_array($type, $allowedvalues)) { throw new invalid_parameter_exception('Invalid value for type parameter (value: ' . $type . '),' . 'allowed values are: ' . implode(',', $allowedvalues)); } // Check if private messaging between users is allowed. if (empty($CFG->messaging)) { // If we are retreiving only conversations, and messaging is disabled, throw an exception. if ($type == "conversations") { throw new moodle_exception('disabled', 'message'); } if ($type == "both") { $warning = array(); $warning['item'] = 'message'; $warning['itemid'] = $USER->id; $warning['warningcode'] = '1'; $warning['message'] = 'Private messages (conversations) are not enabled in this site. Only notifications will be returned'; $warnings[] = $warning; } } if (!empty($useridto)) { if (core_user::is_real_user($useridto)) { $userto = core_user::get_user($useridto, '*', MUST_EXIST); } else { throw new moodle_exception('invaliduser'); } } if (!empty($useridfrom)) { // We use get_user here because the from user can be the noreply or support user. $userfrom = core_user::get_user($useridfrom, '*', MUST_EXIST); } // Check if the current user is the sender/receiver or just a privileged user. if ($useridto != $USER->id and $useridfrom != $USER->id and !has_capability('moodle/site:readallmessages', $context)) { throw new moodle_exception('accessdenied', 'admin'); } // Which type of messages to retrieve. $notifications = -1; if ($type != 'both') { $notifications = $type == 'notifications' ? 1 : 0; } $orderdirection = $newestfirst ? 'DESC' : 'ASC'; $sort = "mr.timecreated {$orderdirection}"; if ($messages = message_get_messages($useridto, $useridfrom, $notifications, $read, $sort, $limitfrom, $limitnum)) { $canviewfullname = has_capability('moodle/site:viewfullnames', $context); // In some cases, we don't need to get the to/from user objects from the sql query. $userfromfullname = ''; $usertofullname = ''; // In this case, the useridto field is not empty, so we can get the user destinatary fullname from there. if (!empty($useridto)) { $usertofullname = fullname($userto, $canviewfullname); // The user from may or may not be filled. if (!empty($useridfrom)) { $userfromfullname = fullname($userfrom, $canviewfullname); } } else { // If the useridto field is empty, the useridfrom must be filled. $userfromfullname = fullname($userfrom, $canviewfullname); } foreach ($messages as $mid => $message) { // Do not return deleted messages. if ($useridto == $USER->id and $message->timeusertodeleted or $useridfrom == $USER->id and $message->timeuserfromdeleted) { unset($messages[$mid]); continue; } // We need to get the user from the query. if (empty($userfromfullname)) { // Check for non-reply and support users. if (core_user::is_real_user($message->useridfrom)) { $user = new stdClass(); $user = username_load_fields_from_object($user, $message, 'userfrom'); $message->userfromfullname = fullname($user, $canviewfullname); } else { $user = core_user::get_user($message->useridfrom); $message->userfromfullname = fullname($user, $canviewfullname); } } else { $message->userfromfullname = $userfromfullname; } // We need to get the user from the query. if (empty($usertofullname)) { $user = new stdClass(); $user = username_load_fields_from_object($user, $message, 'userto'); $message->usertofullname = fullname($user, $canviewfullname); } else { $message->usertofullname = $usertofullname; } // This field is only available in the message_read table. if (!isset($message->timeread)) { $message->timeread = 0; } $message->text = message_format_message_text($message); $messages[$mid] = (array) $message; } } $results = array('messages' => $messages, 'warnings' => $warnings); return $results; }
/** * Test mark_message_read. */ public function test_mark_message_read() { $this->resetAfterTest(true); $user1 = self::getDataGenerator()->create_user(); $user2 = self::getDataGenerator()->create_user(); $user3 = self::getDataGenerator()->create_user(); // Login as user1. $this->setUser($user1); $this->assertEquals(array(), core_message_external::create_contacts(array($user2->id, $user3->id))); // The user2 sends a couple of messages to user1. $this->send_message($user2, $user1, 'Hello there!'); $this->send_message($user2, $user1, 'How you goin?'); $this->send_message($user3, $user1, 'How you goin?'); $this->send_message($user3, $user2, 'How you goin?'); // Retrieve all messages sent by user2 (they are currently unread). $lastmessages = message_get_messages($user1->id, $user2->id, 0, false); $messageids = array(); foreach ($lastmessages as $m) { $messageid = core_message_external::mark_message_read($m->id, time()); $messageids[] = external_api::clean_returnvalue(core_message_external::mark_message_read_returns(), $messageid); } // Retrieve all messages sent (they are currently read). $lastmessages = message_get_messages($user1->id, $user2->id, 0, true); $this->assertCount(2, $lastmessages); $this->assertArrayHasKey($messageids[0]['messageid'], $lastmessages); $this->assertArrayHasKey($messageids[1]['messageid'], $lastmessages); // Retrieve all messages sent by any user (that are currently unread). $lastmessages = message_get_messages($user1->id, 0, 0, false); $this->assertCount(1, $lastmessages); // Invalid message ids. try { $messageid = core_message_external::mark_message_read($messageids[0]['messageid'] * 2, time()); $this->fail('Exception expected due invalid messageid.'); } catch (dml_missing_record_exception $e) { $this->assertEquals('invalidrecord', $e->errorcode); } // A message to a different user. $lastmessages = message_get_messages($user2->id, $user3->id, 0, false); $messageid = array_pop($lastmessages)->id; try { $messageid = core_message_external::mark_message_read($messageid, time()); $this->fail('Exception expected due invalid messageid.'); } catch (invalid_parameter_exception $e) { $this->assertEquals('invalidparameter', $e->errorcode); } }