/** * 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; }
/** * Trigger the user profile viewed event. * * @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); core_user::require_active_user($user); 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; }
/** * 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); }
if (!$CFG->enablewebservices) { throw new moodle_exception('enablewsdescription', 'webservice'); } // Check if the plugin is properly configured. $typeoflogin = get_config('tool_mobile', 'typeoflogin'); if ($typeoflogin != tool_mobile\api::LOGIN_VIA_BROWSER and $typeoflogin != tool_mobile\api::LOGIN_VIA_EMBEDDED_BROWSER) { throw new moodle_exception('pluginnotenabledorconfigured', 'tool_mobile'); } // Check if the service exists and is enabled. $service = $DB->get_record('external_services', array('shortname' => $serviceshortname, 'enabled' => 1)); if (empty($service)) { throw new moodle_exception('servicenotavailable', 'webservice'); } require_login(0, false); // Require an active user: not guest, not suspended. core_user::require_active_user($USER); // Get an existing token or create a new one. $token = external_generate_token_for_current_user($service); // Log token access. $DB->set_field('external_tokens', 'lastaccess', time(), array('id' => $token->id)); $params = array('objectid' => $token->id); $event = \core\event\webservice_token_sent::create($params); $event->add_record_snapshot('external_tokens', $token); $event->trigger(); // Passport is generated in the mobile app, so the app opening can be validated using that variable. // Passports are valid only one time, it's deleted in the app once used. $siteid = md5($CFG->wwwroot . $passport); $apptoken = base64_encode($siteid . ':::' . $token->token); // Redirect using the custom URL scheme checking first if a URL scheme is forced in the site settings. $forcedurlscheme = get_config('tool_mobile', 'forcedurlscheme'); if (!empty($forcedurlscheme)) {
/** * Return user preferences. * * @param string $name preference name, empty for all * @param int $userid id of the user, 0 for current user * @return array of warnings and preferences * @since Moodle 3.2 * @throws moodle_exception */ public static function get_user_preferences($name = '', $userid = 0) { global $USER; $params = self::validate_parameters(self::get_user_preferences_parameters(), array('name' => $name, 'userid' => $userid)); $preferences = array(); $warnings = array(); $context = context_system::instance(); self::validate_context($context); if (empty($params['name'])) { $name = null; } if (empty($params['userid'])) { $user = null; } else { $user = core_user::get_user($params['userid'], '*', MUST_EXIST); core_user::require_active_user($user); if ($user->id != $USER->id) { // Only admins can retrieve other users preferences. require_capability('moodle/site:config', $context); } } $userpreferences = get_user_preferences($name, null, $user); // Check if we received just one preference. if (!is_array($userpreferences)) { $userpreferences = array($name => $userpreferences); } foreach ($userpreferences as $name => $value) { $preferences[] = array('name' => $name, 'value' => $value); } $result = array(); $result['preferences'] = $preferences; $result['warnings'] = $warnings; return $result; }
/** * 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; }
/** * Test require_active_user */ public function test_require_active_user() { global $DB; // Create a default user for the test. $userexpected = $this->getDataGenerator()->create_user(); // Simple case, all good. core_user::require_active_user($userexpected, true, true); // Set user not confirmed. $DB->set_field('user', 'confirmed', 0, array('id' => $userexpected->id)); try { core_user::require_active_user($userexpected); } catch (moodle_exception $e) { $this->assertEquals('usernotconfirmed', $e->errorcode); } $DB->set_field('user', 'confirmed', 1, array('id' => $userexpected->id)); // Set nologin auth method. $DB->set_field('user', 'auth', 'nologin', array('id' => $userexpected->id)); try { core_user::require_active_user($userexpected, false, true); } catch (moodle_exception $e) { $this->assertEquals('suspended', $e->errorcode); } // Check no exceptions are thrown if we don't specify to check suspended. core_user::require_active_user($userexpected); $DB->set_field('user', 'auth', 'manual', array('id' => $userexpected->id)); // Set user suspended. $DB->set_field('user', 'suspended', 1, array('id' => $userexpected->id)); try { core_user::require_active_user($userexpected, true); } catch (moodle_exception $e) { $this->assertEquals('suspended', $e->errorcode); } // Check no exceptions are thrown if we don't specify to check suspended. core_user::require_active_user($userexpected); // Delete user. delete_user($userexpected); try { core_user::require_active_user($userexpected); } catch (moodle_exception $e) { $this->assertEquals('userdeleted', $e->errorcode); } // Use a not real user. $noreplyuser = core_user::get_noreply_user(); try { core_user::require_active_user($noreplyuser, true); } catch (moodle_exception $e) { $this->assertEquals('invaliduser', $e->errorcode); } // Get the guest user. $guestuser = $DB->get_record('user', array('username' => 'guest')); try { core_user::require_active_user($guestuser, true); } catch (moodle_exception $e) { $this->assertEquals('guestsarenotallowed', $e->errorcode); } }
/** * 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; }
/** * Check that the user has enough permission to retrieve message or notifications preferences. * * @param int $userid the user id requesting the preferences * @return stdClass full user object * @throws moodle_exception * @since Moodle 3.2 */ protected static function validate_preferences_permissions($userid) { global $USER; if (empty($userid)) { $user = $USER; } else { $user = core_user::get_user($userid, '*', MUST_EXIST); core_user::require_active_user($user); } $systemcontext = context_system::instance(); self::validate_context($systemcontext); // Check access control. if ($user->id == $USER->id) { // Editing own message profile. require_capability('moodle/user:editownmessageprofile', $systemcontext); } else { // Teachers, parents, etc. $personalcontext = context_user::instance($user->id); require_capability('moodle/user:editmessageprofile', $personalcontext); } return $user; }
/** * Generate or return an existing token for the current authenticated user. * This function is used for creating a valid token for users authenticathing via login/token.php or admin/tool/mobile/launch.php. * * @param stdClass $service external service object * @return stdClass token object * @since Moodle 3.2 * @throws moodle_exception */ function external_generate_token_for_current_user($service) { global $DB, $USER; core_user::require_active_user($USER, true, true); // Check if there is any required system capability. if ($service->requiredcapability and !has_capability($service->requiredcapability, context_system::instance())) { throw new moodle_exception('missingrequiredcapability', 'webservice', '', $service->requiredcapability); } // Specific checks related to user restricted service. if ($service->restrictedusers) { $authoriseduser = $DB->get_record('external_services_users', array('externalserviceid' => $service->id, 'userid' => $USER->id)); if (empty($authoriseduser)) { throw new moodle_exception('usernotallowed', 'webservice', '', $service->shortname); } if (!empty($authoriseduser->validuntil) and $authoriseduser->validuntil < time()) { throw new moodle_exception('invalidtimedtoken', 'webservice'); } if (!empty($authoriseduser->iprestriction) and !address_in_subnet(getremoteaddr(), $authoriseduser->iprestriction)) { throw new moodle_exception('invalidiptoken', 'webservice'); } } // Check if a token has already been created for this user and this service. $conditions = array('userid' => $USER->id, 'externalserviceid' => $service->id, 'tokentype' => EXTERNAL_TOKEN_PERMANENT); $tokens = $DB->get_records('external_tokens', $conditions, 'timecreated ASC'); // A bit of sanity checks. foreach ($tokens as $key => $token) { // Checks related to a specific token. (script execution continue). $unsettoken = false; // If sid is set then there must be a valid associated session no matter the token type. if (!empty($token->sid)) { if (!\core\session\manager::session_exists($token->sid)) { // This token will never be valid anymore, delete it. $DB->delete_records('external_tokens', array('sid' => $token->sid)); $unsettoken = true; } } // Remove token is not valid anymore. if (!empty($token->validuntil) and $token->validuntil < time()) { $DB->delete_records('external_tokens', array('token' => $token->token, 'tokentype' => EXTERNAL_TOKEN_PERMANENT)); $unsettoken = true; } // Remove token if its ip not in whitelist. if (isset($token->iprestriction) and !address_in_subnet(getremoteaddr(), $token->iprestriction)) { $unsettoken = true; } if ($unsettoken) { unset($tokens[$key]); } } // If some valid tokens exist then use the most recent. if (count($tokens) > 0) { $token = array_pop($tokens); } else { $context = context_system::instance(); $isofficialservice = $service->shortname == MOODLE_OFFICIAL_MOBILE_SERVICE; if ($isofficialservice and has_capability('moodle/webservice:createmobiletoken', $context) or !is_siteadmin($USER) && has_capability('moodle/webservice:createtoken', $context)) { // Create a new token. $token = new stdClass(); $token->token = md5(uniqid(rand(), 1)); $token->userid = $USER->id; $token->tokentype = EXTERNAL_TOKEN_PERMANENT; $token->contextid = context_system::instance()->id; $token->creatorid = $USER->id; $token->timecreated = time(); $token->externalserviceid = $service->id; // MDL-43119 Token valid for 3 months (12 weeks). $token->validuntil = $token->timecreated + 12 * WEEKSECS; $token->iprestriction = null; $token->sid = null; $token->lastaccess = null; // Generate the private token, it must be transmitted only via https. $token->privatetoken = random_string(64); $token->id = $DB->insert_record('external_tokens', $token); $eventtoken = clone $token; $eventtoken->privatetoken = null; $params = array('objectid' => $eventtoken->id, 'relateduserid' => $USER->id, 'other' => array('auto' => true)); $event = \core\event\webservice_token_created::create($params); $event->add_record_snapshot('external_tokens', $eventtoken); $event->trigger(); } else { throw new moodle_exception('cannotcreatetoken', 'webservice', '', $service->shortname); } } return $token; }
/** * 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 3.2 * @throws moodle_exception */ public static function view_grade_report($courseid, $userid = 0) { global $USER; $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); } $systemcontext = context_system::instance(); $personalcontext = context_user::instance($userid); $access = grade_report_overview::check_access($systemcontext, $context, $personalcontext, $course, $userid); if (!$access) { throw new moodle_exception('nopermissiontoviewgrades', 'error'); } grade_report_overview::viewed($context, $course->id, $userid); $result = array(); $result['status'] = true; $result['warnings'] = $warnings; return $result; }
/** * 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'], '*', MUST_EXIST); core_user::require_active_user($user); if ($course->id != SITEID and !can_access_course($course, $user, '', true)) { throw new moodle_exception('notenrolledprofile'); } } note_view($context, $params['userid']); $result = array(); $result['status'] = true; $result['warnings'] = $warnings; return $result; }
/** * Update or delete the user picture in the site * * @param int $draftitemid id of the user draft file to use as image * @param bool $delete if we should delete the user picture * @param int $userid id of the user, 0 for current user * @return array warnings and success status * @since Moodle 3.2 * @throws moodle_exception */ public static function update_picture($draftitemid, $delete = false, $userid = 0) { global $CFG, $USER, $PAGE; $params = self::validate_parameters(self::update_picture_parameters(), array('draftitemid' => $draftitemid, 'delete' => $delete, 'userid' => $userid)); $context = context_system::instance(); self::validate_context($context); if (!empty($CFG->disableuserimages)) { throw new moodle_exception('userimagesdisabled', 'admin'); } if (empty($params['userid']) or $params['userid'] == $USER->id) { $user = $USER; require_capability('moodle/user:editownprofile', $context); } else { $user = core_user::get_user($params['userid'], '*', MUST_EXIST); core_user::require_active_user($user); $personalcontext = context_user::instance($user->id); require_capability('moodle/user:editprofile', $personalcontext); if (is_siteadmin($user) and !is_siteadmin($USER)) { // Only admins may edit other admins. throw new moodle_exception('useradmineditadmin'); } } // Load the appropriate auth plugin. $userauth = get_auth_plugin($user->auth); if (is_mnet_remote_user($user) or !$userauth->can_edit_profile() or $userauth->edit_profile_url()) { throw new moodle_exception('noprofileedit', 'auth'); } $filemanageroptions = array('maxbytes' => $CFG->maxbytes, 'subdirs' => 0, 'maxfiles' => 1, 'accepted_types' => 'web_image'); $user->deletepicture = $params['delete']; $user->imagefile = $params['draftitemid']; $success = core_user::update_picture($user, $filemanageroptions); $result = array('success' => $success, 'warnings' => array()); if ($success) { $userpicture = new user_picture(core_user::get_user($user->id)); $userpicture->size = 1; // Size f1. $result['profileimageurl'] = $userpicture->get_url($PAGE)->out(false); } return $result; }
/** * 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; }
$context = context_system::instance(); $PAGE->set_context($context); // Force https. $PAGE->https_required(); // Check if the user is already logged-in. if (isloggedin() and !isguestuser()) { delete_user_key('tool_mobile', $userid); if ($USER->id == $userid) { redirect($urltogo); } else { throw new moodle_exception('alreadyloggedin', 'error', '', format_string(fullname($USER))); } } tool_mobile\api::check_autologin_prerequisites($userid); // Validate and delete the key. $key = validate_user_key($key, 'tool_mobile', null); delete_user_key('tool_mobile', $userid); // Double check key belong to user. if ($key->userid != $userid) { throw new moodle_exception('invalidkey'); } // Key validated, now require an active user: not guest, not suspended. $user = core_user::get_user($key->userid, '*', MUST_EXIST); core_user::require_active_user($user, true, true); // Do the user log-in. if (!($user = get_complete_user_data('id', $user->id))) { throw new moodle_exception('cannotfinduser', '', '', $user->id); } complete_user_login($user); \core\session\manager::apply_concurrent_login_limit($user->id, session_id()); redirect($urltogo);
/** * 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; }
/** * Retrieve a list of users blocked * * @param int $userid the user whose blocked users we want to retrieve * @return external_description * @since 2.9 */ public static function get_blocked_users($userid) { global $CFG, $USER, $PAGE; require_once $CFG->dirroot . "/message/lib.php"; // Warnings array, it can be empty at the end but is mandatory. $warnings = array(); // Validate params. $params = array('userid' => $userid); $params = self::validate_parameters(self::get_blocked_users_parameters(), $params); $userid = $params['userid']; // Validate context. $context = context_system::instance(); self::validate_context($context); // Check if private messaging between users is allowed. if (empty($CFG->messaging)) { throw new moodle_exception('disabled', 'message'); } $user = core_user::get_user($userid, '*', MUST_EXIST); core_user::require_active_user($user); // Check if we have permissions for retrieve the information. if ($userid != $USER->id and !has_capability('moodle/site:readallmessages', $context)) { throw new moodle_exception('accessdenied', 'admin'); } // Now, we can get safely all the blocked users. $users = message_get_blocked_users($user); $blockedusers = array(); foreach ($users as $user) { $newuser = array('id' => $user->id, 'fullname' => fullname($user)); $userpicture = new user_picture($user); $userpicture->size = 1; // Size f1. $newuser['profileimageurl'] = $userpicture->get_url($PAGE)->out(false); $blockedusers[] = $newuser; } $results = array('users' => $blockedusers, 'warnings' => $warnings); return $results; }
/** * 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; }
/** * Set user preferences. * * @param array $preferences list of preferences including name, value and userid * @return array of warnings and preferences saved * @since Moodle 3.2 * @throws moodle_exception */ public static function set_user_preferences($preferences) { global $USER; $params = self::validate_parameters(self::set_user_preferences_parameters(), array('preferences' => $preferences)); $warnings = array(); $saved = array(); $context = context_system::instance(); self::validate_context($context); require_capability('moodle/site:config', $context); $userscache = array(); foreach ($params['preferences'] as $pref) { // Check to which user set the preference. if (!empty($userscache[$pref['userid']])) { $user = $userscache[$pref['userid']]; } else { try { $user = core_user::get_user($pref['userid'], '*', MUST_EXIST); core_user::require_active_user($user); $userscache[$pref['userid']] = $user; } catch (Exception $e) { $warnings[] = array('item' => 'user', 'itemid' => $pref['userid'], 'warningcode' => 'invaliduser', 'message' => $e->getMessage()); continue; } } try { set_user_preference($pref['name'], $pref['value'], $user); $saved[] = array('name' => $pref['name'], 'userid' => $user->id); } catch (Exception $e) { $warnings[] = array('item' => 'user', 'itemid' => $user->id, 'warningcode' => 'errorsavingpreference', 'message' => $e->getMessage()); } } $result = array(); $result['saved'] = $saved; $result['warnings'] = $warnings; return $result; }
/** * 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; }
/** * 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'], '*', MUST_EXIST); core_user::require_active_user($user); $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; }
/** * 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; }
/** * Get the notification preferences for a given user. * * @param int $userid id of the user, 0 for current user * @return external_description * @throws moodle_exception * @since 3.2 */ public static function get_user_notification_preferences($userid = 0) { global $USER, $PAGE; $params = self::validate_parameters(self::get_user_notification_preferences_parameters(), array('userid' => $userid)); if (empty($params['userid'])) { $user = $USER; } else { $user = core_user::get_user($params['userid'], '*', MUST_EXIST); core_user::require_active_user($user); } $systemcontext = context_system::instance(); self::validate_context($systemcontext); // Check access control. if ($user->id == $USER->id) { // Editing own message profile. require_capability('moodle/user:editownmessageprofile', $systemcontext); } else { // Teachers, parents, etc. $personalcontext = context_user::instance($user->id); require_capability('moodle/user:editmessageprofile', $personalcontext); } $processors = get_message_processors(); $providers = message_get_providers_for_user($user->id); $preferences = \core_message\api::get_all_message_preferences($processors, $providers, $user); $notificationlist = new \core_message\output\preferences\notification_list($processors, $providers, $preferences, $user); $renderer = $PAGE->get_renderer('core_message'); $result = array('warnings' => array(), 'preferences' => $notificationlist->export_for_template($renderer)); return $result; }