Merge branch 'MDL-63408_master' of git://github.com/markn86/moodle
authorAndrew Nicols <andrew@nicols.co.uk>
Tue, 23 Oct 2018 00:50:40 +0000 (08:50 +0800)
committerAndrew Nicols <andrew@nicols.co.uk>
Tue, 23 Oct 2018 00:50:40 +0000 (08:50 +0800)
1  2 
message/classes/api.php
message/tests/api_test.php

@@@ -1798,74 -1758,83 +1798,154 @@@ class api 
              'userid' => $userid]);
      }
  
 +    /**
 +     * Checks if the sender can message the recipient.
 +     *
 +     * @param \stdClass $recipient The user object.
 +     * @param \stdClass $sender The user object.
 +     * @return bool true if recipient hasn't blocked sender and sender can contact to recipient, false otherwise.
 +     */
 +    protected static function can_contact_user(\stdClass $recipient, \stdClass $sender) : bool {
 +        if (has_capability('moodle/site:messageanyuser', \context_system::instance(), $sender->id)) {
 +            // The sender has the ability to contact any user across the entire site.
 +            return true;
 +        }
 +
 +        // The initial value of $cancontact is null to indicate that a value has not been determined.
 +        $cancontact = null;
 +
 +        if (self::is_blocked($recipient->id, $sender->id)) {
 +            // The recipient has specifically blocked this sender.
 +            $cancontact = false;
 +        }
 +
 +        $sharedcourses = null;
 +        if (null === $cancontact) {
 +            // There are three user preference options:
 +            // - Site: Allow anyone not explicitly blocked to contact me;
 +            // - Course members: Allow anyone I am in a course with to contact me; and
 +            // - Contacts: Only allow my contacts to contact me.
 +            //
 +            // The Site option is only possible when the messagingallusers site setting is also enabled.
 +
 +            $privacypreference = self::get_user_privacy_messaging_preference($recipient->id);
 +            if (self::MESSAGE_PRIVACY_SITE === $privacypreference) {
 +                // The user preference is to allow any user to contact them.
 +                // No need to check anything else.
 +                $cancontact = true;
 +            } else {
 +                // This user only allows their own contacts, and possibly course peers, to contact them.
 +                // If the users are contacts then we can avoid the more expensive shared courses check.
 +                $cancontact = self::is_contact($sender->id, $recipient->id);
 +
 +                if (!$cancontact && self::MESSAGE_PRIVACY_COURSEMEMBER === $privacypreference) {
 +                    // The users are not contacts and the user allows course member messaging.
 +                    // Check whether these two users share any course together.
 +                    $sharedcourses = enrol_get_shared_courses($recipient->id, $sender->id, true);
 +                    $cancontact = (!empty($sharedcourses));
 +                }
 +            }
 +        }
 +
 +        if (false === $cancontact) {
 +            // At the moment the users cannot contact one another.
 +            // Check whether the messageanyuser capability applies in any of the shared courses.
 +            // This is intended to allow teachers to message students regardless of message settings.
 +
 +            // Note: You cannot use empty($sharedcourses) here because this may be an empty array.
 +            if (null === $sharedcourses) {
 +                $sharedcourses = enrol_get_shared_courses($recipient->id, $sender->id, true);
 +            }
 +
 +            foreach ($sharedcourses as $course) {
 +                // Note: enrol_get_shared_courses will preload any shared context.
 +                if (has_capability('moodle/site:messageanyuser', \context_course::instance($course->id), $sender->id)) {
 +                    $cancontact = true;
 +                    break;
 +                }
 +            }
 +        }
 +
 +        return $cancontact;
 +    }
++
+     /**
+      * Add some new members to an existing conversation.
+      *
+      * @param array $userids User ids array to add as members.
+      * @param int $convid The conversation id. Must exists.
+      * @throws \dml_missing_record_exception If convid conversation doesn't exist
+      * @throws \dml_exception If there is a database error
+      * @throws \moodle_exception If trying to add a member(s) to a non-group conversation
+      */
+     public static function add_members_to_conversation(array $userids, int $convid) {
+         global $DB;
+         $conversation = $DB->get_record('message_conversations', ['id' => $convid], '*', MUST_EXIST);
+         // We can only add members to a group conversation.
+         if ($conversation->type != self::MESSAGE_CONVERSATION_TYPE_GROUP) {
+             throw new \moodle_exception('You can not add members to a non-group conversation.');
+         }
+         // Be sure we are not trying to add a non existing user to the conversation. Work only with existing users.
+         list($useridcondition, $params) = $DB->get_in_or_equal($userids, SQL_PARAMS_NAMED);
+         $existingusers = array_keys($DB->get_records_select_menu('user',
+             "id $useridcondition", $params, 'id', 'id, id'));
+         // Be sure we are not adding a user is already member of the conversation. Take all the members.
+         $memberuserids = array_values($DB->get_records_menu(
+             'message_conversation_members', ['conversationid' => $convid], 'id', 'id, userid')
+         );
+         // Work with existing new members.
+         $members = array();
+         $newuserids = array_diff($existingusers, $memberuserids);
+         foreach ($newuserids as $userid) {
+             $member = new \stdClass();
+             $member->conversationid = $convid;
+             $member->userid = $userid;
+             $member->timecreated = time();
+             $members[] = $member;
+         }
+         $DB->insert_records('message_conversation_members', $members);
+     }
+     /**
+      * Remove some members from an existing conversation.
+      *
+      * @param array $userids The user ids to remove from conversation members.
+      * @param int $convid The conversation id. Must exists.
+      * @throws \dml_exception
+      * @throws \moodle_exception If trying to remove a member(s) from a non-group conversation
+      */
+     public static function remove_members_from_conversation(array $userids, int $convid) {
+         global $DB;
+         $conversation = $DB->get_record('message_conversations', ['id' => $convid], '*', MUST_EXIST);
+         if ($conversation->type != self::MESSAGE_CONVERSATION_TYPE_GROUP) {
+             throw new \moodle_exception('You can not remove members from a non-group conversation.');
+         }
+         list($useridcondition, $params) = $DB->get_in_or_equal($userids, SQL_PARAMS_NAMED);
+         $params['convid'] = $convid;
+         $DB->delete_records_select('message_conversation_members',
+             "conversationid = :convid AND userid $useridcondition", $params);
+     }
+     /**
+      * Count conversation members.
+      *
+      * @param int $convid The conversation id.
+      * @return int Number of conversation members.
+      * @throws \dml_exception
+      */
+     public static function count_conversation_members(int $convid) : int {
+         global $DB;
+         return $DB->count_records('message_conversation_members', ['conversationid' => $convid]);
+     }
  }
Simple merge