MDL-63303 message: add count_conversations to api
This commit is contained in:
@@ -1297,6 +1297,84 @@ class api {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the count of conversations (collection of messages from a single user) for
|
||||
* the given user.
|
||||
*
|
||||
* @param \stdClass $user The user who's conversations should be counted
|
||||
* @param int $type The conversation type
|
||||
* @param bool $excludefavourites Exclude favourite conversations
|
||||
* @return int the count of the user's unread conversations
|
||||
*/
|
||||
public static function count_conversations($user, int $type = null, bool $excludefavourites = false) {
|
||||
global $DB;
|
||||
|
||||
$params = [];
|
||||
$favouritessql = '';
|
||||
|
||||
if ($excludefavourites) {
|
||||
$favouritessql = "AND m.conversationid NOT IN (
|
||||
SELECT itemid
|
||||
FROM {favourite}
|
||||
WHERE component = 'core_message'
|
||||
AND itemtype = 'message_conversations'
|
||||
AND userid = ?
|
||||
)";
|
||||
$params[] = $user->id;
|
||||
}
|
||||
|
||||
switch($type) {
|
||||
case null:
|
||||
$params = array_merge([$user->id, self::MESSAGE_ACTION_DELETED, $user->id], $params);
|
||||
$sql = "SELECT COUNT(DISTINCT(m.conversationid))
|
||||
FROM {messages} m
|
||||
LEFT JOIN {message_conversations} c
|
||||
ON m.conversationid = c.id
|
||||
LEFT JOIN {message_user_actions} ma
|
||||
ON ma.messageid = m.id
|
||||
LEFT JOIN {message_conversation_members} mcm
|
||||
ON m.conversationid = mcm.conversationid
|
||||
WHERE mcm.userid = ?
|
||||
AND (
|
||||
c.type != " . self::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL . "
|
||||
OR
|
||||
(
|
||||
(ma.action IS NULL OR ma.action != ? OR ma.userid != ?)
|
||||
AND c.type = " . self::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL . "
|
||||
)
|
||||
)
|
||||
${favouritessql}";
|
||||
break;
|
||||
case self::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL:
|
||||
$params = array_merge([self::MESSAGE_ACTION_DELETED, $user->id, $user->id], $params);
|
||||
$sql = "SELECT COUNT(DISTINCT(m.conversationid))
|
||||
FROM {messages} m
|
||||
LEFT JOIN {message_conversations} c
|
||||
ON m.conversationid = c.id
|
||||
LEFT JOIN {message_user_actions} ma
|
||||
ON ma.messageid = m.id
|
||||
LEFT JOIN {message_conversation_members} mcm
|
||||
ON m.conversationid = mcm.conversationid
|
||||
WHERE (ma.action IS NULL OR ma.action != ? OR ma.userid != ?)
|
||||
AND mcm.userid = ?
|
||||
AND c.type = " . self::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL . "
|
||||
${favouritessql}";
|
||||
break;
|
||||
default:
|
||||
$params = array_merge([$user->id, $type], $params);
|
||||
$sql = "SELECT COUNT(m.conversationid)
|
||||
FROM {message_conversation_members} m
|
||||
LEFT JOIN {message_conversations} c
|
||||
ON m.conversationid = c.id
|
||||
WHERE m.userid = ?
|
||||
AND c.type = ?
|
||||
${favouritessql}";
|
||||
|
||||
}
|
||||
|
||||
return $DB->count_records_sql($sql, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks all messages being sent to a user in a particular conversation.
|
||||
*
|
||||
|
||||
@@ -5598,6 +5598,241 @@ class core_message_api_testcase extends core_message_messagelib_testcase {
|
||||
\core_message\api::send_message_to_conversation($user2->id, $ic1->id, 'test', FORMAT_MOODLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for test_count_conversations().
|
||||
*/
|
||||
public function test_count_conversations_test_cases() {
|
||||
$typeindividual = \core_message\api::MESSAGE_CONVERSATION_TYPE_INDIVIDUAL;
|
||||
$typegroup = \core_message\api::MESSAGE_CONVERSATION_TYPE_GROUP;
|
||||
list($user1, $user2, $user3, $user4, $user5) = [0, 1, 2, 3, 4];
|
||||
$conversations = [
|
||||
[
|
||||
'type' => $typeindividual,
|
||||
'users' => [$user1, $user2],
|
||||
'messages' => [$user1, $user2],
|
||||
'favourites' => [$user1]
|
||||
],
|
||||
[
|
||||
'type' => $typeindividual,
|
||||
'users' => [$user1, $user3],
|
||||
'messages' => [$user1, $user1],
|
||||
'favourites' => []
|
||||
],
|
||||
[
|
||||
'type' => $typegroup,
|
||||
'users' => [$user1, $user2, $user3, $user4],
|
||||
'messages' => [$user1, $user2, $user3, $user4],
|
||||
'favourites' => []
|
||||
],
|
||||
];
|
||||
|
||||
return [
|
||||
'No conversations' => [
|
||||
'conversationConfigs' => $conversations,
|
||||
'deleteuser' => null,
|
||||
'delete' => [],
|
||||
'arguments' => [$user5],
|
||||
'expected' => 0
|
||||
],
|
||||
'No individual conversations' => [
|
||||
'conversationConfigs' => $conversations,
|
||||
'deleteuser' => null,
|
||||
'delete' => [],
|
||||
'arguments' => [$user4, $typeindividual],
|
||||
'expected' => 0
|
||||
],
|
||||
'No individual conversations, 1 group conversation' => [
|
||||
'conversationConfigs' => $conversations,
|
||||
'deleteuser' => null,
|
||||
'delete' => [],
|
||||
'arguments' => [$user4],
|
||||
'expected' => 1
|
||||
],
|
||||
'1 - Multiple individual conversations, 1 group conversation' => [
|
||||
'conversationConfigs' => $conversations,
|
||||
'deleteuser' => null,
|
||||
'delete' => [],
|
||||
'arguments' => [$user1, $typegroup],
|
||||
'expected' => 1
|
||||
],
|
||||
'2 - Multiple individual conversations, 1 group conversation' => [
|
||||
'conversationConfigs' => $conversations,
|
||||
'deleteuser' => null,
|
||||
'delete' => [],
|
||||
'arguments' => [$user2, $typegroup],
|
||||
'expected' => 1
|
||||
],
|
||||
'3 - Multiple individual conversations, 1 group conversation' => [
|
||||
'conversationConfigs' => $conversations,
|
||||
'deleteuser' => null,
|
||||
'delete' => [],
|
||||
'arguments' => [$user3, $typegroup],
|
||||
'expected' => 1
|
||||
],
|
||||
'4 - Multiple individual conversations, 1 group conversation' => [
|
||||
'conversationConfigs' => $conversations,
|
||||
'deleteuser' => null,
|
||||
'delete' => [],
|
||||
'arguments' => [$user4, $typegroup],
|
||||
'expected' => 1
|
||||
],
|
||||
'Individual exclude favourites' => [
|
||||
'conversationConfigs' => $conversations,
|
||||
'deleteuser' => null,
|
||||
'delete' => [],
|
||||
'arguments' => [$user1, $typeindividual, true],
|
||||
'expected' => 1
|
||||
],
|
||||
'Individual include favourites' => [
|
||||
'conversationConfigs' => $conversations,
|
||||
'deleteuser' => null,
|
||||
'delete' => [],
|
||||
'arguments' => [$user1, $typeindividual, false],
|
||||
'expected' => 2
|
||||
],
|
||||
'All exclude favourites' => [
|
||||
'conversationConfigs' => $conversations,
|
||||
'deleteuser' => null,
|
||||
'delete' => [],
|
||||
'arguments' => [$user1, null, true],
|
||||
'expected' => 2
|
||||
],
|
||||
'All include favourites' => [
|
||||
'conversationConfigs' => $conversations,
|
||||
'deleteuser' => null,
|
||||
'delete' => [],
|
||||
'arguments' => [$user1, null, false],
|
||||
'expected' => 3
|
||||
],
|
||||
'Delete single message individual' => [
|
||||
'conversationConfigs' => $conversations,
|
||||
'deleteuser' => $user1,
|
||||
'delete' => [1],
|
||||
'arguments' => [$user1, $typeindividual],
|
||||
'expected' => 2
|
||||
],
|
||||
'Delete single message all' => [
|
||||
'conversationConfigs' => $conversations,
|
||||
'deleteuser' => $user1,
|
||||
'delete' => [1],
|
||||
'arguments' => [$user1, null],
|
||||
'expected' => 3
|
||||
],
|
||||
'Delete all message individual conversation include favourites' => [
|
||||
'conversationConfigs' => $conversations,
|
||||
'deleteuser' => $user1,
|
||||
'delete' => [2, 3],
|
||||
'arguments' => [$user1, $typeindividual, false],
|
||||
'expected' => 1
|
||||
],
|
||||
'Delete all message individual conversation exclude favourites' => [
|
||||
'conversationConfigs' => $conversations,
|
||||
'deleteuser' => $user1,
|
||||
'delete' => [2, 3],
|
||||
'arguments' => [$user1, $typeindividual, true],
|
||||
'expected' => 0
|
||||
],
|
||||
'Delete all message individual conversation include favourites diff user' => [
|
||||
'conversationConfigs' => $conversations,
|
||||
'deleteuser' => $user1,
|
||||
'delete' => [2, 3],
|
||||
'arguments' => [$user2, $typeindividual, false],
|
||||
'expected' => 1
|
||||
],
|
||||
'Delete all message individual conversation exclude favourites diff user' => [
|
||||
'conversationConfigs' => $conversations,
|
||||
'deleteuser' => $user1,
|
||||
'delete' => [2, 3],
|
||||
'arguments' => [$user2, $typeindividual, true],
|
||||
'expected' => 1
|
||||
],
|
||||
'Delete all message group conversation include favourites' => [
|
||||
'conversationConfigs' => $conversations,
|
||||
'deleteuser' => $user1,
|
||||
'delete' => [4, 5, 6, 7],
|
||||
'arguments' => [$user1, $typegroup, false],
|
||||
'expected' => 1
|
||||
],
|
||||
'Delete all message group conversation include favourites' => [
|
||||
'conversationConfigs' => $conversations,
|
||||
'deleteuser' => $user1,
|
||||
'delete' => [4, 5, 6, 7],
|
||||
'arguments' => [$user1, null, false],
|
||||
'expected' => 3
|
||||
],
|
||||
'Delete all message group conversation exclude favourites' => [
|
||||
'conversationConfigs' => $conversations,
|
||||
'deleteuser' => $user1,
|
||||
'delete' => [4, 5, 6, 7],
|
||||
'arguments' => [$user1, null, true],
|
||||
'expected' => 2
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the count_conversations() function.
|
||||
*
|
||||
* @dataProvider test_count_conversations_test_cases()
|
||||
* @param array $conversationconfigs Conversations to create
|
||||
* @param int $deleteuser The user who is deleting the messages
|
||||
* @param array $delete The list of messages to delete (by index)
|
||||
* @param array $arguments Arguments for the count conversations function
|
||||
* @param int $expected The expected result
|
||||
*/
|
||||
public function test_count_conversations(
|
||||
$conversationconfigs,
|
||||
$deleteuser,
|
||||
$delete,
|
||||
$arguments,
|
||||
$expected
|
||||
) {
|
||||
$generator = $this->getDataGenerator();
|
||||
$users = [
|
||||
$generator->create_user(),
|
||||
$generator->create_user(),
|
||||
$generator->create_user(),
|
||||
$generator->create_user(),
|
||||
$generator->create_user()
|
||||
];
|
||||
|
||||
$user = $users[$arguments[0]];
|
||||
$deleteuser = !is_null($deleteuser) ? $users[$deleteuser] : null;
|
||||
$arguments[0] = $user;
|
||||
$systemcontext = \context_system::instance();
|
||||
$conversations = [];
|
||||
$messageids = [];
|
||||
|
||||
foreach ($conversationconfigs as $config) {
|
||||
$conversation = \core_message\api::create_conversation(
|
||||
$config['type'],
|
||||
array_map(function($userindex) use ($users) {
|
||||
return $users[$userindex]->id;
|
||||
}, $config['users'])
|
||||
);
|
||||
|
||||
foreach ($config['messages'] as $userfromindex) {
|
||||
$userfrom = $users[$userfromindex];
|
||||
$messageids[] = testhelper::send_fake_message_to_conversation($userfrom, $conversation->id);
|
||||
}
|
||||
|
||||
foreach ($config['favourites'] as $userfromindex) {
|
||||
$userfrom = $users[$userfromindex];
|
||||
$usercontext = \context_user::instance($userfrom->id);
|
||||
$ufservice = \core_favourites\service_factory::get_service_for_user_context($usercontext);
|
||||
$ufservice->create_favourite('core_message', 'message_conversations', $conversation->id, $systemcontext);
|
||||
}
|
||||
|
||||
$conversations[] = $conversation;
|
||||
}
|
||||
|
||||
foreach ($delete as $messageindex) {
|
||||
\core_message\api::delete_message($deleteuser->id, $messageids[$messageindex]);
|
||||
}
|
||||
|
||||
$this->assertEquals($expected, \core_message\api::count_conversations(...$arguments));
|
||||
}
|
||||
|
||||
/**
|
||||
* Comparison function for sorting contacts.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user