/** * 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)); }
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; }
/** * 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; }
/** * 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; }
/** * 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); }
/** * 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; }
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)); }
/** * 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()}"); } } }
/** * 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; }
/** * 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; }
/** * 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; }
/** * 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; }
/** * 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; }
/** * 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; }
/** * Return selected user fullname. * * @return string user fullname. */ public function get_selected_user_fullname() { $user = core_user::get_user($this->userid); return fullname($user); }
/** * 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); }
/** * 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; }
/** * 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; }
/** * 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; }
/** * 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; }
/** * 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); } } }
/** * 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); } }
/** * 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'); }
/** * 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)); }
/** * 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; }
/** * 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); }
/** * 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; }
/** * 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; } }
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);
/** * 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; }