Ejemplo n.º 1
0
 /**
  * Get popup notifications for the specified users. Nothing is returned if notifications are disabled.
  *
  * @param int $useridto the user id who received the notification
  * @param string $sort the column name to order by including optionally direction
  * @param int $limit limit the number of result returned
  * @param int $offset offset the result set by this amount
  * @return array notification records
  * @throws \moodle_exception
  * @since 3.2
  */
 public static function get_popup_notifications($useridto = 0, $sort = 'DESC', $limit = 0, $offset = 0)
 {
     global $DB, $USER;
     $sort = strtoupper($sort);
     if ($sort != 'DESC' && $sort != 'ASC') {
         throw new \moodle_exception('invalid parameter: sort: must be "DESC" or "ASC"');
     }
     if (empty($useridto)) {
         $useridto = $USER->id;
     }
     $params = ['useridto1' => $useridto, 'useridto2' => $useridto];
     // Is notification enabled ?
     if ($useridto == $USER->id) {
         $disabled = $USER->emailstop;
     } else {
         $user = \core_user::get_user($useridto, "emailstop", MUST_EXIST);
         $disabled = $user->emailstop;
     }
     if ($disabled) {
         // Notifications are disabled, no need to run giant queries.
         return array();
     }
     $sql = "SELECT * FROM (\n                    SELECT concat('r', r.id) as uniqueid, r.id, r.useridfrom, r.useridto,\n                        r.subject, r.fullmessage, r.fullmessageformat,\n                        r.fullmessagehtml, r.smallmessage, r.notification, r.contexturl,\n                        r.contexturlname, r.timecreated, r.timeuserfromdeleted, r.timeusertodeleted,\n                        r.component, r.eventtype, r.timeread\n                    FROM {message_read} r\n                    WHERE r.notification = 1\n                    AND r.id IN (SELECT messageid FROM {message_popup} WHERE isread = 1)\n                    AND r.useridto = :useridto1\n                UNION ALL\n                    SELECT concat('u', u.id) as uniqueid, u.id, u.useridfrom, u.useridto,\n                        u.subject, u.fullmessage, u.fullmessageformat,\n                        u.fullmessagehtml, u.smallmessage, u.notification, u.contexturl,\n                        u.contexturlname, u.timecreated, u.timeuserfromdeleted, u.timeusertodeleted,\n                        u.component, u.eventtype, 0 as timeread\n                    FROM {message} u\n                    WHERE u.notification = 1\n                    AND u.id IN (SELECT messageid FROM {message_popup} WHERE isread = 0)\n                    AND u.useridto = :useridto2\n                ) f ORDER BY timecreated {$sort}, timeread {$sort}, id {$sort}";
     return array_values($DB->get_records_sql($sql, $params, $offset, $limit));
 }
Ejemplo n.º 2
0
 public function export_for_template(\renderer_base $output)
 {
     $data = new \stdClass();
     $data->contacts = array();
     $userids = array();
     foreach ($this->contacts as $contact) {
         $contact = new contact($contact);
         $contactdata = $contact->export_for_template($output);
         $userids[$contactdata->userid] = $contactdata->userid;
         // Check if the contact was selected.
         if ($this->contactuserid == $contactdata->userid) {
             $contactdata->selected = true;
         }
         $data->contacts[] = $contactdata;
     }
     // Check if the other user is not part of the contacts. We may be sending a message to someone
     // we have not had a conversation with, so we want to add a new item to the contacts array.
     if ($this->contactuserid && !isset($userids[$this->contactuserid])) {
         $user = \core_user::get_user($this->contactuserid);
         // Set an empty message so that we know we are messaging the user, and not viewing their profile.
         $user->smallmessage = '';
         $user->useridfrom = $user->id;
         $contact = \core_message\helper::create_contact($user);
         $contact = new contact($contact);
         $contactdata = $contact->export_for_template($output);
         $contactdata->selected = true;
         // Put the contact at the front.
         array_unshift($data->contacts, $contactdata);
     }
     return $data;
 }
Ejemplo n.º 3
0
 /**
  * Generates the message object for a give subscription and event.
  *
  * @param int $subscriptionid Subscription instance
  * @param \stdClass $eventobj Event data
  *
  * @return false|\stdClass message object
  */
 protected function generate_message($subscriptionid, \stdClass $eventobj)
 {
     try {
         $subscription = subscription_manager::get_subscription($subscriptionid);
     } catch (\dml_exception $e) {
         // Race condition, someone deleted the subscription.
         return false;
     }
     $user = \core_user::get_user($subscription->userid);
     $context = \context_user::instance($user->id, IGNORE_MISSING);
     if ($context === false) {
         // User context doesn't exist. Should never happen, nothing to do return.
         return false;
     }
     $template = $subscription->template;
     $template = $this->replace_placeholders($template, $subscription, $eventobj, $context);
     $msgdata = new \stdClass();
     $msgdata->component = 'tool_monitor';
     // Your component name.
     $msgdata->name = 'notification';
     // This is the message name from messages.php.
     $msgdata->userfrom = \core_user::get_noreply_user();
     $msgdata->userto = $user;
     $msgdata->subject = $subscription->get_name($context);
     $msgdata->fullmessage = format_text($template, $subscription->templateformat, array('context' => $context));
     $msgdata->fullmessageformat = $subscription->templateformat;
     $msgdata->fullmessagehtml = format_text($template, $subscription->templateformat, array('context' => $context));
     $msgdata->smallmessage = '';
     $msgdata->notification = 1;
     // This is only set to 0 for personal messages between users.
     return $msgdata;
 }
Ejemplo n.º 4
0
 /**
  * Constructor.
  *
  * @param int $currentuserid The current user we are wanting to view messages for
  * @param int $otheruserid The other user we are wanting to view messages for
  * @param array $messages
  */
 public function __construct($currentuserid, $otheruserid, $messages)
 {
     $ufields = 'id, ' . get_all_user_name_fields(true) . ', lastaccess';
     $this->currentuserid = $currentuserid;
     if ($otheruserid) {
         $this->otheruserid = $otheruserid;
         $this->otheruser = \core_user::get_user($otheruserid, $ufields, MUST_EXIST);
     }
     $this->messages = $messages;
 }
Ejemplo n.º 5
0
/**
 * This function is used to generate and display the log activity graph
 *
 * @global stdClass $CFG
 * @param  stdClass $course course instance
 * @param  int|stdClass    $user id/object of the user whose logs are needed
 * @param  string $typeormode type of logs graph needed (usercourse.png/userday.png) or the mode (today, all).
 * @param  int $date timestamp in GMT (seconds since epoch)
 * @param  string $logreader Log reader.
 * @return void
 */
function report_log_print_graph($course, $user, $typeormode, $date = 0, $logreader = '')
{
    global $CFG, $OUTPUT;
    if (!is_object($user)) {
        $user = core_user::get_user($user);
    }
    $logmanager = get_log_manager();
    $readers = $logmanager->get_readers();
    if (empty($logreader)) {
        $reader = reset($readers);
    } else {
        $reader = $readers[$logreader];
    }
    // If reader is not a sql_internal_table_reader and not legacy store then don't show graph.
    if (!$reader instanceof \core\log\sql_internal_table_reader && !$reader instanceof logstore_legacy\log\store) {
        return array();
    }
    $coursecontext = context_course::instance($course->id);
    $a = new stdClass();
    $a->coursename = format_string($course->shortname, true, array('context' => $coursecontext));
    $a->username = fullname($user, true);
    if ($typeormode == 'today' || $typeormode == 'userday.png') {
        $logs = report_log_usertoday_data($course, $user, $date, $logreader);
        $title = get_string("hitsoncoursetoday", "", $a);
    } else {
        if ($typeormode == 'all' || $typeormode == 'usercourse.png') {
            $logs = report_log_userall_data($course, $user, $logreader);
            $title = get_string("hitsoncourse", "", $a);
        }
    }
    if (!empty($CFG->preferlinegraphs)) {
        $chart = new \core\chart_line();
    } else {
        $chart = new \core\chart_bar();
    }
    $series = new \core\chart_series(get_string("hits"), $logs['series']);
    $chart->add_series($series);
    $chart->set_title($title);
    $chart->set_labels($logs['labels']);
    $yaxis = $chart->get_yaxis(0, true);
    $yaxis->set_label(get_string("hits"));
    $yaxis->set_stepsize(max(1, round(max($logs['series']) / 10)));
    echo $OUTPUT->render($chart);
}
Ejemplo n.º 6
0
 /**
  * Returns the list of badges awarded to a user.
  *
  * @param int $userid       user id
  * @param int $courseid     course id
  * @param int $page         page of records to return
  * @param int $perpage      number of records to return per page
  * @param string  $search   a simple string to search for
  * @param bool $onlypublic  whether to return only public badges
  * @return array array containing warnings and the awarded badges
  * @since  Moodle 3.1
  * @throws moodle_exception
  */
 public static function get_user_badges($userid = 0, $courseid = 0, $page = 0, $perpage = 0, $search = '', $onlypublic = false)
 {
     global $CFG, $USER;
     $warnings = array();
     $params = array('userid' => $userid, 'courseid' => $courseid, 'page' => $page, 'perpage' => $perpage, 'search' => $search, 'onlypublic' => $onlypublic);
     $params = self::validate_parameters(self::get_user_badges_parameters(), $params);
     if (empty($CFG->enablebadges)) {
         throw new moodle_exception('badgesdisabled', 'badges');
     }
     if (empty($CFG->badges_allowcoursebadges) && $params['courseid'] != 0) {
         throw new moodle_exception('coursebadgesdisabled', 'badges');
     }
     // Default value for userid.
     if (empty($params['userid'])) {
         $params['userid'] = $USER->id;
     }
     // Validate the user.
     $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
     core_user::require_active_user($user);
     $usercontext = context_user::instance($user->id);
     self::validate_context($usercontext);
     if ($USER->id != $user->id) {
         require_capability('moodle/badges:viewotherbadges', $usercontext);
         // We are looking other user's badges, we must retrieve only public badges.
         $params['onlypublic'] = true;
     }
     $userbadges = badges_get_user_badges($user->id, $params['courseid'], $params['page'], $params['perpage'], $params['search'], $params['onlypublic']);
     $result = array();
     $result['badges'] = array();
     $result['warnings'] = $warnings;
     foreach ($userbadges as $badge) {
         $context = $badge->type == BADGE_TYPE_SITE ? context_system::instance() : context_course::instance($badge->courseid);
         $badge->badgeurl = moodle_url::make_webservice_pluginfile_url($context->id, 'badges', 'badgeimage', $badge->id, '/', 'f1')->out(false);
         // Return all the information if we are requesting our own badges.
         // Or, if we have permissions for configuring badges in the badge context.
         if ($USER->id == $user->id or has_capability('moodle/badges:configuredetails', $context)) {
             $result['badges'][] = (array) $badge;
         } else {
             $result['badges'][] = array('name' => $badge->name, 'description' => $badge->description, 'badgeurl' => $badge->badgeurl, 'issuername' => $badge->issuername, 'issuerurl' => $badge->issuerurl, 'issuercontact' => $badge->issuercontact, 'uniquehash' => $badge->uniquehash, 'dateissued' => $badge->dateissued, 'dateexpire' => $badge->dateexpire);
         }
     }
     return $result;
 }
Ejemplo n.º 7
0
 public function test_get_user()
 {
     global $CFG;
     $this->resetAfterTest(true);
     // Create user and try fetach it with api.
     $user = $this->getDataGenerator()->create_user();
     $this->assertEquals($user, core_user::get_user($user->id, '*', MUST_EXIST));
     // Test noreply user.
     $CFG->noreplyuserid = null;
     $noreplyuser = core_user::get_noreply_user();
     $this->assertEquals(1, $noreplyuser->emailstop);
     $this->assertFalse(core_user::is_real_user($noreplyuser->id));
     $this->assertEquals($CFG->noreplyaddress, $noreplyuser->email);
     $this->assertEquals(get_string('noreplyname'), $noreplyuser->firstname);
     // Set user as noreply user and make sure noreply propery is set.
     core_user::reset_internal_users();
     $CFG->noreplyuserid = $user->id;
     $noreplyuser = core_user::get_noreply_user();
     $this->assertEquals(1, $noreplyuser->emailstop);
     $this->assertTrue(core_user::is_real_user($noreplyuser->id));
     // Test support user.
     core_user::reset_internal_users();
     $CFG->supportemail = null;
     $CFG->noreplyuserid = null;
     $supportuser = core_user::get_support_user();
     $adminuser = get_admin();
     $this->assertEquals($adminuser, $supportuser);
     $this->assertTrue(core_user::is_real_user($supportuser->id));
     // When supportemail is set.
     core_user::reset_internal_users();
     $CFG->supportemail = '*****@*****.**';
     $supportuser = core_user::get_support_user();
     $this->assertEquals(core_user::SUPPORT_USER, $supportuser->id);
     $this->assertFalse(core_user::is_real_user($supportuser->id));
     // Set user as support user and make sure noreply propery is set.
     core_user::reset_internal_users();
     $CFG->supportuserid = $user->id;
     $supportuser = core_user::get_support_user();
     $this->assertEquals($user, $supportuser);
     $this->assertTrue(core_user::is_real_user($supportuser->id));
 }
Ejemplo n.º 8
0
 /**
  * Run the deletion task.
  *
  * @throws \coding_exception if the module could not be removed.
  */
 public function execute()
 {
     global $CFG;
     require_once $CFG->dirroot . '/course/lib.php';
     // Set the proper user.
     if ($this->get_custom_data()->userid !== $this->get_custom_data()->realuserid) {
         $realuser = \core_user::get_user($this->get_custom_data()->realuserid, '*', MUST_EXIST);
         cron_setup_user($realuser);
         \core\session\manager::loginas($this->get_custom_data()->userid, \context_system::instance(), false);
     } else {
         $user = \core_user::get_user($this->get_custom_data()->userid, '*', MUST_EXIST);
         cron_setup_user($user);
     }
     $cms = $this->get_custom_data()->cms;
     foreach ($cms as $cm) {
         try {
             course_delete_module($cm->id);
         } catch (\Exception $e) {
             throw new \coding_exception("The course module {$cm->id} could not be deleted. {$e->getTraceAsString()}");
         }
     }
 }
Ejemplo n.º 9
0
 /**
  * Whether the user can access the document or not.
  *
  * @param int $id The message instance id.
  * @return int
  */
 public function check_access($id)
 {
     global $CFG, $DB, $USER;
     if (!$CFG->messaging) {
         return \core_search\manager::ACCESS_DENIED;
     }
     $message = $DB->get_record('message_read', array('id' => $id));
     if (!$message) {
         return \core_search\manager::ACCESS_DELETED;
     }
     $userfrom = \core_user::get_user($message->useridfrom, 'id, deleted');
     $userto = \core_user::get_user($message->useridto, 'id, deleted');
     if (!$userfrom || !$userto || $userfrom->deleted || $userto->deleted) {
         return \core_search\manager::ACCESS_DELETED;
     }
     if ($USER->id != $userto->id) {
         return \core_search\manager::ACCESS_DENIED;
     }
     if ($message->timeusertodeleted != 0) {
         return \core_search\manager::ACCESS_DELETED;
     }
     return \core_search\manager::ACCESS_GRANTED;
 }
Ejemplo n.º 10
0
 /**
  * Returns information about an assignment submission status for a given user.
  *
  * @param int $assignid assignment instance id
  * @param int $userid user id (empty for current user)
  * @return array of warnings and grading, status, feedback and previous attempts information
  * @since Moodle 3.1
  * @throws required_capability_exception
  */
 public static function get_submission_status($assignid, $userid = 0)
 {
     global $USER;
     $warnings = array();
     $params = array('assignid' => $assignid, 'userid' => $userid);
     $params = self::validate_parameters(self::get_submission_status_parameters(), $params);
     list($assign, $course, $cm, $context) = self::validate_assign($params['assignid']);
     // Default value for userid.
     if (empty($params['userid'])) {
         $params['userid'] = $USER->id;
     }
     $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
     core_user::require_active_user($user);
     if (!$assign->can_view_submission($user->id)) {
         throw new required_capability_exception($context, 'mod/assign:viewgrades', 'nopermission', '');
     }
     $gradingsummary = $lastattempt = $feedback = $previousattempts = null;
     // Get the renderable since it contais all the info we need.
     if ($assign->can_view_grades()) {
         $gradingsummary = $assign->get_assign_grading_summary_renderable();
     }
     // Retrieve the rest of the renderable objects.
     if (has_capability('mod/assign:submit', $assign->get_context(), $user)) {
         $lastattempt = $assign->get_assign_submission_status_renderable($user, true);
     }
     $feedback = $assign->get_assign_feedback_status_renderable($user);
     $previousattempts = $assign->get_assign_attempt_history_renderable($user);
     // Now, build the result.
     $result = array();
     // First of all, grading summary, this is suitable for teachers/managers.
     if ($gradingsummary) {
         $result['gradingsummary'] = $gradingsummary;
     }
     // Did we submit anything?
     if ($lastattempt) {
         $submissionplugins = $assign->get_submission_plugins();
         if (empty($lastattempt->submission)) {
             unset($lastattempt->submission);
         } else {
             $lastattempt->submission->plugins = self::get_plugins_data($assign, $submissionplugins, $lastattempt->submission);
         }
         if (empty($lastattempt->teamsubmission)) {
             unset($lastattempt->teamsubmission);
         } else {
             $lastattempt->teamsubmission->plugins = self::get_plugins_data($assign, $submissionplugins, $lastattempt->teamsubmission);
         }
         // We need to change the type of some of the structures retrieved from the renderable.
         if (!empty($lastattempt->submissiongroup)) {
             $lastattempt->submissiongroup = $lastattempt->submissiongroup->id;
         } else {
             unset($lastattempt->submissiongroup);
         }
         if (!empty($lastattempt->usergroups)) {
             $lastattempt->usergroups = array_keys($lastattempt->usergroups);
         }
         // We cannot use array_keys here.
         if (!empty($lastattempt->submissiongroupmemberswhoneedtosubmit)) {
             $lastattempt->submissiongroupmemberswhoneedtosubmit = array_map(function ($e) {
                 return $e->id;
             }, $lastattempt->submissiongroupmemberswhoneedtosubmit);
         }
         $result['lastattempt'] = $lastattempt;
     }
     // The feedback for our latest submission.
     if ($feedback) {
         if ($feedback->grade) {
             $feedbackplugins = $assign->get_feedback_plugins();
             $feedback->plugins = self::get_plugins_data($assign, $feedbackplugins, $feedback->grade);
         } else {
             unset($feedback->plugins);
             unset($feedback->grade);
         }
         $result['feedback'] = $feedback;
     }
     // Retrieve only previous attempts.
     if ($previousattempts and count($previousattempts->submissions) > 1) {
         // Don't show the last one because it is the current submission.
         array_pop($previousattempts->submissions);
         // Show newest to oldest.
         $previousattempts->submissions = array_reverse($previousattempts->submissions);
         foreach ($previousattempts->submissions as $i => $submission) {
             $attempt = array();
             $grade = null;
             foreach ($previousattempts->grades as $onegrade) {
                 if ($onegrade->attemptnumber == $submission->attemptnumber) {
                     $grade = $onegrade;
                     break;
                 }
             }
             $attempt['attemptnumber'] = $submission->attemptnumber;
             if ($submission) {
                 $submission->plugins = self::get_plugins_data($assign, $previousattempts->submissionplugins, $submission);
                 $attempt['submission'] = $submission;
             }
             if ($grade) {
                 // From object to id.
                 $grade->grader = $grade->grader->id;
                 $feedbackplugins = self::get_plugins_data($assign, $previousattempts->feedbackplugins, $grade);
                 $attempt['grade'] = $grade;
                 $attempt['feedbackplugins'] = $feedbackplugins;
             }
             $result['previousattempts'][] = $attempt;
         }
     }
     $result['warnings'] = $warnings;
     return $result;
 }
Ejemplo n.º 11
0
 /**
  * Trigger the user report events, do the same that the web interface view of the report
  *
  * @param int $courseid id of course
  * @param int $userid id of the user the report belongs to
  * @return array of warnings and status result
  * @since Moodle 2.9
  * @throws moodle_exception
  */
 public static function view_grade_report($courseid, $userid = 0)
 {
     global $CFG, $USER;
     require_once $CFG->dirroot . "/grade/lib.php";
     require_once $CFG->dirroot . "/grade/report/user/lib.php";
     $params = self::validate_parameters(self::view_grade_report_parameters(), array('courseid' => $courseid, 'userid' => $userid));
     $warnings = array();
     $course = get_course($params['courseid']);
     $context = context_course::instance($course->id);
     self::validate_context($context);
     $userid = $params['userid'];
     if (empty($userid)) {
         $userid = $USER->id;
     } else {
         $user = core_user::get_user($userid, '*', MUST_EXIST);
         core_user::require_active_user($user);
     }
     $access = false;
     if (has_capability('moodle/grade:viewall', $context)) {
         // Can view all course grades (any user).
         $access = true;
     } else {
         if ($userid == $USER->id and has_capability('moodle/grade:view', $context) and $course->showgrades) {
             // View own grades.
             $access = true;
         }
     }
     if (!$access) {
         throw new moodle_exception('nopermissiontoviewgrades', 'error');
     }
     // Create a report instance. We don't need the gpr second parameter.
     $report = new grade_report_user($course->id, null, $context, $userid);
     $report->viewed();
     $result = array();
     $result['status'] = true;
     $result['warnings'] = $warnings;
     return $result;
 }
Ejemplo n.º 12
0
/**
 * Called when a message provider wants to send a message.
 * This functions checks the message recipient's message processor configuration then
 * sends the message to the configured processors
 *
 * Required parameters of the $eventdata object:
 *  component string component name. must exist in message_providers
 *  name string message type name. must exist in message_providers
 *  userfrom object|int the user sending the message
 *  userto object|int the message recipient
 *  subject string the message subject
 *  fullmessage string the full message in a given format
 *  fullmessageformat int the format if the full message (FORMAT_MOODLE, FORMAT_HTML, ..)
 *  fullmessagehtml string the full version (the message processor will choose with one to use)
 *  smallmessage string the small version of the message
 *
 * Optional parameters of the $eventdata object:
 *  notification bool should the message be considered as a notification rather than a personal message
 *  contexturl string if this is a notification then you can specify a url to view the event. For example the forum post the user is being notified of.
 *  contexturlname string the display text for contexturl
 *
 * @category message
 * @param object $eventdata information about the message (component, userfrom, userto, ...)
 * @return mixed the integer ID of the new message or false if there was a problem with a processor
 */
function message_send($eventdata)
{
    global $CFG, $DB;
    //new message ID to return
    $messageid = false;
    // Fetch default (site) preferences
    $defaultpreferences = get_message_output_default_preferences();
    $preferencebase = $eventdata->component . '_' . $eventdata->name;
    // If message provider is disabled then don't do any processing.
    if (!empty($defaultpreferences->{$preferencebase . '_disable'})) {
        return $messageid;
    }
    //TODO: we need to solve problems with database transactions here somehow, for now we just prevent transactions - sorry
    $DB->transactions_forbidden();
    // By default a message is a notification. Only personal/private messages aren't notifications.
    if (!isset($eventdata->notification)) {
        $eventdata->notification = 1;
    }
    if (is_number($eventdata->userto)) {
        $eventdata->userto = core_user::get_user($eventdata->userto);
    }
    if (is_int($eventdata->userfrom)) {
        $eventdata->userfrom = core_user::get_user($eventdata->userfrom);
    }
    $usertoisrealuser = core_user::is_real_user($eventdata->userto->id) != false;
    // If recipient is internal user (noreply user), and emailstop is set then don't send any msg.
    if (!$usertoisrealuser && !empty($eventdata->userto->emailstop)) {
        debugging('Attempt to send msg to internal (noreply) user', DEBUG_NORMAL);
        return false;
    }
    if (!isset($eventdata->userto->auth) or !isset($eventdata->userto->suspended) or !isset($eventdata->userto->deleted)) {
        $eventdata->userto = core_user::get_user($eventdata->userto->id);
    }
    //after how long inactive should the user be considered logged off?
    if (isset($CFG->block_online_users_timetosee)) {
        $timetoshowusers = $CFG->block_online_users_timetosee * 60;
    } else {
        $timetoshowusers = 300;
        //5 minutes
    }
    // Work out if the user is logged in or not
    if (!empty($eventdata->userto->lastaccess) && time() - $timetoshowusers < $eventdata->userto->lastaccess) {
        $userstate = 'loggedin';
    } else {
        $userstate = 'loggedoff';
    }
    // Create the message object
    $savemessage = new stdClass();
    $savemessage->useridfrom = $eventdata->userfrom->id;
    $savemessage->useridto = $eventdata->userto->id;
    $savemessage->subject = $eventdata->subject;
    $savemessage->fullmessage = $eventdata->fullmessage;
    $savemessage->fullmessageformat = $eventdata->fullmessageformat;
    $savemessage->fullmessagehtml = $eventdata->fullmessagehtml;
    $savemessage->smallmessage = $eventdata->smallmessage;
    $savemessage->notification = $eventdata->notification;
    if (!empty($eventdata->contexturl)) {
        $savemessage->contexturl = $eventdata->contexturl;
    } else {
        $savemessage->contexturl = null;
    }
    if (!empty($eventdata->contexturlname)) {
        $savemessage->contexturlname = $eventdata->contexturlname;
    } else {
        $savemessage->contexturlname = null;
    }
    $savemessage->timecreated = time();
    if (PHPUNIT_TEST and class_exists('phpunit_util')) {
        // Add some more tests to make sure the normal code can actually work.
        $componentdir = core_component::get_component_directory($eventdata->component);
        if (!$componentdir or !is_dir($componentdir)) {
            throw new coding_exception('Invalid component specified in message-send(): ' . $eventdata->component);
        }
        if (!file_exists("{$componentdir}/db/messages.php")) {
            throw new coding_exception("{$eventdata->component} does not contain db/messages.php necessary for message_send()");
        }
        $messageproviders = null;
        include "{$componentdir}/db/messages.php";
        if (!isset($messageproviders[$eventdata->name])) {
            throw new coding_exception("Missing messaging defaults for event '{$eventdata->name}' in '{$eventdata->component}' messages.php file");
        }
        unset($componentdir);
        unset($messageproviders);
        // Now ask phpunit if it wants to catch this message.
        if (phpunit_util::is_redirecting_messages()) {
            $savemessage->timeread = time();
            $messageid = $DB->insert_record('message_read', $savemessage);
            $message = $DB->get_record('message_read', array('id' => $messageid));
            phpunit_util::message_sent($message);
            return $messageid;
        }
    }
    // Fetch enabled processors
    $processors = get_message_processors(true);
    // Preset variables
    $processorlist = array();
    // Fill in the array of processors to be used based on default and user preferences
    foreach ($processors as $processor) {
        // Skip adding processors for internal user, if processor doesn't support sending message to internal user.
        if (!$usertoisrealuser && !$processor->object->can_send_to_any_users()) {
            continue;
        }
        // First find out permissions
        $defaultpreference = $processor->name . '_provider_' . $preferencebase . '_permitted';
        if (isset($defaultpreferences->{$defaultpreference})) {
            $permitted = $defaultpreferences->{$defaultpreference};
        } else {
            // MDL-25114 They supplied an $eventdata->component $eventdata->name combination which doesn't
            // exist in the message_provider table (thus there is no default settings for them).
            $preferrormsg = "Could not load preference {$defaultpreference}. Make sure the component and name you supplied\n                    to message_send() are valid.";
            throw new coding_exception($preferrormsg);
        }
        // Find out if user has configured this output
        // Some processors cannot function without settings from the user
        $userisconfigured = $processor->object->is_user_configured($eventdata->userto);
        // DEBUG: notify if we are forcing unconfigured output
        if ($permitted == 'forced' && !$userisconfigured) {
            debugging('Attempt to force message delivery to user who has "' . $processor->name . '" output unconfigured', DEBUG_NORMAL);
        }
        // Warn developers that necessary data is missing regardless of how the processors are configured
        if (!isset($eventdata->userto->emailstop)) {
            debugging('userto->emailstop is not set. Retrieving it from the user table');
            $eventdata->userto->emailstop = $DB->get_field('user', 'emailstop', array('id' => $eventdata->userto->id));
        }
        // Populate the list of processors we will be using
        if ($permitted == 'forced' && $userisconfigured) {
            // An admin is forcing users to use this message processor. Use this processor unconditionally.
            $processorlist[] = $processor->name;
        } else {
            if ($permitted == 'permitted' && $userisconfigured && !$eventdata->userto->emailstop) {
                // User has not disabled notifications
                // See if user set any notification preferences, otherwise use site default ones
                $userpreferencename = 'message_provider_' . $preferencebase . '_' . $userstate;
                if ($userpreference = get_user_preferences($userpreferencename, null, $eventdata->userto->id)) {
                    if (in_array($processor->name, explode(',', $userpreference))) {
                        $processorlist[] = $processor->name;
                    }
                } else {
                    if (isset($defaultpreferences->{$userpreferencename})) {
                        if (in_array($processor->name, explode(',', $defaultpreferences->{$userpreferencename}))) {
                            $processorlist[] = $processor->name;
                        }
                    }
                }
            }
        }
    }
    if (empty($processorlist) && $savemessage->notification) {
        //if they have deselected all processors and its a notification mark it read. The user doesnt want to be bothered
        $savemessage->timeread = time();
        $messageid = $DB->insert_record('message_read', $savemessage);
    } else {
        // Process the message
        // Store unread message just in case we can not send it
        $messageid = $savemessage->id = $DB->insert_record('message', $savemessage);
        $eventdata->savedmessageid = $savemessage->id;
        // Try to deliver the message to each processor
        if (!empty($processorlist)) {
            foreach ($processorlist as $procname) {
                if (!$processors[$procname]->object->send_message($eventdata)) {
                    debugging('Error calling message processor ' . $procname);
                    $messageid = false;
                }
            }
            //if messaging is disabled and they previously had forum notifications handled by the popup processor
            //or any processor that puts a row in message_working then the notification will remain forever
            //unread. To prevent this mark the message read if messaging is disabled
            if (empty($CFG->messaging)) {
                require_once $CFG->dirroot . '/message/lib.php';
                $messageid = message_mark_message_read($savemessage, time());
            } else {
                if ($DB->count_records('message_working', array('unreadmessageid' => $savemessage->id)) == 0) {
                    //if there is no more processors that want to process this we can move message to message_read
                    require_once $CFG->dirroot . '/message/lib.php';
                    $messageid = message_mark_message_read($savemessage, time(), true);
                }
            }
        }
    }
    // We may be sending a message from the 'noreply' address, which means we are not actually sending a
    // message from a valid user. In this case, we will set the userid to 0.
    // Check if the userid is valid.
    if (core_user::is_real_user($eventdata->userfrom->id)) {
        $userfromid = $eventdata->userfrom->id;
    } else {
        $userfromid = 0;
    }
    // Trigger event for sending a message.
    $event = \core\event\message_sent::create(array('userid' => $userfromid, 'context' => context_system::instance(), 'relateduserid' => $eventdata->userto->id, 'other' => array('messageid' => $messageid)));
    $event->trigger();
    return $messageid;
}
Ejemplo n.º 13
0
 /**
  * Get Course completion status
  *
  * @param int $courseid ID of the Course
  * @param int $userid ID of the User
  * @return array of course completion status and warnings
  * @since Moodle 2.9
  * @throws moodle_exception
  */
 public static function get_course_completion_status($courseid, $userid)
 {
     global $CFG, $USER;
     require_once $CFG->libdir . '/grouplib.php';
     $warnings = array();
     $arrayparams = array('courseid' => $courseid, 'userid' => $userid);
     $params = self::validate_parameters(self::get_course_completion_status_parameters(), $arrayparams);
     $course = get_course($params['courseid']);
     $user = core_user::get_user($params['userid'], 'id', MUST_EXIST);
     $context = context_course::instance($course->id);
     self::validate_context($context);
     // Can current user see user's course completion status?
     // This check verifies if completion is enabled because $course is mandatory.
     if (!completion_can_view_data($user->id, $course)) {
         throw new moodle_exception('cannotviewreport');
     }
     // The previous function doesn't check groups.
     if ($user->id != $USER->id) {
         if (!groups_user_groups_visible($course, $user->id)) {
             // We are not in the same group!
             throw new moodle_exception('accessdenied', 'admin');
         }
     }
     $info = new completion_info($course);
     // Check this user is enroled.
     if (!$info->is_tracked_user($user->id)) {
         if ($USER->id == $user->id) {
             throw new moodle_exception('notenroled', 'completion');
         } else {
             throw new moodle_exception('usernotenroled', 'completion');
         }
     }
     $completions = $info->get_completions($user->id);
     if (empty($completions)) {
         throw new moodle_exception('nocriteriaset', 'completion');
     }
     // Load course completion.
     $completionparams = array('userid' => $user->id, 'course' => $course->id);
     $ccompletion = new completion_completion($completionparams);
     $completionrows = array();
     // Loop through course criteria.
     foreach ($completions as $completion) {
         $criteria = $completion->get_criteria();
         $completionrow = array();
         $completionrow['type'] = $criteria->criteriatype;
         $completionrow['title'] = $criteria->get_title();
         $completionrow['status'] = $completion->get_status();
         $completionrow['complete'] = $completion->is_complete();
         $completionrow['timecompleted'] = $completion->timecompleted;
         $completionrow['details'] = $criteria->get_details($completion);
         $completionrows[] = $completionrow;
     }
     $result = array('completed' => $info->is_course_complete($user->id), 'aggregation' => $info->get_aggregation_method(), 'completions' => $completionrows);
     $results = array('completionstatus' => $result, 'warnings' => $warnings);
     return $results;
 }
Ejemplo n.º 14
0
 /**
  * Retrieves SCO tracking data for the given user id and attempt number
  *
  * @param int $scoid the sco id
  * @param int $userid the user id
  * @param int $attempt the attempt number
  * @return array warnings and the scoes data
  * @since Moodle 3.0
  */
 public static function get_scorm_sco_tracks($scoid, $userid, $attempt = 0)
 {
     global $USER, $DB;
     $params = self::validate_parameters(self::get_scorm_sco_tracks_parameters(), array('scoid' => $scoid, 'userid' => $userid, 'attempt' => $attempt));
     $tracks = array();
     $warnings = array();
     $sco = scorm_get_sco($params['scoid'], SCO_ONLY);
     if (!$sco) {
         throw new moodle_exception('cannotfindsco', 'scorm');
     }
     $scorm = $DB->get_record('scorm', array('id' => $sco->scorm), '*', MUST_EXIST);
     $cm = get_coursemodule_from_instance('scorm', $scorm->id);
     $context = context_module::instance($cm->id);
     self::validate_context($context);
     $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
     core_user::require_active_user($user);
     // Extra checks so only users with permissions can view other users attempts.
     if ($USER->id != $user->id) {
         require_capability('mod/scorm:viewreport', $context);
     }
     scorm_require_available($scorm, true, $context);
     if (empty($params['attempt'])) {
         $params['attempt'] = scorm_get_last_attempt($scorm->id, $user->id);
     }
     $attempted = false;
     if ($scormtracks = scorm_get_tracks($sco->id, $params['userid'], $params['attempt'])) {
         // Check if attempted.
         if ($scormtracks->status != '') {
             $attempted = true;
             foreach ($scormtracks as $element => $value) {
                 $tracks[] = array('element' => $element, 'value' => $value);
             }
         }
     }
     if (!$attempted) {
         $warnings[] = array('item' => 'attempt', 'itemid' => $params['attempt'], 'warningcode' => 'notattempted', 'message' => get_string('notattempted', 'scorm'));
     }
     $result = array();
     $result['data']['attempt'] = $params['attempt'];
     $result['data']['tracks'] = $tracks;
     $result['warnings'] = $warnings;
     return $result;
 }
Ejemplo n.º 15
0
 /**
  * Return selected user fullname.
  *
  * @return string user fullname.
  */
 public function get_selected_user_fullname()
 {
     $user = core_user::get_user($this->userid);
     return fullname($user);
 }
Ejemplo n.º 16
0
/**
 * Called when a message provider wants to send a message.
 * This functions checks the message recipient's message processor configuration then
 * sends the message to the configured processors
 *
 * Required parameters of the $eventdata object:
 *  component string component name. must exist in message_providers
 *  name string message type name. must exist in message_providers
 *  userfrom object|int the user sending the message
 *  userto object|int the message recipient
 *  subject string the message subject
 *  fullmessage string the full message in a given format
 *  fullmessageformat int the format if the full message (FORMAT_MOODLE, FORMAT_HTML, ..)
 *  fullmessagehtml string the full version (the message processor will choose with one to use)
 *  smallmessage string the small version of the message
 *
 * Optional parameters of the $eventdata object:
 *  notification bool should the message be considered as a notification rather than a personal message
 *  contexturl string if this is a notification then you can specify a url to view the event. For example the forum post the user is being notified of.
 *  contexturlname string the display text for contexturl
 *
 * Note: processor failure is is not reported as false return value,
 *       earlier versions did not do it consistently either.
 *
 * @todo MDL-55449 Drop support for stdClass in Moodle 3.6
 * @category message
 * @param \core\message\message $eventdata information about the message (component, userfrom, userto, ...)
 * @return mixed the integer ID of the new message or false if there was a problem with submitted data
 */
function message_send($eventdata) {
    global $CFG, $DB;

    // TODO MDL-55449 Drop support for stdClass in Moodle 3.6.
    if ($eventdata instanceof \stdClass) {
        if (!isset($eventdata->courseid)) {
            $eventdata->courseid = null;
        }

        debugging('eventdata as \stdClass is deprecated. Please use core\message\message instead.', DEBUG_DEVELOPER);
    }

    //new message ID to return
    $messageid = false;

    // Fetch default (site) preferences
    $defaultpreferences = get_message_output_default_preferences();
    $preferencebase = $eventdata->component.'_'.$eventdata->name;
    // If message provider is disabled then don't do any processing.
    if (!empty($defaultpreferences->{$preferencebase.'_disable'})) {
        return $messageid;
    }

    // By default a message is a notification. Only personal/private messages aren't notifications.
    if (!isset($eventdata->notification)) {
        $eventdata->notification = 1;
    }

    if (!is_object($eventdata->userto)) {
        $eventdata->userto = core_user::get_user($eventdata->userto);
    }
    if (!is_object($eventdata->userfrom)) {
        $eventdata->userfrom = core_user::get_user($eventdata->userfrom);
    }
    if (!$eventdata->userto) {
        debugging('Attempt to send msg to unknown user', DEBUG_NORMAL);
        return false;
    }
    if (!$eventdata->userfrom) {
        debugging('Attempt to send msg from unknown user', DEBUG_NORMAL);
        return false;
    }

    // Verify all necessary data fields are present.
    if (!isset($eventdata->userto->auth) or !isset($eventdata->userto->suspended)
            or !isset($eventdata->userto->deleted) or !isset($eventdata->userto->emailstop)) {

        debugging('Necessary properties missing in userto object, fetching full record', DEBUG_DEVELOPER);
        $eventdata->userto = core_user::get_user($eventdata->userto->id);
    }

    $usertoisrealuser = (core_user::is_real_user($eventdata->userto->id) != false);
    // If recipient is internal user (noreply user), and emailstop is set then don't send any msg.
    if (!$usertoisrealuser && !empty($eventdata->userto->emailstop)) {
        debugging('Attempt to send msg to internal (noreply) user', DEBUG_NORMAL);
        return false;
    }

    //after how long inactive should the user be considered logged off?
    if (isset($CFG->block_online_users_timetosee)) {
        $timetoshowusers = $CFG->block_online_users_timetosee * 60;
    } else {
        $timetoshowusers = 300;//5 minutes
    }

    // Work out if the user is logged in or not
    if (!empty($eventdata->userto->lastaccess) && (time()-$timetoshowusers) < $eventdata->userto->lastaccess) {
        $userstate = 'loggedin';
    } else {
        $userstate = 'loggedoff';
    }

    // Create the message object
    $savemessage = new stdClass();
    $savemessage->courseid          = $eventdata->courseid;
    $savemessage->useridfrom        = $eventdata->userfrom->id;
    $savemessage->useridto          = $eventdata->userto->id;
    $savemessage->subject           = $eventdata->subject;
    $savemessage->fullmessage       = $eventdata->fullmessage;
    $savemessage->fullmessageformat = $eventdata->fullmessageformat;
    $savemessage->fullmessagehtml   = $eventdata->fullmessagehtml;
    $savemessage->smallmessage      = $eventdata->smallmessage;
    $savemessage->notification      = $eventdata->notification;
    $savemessage->eventtype         = $eventdata->name;
    $savemessage->component         = $eventdata->component;

    if (!empty($eventdata->contexturl)) {
        $savemessage->contexturl = (string)$eventdata->contexturl;
    } else {
        $savemessage->contexturl = null;
    }

    if (!empty($eventdata->contexturlname)) {
        $savemessage->contexturlname = (string)$eventdata->contexturlname;
    } else {
        $savemessage->contexturlname = null;
    }

    $savemessage->timecreated = time();

    if (PHPUNIT_TEST and class_exists('phpunit_util')) {
        // Add some more tests to make sure the normal code can actually work.
        $componentdir = core_component::get_component_directory($eventdata->component);
        if (!$componentdir or !is_dir($componentdir)) {
            throw new coding_exception('Invalid component specified in message-send(): '.$eventdata->component);
        }
        if (!file_exists("$componentdir/db/messages.php")) {
            throw new coding_exception("$eventdata->component does not contain db/messages.php necessary for message_send()");
        }
        $messageproviders = null;
        include("$componentdir/db/messages.php");
        if (!isset($messageproviders[$eventdata->name])) {
            throw new coding_exception("Missing messaging defaults for event '$eventdata->name' in '$eventdata->component' messages.php file");
        }
        unset($componentdir);
        unset($messageproviders);
        // Now ask phpunit if it wants to catch this message.
        if (phpunit_util::is_redirecting_messages()) {
            $savemessage->timeread = time();
            $messageid = $DB->insert_record('message_read', $savemessage);
            $message = $DB->get_record('message_read', array('id'=>$messageid));
            phpunit_util::message_sent($message);
            return $messageid;
        }
    }

    // Fetch enabled processors
    $processors = get_message_processors(true);

    // Preset variables
    $processorlist = array();
    // Fill in the array of processors to be used based on default and user preferences
    foreach ($processors as $processor) {
        // Skip adding processors for internal user, if processor doesn't support sending message to internal user.
        if (!$usertoisrealuser && !$processor->object->can_send_to_any_users()) {
            continue;
        }

        // First find out permissions
        $defaultpreference = $processor->name.'_provider_'.$preferencebase.'_permitted';
        if (isset($defaultpreferences->{$defaultpreference})) {
            $permitted = $defaultpreferences->{$defaultpreference};
        } else {
            // MDL-25114 They supplied an $eventdata->component $eventdata->name combination which doesn't
            // exist in the message_provider table (thus there is no default settings for them).
            $preferrormsg = "Could not load preference $defaultpreference. Make sure the component and name you supplied
                    to message_send() are valid.";
            throw new coding_exception($preferrormsg);
        }

        // Find out if user has configured this output
        // Some processors cannot function without settings from the user
        $userisconfigured = $processor->object->is_user_configured($eventdata->userto);

        // DEBUG: notify if we are forcing unconfigured output
        if ($permitted == 'forced' && !$userisconfigured) {
            debugging('Attempt to force message delivery to user who has "'.$processor->name.'" output unconfigured', DEBUG_NORMAL);
        }

        // Populate the list of processors we will be using
        if ($permitted == 'forced' && $userisconfigured) {
            // An admin is forcing users to use this message processor. Use this processor unconditionally.
            $processorlist[] = $processor->name;
        } else if ($permitted == 'permitted' && $userisconfigured && !$eventdata->userto->emailstop) {
            // User has not disabled notifications
            // See if user set any notification preferences, otherwise use site default ones
            $userpreferencename = 'message_provider_'.$preferencebase.'_'.$userstate;
            if ($userpreference = get_user_preferences($userpreferencename, null, $eventdata->userto)) {
                if (in_array($processor->name, explode(',', $userpreference))) {
                    $processorlist[] = $processor->name;
                }
            } else if (isset($defaultpreferences->{$userpreferencename})) {
                if (in_array($processor->name, explode(',', $defaultpreferences->{$userpreferencename}))) {
                    $processorlist[] = $processor->name;
                }
            }
        }
    }

    // Only cache messages, not notifications.
    if (empty($savemessage->notification)) {
        // Cache the timecreated value of the last message between these two users.
        $cache = cache::make('core', 'message_time_last_message_between_users');
        $key = \core_message\helper::get_last_message_time_created_cache_key($savemessage->useridfrom,
            $savemessage->useridto);
        $cache->set($key, $savemessage->timecreated);
    }

    // Store unread message just in case we get a fatal error any time later.
    $savemessage->id = $DB->insert_record('message', $savemessage);
    $eventdata->savedmessageid = $savemessage->id;

    // Let the manager do the sending or buffering when db transaction in progress.
    return \core\message\manager::send_message($eventdata, $savemessage, $processorlist);
}
Ejemplo n.º 17
0
 /**
  * Deletes a message
  *
  * @param  int $messageid the message id
  * @param  int $userid the user id of who we want to delete the message for
  * @param  bool $read if is a message read (default to true)
  * @return external_description
  * @throws moodle_exception
  * @since 3.1
  */
 public static function delete_message($messageid, $userid, $read = true)
 {
     global $CFG, $DB;
     // Check if private messaging between users is allowed.
     if (empty($CFG->messaging)) {
         throw new moodle_exception('disabled', 'message');
     }
     // Warnings array, it can be empty at the end but is mandatory.
     $warnings = array();
     // Validate params.
     $params = array('messageid' => $messageid, 'userid' => $userid, 'read' => $read);
     $params = self::validate_parameters(self::delete_message_parameters(), $params);
     // Validate context.
     $context = context_system::instance();
     self::validate_context($context);
     $messagestable = $params['read'] ? 'message_read' : 'message';
     $message = $DB->get_record($messagestable, array('id' => $params['messageid']), '*', MUST_EXIST);
     $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
     core_user::require_active_user($user);
     $status = false;
     if (message_can_delete_message($message, $user->id)) {
         $status = message_delete_message($message, $user->id);
     } else {
         throw new moodle_exception('You do not have permission to delete this message');
     }
     $results = array('status' => $status, 'warnings' => $warnings);
     return $results;
 }
Ejemplo n.º 18
0
 /**
  * Simulate the /user/index.php and /user/profile.php web interface page triggering events
  *
  * @param int $userid id of user
  * @param int $courseid id of course
  * @return array of warnings and status result
  * @since Moodle 2.9
  * @throws moodle_exception
  */
 public static function view_user_profile($userid, $courseid = 0)
 {
     global $CFG, $USER;
     require_once $CFG->dirroot . "/user/profile/lib.php";
     $params = self::validate_parameters(self::view_user_profile_parameters(), array('userid' => $userid, 'courseid' => $courseid));
     $warnings = array();
     if (empty($params['userid'])) {
         $params['userid'] = $USER->id;
     }
     if (empty($params['courseid'])) {
         $params['courseid'] = SITEID;
     }
     $course = get_course($params['courseid']);
     $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
     if ($user->deleted) {
         throw new moodle_exception('userdeleted');
     }
     if (isguestuser($user)) {
         // Can not view profile of guest - thre is nothing to see there.
         throw new moodle_exception('invaliduserid');
     }
     if ($course->id == SITEID) {
         $coursecontext = context_system::instance();
     } else {
         $coursecontext = context_course::instance($course->id);
     }
     self::validate_context($coursecontext);
     $currentuser = $USER->id == $user->id;
     $usercontext = context_user::instance($user->id);
     if (!$currentuser and !has_capability('moodle/user:viewdetails', $coursecontext) and !has_capability('moodle/user:viewdetails', $usercontext)) {
         throw new moodle_exception('cannotviewprofile');
     }
     // Case like user/profile.php.
     if ($course->id == SITEID) {
         profile_view($user, $usercontext);
     } else {
         // Case like user/view.php.
         if (!$currentuser and !can_access_course($course, $user, '', true)) {
             throw new moodle_exception('notenrolledprofile');
         }
         profile_view($user, $coursecontext, $course);
     }
     $result = array();
     $result['status'] = true;
     $result['warnings'] = $warnings;
     return $result;
 }
Ejemplo n.º 19
0
 /**
  * Gets a list of groups that the user is allowed to access within the specified activity.
  *
  * @throws moodle_exception
  * @param int $cmid course module id
  * @param int $userid id of user.
  * @return array of group objects (id, name, description, format) and possible warnings.
  * @since Moodle 3.0
  */
 public static function get_activity_allowed_groups($cmid, $userid = 0)
 {
     global $USER;
     // Warnings array, it can be empty at the end but is mandatory.
     $warnings = array();
     $params = array('cmid' => $cmid, 'userid' => $userid);
     $params = self::validate_parameters(self::get_activity_allowed_groups_parameters(), $params);
     $cmid = $params['cmid'];
     $userid = $params['userid'];
     $cm = get_coursemodule_from_id(null, $cmid, 0, false, MUST_EXIST);
     // Security checks.
     $context = context_module::instance($cm->id);
     $coursecontext = context_course::instance($cm->course);
     self::validate_context($context);
     if (empty($userid)) {
         $userid = $USER->id;
     }
     $user = core_user::get_user($userid, '*', MUST_EXIST);
     core_user::require_active_user($user);
     // Check if we have permissions for retrieve the information.
     if ($user->id != $USER->id) {
         if (!has_capability('moodle/course:managegroups', $context)) {
             throw new moodle_exception('accessdenied', 'admin');
         }
         // Validate if the user is enrolled in the course.
         $course = get_course($cm->course);
         if (!can_access_course($course, $user, '', true)) {
             // We return a warning because the function does not fail for not enrolled users.
             $warning = array();
             $warning['item'] = 'course';
             $warning['itemid'] = $cm->course;
             $warning['warningcode'] = '1';
             $warning['message'] = "User {$user->id} cannot access course {$cm->course}";
             $warnings[] = $warning;
         }
     }
     $usergroups = array();
     if (empty($warnings)) {
         $groups = groups_get_activity_allowed_groups($cm, $user->id);
         foreach ($groups as $group) {
             list($group->description, $group->descriptionformat) = external_format_text($group->description, $group->descriptionformat, $coursecontext->id, 'group', 'description', $group->id);
             $group->courseid = $cm->course;
             $usergroups[] = $group;
         }
     }
     $results = array('groups' => $usergroups, 'warnings' => $warnings);
     return $results;
 }
Ejemplo n.º 20
0
/**
 * Utility function for getting a subwiki by group and user, validating that the user can view it.
 * If the subwiki doesn't exists in DB yet it'll have id -1.
 *
 * @param stdClass $wiki The wiki.
 * @param int $groupid Group ID. 0 means the subwiki doesn't use groups.
 * @param int $userid User ID. 0 means the subwiki doesn't use users.
 * @return stdClass Subwiki. If it doesn't exists in DB yet it'll have id -1. If the user can't view the
 *                  subwiki this function will return false.
 * @since  Moodle 3.1
 * @throws moodle_exception
 */
function wiki_get_subwiki_by_group_and_user_with_validation($wiki, $groupid, $userid)
{
    global $USER, $DB;
    // Get subwiki based on group and user.
    if (!($subwiki = wiki_get_subwiki_by_group($wiki->id, $groupid, $userid))) {
        // The subwiki doesn't exist.
        // Validate if user is valid.
        if ($userid != 0) {
            $user = core_user::get_user($userid, '*', MUST_EXIST);
            core_user::require_active_user($user);
        }
        // Validate that groupid is valid.
        if ($groupid != 0 && !groups_group_exists($groupid)) {
            throw new moodle_exception('cannotfindgroup', 'error');
        }
        // Valid data but subwiki not found. We'll simulate a subwiki object to check if the user would be able to see it
        // if it existed. If he's able to see it then we'll return an empty array because the subwiki has no pages.
        $subwiki = new stdClass();
        $subwiki->id = -1;
        $subwiki->wikiid = $wiki->id;
        $subwiki->userid = $userid;
        $subwiki->groupid = $groupid;
    }
    // Check that the user can view the subwiki. This function checks capabilities.
    if (!wiki_user_can_view($subwiki, $wiki)) {
        return false;
    }
    return $subwiki;
}
Ejemplo n.º 21
0
 /**
  * Group member removed
  *
  * @param \core\event\group_member_removed $event
  * @return void
  */
 public static function group_member_removed(\core\event\group_member_removed $event)
 {
     global $DB;
     $group = $event->get_record_snapshot('groups', $event->objectid);
     $user = \core_user::get_user($event->relateduserid, '*', MUST_EXIST);
     $courseids = local_metagroups_parent_courses($group->courseid);
     foreach ($courseids as $courseid) {
         $course = get_course($courseid);
         if ($metagroup = $DB->get_record('groups', array('courseid' => $course->id, 'idnumber' => $group->id))) {
             groups_remove_member($metagroup, $user);
         }
     }
 }
Ejemplo n.º 22
0
 /**
  * Parses the submitted form data and saves it into preferences array.
  *
  * @param stdClass $form preferences form class
  * @param array $preferences preferences array
  */
 function process_form($form, &$preferences)
 {
     global $CFG;
     if (isset($form->email_email)) {
         $preferences['message_processor_email_email'] = $form->email_email;
     }
     if (isset($form->preference_mailcharset)) {
         $preferences['mailcharset'] = $form->preference_mailcharset;
     }
     if (isset($form->mailformat) && isset($form->userid)) {
         require_once $CFG->dirroot . '/user/lib.php';
         $user = core_user::get_user($form->userid, '*', MUST_EXIST);
         $user->mailformat = clean_param($form->mailformat, PARAM_INT);
         user_update_user($user, false, false);
     }
 }
Ejemplo n.º 23
0
/**
 * Print the results of a message search
 *
 * @param mixed $frm submitted form data
 * @param bool $showicontext show text next to action icons?
 * @param object $currentuser the current user
 * @return void
 */
function message_print_search_results($frm, $showicontext=false, $currentuser=null) {
    global $USER, $DB, $OUTPUT;

    if (empty($currentuser)) {
        $currentuser = $USER;
    }

    echo html_writer::start_tag('div', array('class' => 'mdl-left'));

    $personsearch = false;
    $personsearchstring = null;
    if (!empty($frm->personsubmit) and !empty($frm->name)) {
        $personsearch = true;
        $personsearchstring = $frm->name;
    } else if (!empty($frm->combinedsubmit) and !empty($frm->combinedsearch)) {
        $personsearch = true;
        $personsearchstring = $frm->combinedsearch;
    }

    // Search for person.
    if ($personsearch) {
        if (optional_param('mycourses', 0, PARAM_BOOL)) {
            $users = array();
            $mycourses = enrol_get_my_courses('id');
            $mycoursesids = array();
            foreach ($mycourses as $mycourse) {
                $mycoursesids[] = $mycourse->id;
            }
            $susers = message_search_users($mycoursesids, $personsearchstring);
            foreach ($susers as $suser) {
                $users[$suser->id] = $suser;
            }
        } else {
            $users = message_search_users(SITEID, $personsearchstring);
        }

        if (!empty($users)) {
            echo html_writer::start_tag('p', array('class' => 'heading searchresultcount'));
            echo get_string('userssearchresults', 'message', count($users));
            echo html_writer::end_tag('p');

            echo html_writer::start_tag('table', array('class' => 'messagesearchresults'));
            foreach ($users as $user) {

                if ( $user->contactlistid )  {
                    if ($user->blocked == 0) { // User is not blocked.
                        $strcontact = message_contact_link($user->id, 'remove', true, null, $showicontext);
                        $strblock   = message_contact_link($user->id, 'block', true, null, $showicontext);
                    } else { // blocked
                        $strcontact = message_contact_link($user->id, 'add', true, null, $showicontext);
                        $strblock   = message_contact_link($user->id, 'unblock', true, null, $showicontext);
                    }
                } else {
                    $strcontact = message_contact_link($user->id, 'add', true, null, $showicontext);
                    $strblock   = message_contact_link($user->id, 'block', true, null, $showicontext);
                }

                // Should we show just the icon or icon and text?
                $histicontext = 'icon';
                if ($showicontext) {
                    $histicontext = 'both';
                }
                $strhistory = message_history_link($USER->id, $user->id, true, '', '', $histicontext);

                echo html_writer::start_tag('tr');

                echo html_writer::start_tag('td', array('class' => 'pix'));
                echo $OUTPUT->user_picture($user, array('size' => 20, 'courseid' => SITEID));
                echo html_writer::end_tag('td');

                echo html_writer::start_tag('td',array('class' => 'contact'));
                $action = null;
                $link = new moodle_url("/message/index.php?id=$user->id");
                echo $OUTPUT->action_link($link, fullname($user), $action, array('title' => get_string('sendmessageto', 'message', fullname($user))));
                echo html_writer::end_tag('td');

                echo html_writer::tag('td', $strcontact, array('class' => 'link'));
                echo html_writer::tag('td', $strblock, array('class' => 'link'));
                echo html_writer::tag('td', $strhistory, array('class' => 'link'));

                echo html_writer::end_tag('tr');
            }
            echo html_writer::end_tag('table');

        } else {
            echo html_writer::start_tag('p', array('class' => 'heading searchresultcount'));
            echo get_string('userssearchresults', 'message', 0).'<br /><br />';
            echo html_writer::end_tag('p');
        }
    }

    // search messages for keywords
    $messagesearch = false;
    $messagesearchstring = null;
    if (!empty($frm->keywords)) {
        $messagesearch = true;
        $messagesearchstring = clean_text(trim($frm->keywords));
    } else if (!empty($frm->combinedsubmit) and !empty($frm->combinedsearch)) {
        $messagesearch = true;
        $messagesearchstring = clean_text(trim($frm->combinedsearch));
    }

    if ($messagesearch) {
        if ($messagesearchstring) {
            $keywords = explode(' ', $messagesearchstring);
        } else {
            $keywords = array();
        }
        $tome     = false;
        $fromme   = false;
        $courseid = 'none';

        if (empty($frm->keywordsoption)) {
            $frm->keywordsoption = 'allmine';
        }

        switch ($frm->keywordsoption) {
            case 'tome':
                $tome   = true;
                break;
            case 'fromme':
                $fromme = true;
                break;
            case 'allmine':
                $tome   = true;
                $fromme = true;
                break;
            case 'allusers':
                $courseid = SITEID;
                break;
            case 'courseusers':
                $courseid = $frm->courseid;
                break;
            default:
                $tome   = true;
                $fromme = true;
        }

        if (($messages = message_search($keywords, $fromme, $tome, $courseid)) !== false) {

            // Get a list of contacts.
            if (($contacts = $DB->get_records('message_contacts', array('userid' => $USER->id), '', 'contactid, blocked') ) === false) {
                $contacts = array();
            }

            // Print heading with number of results.
            echo html_writer::start_tag('p', array('class' => 'heading searchresultcount'));
            $countresults = count($messages);
            if ($countresults == MESSAGE_SEARCH_MAX_RESULTS) {
                echo get_string('keywordssearchresultstoomany', 'message', $countresults).' ("'.s($messagesearchstring).'")';
            } else {
                echo get_string('keywordssearchresults', 'message', $countresults);
            }
            echo html_writer::end_tag('p');

            // Print table headings.
            echo html_writer::start_tag('table', array('class' => 'messagesearchresults', 'cellspacing' => '0'));

            $headertdstart = html_writer::start_tag('td', array('class' => 'messagesearchresultscol'));
            $headertdend   = html_writer::end_tag('td');
            echo html_writer::start_tag('tr');
            echo $headertdstart.get_string('from').$headertdend;
            echo $headertdstart.get_string('to').$headertdend;
            echo $headertdstart.get_string('message', 'message').$headertdend;
            echo $headertdstart.get_string('timesent', 'message').$headertdend;
            echo html_writer::end_tag('tr');

            $blockedcount = 0;
            $dateformat = get_string('strftimedatetimeshort');
            $strcontext = get_string('context', 'message');
            foreach ($messages as $message) {

                // Ignore messages to and from blocked users unless $frm->includeblocked is set.
                if (!optional_param('includeblocked', 0, PARAM_BOOL) and (
                      ( isset($contacts[$message->useridfrom]) and ($contacts[$message->useridfrom]->blocked == 1)) or
                      ( isset($contacts[$message->useridto]  ) and ($contacts[$message->useridto]->blocked   == 1))
                                                )
                   ) {
                    $blockedcount ++;
                    continue;
                }

                // Load user-to record.
                if ($message->useridto !== $USER->id) {
                    $userto = core_user::get_user($message->useridto);
                    $tocontact = (array_key_exists($message->useridto, $contacts) and
                                    ($contacts[$message->useridto]->blocked == 0) );
                    $toblocked = (array_key_exists($message->useridto, $contacts) and
                                    ($contacts[$message->useridto]->blocked == 1) );
                } else {
                    $userto = false;
                    $tocontact = false;
                    $toblocked = false;
                }

                // Load user-from record.
                if ($message->useridfrom !== $USER->id) {
                    $userfrom = core_user::get_user($message->useridfrom);
                    $fromcontact = (array_key_exists($message->useridfrom, $contacts) and
                                    ($contacts[$message->useridfrom]->blocked == 0) );
                    $fromblocked = (array_key_exists($message->useridfrom, $contacts) and
                                    ($contacts[$message->useridfrom]->blocked == 1) );
                } else {
                    $userfrom = false;
                    $fromcontact = false;
                    $fromblocked = false;
                }

                // Find date string for this message.
                $date = usergetdate($message->timecreated);
                $datestring = $date['year'].$date['mon'].$date['mday'];

                // Print out message row.
                echo html_writer::start_tag('tr', array('valign' => 'top'));

                echo html_writer::start_tag('td', array('class' => 'contact'));
                message_print_user($userfrom, $fromcontact, $fromblocked, $showicontext);
                echo html_writer::end_tag('td');

                echo html_writer::start_tag('td', array('class' => 'contact'));
                message_print_user($userto, $tocontact, $toblocked, $showicontext);
                echo html_writer::end_tag('td');

                echo html_writer::start_tag('td', array('class' => 'summary'));
                echo message_get_fragment($message->smallmessage, $keywords);
                echo html_writer::start_tag('div', array('class' => 'link'));

                // If the user clicks the context link display message sender on the left.
                // EXCEPT if the current user is in the conversation. Current user == always on the left.
                $leftsideuserid = $rightsideuserid = null;
                if ($currentuser->id == $message->useridto) {
                    $leftsideuserid = $message->useridto;
                    $rightsideuserid = $message->useridfrom;
                } else {
                    $leftsideuserid = $message->useridfrom;
                    $rightsideuserid = $message->useridto;
                }
                message_history_link($leftsideuserid, $rightsideuserid, false,
                                     $messagesearchstring, 'm'.$message->id, $strcontext);
                echo html_writer::end_tag('div');
                echo html_writer::end_tag('td');

                echo html_writer::tag('td', userdate($message->timecreated, $dateformat), array('class' => 'date'));

                echo html_writer::end_tag('tr');
            }


            if ($blockedcount > 0) {
                echo html_writer::start_tag('tr');
                echo html_writer::tag('td', get_string('blockedmessages', 'message', $blockedcount), array('colspan' => 4, 'align' => 'center'));
                echo html_writer::end_tag('tr');
            }
            echo html_writer::end_tag('table');

        } else {
            echo html_writer::tag('p', get_string('keywordssearchresults', 'message', 0), array('class' => 'heading'));
        }
    }

    if (!$personsearch && !$messagesearch) {
        //they didn't enter any search terms
        echo $OUTPUT->notification(get_string('emptysearchstring', 'message'));
    }

    echo html_writer::end_tag('div');
}
Ejemplo n.º 24
0
/**
 * Handles displaying processor settings in a fragment.
 *
 * @param array $args
 * @return bool|string
 * @throws moodle_exception
 */
function message_output_fragment_processor_settings($args = []) {
    global $PAGE;

    if (!isset($args['type'])) {
        throw new moodle_exception('Must provide a processor type');
    }

    if (!isset($args['userid'])) {
        throw new moodle_exception('Must provide a userid');
    }

    $type = $args['type'];
    $userid = $args['userid'];

    $user = core_user::get_user($userid, '*', MUST_EXIST);
    $processor = get_message_processor($type);
    $providers = message_get_providers_for_user($userid);
    $processorwrapper = new stdClass();
    $processorwrapper->object = $processor;
    $preferences = \core_message\api::get_all_message_preferences([$processorwrapper], $providers, $user);

    $processoroutput = new \core_message\output\preferences\processor($processor, $preferences, $user, $type);
    $renderer = $PAGE->get_renderer('core', 'message');

    return $renderer->render_from_template('core_message/preferences_processor', $processoroutput->export_for_template($renderer));
}
Ejemplo n.º 25
0
 /**
  * Simulates the web interface view of notes/index.php: trigger events
  *
  * @param int $courseid id of the course
  * @param int $userid id of the user
  * @return array of warnings and status result
  * @since Moodle 2.9
  * @throws moodle_exception
  */
 public static function view_notes($courseid, $userid = 0)
 {
     global $CFG;
     require_once $CFG->dirroot . "/notes/lib.php";
     if (empty($CFG->enablenotes)) {
         throw new moodle_exception('notesdisabled', 'notes');
     }
     $warnings = array();
     $arrayparams = array('courseid' => $courseid, 'userid' => $userid);
     $params = self::validate_parameters(self::view_notes_parameters(), $arrayparams);
     if (empty($params['courseid'])) {
         $params['courseid'] = SITEID;
     }
     $course = get_course($params['courseid']);
     if ($course->id == SITEID) {
         $context = context_system::instance();
     } else {
         $context = context_course::instance($course->id);
     }
     // First of all, validate the context before do further permission checks.
     self::validate_context($context);
     require_capability('moodle/notes:view', $context);
     if (!empty($params['userid'])) {
         $user = core_user::get_user($params['userid'], 'id, deleted', MUST_EXIST);
         if ($user->deleted) {
             throw new moodle_exception('userdeleted');
         }
         if (isguestuser($user)) {
             throw new moodle_exception('invaliduserid');
         }
         if ($course->id != SITEID and !is_enrolled($context, $user, '', true)) {
             throw new moodle_exception('notenrolledprofile');
         }
     }
     note_view($context, $params['userid']);
     $result = array();
     $result['status'] = true;
     $result['warnings'] = $warnings;
     return $result;
 }
Ejemplo n.º 26
0
 /**
  * Return the list of mobile devices that are registered in Moodle for the given user.
  *
  * @param  string  $appid  app unique id (usually a reversed domain)
  * @param  integer $userid the user id, 0 for current user
  * @return array warnings and devices
  * @throws moodle_exception
  * @since Moodle 3.2
  */
 public static function get_user_devices($appid, $userid = 0)
 {
     global $USER;
     $params = self::validate_parameters(self::get_user_devices_parameters(), array('appid' => $appid, 'userid' => $userid));
     $context = context_system::instance();
     self::validate_context($context);
     if (empty($params['userid'])) {
         $user = $USER;
     } else {
         $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
         core_user::require_active_user($user);
         // Allow only admins to retrieve other users devices.
         if ($user->id != $USER->id) {
             require_capability('moodle/site:config', $context);
         }
     }
     $warnings = array();
     $devices = array();
     // Check if mobile notifications are enabled.
     if (!self::is_system_configured()) {
         $warnings[] = array('item' => 'user', 'itemid' => $user->id, 'warningcode' => 'systemnotconfigured', 'message' => 'Mobile notifications are not configured');
     } else {
         // We catch exceptions here because get_user_devices may try to connect to Airnotifier.
         try {
             $manager = new message_airnotifier_manager();
             $devices = $manager->get_user_devices($appid, $user->id);
         } catch (Exception $e) {
             $warnings[] = array('item' => 'user', 'itemid' => $user->id, 'warningcode' => 'errorgettingdevices', 'message' => $e->getMessage());
         }
     }
     return array('devices' => $devices, 'warnings' => $warnings);
 }
Ejemplo n.º 27
0
 /**
  * Combines the review options from a number of different quiz attempts.
  *
  * @param int $quizid quiz instance id
  * @param int $userid user id (empty for current user)
  * @return array of warnings and the review options
  * @since Moodle 3.1
  */
 public static function get_combined_review_options($quizid, $userid = 0)
 {
     global $DB, $USER;
     $warnings = array();
     $params = array('quizid' => $quizid, 'userid' => $userid);
     $params = self::validate_parameters(self::get_combined_review_options_parameters(), $params);
     list($quiz, $course, $cm, $context) = self::validate_quiz($params['quizid']);
     // Default value for userid.
     if (empty($params['userid'])) {
         $params['userid'] = $USER->id;
     }
     $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
     core_user::require_active_user($user);
     // Extra checks so only users with permissions can view other users attempts.
     if ($USER->id != $user->id) {
         require_capability('mod/quiz:viewreports', $context);
     }
     $attempts = quiz_get_user_attempts($quiz->id, $user->id, 'all', true);
     $result = array();
     $result['someoptions'] = [];
     $result['alloptions'] = [];
     list($someoptions, $alloptions) = quiz_get_combined_reviewoptions($quiz, $attempts);
     foreach (array('someoptions', 'alloptions') as $typeofoption) {
         foreach (${$typeofoption} as $key => $value) {
             $result[$typeofoption][] = array("name" => $key, "value" => !empty($value) ? $value : 0);
         }
     }
     $result['warnings'] = $warnings;
     return $result;
 }
Ejemplo n.º 28
0
 /**
  * Creates an small test course with fixed data set and checks the used sections and users.
  */
 public function test_fixed_data_set()
 {
     $this->resetAfterTest();
     $this->setAdminUser();
     // Create the S course (more sections and activities than XS).
     $backend = new tool_generator_course_backend('TOOL_S_COURSE_1', 1, true, false, false);
     $courseid = $backend->make();
     // Get course details.
     $course = get_course($courseid);
     $modinfo = get_fast_modinfo($course);
     // Check module instances belongs to section 1.
     $instances = $modinfo->get_instances_of('page');
     foreach ($instances as $instance) {
         $this->assertEquals(1, $instance->sectionnum);
     }
     // Users that started discussions are the same.
     $forums = $modinfo->get_instances_of('forum');
     $discussions = forum_get_discussions(reset($forums), 'd.timemodified ASC');
     $lastusernumber = 0;
     $discussionstarters = array();
     foreach ($discussions as $discussion) {
         $usernumber = core_user::get_user($discussion->userid, 'id, idnumber')->idnumber;
         // Checks that the users are odd numbers.
         $this->assertEquals(1, $usernumber % 2);
         // Checks that the users follows an increasing order.
         $this->assertGreaterThan($lastusernumber, $usernumber);
         $lastusernumber = $usernumber;
         $discussionstarters[$discussion->userid] = $discussion->subject;
     }
 }
Ejemplo n.º 29
0
    throw new moodle_exception('disabled', 'core_message');
}
$PAGE->set_context(null);
require_sesskey();
$action = optional_param('action', null, PARAM_ALPHA);
$response = null;
switch ($action) {
    // Sending a message.
    case 'sendmessage':
        $userid = required_param('userid', PARAM_INT);
        if (empty($userid) || isguestuser($userid) || $userid == $USER->id) {
            // Cannot send messags to self, nobody or a guest.
            throw new coding_exception('Invalid user to send the message to');
        }
        $message = required_param('message', PARAM_RAW);
        $user2 = core_user::get_user($userid);
        // Only attempt to send the message if we have permission to message
        // the recipient.
        if (message_can_post_message($user2, $USER)) {
            $messageid = message_post_message($USER, $user2, $message, FORMAT_MOODLE);
            if (!$messageid) {
                throw new moodle_exception('errorwhilesendingmessage', 'core_message');
            }
        } else {
            throw new moodle_exception('unabletomessageuser', 'core_message');
        }
        $response = array();
        break;
}
if ($response !== null) {
    echo json_encode($response);
Ejemplo n.º 30
0
 /**
  * Returns a list of grades tables for users in a course.
  *
  * @param int $courseid Course Id
  * @param int $userid   Only this user (optional)
  *
  * @return array the grades tables
  * @since Moodle 2.9
  */
 public static function get_grades_table($courseid, $userid = 0)
 {
     global $CFG, $USER;
     $warnings = array();
     // Validate the parameter.
     $params = self::validate_parameters(self::get_grades_table_parameters(), array('courseid' => $courseid, 'userid' => $userid));
     // Compact/extract functions are not recommended.
     $courseid = $params['courseid'];
     $userid = $params['userid'];
     // Function get_course internally throws an exception if the course doesn't exist.
     $course = get_course($courseid);
     $context = context_course::instance($courseid);
     self::validate_context($context);
     // Specific capabilities.
     require_capability('gradereport/user:view', $context);
     $user = null;
     if (empty($userid)) {
         require_capability('moodle/grade:viewall', $context);
     } else {
         $user = core_user::get_user($userid, '*', MUST_EXIST);
     }
     $access = false;
     if (has_capability('moodle/grade:viewall', $context)) {
         // Can view all course grades.
         $access = true;
     } else {
         if ($userid == $USER->id and has_capability('moodle/grade:view', $context) and $course->showgrades) {
             // View own grades.
             $access = true;
         }
     }
     if (!$access) {
         throw new moodle_exception('nopermissiontoviewgrades', 'error');
     }
     // Require files here to save some memory in case validation fails.
     require_once $CFG->dirroot . '/group/lib.php';
     require_once $CFG->libdir . '/gradelib.php';
     require_once $CFG->dirroot . '/grade/lib.php';
     require_once $CFG->dirroot . '/grade/report/user/lib.php';
     $gpr = new grade_plugin_return(array('type' => 'report', 'plugin' => 'user', 'courseid' => $courseid, 'userid' => $userid));
     $tables = array();
     // Just one user.
     if ($user) {
         $report = new grade_report_user($courseid, $gpr, $context, $userid);
         $report->fill_table();
         $tables[] = array('courseid' => $courseid, 'userid' => $user->id, 'userfullname' => fullname($user), 'maxdepth' => $report->maxdepth, 'tabledata' => $report->tabledata);
     } else {
         $defaultgradeshowactiveenrol = !empty($CFG->grade_report_showonlyactiveenrol);
         $showonlyactiveenrol = get_user_preferences('grade_report_showonlyactiveenrol', $defaultgradeshowactiveenrol);
         $showonlyactiveenrol = $showonlyactiveenrol || !has_capability('moodle/course:viewsuspendedusers', $context);
         $gui = new graded_users_iterator($course);
         $gui->require_active_enrolment($showonlyactiveenrol);
         $gui->init();
         while ($userdata = $gui->next_user()) {
             $currentuser = $userdata->user;
             $report = new grade_report_user($courseid, $gpr, $context, $currentuser->id);
             $report->fill_table();
             $tables[] = array('courseid' => $courseid, 'userid' => $currentuser->id, 'userfullname' => fullname($currentuser), 'maxdepth' => $report->maxdepth, 'tabledata' => $report->tabledata);
         }
         $gui->close();
     }
     $result = array();
     $result['tables'] = $tables;
     $result['warnings'] = $warnings;
     return $result;
 }