/** * Add a "Compile" menu link to the Course Admin block as the top link. * * @author Gerald Albion * date 2014-10-31 * @copyright 2014 Royal Roads University * @param object $settingsnav Main navigation object. * @param object $context Course context. */ function local_compile_extends_settings_navigation($settingsnav, $context) { // Context must be course. if ($context->contextlevel != CONTEXT_COURSE) { return; } // Must be in a valid course: Cannot be course id 0. if ($context->instanceid == 0) { return; } // Must be in a valid course: Course must be retrievable. if (!($course = get_course($context->instanceid))) { return; } // Must be enrolled or otherwise allowed to view the course. if (!(is_enrolled($context) || is_viewing($context))) { return; } // Must have a course admin menu in which to add link. if (!($coursenode = $settingsnav->find('courseadmin', navigation_node::TYPE_COURSE))) { return; } // Good to go. Build the menu item. $url = new moodle_url('/local/compile/list_modules.php', array('id' => $course->id)); $newnode = navigation_node::create(get_string('menucaption', 'local_compile'), $url, navigation_node::NODETYPE_LEAF, 'compile', 'compile', new pix_icon('i/settings', '')); // We want to put this link at the top: find the existing top (first) node. $firstnode = $coursenode->get_children_key_list()[0]; // Add the menu item to the menu, before the first node. $coursenode->add_node($newnode, $firstnode); }
/** * Return information about this specific context level * * @param $component * @param $filearea * @param $itemid * @param $filepath * @param $filename */ public function get_file_info($component, $filearea, $itemid, $filepath, $filename) { if (!is_enrolled($this->context) and !is_viewing($this->context)) { // no peaking here if not enrolled or inspector return null; } if (empty($component)) { return $this; } if ($component == 'mod_' . $this->modname and $filearea === 'intro') { return $this->get_area_intro($itemid, $filepath, $filename); } else { if ($component == 'backup' and $filearea === 'activity') { return $this->get_area_backup($itemid, $filepath, $filename); } } $functionname = 'mod_' . $this->modname . '_get_file_info'; $functionname_old = $this->modname . '_get_file_info'; if (function_exists($functionname)) { return $functionname($this->browser, $this->areas, $this->course, $this->cm, $this->context, $filearea, $itemid, $filepath, $filename); } else { if (function_exists($functionname_old)) { return $functionname_old($this->browser, $this->areas, $this->course, $this->cm, $this->context, $filearea, $itemid, $filepath, $filename); } } return null; }
/** * Return information about this specific context level * * @param $component * @param $filearea * @param $itemid * @param $filepath * @param $filename */ public function get_file_info($component, $filearea, $itemid, $filepath, $filename) { // try to emulate require_login() tests here if (!isloggedin()) { return null; } $coursecontext = get_course_context($this->context); if (!$this->course->visible and !has_capability('moodle/course:viewhiddencourses', $coursecontext)) { return null; } if (!is_viewing($this->context) and !is_enrolled($this->context)) { // no peaking here if not enrolled or inspector return null; } $modinfo = get_fast_modinfo($this->course); $cminfo = $modinfo->get_cm($this->cm->id); if (!$cminfo->uservisible) { // activity hidden sorry return null; } if (empty($component)) { return $this; } if ($component == 'mod_' . $this->modname and $filearea === 'intro') { return $this->get_area_intro($itemid, $filepath, $filename); } else { if ($component == 'backup' and $filearea === 'activity') { return $this->get_area_backup($itemid, $filepath, $filename); } } $functionname = 'mod_' . $this->modname . '_get_file_info'; $functionname_old = $this->modname . '_get_file_info'; if (function_exists($functionname)) { return $functionname($this->browser, $this->areas, $this->course, $this->cm, $this->context, $filearea, $itemid, $filepath, $filename); } else { if (function_exists($functionname_old)) { return $functionname_old($this->browser, $this->areas, $this->course, $this->cm, $this->context, $filearea, $itemid, $filepath, $filename); } } return null; }
/** * Is current user allowed to access this report * * @private defined in lib.php for performance reasons * * @param stdClass $user * @param stdClass $course * @return bool */ function report_outline_can_access_user_report($user, $course) { global $USER; $coursecontext = context_course::instance($course->id); $personalcontext = context_user::instance($user->id); if (has_capability('report/outline:view', $coursecontext)) { return true; } if (has_capability('moodle/user:viewuseractivitiesreport', $personalcontext)) { if ($course->showreports and (is_viewing($coursecontext, $user) or is_enrolled($coursecontext, $user))) { return true; } } else { if ($user->id == $USER->id) { if ($course->showreports and (is_viewing($coursecontext, $USER) or is_enrolled($coursecontext, $USER))) { return true; } } } return false; }
/** * Return information about this specific context level * * @param string $component component * @param string $filearea file area * @param int $itemid item ID * @param string $filepath file path * @param string $filename file name * @return file_info|null file_info instance or null if not found or access not allowed */ public function get_file_info($component, $filearea, $itemid, $filepath, $filename) { // try to emulate require_login() tests here if (!isloggedin()) { return null; } if (!$this->course->visible and !has_capability('moodle/course:viewhiddencourses', $this->context)) { return null; } if (!is_viewing($this->context) and !is_enrolled($this->context)) { // no peaking here if not enrolled or inspector return null; } if (empty($component)) { return $this; } $methodname = "get_area_{$component}_{$filearea}"; if (method_exists($this, $methodname)) { return $this->{$methodname}($itemid, $filepath, $filename); } return null; }
/** * Get the blog options relating to the given module for the given user * * @staticvar array $moduleoptions Cache * @param stdClass|cm_info $module The module to get options for * @param stdClass $user The user to get options for null == currentuser * @return array */ function blog_get_options_for_module($module, $user = null) { global $CFG, $USER; // Cache static $moduleoptions = array(); $options = array(); // User must be logged in, blogs must be enabled if (!blog_is_enabled_for_user()) { return $options; } // Check the user can associate with the module $modcontext = context_module::instance($module->id); $sitecontext = context_system::instance(); if (!has_capability('moodle/blog:associatemodule', $modcontext)) { return $options; } // Generate the cache key $key = $module->id . ':'; if (!empty($user)) { $key .= $user->id; } else { $key .= $USER->id; } if (array_key_exists($key, $moduleoptions)) { // Serve from the cache so we don't have to regenerate return $moduleoptions[$module->id]; } $canparticipate = (is_enrolled($modcontext) or is_viewing($modcontext)); if (has_capability('moodle/blog:view', $modcontext)) { // Save correct module name for later usage. $modulename = get_string('modulename', $module->modname); // We can view! if ($CFG->bloglevel >= BLOG_SITE_LEVEL) { // View all entries about this module $a = new stdClass(); $a->type = $modulename; $options['moduleview'] = array('string' => get_string('viewallmodentries', 'blog', $a), 'link' => new moodle_url('/blog/index.php', array('modid' => $module->id))); } // View MY entries about this module $options['moduleviewmine'] = array('string' => get_string('viewmyentriesaboutmodule', 'blog', $modulename), 'link' => new moodle_url('/blog/index.php', array('modid' => $module->id, 'userid' => $USER->id))); if (!empty($user) && $CFG->bloglevel >= BLOG_SITE_LEVEL) { // View the given users entries about this module $a = new stdClass(); $a->mod = $modulename; $a->user = fullname($user); $options['moduleviewuser'] = array('string' => get_string('blogentriesbyuseraboutmodule', 'blog', $a), 'link' => new moodle_url('/blog/index.php', array('modid' => $module->id, 'userid' => $user->id))); } } if (has_capability('moodle/blog:create', $sitecontext) and $canparticipate) { // The user can blog about this module $options['moduleadd'] = array('string' => get_string('blogaboutthismodule', 'blog', $modulename), 'link' => new moodle_url('/blog/edit.php', array('action' => 'add', 'modid' => $module->id))); } // Cache the options $moduleoptions[$key] = $options; // Return the options return $options; }
/** * This function checks that the current user is logged in and has the * required privileges * * This function checks that the current user is logged in, and optionally * whether they are allowed to be in a particular course and view a particular * course module. * If they are not logged in, then it redirects them to the site login unless * $autologinguest is set and {@link $CFG}->autologinguests is set to 1 in which * case they are automatically logged in as guests. * If $courseid is given and the user is not enrolled in that course then the * user is redirected to the course enrolment page. * If $cm is given and the course module is hidden and the user is not a teacher * in the course then the user is redirected to the course home page. * * When $cm parameter specified, this function sets page layout to 'module'. * You need to change it manually later if some other layout needed. * * @param mixed $courseorid id of the course or course object * @param bool $autologinguest default true * @param object $cm course module object * @param bool $setwantsurltome Define if we want to set $SESSION->wantsurl, defaults to * true. Used to avoid (=false) some scripts (file.php...) to set that variable, * in order to keep redirects working properly. MDL-14495 * @param bool $preventredirect set to true in scripts that can not redirect (CLI, rss feeds, etc.), throws exceptions * @return mixed Void, exit, and die depending on path */ function require_login($courseorid = NULL, $autologinguest = true, $cm = NULL, $setwantsurltome = true, $preventredirect = false) { global $CFG, $SESSION, $USER, $FULLME, $PAGE, $SITE, $DB, $OUTPUT; // setup global $COURSE, themes, language and locale if (!empty($courseorid)) { if (is_object($courseorid)) { $course = $courseorid; } else { if ($courseorid == SITEID) { $course = clone $SITE; } else { $course = $DB->get_record('course', array('id' => $courseorid), '*', MUST_EXIST); } } if ($cm) { if ($cm->course != $course->id) { throw new coding_exception('course and cm parameters in require_login() call do not match!!'); } // make sure we have a $cm from get_fast_modinfo as this contains activity access details if (!$cm instanceof cm_info) { // note: nearly all pages call get_fast_modinfo anyway and it does not make any // db queries so this is not really a performance concern, however it is obviously // better if you use get_fast_modinfo to get the cm before calling this. $modinfo = get_fast_modinfo($course); $cm = $modinfo->get_cm($cm->id); } $PAGE->set_cm($cm, $course); // set's up global $COURSE $PAGE->set_pagelayout('incourse'); } else { $PAGE->set_course($course); // set's up global $COURSE } } else { // do not touch global $COURSE via $PAGE->set_course(), // the reasons is we need to be able to call require_login() at any time!! $course = $SITE; if ($cm) { throw new coding_exception('cm parameter in require_login() requires valid course parameter!'); } } // If the user is not even logged in yet then make sure they are if (!isloggedin()) { if ($autologinguest and !empty($CFG->guestloginbutton) and !empty($CFG->autologinguests)) { if (!($guest = get_complete_user_data('id', $CFG->siteguest))) { // misconfigured site guest, just redirect to login page redirect(get_login_url()); exit; // never reached } $lang = isset($SESSION->lang) ? $SESSION->lang : $CFG->lang; complete_user_login($guest, false); $USER->autologinguest = true; $SESSION->lang = $lang; } else { //NOTE: $USER->site check was obsoleted by session test cookie, // $USER->confirmed test is in login/index.php if ($preventredirect) { throw new require_login_exception('You are not logged in'); } if ($setwantsurltome) { // TODO: switch to PAGE->url $SESSION->wantsurl = $FULLME; } if (!empty($_SERVER['HTTP_REFERER'])) { $SESSION->fromurl = $_SERVER['HTTP_REFERER']; } redirect(get_login_url()); exit; // never reached } } // loginas as redirection if needed if ($course->id != SITEID and session_is_loggedinas()) { if ($USER->loginascontext->contextlevel == CONTEXT_COURSE) { if ($USER->loginascontext->instanceid != $course->id) { print_error('loginasonecourse', '', $CFG->wwwroot . '/course/view.php?id=' . $USER->loginascontext->instanceid); } } } // check whether the user should be changing password (but only if it is REALLY them) if (get_user_preferences('auth_forcepasswordchange') && !session_is_loggedinas()) { $userauth = get_auth_plugin($USER->auth); if ($userauth->can_change_password() and !$preventredirect) { $SESSION->wantsurl = $FULLME; if ($changeurl = $userauth->change_password_url()) { //use plugin custom url redirect($changeurl); } else { //use moodle internal method if (empty($CFG->loginhttps)) { redirect($CFG->wwwroot . '/login/change_password.php'); } else { $wwwroot = str_replace('http:', 'https:', $CFG->wwwroot); redirect($wwwroot . '/login/change_password.php'); } } } else { print_error('nopasswordchangeforced', 'auth'); } } // Check that the user account is properly set up if (user_not_fully_set_up($USER)) { if ($preventredirect) { throw new require_login_exception('User not fully set-up'); } $SESSION->wantsurl = $FULLME; redirect($CFG->wwwroot . '/user/edit.php?id=' . $USER->id . '&course=' . SITEID); } // Make sure the USER has a sesskey set up. Used for CSRF protection. sesskey(); // Do not bother admins with any formalities if (is_siteadmin()) { //set accesstime or the user will appear offline which messes up messaging user_accesstime_log($course->id); return; } // Check that the user has agreed to a site policy if there is one - do not test in case of admins if (!$USER->policyagreed and !is_siteadmin()) { if (!empty($CFG->sitepolicy) and !isguestuser()) { if ($preventredirect) { throw new require_login_exception('Policy not agreed'); } $SESSION->wantsurl = $FULLME; redirect($CFG->wwwroot . '/user/policy.php'); } else { if (!empty($CFG->sitepolicyguest) and isguestuser()) { if ($preventredirect) { throw new require_login_exception('Policy not agreed'); } $SESSION->wantsurl = $FULLME; redirect($CFG->wwwroot . '/user/policy.php'); } } } // Fetch the system context, the course context, and prefetch its child contexts $sysctx = get_context_instance(CONTEXT_SYSTEM); $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id, MUST_EXIST); if ($cm) { $cmcontext = get_context_instance(CONTEXT_MODULE, $cm->id, MUST_EXIST); } else { $cmcontext = null; } // If the site is currently under maintenance, then print a message if (!empty($CFG->maintenance_enabled) and !has_capability('moodle/site:config', $sysctx)) { if ($preventredirect) { throw new require_login_exception('Maintenance in progress'); } print_maintenance_message(); } // make sure the course itself is not hidden if ($course->id == SITEID) { // frontpage can not be hidden } else { if (is_role_switched($course->id)) { // when switching roles ignore the hidden flag - user had to be in course to do the switch } else { if (!$course->visible and !has_capability('moodle/course:viewhiddencourses', $coursecontext)) { // originally there was also test of parent category visibility, // BUT is was very slow in complex queries involving "my courses" // now it is also possible to simply hide all courses user is not enrolled in :-) if ($preventredirect) { throw new require_login_exception('Course is hidden'); } notice(get_string('coursehidden'), $CFG->wwwroot . '/'); } } } // is the user enrolled? if ($course->id == SITEID) { // everybody is enrolled on the frontpage } else { if (session_is_loggedinas()) { // Make sure the REAL person can access this course first $realuser = session_get_realuser(); if (!is_enrolled($coursecontext, $realuser->id, '', true) and !is_viewing($coursecontext, $realuser->id) and !is_siteadmin($realuser->id)) { if ($preventredirect) { throw new require_login_exception('Invalid course login-as access'); } echo $OUTPUT->header(); notice(get_string('studentnotallowed', '', fullname($USER, true)), $CFG->wwwroot . '/'); } } // very simple enrolment caching - changes in course setting are not reflected immediately if (!isset($USER->enrol)) { $USER->enrol = array(); $USER->enrol['enrolled'] = array(); $USER->enrol['tempguest'] = array(); } $access = false; if (is_viewing($coursecontext, $USER)) { // ok, no need to mess with enrol $access = true; } else { if (isset($USER->enrol['enrolled'][$course->id])) { if ($USER->enrol['enrolled'][$course->id] == 0) { $access = true; } else { if ($USER->enrol['enrolled'][$course->id] > time()) { $access = true; } else { //expired unset($USER->enrol['enrolled'][$course->id]); } } } if (isset($USER->enrol['tempguest'][$course->id])) { if ($USER->enrol['tempguest'][$course->id] == 0) { $access = true; } else { if ($USER->enrol['tempguest'][$course->id] > time()) { $access = true; } else { //expired unset($USER->enrol['tempguest'][$course->id]); $USER->access = remove_temp_roles($coursecontext, $USER->access); } } } if ($access) { // cache ok } else { if (is_enrolled($coursecontext, $USER, '', true)) { // active participants may always access // TODO: refactor this into some new function $now = time(); $sql = "SELECT MAX(ue.timeend)\n FROM {user_enrolments} ue\n JOIN {enrol} e ON (e.id = ue.enrolid AND e.courseid = :courseid)\n JOIN {user} u ON u.id = ue.userid\n WHERE ue.userid = :userid AND ue.status = :active AND e.status = :enabled AND u.deleted = 0\n AND ue.timestart < :now1 AND (ue.timeend = 0 OR ue.timeend > :now2)"; $params = array('enabled' => ENROL_INSTANCE_ENABLED, 'active' => ENROL_USER_ACTIVE, 'userid' => $USER->id, 'courseid' => $coursecontext->instanceid, 'now1' => $now, 'now2' => $now); $until = $DB->get_field_sql($sql, $params); if (!$until or $until > time() + ENROL_REQUIRE_LOGIN_CACHE_PERIOD) { $until = time() + ENROL_REQUIRE_LOGIN_CACHE_PERIOD; } $USER->enrol['enrolled'][$course->id] = $until; $access = true; // remove traces of previous temp guest access $USER->access = remove_temp_roles($coursecontext, $USER->access); } else { $instances = $DB->get_records('enrol', array('courseid' => $course->id, 'status' => ENROL_INSTANCE_ENABLED), 'sortorder, id ASC'); $enrols = enrol_get_plugins(true); // first ask all enabled enrol instances in course if they want to auto enrol user foreach ($instances as $instance) { if (!isset($enrols[$instance->enrol])) { continue; } // Get a duration for the guestaccess, a timestamp in the future or false. $until = $enrols[$instance->enrol]->try_autoenrol($instance); if ($until !== false) { $USER->enrol['enrolled'][$course->id] = $until; $USER->access = remove_temp_roles($coursecontext, $USER->access); $access = true; break; } } // if not enrolled yet try to gain temporary guest access if (!$access) { foreach ($instances as $instance) { if (!isset($enrols[$instance->enrol])) { continue; } // Get a duration for the guestaccess, a timestamp in the future or false. $until = $enrols[$instance->enrol]->try_guestaccess($instance); if ($until !== false) { $USER->enrol['tempguest'][$course->id] = $until; $access = true; break; } } } } } } if (!$access) { if ($preventredirect) { throw new require_login_exception('Not enrolled'); } $SESSION->wantsurl = $FULLME; redirect($CFG->wwwroot . '/enrol/index.php?id=' . $course->id); } } // Check visibility of activity to current user; includes visible flag, groupmembersonly, // conditional availability, etc if ($cm && !$cm->uservisible) { if ($preventredirect) { throw new require_login_exception('Activity is hidden'); } redirect($CFG->wwwroot, get_string('activityiscurrentlyhidden')); } // Finally access granted, update lastaccess times user_accesstime_log($course->id); }
/** * Add navigation nodes * @param navigation_node $coursenode * @param object $course * @return void */ function enrol_add_course_navigation(navigation_node $coursenode, $course) { global $CFG; $coursecontext = context_course::instance($course->id); $instances = enrol_get_instances($course->id, true); $plugins = enrol_get_plugins(true); // we do not want to break all course pages if there is some borked enrol plugin, right? foreach ($instances as $k => $instance) { if (!isset($plugins[$instance->enrol])) { unset($instances[$k]); } } $usersnode = $coursenode->add(get_string('users'), null, navigation_node::TYPE_CONTAINER, null, 'users'); if ($course->id != SITEID) { // list all participants - allows assigning roles, groups, etc. if (has_capability('moodle/course:enrolreview', $coursecontext)) { $url = new moodle_url('/enrol/users.php', array('id' => $course->id)); $usersnode->add(get_string('enrolledusers', 'enrol'), $url, navigation_node::TYPE_SETTING, null, 'review', new pix_icon('i/enrolusers', '')); } // manage enrol plugin instances if (has_capability('moodle/course:enrolconfig', $coursecontext) or has_capability('moodle/course:enrolreview', $coursecontext)) { $url = new moodle_url('/enrol/instances.php', array('id' => $course->id)); } else { $url = NULL; } $instancesnode = $usersnode->add(get_string('enrolmentinstances', 'enrol'), $url, navigation_node::TYPE_SETTING, null, 'manageinstances'); // each instance decides how to configure itself or how many other nav items are exposed foreach ($instances as $instance) { if (!isset($plugins[$instance->enrol])) { continue; } $plugins[$instance->enrol]->add_course_navigation($instancesnode, $instance); } if (!$url) { $instancesnode->trim_if_empty(); } } // Manage groups in this course or even frontpage if (($course->groupmode || !$course->groupmodeforce) && has_capability('moodle/course:managegroups', $coursecontext)) { $url = new moodle_url('/group/index.php', array('id' => $course->id)); $usersnode->add(get_string('groups'), $url, navigation_node::TYPE_SETTING, null, 'groups', new pix_icon('i/group', '')); } if (has_any_capability(array('moodle/role:assign', 'moodle/role:safeoverride', 'moodle/role:override', 'moodle/role:review'), $coursecontext)) { // Override roles if (has_capability('moodle/role:review', $coursecontext)) { $url = new moodle_url('/admin/roles/permissions.php', array('contextid' => $coursecontext->id)); } else { $url = NULL; } $permissionsnode = $usersnode->add(get_string('permissions', 'role'), $url, navigation_node::TYPE_SETTING, null, 'override'); // Add assign or override roles if allowed if ($course->id == SITEID or !empty($CFG->adminsassignrolesincourse) and is_siteadmin()) { if (has_capability('moodle/role:assign', $coursecontext)) { $url = new moodle_url('/admin/roles/assign.php', array('contextid' => $coursecontext->id)); $permissionsnode->add(get_string('assignedroles', 'role'), $url, navigation_node::TYPE_SETTING, null, 'roles', new pix_icon('i/assignroles', '')); } } // Check role permissions if (has_any_capability(array('moodle/role:assign', 'moodle/role:safeoverride', 'moodle/role:override', 'moodle/role:assign'), $coursecontext)) { $url = new moodle_url('/admin/roles/check.php', array('contextid' => $coursecontext->id)); $permissionsnode->add(get_string('checkpermissions', 'role'), $url, navigation_node::TYPE_SETTING, null, 'permissions', new pix_icon('i/checkpermissions', '')); } } // Deal somehow with users that are not enrolled but still got a role somehow if ($course->id != SITEID) { //TODO, create some new UI for role assignments at course level if (has_capability('moodle/role:assign', $coursecontext)) { /* Added for Subadmin */ $context = get_context_instance(CONTEXT_SYSTEM); $roles = get_user_roles($context, $USER->id, false); $role = key($roles); $currentuserrolename = $roles[$role]->shortname; /* End of Subadmin */ if ($currentuserrolename != "subadmin") { $url = new moodle_url('/enrol/otherusers.php', array('id' => $course->id)); $usersnode->add(get_string('notenrolledusers', 'enrol'), $url, navigation_node::TYPE_SETTING, null, 'otherusers', new pix_icon('i/assignroles', '')); } } } // just in case nothing was actually added $usersnode->trim_if_empty(); if ($course->id != SITEID) { if (isguestuser() or !isloggedin()) { // guest account can not be enrolled - no links for them } else { if (is_enrolled($coursecontext)) { // unenrol link if possible foreach ($instances as $instance) { if (!isset($plugins[$instance->enrol])) { continue; } $plugin = $plugins[$instance->enrol]; if ($unenrollink = $plugin->get_unenrolself_link($instance)) { $shortname = format_string($course->shortname, true, array('context' => $coursecontext)); $coursenode->add(get_string('unenrolme', 'core_enrol', $shortname), $unenrollink, navigation_node::TYPE_SETTING, null, 'unenrolself', new pix_icon('i/user', '')); break; //TODO. deal with multiple unenrol links - not likely case, but still... } } } else { // enrol link if possible if (is_viewing($coursecontext)) { // better not show any enrol link, this is intended for managers and inspectors } else { foreach ($instances as $instance) { if (!isset($plugins[$instance->enrol])) { continue; } $plugin = $plugins[$instance->enrol]; if ($plugin->show_enrolme_link($instance)) { $url = new moodle_url('/enrol/index.php', array('id' => $course->id)); $shortname = format_string($course->shortname, true, array('context' => $coursecontext)); $coursenode->add(get_string('enrolme', 'core_enrol', $shortname), $url, navigation_node::TYPE_SETTING, null, 'enrolself', new pix_icon('i/user', '')); break; } } } } } } }
/** * Is current user allowed to access this report * * @private defined in lib.php for performance reasons * * @param stdClass $user * @param stdClass $course * @return bool */ function report_comments_can_access_user_report($user, $course) { global $USER, $CFG; if (empty($CFG->enablecomments)) { return false; } if ($course->id != SITEID and !$course->enablecomments) { return false; } $coursecontext = context_course::instance($course->id); if (has_capability('report/comments:view', $coursecontext)) { return true; } $personalcontext = context_user::instance($user->id); if (has_capability('moodle/user:viewuseractivitiesreport', $personalcontext)) { if ($course->showreports and (is_viewing($coursecontext, $user) or is_enrolled($coursecontext, $user))) { return true; } } else { if ($user->id == $USER->id) { if ($course->showreports and (is_viewing($coursecontext, $USER) or is_enrolled($coursecontext, $USER))) { return true; } } } return false; }
/** * this function used checked logged in user having costcenter privileges or not * * @package custom * @method require_costcenter_login * @param int $courseodir (holds the course id) * @return int */ function require_costcenter_login($courseorid) { global $CFG, $SESSION, $USER, $PAGE, $SITE, $DB, $OUTPUT, $COSTCENTER; if (!empty($courseorid)) { if (is_object($courseorid)) { $course = $courseorid; } else if ($courseorid == SITEID) { $course = clone($SITE); } else { $course = $DB->get_record('course', array('id' => $courseorid), '*', MUST_EXIST); } $coursecontext = context_course::instance($course->id, MUST_EXIST); if ($COSTCENTER) { if (!in_array($course->id, $COSTCENTER->courses)) throw new coding_exception('course is not belongs to your costcenter, Dont have permission to access'); else if (\core\session\manager::is_loggedinas()) { // Make sure the REAL person can access this course first. $realuser = \core\session\manager::get_realuser(); if (!is_enrolled($coursecontext, $realuser->id, '', true) and ! is_viewing($coursecontext, $realuser->id) and ! is_siteadmin($realuser->id)) { if ($preventredirect) { throw new require_login_exception('Invalid course login-as access'); } echo $OUTPUT->header(); notice(get_string('studentnotallowed', '', fullname($USER, true)), $CFG->wwwroot . '/'); } } // else if(! in_array($course->id,$COSTCENTER->enroledcourses)){ // throw new coding_exception('Dont have permission to access'); // } else { return true; } } } return true; }
/** * Returns posts made by the selected user in the requested courses. * * This method can be used to return all of the posts made by the requested user * within the given courses. * For each course the access of the current user and requested user is checked * and then for each post access to the post and forum is checked as well. * * This function is safe to use with usercapabilities. * * @global moodle_database $DB * @param stdClass $user The user whose posts we want to get * @param array $courses The courses to search * @param bool $musthaveaccess If set to true errors will be thrown if the user * cannot access one or more of the courses to search * @param bool $discussionsonly If set to true only discussion starting posts * will be returned. * @param int $limitfrom The offset of records to return * @param int $limitnum The number of records to return * @return stdClass An object the following properties * ->totalcount: the total number of posts made by the requested user * that the current user can see. * ->courses: An array of courses the current user can see that the * requested user has posted in. * ->forums: An array of forums relating to the posts returned in the * property below. * ->posts: An array containing the posts to show for this request. */ function forum_get_posts_by_user($user, array $courses, $musthaveaccess = false, $discussionsonly = false, $limitfrom = 0, $limitnum = 50) { global $DB, $USER, $CFG; $return = new stdClass; $return->totalcount = 0; // The total number of posts that the current user is able to view $return->courses = array(); // The courses the current user can access $return->forums = array(); // The forums that the current user can access that contain posts $return->posts = array(); // The posts to display // First up a small sanity check. If there are no courses to check we can // return immediately, there is obviously nothing to search. if (empty($courses)) { return $return; } // A couple of quick setups $isloggedin = isloggedin(); $isguestuser = $isloggedin && isguestuser(); $iscurrentuser = $isloggedin && $USER->id == $user->id; // Checkout whether or not the current user has capabilities over the requested // user and if so they have the capabilities required to view the requested // users content. $usercontext = context_user::instance($user->id, MUST_EXIST); $hascapsonuser = !$iscurrentuser && $DB->record_exists('role_assignments', array('userid' => $USER->id, 'contextid' => $usercontext->id)); $hascapsonuser = $hascapsonuser && has_all_capabilities(array('moodle/user:viewdetails', 'moodle/user:readuserposts'), $usercontext); // Before we actually search each course we need to check the user's access to the // course. If the user doesn't have the appropraite access then we either throw an // error if a particular course was requested or we just skip over the course. foreach ($courses as $course) { $coursecontext = context_course::instance($course->id, MUST_EXIST); if ($iscurrentuser || $hascapsonuser) { // If it is the current user, or the current user has capabilities to the // requested user then all we need to do is check the requested users // current access to the course. // Note: There is no need to check group access or anything of the like // as either the current user is the requested user, or has granted // capabilities on the requested user. Either way they can see what the // requested user posted, although its VERY unlikely in the `parent` situation // that the current user will be able to view the posts in context. if (!is_viewing($coursecontext, $user) && !is_enrolled($coursecontext, $user)) { // Need to have full access to a course to see the rest of own info if ($musthaveaccess) { print_error('errorenrolmentrequired', 'forum'); } continue; } } else { // Check whether the current user is enrolled or has access to view the course // if they don't we immediately have a problem. if (!can_access_course($course)) { if ($musthaveaccess) { print_error('errorenrolmentrequired', 'forum'); } continue; } // Check whether the requested user is enrolled or has access to view the course // if they don't we immediately have a problem. if (!can_access_course($course, $user)) { if ($musthaveaccess) { print_error('notenrolled', 'forum'); } continue; } // If groups are in use and enforced throughout the course then make sure // we can meet in at least one course level group. // Note that we check if either the current user or the requested user have // the capability to access all groups. This is because with that capability // a user in group A could post in the group B forum. Grrrr. if (groups_get_course_groupmode($course) == SEPARATEGROUPS && $course->groupmodeforce && !has_capability('moodle/site:accessallgroups', $coursecontext) && !has_capability('moodle/site:accessallgroups', $coursecontext, $user->id)) { // If its the guest user to bad... the guest user cannot access groups if (!$isloggedin or $isguestuser) { // do not use require_login() here because we might have already used require_login($course) if ($musthaveaccess) { redirect(get_login_url()); } continue; } // Get the groups of the current user $mygroups = array_keys(groups_get_all_groups($course->id, $USER->id, $course->defaultgroupingid, 'g.id, g.name')); // Get the groups the requested user is a member of $usergroups = array_keys(groups_get_all_groups($course->id, $user->id, $course->defaultgroupingid, 'g.id, g.name')); // Check whether they are members of the same group. If they are great. $intersect = array_intersect($mygroups, $usergroups); if (empty($intersect)) { // But they're not... if it was a specific course throw an error otherwise // just skip this course so that it is not searched. if ($musthaveaccess) { print_error("groupnotamember", '', $CFG->wwwroot."/course/view.php?id=$course->id"); } continue; } } } // Woo hoo we got this far which means the current user can search this // this course for the requested user. Although this is only the course accessibility // handling that is complete, the forum accessibility tests are yet to come. $return->courses[$course->id] = $course; } // No longer beed $courses array - lose it not it may be big unset($courses); // Make sure that we have some courses to search if (empty($return->courses)) { // If we don't have any courses to search then the reality is that the current // user doesn't have access to any courses is which the requested user has posted. // Although we do know at this point that the requested user has posts. if ($musthaveaccess) { print_error('permissiondenied'); } else { return $return; } } // Next step: Collect all of the forums that we will want to search. // It is important to note that this step isn't actually about searching, it is // about determining which forums we can search by testing accessibility. $forums = forum_get_forums_user_posted_in($user, array_keys($return->courses), $discussionsonly); // Will be used to build the where conditions for the search $forumsearchwhere = array(); // Will be used to store the where condition params for the search $forumsearchparams = array(); // Will record forums where the user can freely access everything $forumsearchfullaccess = array(); // DB caching friendly $now = round(time(), -2); // For each course to search we want to find the forums the user has posted in // and providing the current user can access the forum create a search condition // for the forum to get the requested users posts. foreach ($return->courses as $course) { // Now we need to get the forums $modinfo = get_fast_modinfo($course); if (empty($modinfo->instances['forum'])) { // hmmm, no forums? well at least its easy... skip! continue; } // Iterate foreach ($modinfo->get_instances_of('forum') as $forumid => $cm) { if (!$cm->uservisible or !isset($forums[$forumid])) { continue; } // Get the forum in question $forum = $forums[$forumid]; // This is needed for functionality later on in the forum code.... $forum->cm = $cm; // Check that either the current user can view the forum, or that the // current user has capabilities over the requested user and the requested // user can view the discussion if (!has_capability('mod/forum:viewdiscussion', $cm->context) && !($hascapsonuser && has_capability('mod/forum:viewdiscussion', $cm->context, $user->id))) { continue; } // This will contain forum specific where clauses $forumsearchselect = array(); if (!$iscurrentuser && !$hascapsonuser) { // Make sure we check group access if (groups_get_activity_groupmode($cm, $course) == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $cm->context)) { $groups = $modinfo->get_groups($cm->groupingid); $groups[] = -1; list($groupid_sql, $groupid_params) = $DB->get_in_or_equal($groups, SQL_PARAMS_NAMED, 'grps'.$forumid.'_'); $forumsearchparams = array_merge($forumsearchparams, $groupid_params); $forumsearchselect[] = "d.groupid $groupid_sql"; } // hidden timed discussions if (!empty($CFG->forum_enabletimedposts) && !has_capability('mod/forum:viewhiddentimedposts', $cm->context)) { $forumsearchselect[] = "(d.userid = :userid{$forumid} OR (d.timestart < :timestart{$forumid} AND (d.timeend = 0 OR d.timeend > :timeend{$forumid})))"; $forumsearchparams['userid'.$forumid] = $user->id; $forumsearchparams['timestart'.$forumid] = $now; $forumsearchparams['timeend'.$forumid] = $now; } // qanda access if ($forum->type == 'qanda' && !has_capability('mod/forum:viewqandawithoutposting', $cm->context)) { // We need to check whether the user has posted in the qanda forum. $discussionspostedin = forum_discussions_user_has_posted_in($forum->id, $user->id); if (!empty($discussionspostedin)) { $forumonlydiscussions = array(); // Holds discussion ids for the discussions the user is allowed to see in this forum. foreach ($discussionspostedin as $d) { $forumonlydiscussions[] = $d->id; } list($discussionid_sql, $discussionid_params) = $DB->get_in_or_equal($forumonlydiscussions, SQL_PARAMS_NAMED, 'qanda'.$forumid.'_'); $forumsearchparams = array_merge($forumsearchparams, $discussionid_params); $forumsearchselect[] = "(d.id $discussionid_sql OR p.parent = 0)"; } else { $forumsearchselect[] = "p.parent = 0"; } } if (count($forumsearchselect) > 0) { $forumsearchwhere[] = "(d.forum = :forum{$forumid} AND ".implode(" AND ", $forumsearchselect).")"; $forumsearchparams['forum'.$forumid] = $forumid; } else { $forumsearchfullaccess[] = $forumid; } } else { // The current user/parent can see all of their own posts $forumsearchfullaccess[] = $forumid; } } } // If we dont have any search conditions, and we don't have any forums where // the user has full access then we just return the default. if (empty($forumsearchwhere) && empty($forumsearchfullaccess)) { return $return; } // Prepare a where condition for the full access forums. if (count($forumsearchfullaccess) > 0) { list($fullidsql, $fullidparams) = $DB->get_in_or_equal($forumsearchfullaccess, SQL_PARAMS_NAMED, 'fula'); $forumsearchparams = array_merge($forumsearchparams, $fullidparams); $forumsearchwhere[] = "(d.forum $fullidsql)"; } // Prepare SQL to both count and search. // We alias user.id to useridx because we forum_posts already has a userid field and not aliasing this would break // oracle and mssql. $userfields = user_picture::fields('u', null, 'useridx'); $countsql = 'SELECT COUNT(*) '; $selectsql = 'SELECT p.*, d.forum, d.name AS discussionname, '.$userfields.' '; $wheresql = implode(" OR ", $forumsearchwhere); if ($discussionsonly) { if ($wheresql == '') { $wheresql = 'p.parent = 0'; } else { $wheresql = 'p.parent = 0 AND ('.$wheresql.')'; } } $sql = "FROM {forum_posts} p JOIN {forum_discussions} d ON d.id = p.discussion JOIN {user} u ON u.id = p.userid WHERE ($wheresql) AND p.userid = :userid "; $orderby = "ORDER BY p.modified DESC"; $forumsearchparams['userid'] = $user->id; // Set the total number posts made by the requested user that the current user can see $return->totalcount = $DB->count_records_sql($countsql.$sql, $forumsearchparams); // Set the collection of posts that has been requested $return->posts = $DB->get_records_sql($selectsql.$sql.$orderby, $forumsearchparams, $limitfrom, $limitnum); // We need to build an array of forums for which posts will be displayed. // We do this here to save the caller needing to retrieve them themselves before // printing these forums posts. Given we have the forums already there is // practically no overhead here. foreach ($return->posts as $post) { if (!array_key_exists($post->forum, $return->forums)) { $return->forums[$post->forum] = $forums[$post->forum]; } } return $return; }
protected function define_execution() { global $CFG, $DB; if (!($userid = $this->task->get_userid())) { return; } if (empty($CFG->restorernewroleid)) { // Bad luck, no fallback role for restorers specified return; } $courseid = $this->get_courseid(); $context = context_course::instance($courseid); if (is_enrolled($context, $userid, 'moodle/course:update', true) or is_viewing($context, $userid, 'moodle/course:update')) { // Current user may access the course (admin, category manager or restored teacher enrolment usually) return; } // Try to add role only - we do not need enrolment if user has moodle/course:view or is already enrolled role_assign($CFG->restorernewroleid, $userid, $context); if (is_enrolled($context, $userid, 'moodle/course:update', true) or is_viewing($context, $userid, 'moodle/course:update')) { // Extra role is enough, yay! return; } // The last chance is to create manual enrol if it does not exist and and try to enrol the current user, // hopefully admin selected suitable $CFG->restorernewroleid ... if (!enrol_is_enabled('manual')) { return; } if (!($enrol = enrol_get_plugin('manual'))) { return; } if (!$DB->record_exists('enrol', array('enrol' => 'manual', 'courseid' => $courseid))) { $course = $DB->get_record('course', array('id' => $courseid), '*', MUST_EXIST); $fields = array('status' => ENROL_INSTANCE_ENABLED, 'enrolperiod' => $enrol->get_config('enrolperiod', 0), 'roleid' => $enrol->get_config('roleid', 0)); $enrol->add_instance($course, $fields); } enrol_try_internal_enrol($courseid, $userid); }
/** * This function delegates file serving to individual plugins * * @param string $relativepath * @param bool $forcedownload * @param null|string $preview the preview mode, defaults to serving the original file * @todo MDL-31088 file serving improments */ function file_pluginfile($relativepath, $forcedownload, $preview = null) { global $DB, $CFG, $USER; // relative path must start with '/' if (!$relativepath) { print_error('invalidargorconf'); } else { if ($relativepath[0] != '/') { print_error('pathdoesnotstartslash'); } } // extract relative path components $args = explode('/', ltrim($relativepath, '/')); if (count($args) < 3) { // always at least context, component and filearea print_error('invalidarguments'); } $contextid = (int) array_shift($args); $component = clean_param(array_shift($args), PARAM_COMPONENT); $filearea = clean_param(array_shift($args), PARAM_AREA); list($context, $course, $cm) = get_context_info_array($contextid); $fs = get_file_storage(); // ======================================================================================================================== if ($component === 'blog') { // Blog file serving if ($context->contextlevel != CONTEXT_SYSTEM) { send_file_not_found(); } if ($filearea !== 'attachment' and $filearea !== 'post') { send_file_not_found(); } if (empty($CFG->enableblogs)) { print_error('siteblogdisable', 'blog'); } $entryid = (int) array_shift($args); if (!($entry = $DB->get_record('post', array('module' => 'blog', 'id' => $entryid)))) { send_file_not_found(); } if ($CFG->bloglevel < BLOG_GLOBAL_LEVEL) { require_login(); if (isguestuser()) { print_error('noguest'); } if ($CFG->bloglevel == BLOG_USER_LEVEL) { if ($USER->id != $entry->userid) { send_file_not_found(); } } } if ($entry->publishstate === 'public') { if ($CFG->forcelogin) { require_login(); } } else { if ($entry->publishstate === 'site') { require_login(); //ok } else { if ($entry->publishstate === 'draft') { require_login(); if ($USER->id != $entry->userid) { send_file_not_found(); } } } } $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, $component, $filearea, $entryid, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } send_stored_file($file, 10 * 60, 0, true, array('preview' => $preview)); // download MUST be forced - security! // ======================================================================================================================== } else { if ($component === 'grade') { if (($filearea === 'outcome' or $filearea === 'scale') and $context->contextlevel == CONTEXT_SYSTEM) { // Global gradebook files if ($CFG->forcelogin) { require_login(); } $fullpath = "/{$context->id}/{$component}/{$filearea}/" . implode('/', $args); if (!($file = $fs->get_file_by_hash(sha1($fullpath))) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview)); } else { if ($filearea === 'feedback' and $context->contextlevel == CONTEXT_COURSE) { //TODO: nobody implemented this yet in grade edit form!! send_file_not_found(); if ($CFG->forcelogin || $course->id != SITEID) { require_login($course); } $fullpath = "/{$context->id}/{$component}/{$filearea}/" . implode('/', $args); if (!($file = $fs->get_file_by_hash(sha1($fullpath))) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview)); } else { send_file_not_found(); } } // ======================================================================================================================== } else { if ($component === 'tag') { if ($filearea === 'description' and $context->contextlevel == CONTEXT_SYSTEM) { // All tag descriptions are going to be public but we still need to respect forcelogin if ($CFG->forcelogin) { require_login(); } $fullpath = "/{$context->id}/tag/description/" . implode('/', $args); if (!($file = $fs->get_file_by_hash(sha1($fullpath))) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 60 * 60, 0, true, array('preview' => $preview)); } else { send_file_not_found(); } // ======================================================================================================================== } else { if ($component === 'badges') { require_once $CFG->libdir . '/badgeslib.php'; $badgeid = (int) array_shift($args); $badge = new badge($badgeid); $filename = array_pop($args); if ($filearea === 'badgeimage') { if ($filename !== 'f1' && $filename !== 'f2') { send_file_not_found(); } if (!($file = $fs->get_file($context->id, 'badges', 'badgeimage', $badge->id, '/', $filename . '.png'))) { send_file_not_found(); } \core\session\manager::write_close(); send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview)); } else { if ($filearea === 'userbadge' and $context->contextlevel == CONTEXT_USER) { if (!($file = $fs->get_file($context->id, 'badges', 'userbadge', $badge->id, '/', $filename . '.png'))) { send_file_not_found(); } \core\session\manager::write_close(); send_stored_file($file, 60 * 60, 0, true, array('preview' => $preview)); } } // ======================================================================================================================== } else { if ($component === 'calendar') { if ($filearea === 'event_description' and $context->contextlevel == CONTEXT_SYSTEM) { // All events here are public the one requirement is that we respect forcelogin if ($CFG->forcelogin) { require_login(); } // Get the event if from the args array $eventid = array_shift($args); // Load the event from the database if (!($event = $DB->get_record('event', array('id' => (int) $eventid, 'eventtype' => 'site')))) { send_file_not_found(); } // Get the file and serve if successful $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, $component, $filearea, $eventid, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview)); } else { if ($filearea === 'event_description' and $context->contextlevel == CONTEXT_USER) { // Must be logged in, if they are not then they obviously can't be this user require_login(); // Don't want guests here, potentially saves a DB call if (isguestuser()) { send_file_not_found(); } // Get the event if from the args array $eventid = array_shift($args); // Load the event from the database - user id must match if (!($event = $DB->get_record('event', array('id' => (int) $eventid, 'userid' => $USER->id, 'eventtype' => 'user')))) { send_file_not_found(); } // Get the file and serve if successful $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, $component, $filearea, $eventid, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 0, 0, true, array('preview' => $preview)); } else { if ($filearea === 'event_description' and $context->contextlevel == CONTEXT_COURSE) { // Respect forcelogin and require login unless this is the site.... it probably // should NEVER be the site if ($CFG->forcelogin || $course->id != SITEID) { require_login($course); } // Must be able to at least view the course. This does not apply to the front page. if ($course->id != SITEID && !is_enrolled($context) && !is_viewing($context)) { //TODO: hmm, do we really want to block guests here? send_file_not_found(); } // Get the event id $eventid = array_shift($args); // Load the event from the database we need to check whether it is // a) valid course event // b) a group event // Group events use the course context (there is no group context) if (!($event = $DB->get_record('event', array('id' => (int) $eventid, 'courseid' => $course->id)))) { send_file_not_found(); } // If its a group event require either membership of view all groups capability if ($event->eventtype === 'group') { if (!has_capability('moodle/site:accessallgroups', $context) && !groups_is_member($event->groupid, $USER->id)) { send_file_not_found(); } } else { if ($event->eventtype === 'course' || $event->eventtype === 'site') { // Ok. Please note that the event type 'site' still uses a course context. } else { // Some other type. send_file_not_found(); } } // If we get this far we can serve the file $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, $component, $filearea, $eventid, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview)); } else { send_file_not_found(); } } } // ======================================================================================================================== } else { if ($component === 'user') { if ($filearea === 'icon' and $context->contextlevel == CONTEXT_USER) { if (count($args) == 1) { $themename = theme_config::DEFAULT_THEME; $filename = array_shift($args); } else { $themename = array_shift($args); $filename = array_shift($args); } // fix file name automatically if ($filename !== 'f1' and $filename !== 'f2' and $filename !== 'f3') { $filename = 'f1'; } if ((!empty($CFG->forcelogin) and !isloggedin()) || !empty($CFG->forceloginforprofileimage) && (!isloggedin() || isguestuser())) { // protect images if login required and not logged in; // also if login is required for profile images and is not logged in or guest // do not use require_login() because it is expensive and not suitable here anyway $theme = theme_config::load($themename); redirect($theme->pix_url('u/' . $filename, 'moodle')); // intentionally not cached } if (!($file = $fs->get_file($context->id, 'user', 'icon', 0, '/', $filename . '.png'))) { if (!($file = $fs->get_file($context->id, 'user', 'icon', 0, '/', $filename . '.jpg'))) { if ($filename === 'f3') { // f3 512x512px was introduced in 2.3, there might be only the smaller version. if (!($file = $fs->get_file($context->id, 'user', 'icon', 0, '/', 'f1.png'))) { $file = $fs->get_file($context->id, 'user', 'icon', 0, '/', 'f1.jpg'); } } } } if (!$file) { // bad reference - try to prevent future retries as hard as possible! if ($user = $DB->get_record('user', array('id' => $context->instanceid), 'id, picture')) { if ($user->picture > 0) { $DB->set_field('user', 'picture', 0, array('id' => $user->id)); } } // no redirect here because it is not cached $theme = theme_config::load($themename); $imagefile = $theme->resolve_image_location('u/' . $filename, 'moodle', null); send_file($imagefile, basename($imagefile), 60 * 60 * 24 * 14); } $options = array('preview' => $preview); if (empty($CFG->forcelogin) && empty($CFG->forceloginforprofileimage)) { // Profile images should be cache-able by both browsers and proxies according // to $CFG->forcelogin and $CFG->forceloginforprofileimage. $options['cacheability'] = 'public'; } send_stored_file($file, 60 * 60 * 24 * 365, 0, false, $options); // enable long caching, there are many images on each page } else { if ($filearea === 'private' and $context->contextlevel == CONTEXT_USER) { require_login(); if (isguestuser()) { send_file_not_found(); } if ($USER->id !== $context->instanceid) { send_file_not_found(); } $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, $component, $filearea, 0, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 0, 0, true, array('preview' => $preview)); // must force download - security! } else { if ($filearea === 'profile' and $context->contextlevel == CONTEXT_USER) { if ($CFG->forcelogin) { require_login(); } $userid = $context->instanceid; if ($USER->id == $userid) { // always can access own } else { if (!empty($CFG->forceloginforprofiles)) { require_login(); if (isguestuser()) { send_file_not_found(); } // we allow access to site profile of all course contacts (usually teachers) if (!has_coursecontact_role($userid) && !has_capability('moodle/user:viewdetails', $context)) { send_file_not_found(); } $canview = false; if (has_capability('moodle/user:viewdetails', $context)) { $canview = true; } else { $courses = enrol_get_my_courses(); } while (!$canview && count($courses) > 0) { $course = array_shift($courses); if (has_capability('moodle/user:viewdetails', context_course::instance($course->id))) { $canview = true; } } } } $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, $component, $filearea, 0, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 0, 0, true, array('preview' => $preview)); // must force download - security! } else { if ($filearea === 'profile' and $context->contextlevel == CONTEXT_COURSE) { $userid = (int) array_shift($args); $usercontext = context_user::instance($userid); if ($CFG->forcelogin) { require_login(); } if (!empty($CFG->forceloginforprofiles)) { require_login(); if (isguestuser()) { print_error('noguest'); } //TODO: review this logic of user profile access prevention if (!has_coursecontact_role($userid) and !has_capability('moodle/user:viewdetails', $usercontext)) { print_error('usernotavailable'); } if (!has_capability('moodle/user:viewdetails', $context) && !has_capability('moodle/user:viewdetails', $usercontext)) { print_error('cannotviewprofile'); } if (!is_enrolled($context, $userid)) { print_error('notenrolledprofile'); } if (groups_get_course_groupmode($course) == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context)) { print_error('groupnotamember'); } } $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($usercontext->id, 'user', 'profile', 0, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 0, 0, true, array('preview' => $preview)); // must force download - security! } else { if ($filearea === 'backup' and $context->contextlevel == CONTEXT_USER) { require_login(); if (isguestuser()) { send_file_not_found(); } $userid = $context->instanceid; if ($USER->id != $userid) { send_file_not_found(); } $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, 'user', 'backup', 0, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 0, 0, true, array('preview' => $preview)); // must force download - security! } else { send_file_not_found(); } } } } } // ======================================================================================================================== } else { if ($component === 'coursecat') { if ($context->contextlevel != CONTEXT_COURSECAT) { send_file_not_found(); } if ($filearea === 'description') { if ($CFG->forcelogin) { // no login necessary - unless login forced everywhere require_login(); } $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, 'coursecat', 'description', 0, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview)); } else { send_file_not_found(); } // ======================================================================================================================== } else { if ($component === 'course') { if ($context->contextlevel != CONTEXT_COURSE) { send_file_not_found(); } if ($filearea === 'summary' || $filearea === 'overviewfiles') { if ($CFG->forcelogin) { require_login(); } $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, 'course', $filearea, 0, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview)); } else { if ($filearea === 'section') { if ($CFG->forcelogin) { require_login($course); } else { if ($course->id != SITEID) { require_login($course); } } $sectionid = (int) array_shift($args); if (!($section = $DB->get_record('course_sections', array('id' => $sectionid, 'course' => $course->id)))) { send_file_not_found(); } $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, 'course', 'section', $sectionid, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview)); } else { send_file_not_found(); } } } else { if ($component === 'cohort') { $cohortid = (int) array_shift($args); $cohort = $DB->get_record('cohort', array('id' => $cohortid), '*', MUST_EXIST); $cohortcontext = context::instance_by_id($cohort->contextid); // The context in the file URL must be either cohort context or context of the course underneath the cohort's context. if ($context->id != $cohort->contextid && ($context->contextlevel != CONTEXT_COURSE || !in_array($cohort->contextid, $context->get_parent_context_ids()))) { send_file_not_found(); } // User is able to access cohort if they have view cap on cohort level or // the cohort is visible and they have view cap on course level. $canview = has_capability('moodle/cohort:view', $cohortcontext) || $cohort->visible && has_capability('moodle/cohort:view', $context); if ($filearea === 'description' && $canview) { $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (($file = $fs->get_file($cohortcontext->id, 'cohort', 'description', $cohort->id, $filepath, $filename)) && !$file->is_directory()) { \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview)); } } send_file_not_found(); } else { if ($component === 'group') { if ($context->contextlevel != CONTEXT_COURSE) { send_file_not_found(); } require_course_login($course, true, null, false); $groupid = (int) array_shift($args); $group = $DB->get_record('groups', array('id' => $groupid, 'courseid' => $course->id), '*', MUST_EXIST); if ($course->groupmodeforce and $course->groupmode == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context) and !groups_is_member($group->id, $USER->id)) { // do not allow access to separate group info if not member or teacher send_file_not_found(); } if ($filearea === 'description') { require_login($course); $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, 'group', 'description', $group->id, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview)); } else { if ($filearea === 'icon') { $filename = array_pop($args); if ($filename !== 'f1' and $filename !== 'f2') { send_file_not_found(); } if (!($file = $fs->get_file($context->id, 'group', 'icon', $group->id, '/', $filename . '.png'))) { if (!($file = $fs->get_file($context->id, 'group', 'icon', $group->id, '/', $filename . '.jpg'))) { send_file_not_found(); } } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 60 * 60, 0, false, array('preview' => $preview)); } else { send_file_not_found(); } } } else { if ($component === 'grouping') { if ($context->contextlevel != CONTEXT_COURSE) { send_file_not_found(); } require_login($course); $groupingid = (int) array_shift($args); // note: everybody has access to grouping desc images for now if ($filearea === 'description') { $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, 'grouping', 'description', $groupingid, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview)); } else { send_file_not_found(); } // ======================================================================================================================== } else { if ($component === 'backup') { if ($filearea === 'course' and $context->contextlevel == CONTEXT_COURSE) { require_login($course); require_capability('moodle/backup:downloadfile', $context); $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, 'backup', 'course', 0, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 0, 0, $forcedownload, array('preview' => $preview)); } else { if ($filearea === 'section' and $context->contextlevel == CONTEXT_COURSE) { require_login($course); require_capability('moodle/backup:downloadfile', $context); $sectionid = (int) array_shift($args); $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, 'backup', 'section', $sectionid, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview)); } else { if ($filearea === 'activity' and $context->contextlevel == CONTEXT_MODULE) { require_login($course, false, $cm); require_capability('moodle/backup:downloadfile', $context); $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, 'backup', 'activity', 0, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview)); } else { if ($filearea === 'automated' and $context->contextlevel == CONTEXT_COURSE) { // Backup files that were generated by the automated backup systems. require_login($course); require_capability('moodle/site:config', $context); $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, 'backup', 'automated', 0, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 0, 0, $forcedownload, array('preview' => $preview)); } else { send_file_not_found(); } } } } // ======================================================================================================================== } else { if ($component === 'question') { require_once $CFG->libdir . '/questionlib.php'; question_pluginfile($course, $context, 'question', $filearea, $args, $forcedownload); send_file_not_found(); // ======================================================================================================================== } else { if ($component === 'grading') { if ($filearea === 'description') { // files embedded into the form definition description if ($context->contextlevel == CONTEXT_SYSTEM) { require_login(); } else { if ($context->contextlevel >= CONTEXT_COURSE) { require_login($course, false, $cm); } else { send_file_not_found(); } } $formid = (int) array_shift($args); $sql = "SELECT ga.id\n FROM {grading_areas} ga\n JOIN {grading_definitions} gd ON (gd.areaid = ga.id)\n WHERE gd.id = ? AND ga.contextid = ?"; $areaid = $DB->get_field_sql($sql, array($formid, $context->id), IGNORE_MISSING); if (!$areaid) { send_file_not_found(); } $fullpath = "/{$context->id}/{$component}/{$filearea}/{$formid}/" . implode('/', $args); if (!($file = $fs->get_file_by_hash(sha1($fullpath))) or $file->is_directory()) { send_file_not_found(); } \core\session\manager::write_close(); // Unlock session during file serving. send_stored_file($file, 60 * 60, 0, $forcedownload, array('preview' => $preview)); } // ======================================================================================================================== } else { if (strpos($component, 'mod_') === 0) { $modname = substr($component, 4); if (!file_exists("{$CFG->dirroot}/mod/{$modname}/lib.php")) { send_file_not_found(); } require_once "{$CFG->dirroot}/mod/{$modname}/lib.php"; if ($context->contextlevel == CONTEXT_MODULE) { if ($cm->modname !== $modname) { // somebody tries to gain illegal access, cm type must match the component! send_file_not_found(); } } if ($filearea === 'intro') { if (!plugin_supports('mod', $modname, FEATURE_MOD_INTRO, true)) { send_file_not_found(); } require_course_login($course, true, $cm); // all users may access it $filename = array_pop($args); $filepath = $args ? '/' . implode('/', $args) . '/' : '/'; if (!($file = $fs->get_file($context->id, 'mod_' . $modname, 'intro', 0, $filepath, $filename)) or $file->is_directory()) { send_file_not_found(); } // finally send the file send_stored_file($file, null, 0, false, array('preview' => $preview)); } $filefunction = $component . '_pluginfile'; $filefunctionold = $modname . '_pluginfile'; if (function_exists($filefunction)) { // if the function exists, it must send the file and terminate. Whatever it returns leads to "not found" $filefunction($course, $cm, $context, $filearea, $args, $forcedownload, array('preview' => $preview)); } else { if (function_exists($filefunctionold)) { // if the function exists, it must send the file and terminate. Whatever it returns leads to "not found" $filefunctionold($course, $cm, $context, $filearea, $args, $forcedownload, array('preview' => $preview)); } } send_file_not_found(); // ======================================================================================================================== } else { if (strpos($component, 'block_') === 0) { $blockname = substr($component, 6); // note: no more class methods in blocks please, that is .... if (!file_exists("{$CFG->dirroot}/blocks/{$blockname}/lib.php")) { send_file_not_found(); } require_once "{$CFG->dirroot}/blocks/{$blockname}/lib.php"; if ($context->contextlevel == CONTEXT_BLOCK) { $birecord = $DB->get_record('block_instances', array('id' => $context->instanceid), '*', MUST_EXIST); if ($birecord->blockname !== $blockname) { // somebody tries to gain illegal access, cm type must match the component! send_file_not_found(); } if ($context->get_course_context(false)) { // If block is in course context, then check if user has capability to access course. require_course_login($course); } else { if ($CFG->forcelogin) { // If user is logged out, bp record will not be visible, even if the user would have access if logged in. require_login(); } } $bprecord = $DB->get_record('block_positions', array('contextid' => $context->id, 'blockinstanceid' => $context->instanceid)); // User can't access file, if block is hidden or doesn't have block:view capability if ($bprecord && !$bprecord->visible || !has_capability('moodle/block:view', $context)) { send_file_not_found(); } } else { $birecord = null; } $filefunction = $component . '_pluginfile'; if (function_exists($filefunction)) { // if the function exists, it must send the file and terminate. Whatever it returns leads to "not found" $filefunction($course, $birecord, $context, $filearea, $args, $forcedownload, array('preview' => $preview)); } send_file_not_found(); // ======================================================================================================================== } else { if (strpos($component, '_') === false) { // all core subsystems have to be specified above, no more guessing here! send_file_not_found(); } else { // try to serve general plugin file in arbitrary context $dir = core_component::get_component_directory($component); if (!file_exists("{$dir}/lib.php")) { send_file_not_found(); } include_once "{$dir}/lib.php"; $filefunction = $component . '_pluginfile'; if (function_exists($filefunction)) { // if the function exists, it must send the file and terminate. Whatever it returns leads to "not found" $filefunction($course, $cm, $context, $filearea, $args, $forcedownload, array('preview' => $preview)); } send_file_not_found(); } } } } } } } } } } } } } } } } } }
/** * This function approves the request turning it into a course * * This function converts the course request into a course, at the same time * transferring any files used in the summary to the new course and then removing * the course request and the files associated with it. * * @return int The id of the course that was created from this request */ public function approve() { global $CFG, $DB, $USER; $user = $DB->get_record('user', array('id' => $this->properties->requester, 'deleted' => 0), '*', MUST_EXIST); $category = get_course_category($CFG->defaultrequestcategory); $courseconfig = get_config('moodlecourse'); // Transfer appropriate settings $data = clone $this->properties; unset($data->id); unset($data->reason); unset($data->requester); // Set category $data->category = $category->id; $data->sortorder = $category->sortorder; // place as the first in category // Set misc settings $data->requested = 1; // Apply course default settings $data->format = $courseconfig->format; $data->numsections = $courseconfig->numsections; $data->hiddensections = $courseconfig->hiddensections; $data->newsitems = $courseconfig->newsitems; $data->showgrades = $courseconfig->showgrades; $data->showreports = $courseconfig->showreports; $data->maxbytes = $courseconfig->maxbytes; $data->groupmode = $courseconfig->groupmode; $data->groupmodeforce = $courseconfig->groupmodeforce; $data->visible = $courseconfig->visible; $data->visibleold = $data->visible; $data->lang = $courseconfig->lang; $course = create_course($data); $context = get_context_instance(CONTEXT_COURSE, $course->id, MUST_EXIST); // add enrol instances if (!$DB->record_exists('enrol', array('courseid' => $course->id, 'enrol' => 'manual'))) { if ($manual = enrol_get_plugin('manual')) { $manual->add_default_instance($course); } } // enrol the requester as teacher if necessary if (!empty($CFG->creatornewroleid) and !is_viewing($context, $user, 'moodle/role:assign') and !is_enrolled($context, $user, 'moodle/role:assign')) { enrol_try_internal_enrol($course->id, $user->id, $CFG->creatornewroleid); } $this->delete(); $a = new stdClass(); $a->name = format_string($course->fullname, true, array('context' => get_context_instance(CONTEXT_COURSE, $course->id))); $a->url = $CFG->wwwroot . '/course/view.php?id=' . $course->id; $this->notify($user, $USER, 'courserequestapproved', get_string('courseapprovedsubject'), get_string('courseapprovedemail2', 'moodle', $a)); return $course->id; }
/** * block contents * * @return object */ public function get_content() { global $CFG, $USER, $DB, $OUTPUT, $PAGE; if ($this->content !== NULL) { return $this->content; } if (!isloggedin()) { return ''; // Never useful unless you are logged in } $this->content = new stdClass(); $this->content->text = ''; $this->content->footer = ''; $course = $this->page->course; if ($PAGE->context->contextlevel == CONTEXT_USER) { $user = $DB->get_record('user', array('id' => $PAGE->context->instanceid)); } else { $user = $USER; } if ($course->id == SITEID) { $coursecontext = get_context_instance(CONTEXT_SYSTEM); } else { $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id); // Course context // Make sure they can view the course if (!is_viewing($coursecontext)) { return ''; } } // TODO: clean up the following even more if (!isset($this->config->display_picture) || $this->config->display_picture == 1) { $this->content->text .= '<div class="myprofileitem picture">'; $this->content->text .= $OUTPUT->user_picture($user, array('courseid' => $course->id, 'size' => '100', 'class' => 'profilepicture')); // The new class makes CSS easier $this->content->text .= '</div>'; } $this->content->text .= '<div class="myprofileitem fullname">' . fullname($user) . '</div>'; if (!isset($this->config->display_country) || $this->config->display_country == 1) { $countries = get_string_manager()->get_list_of_countries(); if (isset($countries[$user->country])) { $this->content->text .= '<div class="myprofileitem country">'; $this->content->text .= get_string('country') . ': ' . $countries[$user->country]; $this->content->text .= '</div>'; } } if (!isset($this->config->display_city) || $this->config->display_city == 1) { $this->content->text .= '<div class="myprofileitem city">'; $this->content->text .= get_string('city') . ': ' . $user->city; $this->content->text .= '</div>'; } if (!isset($this->config->display_email) || $this->config->display_email == 1) { $this->content->text .= '<div class="myprofileitem email">'; $this->content->text .= obfuscate_mailto($user->email, ''); $this->content->text .= '</div>'; } if (!empty($this->config->display_icq) && !empty($user->icq)) { $this->content->text .= '<div class="myprofileitem icq">'; $this->content->text .= 'ICQ: ' . $user->icq; $this->content->text .= '</div>'; } if (!empty($this->config->display_skype) && !empty($user->skype)) { $this->content->text .= '<div class="myprofileitem skype">'; $this->content->text .= 'Skype: ' . $user->skype; $this->content->text .= '</div>'; } if (!empty($this->config->display_yahoo) && !empty($user->yahoo)) { $this->content->text .= '<div class="myprofileitem yahoo">'; $this->content->text .= 'Yahoo: ' . $user->yahoo; $this->content->text .= '</div>'; } if (!empty($this->config->display_aim) && !empty($user->aim)) { $this->content->text .= '<div class="myprofileitem aim">'; $this->content->text .= 'AIM: ' . $user->aim; $this->content->text .= '</div>'; } if (!empty($this->config->display_msn) && !empty($user->msn)) { $this->content->text .= '<div class="myprofileitem msn">'; $this->content->text .= 'MSN: ' . $user->msn; $this->content->text .= '</div>'; } if (!empty($this->config->display_phone1) && !empty($user->phone1)) { $this->content->text .= '<div class="myprofileitem phone1">'; $this->content->text .= get_string('phone') . ': ' . $user->phone1; $this->content->text .= '</div>'; } if (!empty($this->config->display_phone2) && !empty($user->phone2)) { $this->content->text .= '<div class="myprofileitem phone2">'; $this->content->text .= get_string('phone') . ': ' . $user->phone2; $this->content->text .= '</div>'; } if (!empty($this->config->display_institution) && !empty($user->institution)) { $this->content->text .= '<div class="myprofileitem institution">'; $this->content->text .= $user->institution; $this->content->text .= '</div>'; } if (!empty($this->config->display_address) && !empty($user->address)) { $this->content->text .= '<div class="myprofileitem address">'; $this->content->text .= $user->address; $this->content->text .= '</div>'; } if (!empty($this->config->display_firstaccess) && !empty($user->firstaccess)) { $this->content->text .= '<div class="myprofileitem firstaccess">'; $this->content->text .= get_string('firstaccess') . ': ' . userdate($user->firstaccess); $this->content->text .= '</div>'; } if (!empty($this->config->display_lastaccess) && !empty($user->lastaccess)) { $this->content->text .= '<div class="myprofileitem lastaccess">'; $this->content->text .= get_string('lastaccess') . ': ' . userdate($user->lastaccess); $this->content->text .= '</div>'; } if (!empty($this->config->display_currentlogin) && !empty($user->currentlogin)) { $this->content->text .= '<div class="myprofileitem currentlogin">'; $this->content->text .= get_string('login') . ': ' . userdate($user->currentlogin); $this->content->text .= '</div>'; } if (!empty($this->config->display_lastip) && !empty($user->lastip)) { $this->content->text .= '<div class="myprofileitem lastip">'; $this->content->text .= 'IP: ' . $user->lastip; $this->content->text .= '</div>'; } $editscript = NULL; if (isguestuser($user)) { // guest account can not be edited } else { if (is_mnet_remote_user($user)) { // cannot edit remote users } else { if (isguestuser() or !isloggedin()) { // guests and not logged in can not edit own profile } else { if ($USER->id == $user->id) { $systemcontext = get_context_instance(CONTEXT_SYSTEM); if (has_capability('moodle/user:update', $systemcontext)) { $editscript = '/user/editadvanced.php'; } else { if (has_capability('moodle/user:editownprofile', $systemcontext)) { $editscript = '/user/edit.php'; } } } else { $systemcontext = get_context_instance(CONTEXT_SYSTEM); $personalcontext = get_context_instance(CONTEXT_USER, $user->id); if (has_capability('moodle/user:update', $systemcontext) and !is_primary_admin($user->id)) { $editscript = '/user/editadvanced.php'; } else { if (has_capability('moodle/user:editprofile', $personalcontext) and !is_primary_admin($user->id)) { //teachers, parents, etc. $editscript = '/user/edit.php'; } } } } } } if ($editscript) { $this->content->text .= '<div class="myprofileitem edit">'; $this->content->text .= '<a href="' . $CFG->wwwroot . $editscript . '?id=' . $user->id . '&course=' . $course->id . '">' . get_string('editmyprofile') . '</a>'; $this->content->text .= '</div>'; } return $this->content; }
/** * this function handles the access policy to contents indexed as searchable documents. If this * function does not exist, the search engine assumes access is allowed. * @uses $CFG, $DB * @param string $path the access path to the module script code * @param string $itemtype the information subclassing (usefull for complex modules, defaults to 'standard') * @param int $this_id the item id within the information class denoted by itemtype. In resources, this id * points to the resource record and not to the module that shows it. * @param object $user the user record denoting the user who searches * @param int $group_id the current group used by the user when searching * @return true if access is allowed, false elsewhere */ function label_check_text_access($path, $itemtype, $this_id, $user, $group_id, $context_id) { global $CFG, $DB; $r = $DB->get_record('label', array('id' => $this_id)); $module_context = $DB->get_record('context', array('id' => $context_id)); $cm = $DB->get_record('course_modules', array('id' => $module_context->instanceid)); if (empty($cm)) { return false; } // Shirai 20090530 - MDL19342 - course module might have been delete $course_context = get_context_instance(CONTEXT_COURSE, $r->course); //check if englobing course is visible if (!is_enrolled($course_context) and !is_viewing($course_context)) { return false; } //check if found course module is visible if (!$cm->visible and !has_capability('moodle/course:viewhiddenactivities', $module_context)) { return false; } return true; }
} else { // normal course require_login($course); // what to do with users temporary accessing this course? should they see the details? } $strpersonalprofile = get_string('personalprofile'); $strparticipants = get_string("participants"); $struser = get_string("user"); $fullname = fullname($user, has_capability('moodle/site:viewfullnames', $coursecontext)); /// Now test the actual capabilities and enrolment in course if ($currentuser) { // me if (!is_enrolled($coursecontext) and !is_viewing($coursecontext)) { // Need to have full access to a course to see the rest of own info echo $OUTPUT->header(); echo $OUTPUT->heading(get_string('notenrolled', '', $fullname)); if (!empty($_SERVER['HTTP_REFERER'])) { echo $OUTPUT->continue_button($_SERVER['HTTP_REFERER']); } echo $OUTPUT->footer(); die; } } else { // somebody else $PAGE->set_title("$strpersonalprofile: "); $PAGE->set_heading("$strpersonalprofile: "); // check course level capabilities
/** * Returns true if the user is able to access the course. * * This function is in no way, shape, or form a substitute for require_login. * It should only be used in circumstances where it is not possible to call require_login * such as the navigation. * * This function checks many of the methods of access to a course such as the view * capability, enrollments, and guest access. It also makes use of the cache * generated by require_login for guest access. * * The flags within the $USER object that are used here should NEVER be used outside * of this function can_access_course and require_login. Doing so WILL break future * versions. * * @param stdClass $course record * @param stdClass|int|null $user user record or id, current user if null * @param string $withcapability Check for this capability as well. * @param bool $onlyactive consider only active enrolments in enabled plugins and time restrictions * @return boolean Returns true if the user is able to access the course */ function can_access_course(stdClass $course, $user = null, $withcapability = '', $onlyactive = false) { global $DB, $USER; // this function originally accepted $coursecontext parameter if ($course instanceof context) { if ($course instanceof context_course) { debugging('deprecated context parameter, please use $course record'); $coursecontext = $course; $course = $DB->get_record('course', array('id' => $coursecontext->instanceid)); } else { debugging('Invalid context parameter, please use $course record'); return false; } } else { $coursecontext = context_course::instance($course->id); } if (!isset($USER->id)) { // should never happen $USER->id = 0; } // make sure there is a user specified if ($user === null) { $userid = $USER->id; } else { $userid = is_object($user) ? $user->id : $user; } unset($user); if ($withcapability and !has_capability($withcapability, $coursecontext, $userid)) { return false; } if ($userid == $USER->id) { if (!empty($USER->access['rsw'][$coursecontext->path])) { // the fact that somebody switched role means they can access the course no matter to what role they switched return true; } } if (!$course->visible and !has_capability('moodle/course:viewhiddencourses', $coursecontext, $userid)) { return false; } if (is_viewing($coursecontext, $userid)) { return true; } if ($userid != $USER->id) { // for performance reasons we do not verify temporary guest access for other users, sorry... return is_enrolled($coursecontext, $userid, '', $onlyactive); } // === from here we deal only with $USER === // verify our caches if (!isset($USER->enrol)) { /** * These flags within the $USER object should NEVER be used outside of this * function can_access_course and the function require_login. * Doing so WILL break future versions!!!! */ $USER->enrol = array(); $USER->enrol['enrolled'] = array(); $USER->enrol['tempguest'] = array(); } if (isset($USER->enrol['enrolled'][$course->id])) { if ($USER->enrol['enrolled'][$course->id] == 0) { return true; } else { if ($USER->enrol['enrolled'][$course->id] > time()) { return true; } } } if (isset($USER->enrol['tempguest'][$course->id])) { if ($USER->enrol['tempguest'][$course->id] == 0) { return true; } else { if ($USER->enrol['tempguest'][$course->id] > time()) { return true; } } } if (is_enrolled($coursecontext, $USER, '', true)) { // active participants may always access // TODO: refactor this into some new function $now = time(); $sql = "SELECT MAX(ue.timeend)\n FROM {user_enrolments} ue\n JOIN {enrol} e ON (e.id = ue.enrolid AND e.courseid = :courseid)\n JOIN {user} u ON u.id = ue.userid\n WHERE ue.userid = :userid AND ue.status = :active AND e.status = :enabled AND u.deleted = 0\n AND ue.timestart < :now1 AND (ue.timeend = 0 OR ue.timeend > :now2)"; $params = array('enabled' => ENROL_INSTANCE_ENABLED, 'active' => ENROL_USER_ACTIVE, 'userid' => $USER->id, 'courseid' => $coursecontext->instanceid, 'now1' => $now, 'now2' => $now); $until = $DB->get_field_sql($sql, $params); if (!$until or $until > time() + ENROL_REQUIRE_LOGIN_CACHE_PERIOD) { $until = time() + ENROL_REQUIRE_LOGIN_CACHE_PERIOD; } $USER->enrol['enrolled'][$course->id] = $until; // remove traces of previous temp guest access remove_temp_course_roles($coursecontext); return true; } unset($USER->enrol['enrolled'][$course->id]); // if not enrolled try to gain temporary guest access $instances = $DB->get_records('enrol', array('courseid' => $course->id, 'status' => ENROL_INSTANCE_ENABLED), 'sortorder, id ASC'); $enrols = enrol_get_plugins(true); foreach ($instances as $instance) { if (!isset($enrols[$instance->enrol])) { continue; } // Get a duration for the guestaccess, a timestamp in the future or false. $until = $enrols[$instance->enrol]->try_guestaccess($instance); if ($until !== false) { $USER->enrol['tempguest'][$course->id] = $until; return true; } } unset($USER->enrol['tempguest'][$course->id]); return false; }
/** * this function handles the access policy to contents indexed as searchable documents. If this * function does not exist, the search engine assumes access is allowed. * @uses $CFG, $DB * @param path the access path to the module script code * @param itemtype the information subclassing (usefull for complex modules, defaults to 'standard') * @param this_id the item id within the information class denoted by itemtype. In resources, this id * points to the resource record and not to the module that shows it. * @param user the user record denoting the user who searches * @param group_id the current group used by the user when searching * @return true if access is allowed, false elsewhere */ function resource_check_text_access($path, $itemtype, $this_id, $user, $group_id, $context_id) { global $CFG, $DB; // include_once("{$CFG->dirroot}/{$path}/lib.php"); $r = $DB->get_record('resource', array('id' => $this_id)); $module_context = $DB->get_record('context', array('id' => $context_id)); $cm = $DB->get_record('course_modules', array('id' => $module_context->instanceid)); if (empty($cm)) { return false; } // Shirai 20090530 - MDL19342 - course module might have been delete $course = $DB->get_record('course', array('id' => $r->course)); $course_context = get_context_instance(CONTEXT_COURSE, $r->course); $course = $DB->get_record('course', array('id' => $r->course)); //check if course is visible if (!$course->visible && !has_capability('moodle/course:viewhiddencourses', $course_context)) { return false; } //check if user is registered in course or course is open to guests if (!is_enrolled($course_context) and !is_viewing($course_context)) { //TODO: guest course access is gone, this needs a different solution return false; } //check if found course module is visible if (!$cm->visible and !has_capability('moodle/course:viewhiddenactivities', $module_context)) { return false; } return true; }
/** * This function checks that the current user is logged in and has the * required privileges * * This function checks that the current user is logged in, and optionally * whether they are allowed to be in a particular course and view a particular * course module. * If they are not logged in, then it redirects them to the site login unless * $autologinguest is set and {@link $CFG}->autologinguests is set to 1 in which * case they are automatically logged in as guests. * If $courseid is given and the user is not enrolled in that course then the * user is redirected to the course enrolment page. * If $cm is given and the course module is hidden and the user is not a teacher * in the course then the user is redirected to the course home page. * * When $cm parameter specified, this function sets page layout to 'module'. * You need to change it manually later if some other layout needed. * * @package core_access * @category access * * @param mixed $courseorid id of the course or course object * @param bool $autologinguest default true * @param object $cm course module object * @param bool $setwantsurltome Define if we want to set $SESSION->wantsurl, defaults to * true. Used to avoid (=false) some scripts (file.php...) to set that variable, * in order to keep redirects working properly. MDL-14495 * @param bool $preventredirect set to true in scripts that can not redirect (CLI, rss feeds, etc.), throws exceptions * @return mixed Void, exit, and die depending on path * @throws coding_exception * @throws require_login_exception */ function require_login($courseorid = null, $autologinguest = true, $cm = null, $setwantsurltome = true, $preventredirect = false) { global $CFG, $SESSION, $USER, $PAGE, $SITE, $DB, $OUTPUT; // Must not redirect when byteserving already started. if (!empty($_SERVER['HTTP_RANGE'])) { $preventredirect = true; } if (AJAX_SCRIPT) { // We cannot redirect for AJAX scripts either. $preventredirect = true; } // Setup global $COURSE, themes, language and locale. if (!empty($courseorid)) { if (is_object($courseorid)) { $course = $courseorid; } else { if ($courseorid == SITEID) { $course = clone $SITE; } else { $course = $DB->get_record('course', array('id' => $courseorid), '*', MUST_EXIST); } } if ($cm) { if ($cm->course != $course->id) { throw new coding_exception('course and cm parameters in require_login() call do not match!!'); } // Make sure we have a $cm from get_fast_modinfo as this contains activity access details. if (!$cm instanceof cm_info) { // Note: nearly all pages call get_fast_modinfo anyway and it does not make any // db queries so this is not really a performance concern, however it is obviously // better if you use get_fast_modinfo to get the cm before calling this. $modinfo = get_fast_modinfo($course); $cm = $modinfo->get_cm($cm->id); } } } else { // Do not touch global $COURSE via $PAGE->set_course(), // the reasons is we need to be able to call require_login() at any time!! $course = $SITE; if ($cm) { throw new coding_exception('cm parameter in require_login() requires valid course parameter!'); } } // If this is an AJAX request and $setwantsurltome is true then we need to override it and set it to false. // Otherwise the AJAX request URL will be set to $SESSION->wantsurl and events such as self enrolment in the future // risk leading the user back to the AJAX request URL. if ($setwantsurltome && defined('AJAX_SCRIPT') && AJAX_SCRIPT) { $setwantsurltome = false; } // Redirect to the login page if session has expired, only with dbsessions enabled (MDL-35029) to maintain current behaviour. if ((!isloggedin() or isguestuser()) && !empty($SESSION->has_timed_out) && !empty($CFG->dbsessions)) { if ($preventredirect) { throw new require_login_session_timeout_exception(); } else { if ($setwantsurltome) { $SESSION->wantsurl = qualified_me(); } redirect(get_login_url()); } } // If the user is not even logged in yet then make sure they are. if (!isloggedin()) { if ($autologinguest and !empty($CFG->guestloginbutton) and !empty($CFG->autologinguests)) { if (!($guest = get_complete_user_data('id', $CFG->siteguest))) { // Misconfigured site guest, just redirect to login page. redirect(get_login_url()); exit; // Never reached. } $lang = isset($SESSION->lang) ? $SESSION->lang : $CFG->lang; complete_user_login($guest); $USER->autologinguest = true; $SESSION->lang = $lang; } else { // NOTE: $USER->site check was obsoleted by session test cookie, $USER->confirmed test is in login/index.php. if ($preventredirect) { throw new require_login_exception('You are not logged in'); } if ($setwantsurltome) { $SESSION->wantsurl = qualified_me(); } $referer = get_local_referer(false); if (!empty($referer)) { $SESSION->fromurl = $referer; } // Give auth plugins an opportunity to authenticate or redirect to an external login page $authsequence = get_enabled_auth_plugins(true); // auths, in sequence foreach ($authsequence as $authname) { $authplugin = get_auth_plugin($authname); $authplugin->pre_loginpage_hook(); if (isloggedin()) { break; } } // If we're still not logged in then go to the login page if (!isloggedin()) { redirect(get_login_url()); exit; // Never reached. } } } // Loginas as redirection if needed. if ($course->id != SITEID and \core\session\manager::is_loggedinas()) { if ($USER->loginascontext->contextlevel == CONTEXT_COURSE) { if ($USER->loginascontext->instanceid != $course->id) { print_error('loginasonecourse', '', $CFG->wwwroot . '/course/view.php?id=' . $USER->loginascontext->instanceid); } } } // Check whether the user should be changing password (but only if it is REALLY them). if (get_user_preferences('auth_forcepasswordchange') && !\core\session\manager::is_loggedinas()) { $userauth = get_auth_plugin($USER->auth); if ($userauth->can_change_password() and !$preventredirect) { if ($setwantsurltome) { $SESSION->wantsurl = qualified_me(); } if ($changeurl = $userauth->change_password_url()) { // Use plugin custom url. redirect($changeurl); } else { // Use moodle internal method. if (empty($CFG->loginhttps)) { redirect($CFG->wwwroot . '/login/change_password.php'); } else { $wwwroot = str_replace('http:', 'https:', $CFG->wwwroot); redirect($wwwroot . '/login/change_password.php'); } } } else { if ($userauth->can_change_password()) { throw new moodle_exception('forcepasswordchangenotice'); } else { throw new moodle_exception('nopasswordchangeforced', 'auth'); } } } // Check that the user account is properly set up. If we can't redirect to // edit their profile, perform just the lax check. It will allow them to // use filepicker on the profile edit page. if ($preventredirect) { $usernotfullysetup = user_not_fully_set_up($USER, false); } else { $usernotfullysetup = user_not_fully_set_up($USER, true); } if ($usernotfullysetup) { if ($preventredirect) { throw new moodle_exception('usernotfullysetup'); } if ($setwantsurltome) { $SESSION->wantsurl = qualified_me(); } redirect($CFG->wwwroot . '/user/edit.php?id=' . $USER->id . '&course=' . SITEID); } // Make sure the USER has a sesskey set up. Used for CSRF protection. sesskey(); // Do not bother admins with any formalities. if (is_siteadmin()) { // Set the global $COURSE. if ($cm) { $PAGE->set_cm($cm, $course); $PAGE->set_pagelayout('incourse'); } else { if (!empty($courseorid)) { $PAGE->set_course($course); } } // Set accesstime or the user will appear offline which messes up messaging. user_accesstime_log($course->id); return; } // Check that the user has agreed to a site policy if there is one - do not test in case of admins. if (!$USER->policyagreed and !is_siteadmin()) { if (!empty($CFG->sitepolicy) and !isguestuser()) { if ($preventredirect) { throw new moodle_exception('sitepolicynotagreed', 'error', '', $CFG->sitepolicy); } if ($setwantsurltome) { $SESSION->wantsurl = qualified_me(); } redirect($CFG->wwwroot . '/user/policy.php'); } else { if (!empty($CFG->sitepolicyguest) and isguestuser()) { if ($preventredirect) { throw new moodle_exception('sitepolicynotagreed', 'error', '', $CFG->sitepolicyguest); } if ($setwantsurltome) { $SESSION->wantsurl = qualified_me(); } redirect($CFG->wwwroot . '/user/policy.php'); } } } // Fetch the system context, the course context, and prefetch its child contexts. $sysctx = context_system::instance(); $coursecontext = context_course::instance($course->id, MUST_EXIST); if ($cm) { $cmcontext = context_module::instance($cm->id, MUST_EXIST); } else { $cmcontext = null; } // If the site is currently under maintenance, then print a message. if (!empty($CFG->maintenance_enabled) and !has_capability('moodle/site:maintenanceaccess', $sysctx)) { if ($preventredirect) { throw new require_login_exception('Maintenance in progress'); } $PAGE->set_context(null); print_maintenance_message(); } // Make sure the course itself is not hidden. if ($course->id == SITEID) { // Frontpage can not be hidden. } else { if (is_role_switched($course->id)) { // When switching roles ignore the hidden flag - user had to be in course to do the switch. } else { if (!$course->visible and !has_capability('moodle/course:viewhiddencourses', $coursecontext)) { // Originally there was also test of parent category visibility, BUT is was very slow in complex queries // involving "my courses" now it is also possible to simply hide all courses user is not enrolled in :-). if ($preventredirect) { throw new require_login_exception('Course is hidden'); } $PAGE->set_context(null); // We need to override the navigation URL as the course won't have been added to the navigation and thus // the navigation will mess up when trying to find it. navigation_node::override_active_url(new moodle_url('/')); notice(get_string('coursehidden'), $CFG->wwwroot . '/'); } } } // Is the user enrolled? if ($course->id == SITEID) { // Everybody is enrolled on the frontpage. } else { if (\core\session\manager::is_loggedinas()) { // Make sure the REAL person can access this course first. $realuser = \core\session\manager::get_realuser(); if (!is_enrolled($coursecontext, $realuser->id, '', true) and !is_viewing($coursecontext, $realuser->id) and !is_siteadmin($realuser->id)) { if ($preventredirect) { throw new require_login_exception('Invalid course login-as access'); } $PAGE->set_context(null); echo $OUTPUT->header(); notice(get_string('studentnotallowed', '', fullname($USER, true)), $CFG->wwwroot . '/'); } } $access = false; if (is_role_switched($course->id)) { // Ok, user had to be inside this course before the switch. $access = true; } else { if (is_viewing($coursecontext, $USER)) { // Ok, no need to mess with enrol. $access = true; } else { if (isset($USER->enrol['enrolled'][$course->id])) { if ($USER->enrol['enrolled'][$course->id] > time()) { $access = true; if (isset($USER->enrol['tempguest'][$course->id])) { unset($USER->enrol['tempguest'][$course->id]); remove_temp_course_roles($coursecontext); } } else { // Expired. unset($USER->enrol['enrolled'][$course->id]); } } if (isset($USER->enrol['tempguest'][$course->id])) { if ($USER->enrol['tempguest'][$course->id] == 0) { $access = true; } else { if ($USER->enrol['tempguest'][$course->id] > time()) { $access = true; } else { // Expired. unset($USER->enrol['tempguest'][$course->id]); remove_temp_course_roles($coursecontext); } } } if (!$access) { // Cache not ok. $until = enrol_get_enrolment_end($coursecontext->instanceid, $USER->id); if ($until !== false) { // Active participants may always access, a timestamp in the future, 0 (always) or false. if ($until == 0) { $until = ENROL_MAX_TIMESTAMP; } $USER->enrol['enrolled'][$course->id] = $until; $access = true; } else { $params = array('courseid' => $course->id, 'status' => ENROL_INSTANCE_ENABLED); $instances = $DB->get_records('enrol', $params, 'sortorder, id ASC'); $enrols = enrol_get_plugins(true); // First ask all enabled enrol instances in course if they want to auto enrol user. foreach ($instances as $instance) { if (!isset($enrols[$instance->enrol])) { continue; } // Get a duration for the enrolment, a timestamp in the future, 0 (always) or false. $until = $enrols[$instance->enrol]->try_autoenrol($instance); if ($until !== false) { if ($until == 0) { $until = ENROL_MAX_TIMESTAMP; } $USER->enrol['enrolled'][$course->id] = $until; $access = true; break; } } // If not enrolled yet try to gain temporary guest access. if (!$access) { foreach ($instances as $instance) { if (!isset($enrols[$instance->enrol])) { continue; } // Get a duration for the guest access, a timestamp in the future or false. $until = $enrols[$instance->enrol]->try_guestaccess($instance); if ($until !== false and $until > time()) { $USER->enrol['tempguest'][$course->id] = $until; $access = true; break; } } } } } } } if (!$access) { if ($preventredirect) { throw new require_login_exception('Not enrolled'); } if ($setwantsurltome) { $SESSION->wantsurl = qualified_me(); } redirect($CFG->wwwroot . '/enrol/index.php?id=' . $course->id); } } // Check visibility of activity to current user; includes visible flag, conditional availability, etc. if ($cm && !$cm->uservisible) { if ($preventredirect) { throw new require_login_exception('Activity is hidden'); } if ($course->id != SITEID) { $url = new moodle_url('/course/view.php', array('id' => $course->id)); } else { $url = new moodle_url('/'); } redirect($url, get_string('activityiscurrentlyhidden')); } // Set the global $COURSE. if ($cm) { $PAGE->set_cm($cm, $course); $PAGE->set_pagelayout('incourse'); } else { if (!empty($courseorid)) { $PAGE->set_course($course); } } // Finally access granted, update lastaccess times. user_accesstime_log($course->id); }
function validation($data, $files) { global $CFG, $DB, $USER; $errors = array(); // validate course association if (!empty($data['courseassoc'])) { $coursecontext = context::instance_by_id($data['courseassoc'], IGNORE_MISSING); $canassociatecourse = has_capability('moodle/blog:associatecourse', $coursecontext); if ($coursecontext->contextlevel == CONTEXT_COURSE && $canassociatecourse) { if (!is_enrolled($coursecontext) and !is_viewing($coursecontext)) { $errors['courseassoc'] = get_string('studentnotallowed', '', fullname($USER, true)); } } else { $errors['courseassoc'] = get_string('error'); } } // validate mod association if (!empty($data['modassoc'])) { $modcontextid = $data['modassoc']; $modcontext = context::instance_by_id($modcontextid, IGNORE_MISSING); $canassociatemodule = has_capability('moodle/blog:associatemodule', $modcontext); if ($canassociatemodule) { // get context of the mod's course $coursecontext = $modcontext->get_course_context(true); // ensure only one course is associated if (!empty($data['courseassoc'])) { if ($data['courseassoc'] != $coursecontext->id) { $errors['modassoc'] = get_string('onlyassociateonecourse', 'blog'); } } else { $data['courseassoc'] = $coursecontext->id; } // ensure the user has access to each mod's course if (!is_enrolled($modcontext) and !is_viewing($modcontext)) { $errors['modassoc'] = get_string('studentnotallowed', '', fullname($USER, true)); } } else { $errors['modassoc'] = get_string('error'); } } if ($errors) { return $errors; } return true; }
// please note this is just a guess! require_login(); $isparent = true; } else { // normal course require_login($course); // what to do with users temporary accessing this course? shoudl they see the details? } $strpersonalprofile = get_string('personalprofile'); $strparticipants = get_string("participants"); $struser = get_string("user"); $fullname = fullname($user, has_capability('moodle/site:viewfullnames', $coursecontext)); /// Now test the actual capabilities and enrolment in course if ($currentuser) { // me if (!is_enrolled($coursecontext) and !is_viewing($coursecontext)) { // Need to have full access to a course to see the rest of own info echo $OUTPUT->header(); echo $OUTPUT->heading(get_string('notenrolled', '', $fullname)); if (!empty($_SERVER['HTTP_REFERER'])) { echo $OUTPUT->continue_button($_SERVER['HTTP_REFERER']); } echo $OUTPUT->footer(); die; } } else { // somebody else $PAGE->set_title("{$strpersonalprofile}: "); $PAGE->set_heading("{$strpersonalprofile}: "); // check course level capabilities if (!has_capability('moodle/user:viewdetails', $coursecontext) && !has_capability('moodle/user:viewdetails', $usercontext)) {
/** * Returns true if the user is able to access the course. * * This function is in no way, shape, or form a substitute for require_login. * It should only be used in circumstances where it is not possible to call require_login * such as the navigation. * * This function checks many of the methods of access to a course such as the view * capability, enrollments, and guest access. It also makes use of the cache * generated by require_login for guest access. * * The flags within the $USER object that are used here should NEVER be used outside * of this function can_access_course and require_login. Doing so WILL break future * versions. * * @global moodle_database $DB * @param stdClass $context * @param stdClass|null $user * @param string $withcapability Check for this capability as well. * @param bool $onlyactive consider only active enrolments in enabled plugins and time restrictions * @param boolean $trustcache If set to false guest access will always be checked * against the enrolment plugins from the course, rather * than the cache generated by require_login. * @return boolean Returns true if the user is able to access the course */ function can_access_course($context, $user = null, $withcapability = '', $onlyactive = false, $trustcache = true) { global $DB, $USER; $coursecontext = get_course_context($context); $courseid = $coursecontext->instanceid; // First check the obvious, is the user viewing or is the user enrolled. if (is_viewing($coursecontext, $user, $withcapability) || is_enrolled($coursecontext, $user, $withcapability, $onlyactive)) { // How easy was that! return true; } $access = false; if (!isset($USER->enrol)) { // Cache hasn't been generated yet so we can't trust it $trustcache = false; /** * These flags within the $USER object should NEVER be used outside of this * function can_access_course and the function require_login. * Doing so WILL break future versions!!!! */ $USER->enrol = array(); $USER->enrol['enrolled'] = array(); $USER->enrol['tempguest'] = array(); } // If we don't trust the cache we need to check with the courses enrolment // plugin instances to see if the user can access the course as a guest. if (!$trustcache) { // Ok, off to the database we go! $instances = $DB->get_records('enrol', array('courseid' => $courseid, 'status' => ENROL_INSTANCE_ENABLED), 'sortorder, id ASC'); $enrols = enrol_get_plugins(true); foreach ($instances as $instance) { if (!isset($enrols[$instance->enrol])) { continue; } $until = $enrols[$instance->enrol]->try_guestaccess($instance); if ($until !== false) { // Never use me anywhere but here and require_login $USER->enrol['tempguest'][$courseid] = $until; $access = true; break; } } } // If we don't already have access (from above) check the cache and see whether // there is record of it in there. if (!$access && isset($USER->enrol['tempguest'][$courseid])) { // Never use me anywhere but here and require_login if ($USER->enrol['tempguest'][$courseid] == 0) { $access = true; } else { if ($USER->enrol['tempguest'][$courseid] > time()) { $access = true; } else { //expired unset($USER->enrol['tempguest'][$courseid]); } } } return $access; }
/** * Prints the discussion view screen for a forum. * * @global object * @global object * @param object $course The current course object. * @param object $forum Forum to be printed. * @param int $maxdiscussions . * @param string $displayformat The display format to use (optional). * @param string $sort Sort arguments for database query (optional). * @param int $groupmode Group mode of the forum (optional). * @param void $unused (originally current group) * @param int $page Page mode, page to display (optional). * @param int $perpage The maximum number of discussions per page(optional) * */ function forum_print_latest_discussions($course, $forum, $maxdiscussions=-1, $displayformat='plain', $sort='', $currentgroup=-1, $groupmode=-1, $page=-1, $perpage=100, $cm=NULL) { global $CFG, $USER, $OUTPUT; if (!$cm) { if (!$cm = get_coursemodule_from_instance('forum', $forum->id, $forum->course)) { print_error('invalidcoursemodule'); } } $context = get_context_instance(CONTEXT_MODULE, $cm->id); if (empty($sort)) { $sort = "d.timemodified DESC"; } $olddiscussionlink = false; // Sort out some defaults if ($perpage <= 0) { $perpage = 0; $page = -1; } if ($maxdiscussions == 0) { // all discussions - backwards compatibility $page = -1; $perpage = 0; if ($displayformat == 'plain') { $displayformat = 'header'; // Abbreviate display by default } } else if ($maxdiscussions > 0) { $page = -1; $perpage = $maxdiscussions; } $fullpost = false; if ($displayformat == 'plain') { $fullpost = true; } // Decide if current user is allowed to see ALL the current discussions or not // First check the group stuff if ($currentgroup == -1 or $groupmode == -1) { $groupmode = groups_get_activity_groupmode($cm, $course); $currentgroup = groups_get_activity_group($cm); } $groups = array(); //cache // If the user can post discussions, then this is a good place to put the // button for it. We do not show the button if we are showing site news // and the current user is a guest. $canstart = forum_user_can_post_discussion($forum, $currentgroup, $groupmode, $cm, $context); if (!$canstart and $forum->type !== 'news') { if (isguestuser() or !isloggedin()) { $canstart = true; } if (!is_enrolled($context) and !is_viewing($context)) { // allow guests and not-logged-in to see the button - they are prompted to log in after clicking the link // normal users with temporary guest access see this button too, they are asked to enrol instead // do not show the button to users with suspended enrolments here $canstart = enrol_selfenrol_available($course->id); } } if ($canstart) { echo '<div class="singlebutton forumaddnew">'; echo "<form id=\"newdiscussionform\" method=\"get\" action=\"$CFG->wwwroot/mod/forum/post.php\">"; echo '<div>'; echo "<input type=\"hidden\" name=\"forum\" value=\"$forum->id\" />"; switch ($forum->type) { case 'news': case 'blog': $buttonadd = get_string('addanewtopic', 'forum'); break; case 'qanda': $buttonadd = get_string('addanewquestion', 'forum'); break; default: $buttonadd = get_string('addanewdiscussion', 'forum'); break; } echo '<input type="submit" value="'.$buttonadd.'" />'; echo '</div>'; echo '</form>'; echo "</div>\n"; } else if (isguestuser() or !isloggedin() or $forum->type == 'news') { // no button and no info } else if ($groupmode and has_capability('mod/forum:startdiscussion', $context)) { // inform users why they can not post new discussion if ($currentgroup) { echo $OUTPUT->notification(get_string('cannotadddiscussion', 'forum')); } else { echo $OUTPUT->notification(get_string('cannotadddiscussionall', 'forum')); } } // Get all the recent discussions we're allowed to see $getuserlastmodified = ($displayformat == 'header'); if (! $discussions = forum_get_discussions($cm, $sort, $fullpost, null, $maxdiscussions, $getuserlastmodified, $page, $perpage) ) { echo '<div class="forumnodiscuss">'; if ($forum->type == 'news') { echo '('.get_string('nonews', 'forum').')'; } else if ($forum->type == 'qanda') { echo '('.get_string('noquestions','forum').')'; } else { echo '('.get_string('nodiscussions', 'forum').')'; } echo "</div>\n"; return; } // If we want paging if ($page != -1) { ///Get the number of discussions found $numdiscussions = forum_get_discussions_count($cm); ///Show the paging bar echo $OUTPUT->paging_bar($numdiscussions, $page, $perpage, "view.php?f=$forum->id"); if ($numdiscussions > 1000) { // saves some memory on sites with very large forums $replies = forum_count_discussion_replies($forum->id, $sort, $maxdiscussions, $page, $perpage); } else { $replies = forum_count_discussion_replies($forum->id); } } else { $replies = forum_count_discussion_replies($forum->id); if ($maxdiscussions > 0 and $maxdiscussions <= count($discussions)) { $olddiscussionlink = true; } } $canviewparticipants = has_capability('moodle/course:viewparticipants',$context); $strdatestring = get_string('strftimerecentfull'); // Check if the forum is tracked. if ($cantrack = forum_tp_can_track_forums($forum)) { $forumtracked = forum_tp_is_tracked($forum); } else { $forumtracked = false; } if ($forumtracked) { $unreads = forum_get_discussions_unread($cm); } else { $unreads = array(); } if ($displayformat == 'header') { echo '<table cellspacing="0" class="forumheaderlist">'; echo '<thead>'; echo '<tr>'; echo '<th class="header topic" scope="col">'.get_string('discussion', 'forum').'</th>'; echo '<th class="header author" colspan="2" scope="col">'.get_string('startedby', 'forum').'</th>'; if ($groupmode > 0) { echo '<th class="header group" scope="col">'.get_string('group').'</th>'; } if (has_capability('mod/forum:viewdiscussion', $context)) { echo '<th class="header replies" scope="col">'.get_string('replies', 'forum').'</th>'; // If the forum can be tracked, display the unread column. if ($cantrack) { echo '<th class="header replies" scope="col">'.get_string('unread', 'forum'); if ($forumtracked) { echo ' <a title="'.get_string('markallread', 'forum'). '" href="'.$CFG->wwwroot.'/mod/forum/markposts.php?f='. $forum->id.'&mark=read&returnpage=view.php">'. '<img src="'.$OUTPUT->pix_url('t/clear') . '" class="iconsmall" alt="'.get_string('markallread', 'forum').'" /></a>'; } echo '</th>'; } } echo '<th class="header lastpost" scope="col">'.get_string('lastpost', 'forum').'</th>'; echo '</tr>'; echo '</thead>'; echo '<tbody>'; } foreach ($discussions as $discussion) { if (!empty($replies[$discussion->discussion])) { $discussion->replies = $replies[$discussion->discussion]->replies; $discussion->lastpostid = $replies[$discussion->discussion]->lastpostid; } else { $discussion->replies = 0; } // SPECIAL CASE: The front page can display a news item post to non-logged in users. // All posts are read in this case. if (!$forumtracked) { $discussion->unread = '-'; } else if (empty($USER)) { $discussion->unread = 0; } else { if (empty($unreads[$discussion->discussion])) { $discussion->unread = 0; } else { $discussion->unread = $unreads[$discussion->discussion]; } } if (isloggedin()) { $ownpost = ($discussion->userid == $USER->id); } else { $ownpost=false; } // Use discussion name instead of subject of first post $discussion->subject = $discussion->name; switch ($displayformat) { case 'header': if ($groupmode > 0) { if (isset($groups[$discussion->groupid])) { $group = $groups[$discussion->groupid]; } else { $group = $groups[$discussion->groupid] = groups_get_group($discussion->groupid); } } else { $group = -1; } forum_print_discussion_header($discussion, $forum, $group, $strdatestring, $cantrack, $forumtracked, $canviewparticipants, $context); break; default: $link = false; if ($discussion->replies) { $link = true; } else { $modcontext = get_context_instance(CONTEXT_MODULE, $cm->id); $link = forum_user_can_post($forum, $discussion, $USER, $cm, $course, $modcontext); } $discussion->forum = $forum->id; forum_print_post($discussion, $discussion, $forum, $cm, $course, $ownpost, 0, $link, false); break; } } if ($displayformat == "header") { echo '</tbody>'; echo '</table>'; } if ($olddiscussionlink) { if ($forum->type == 'news') { $strolder = get_string('oldertopics', 'forum'); } else { $strolder = get_string('olderdiscussions', 'forum'); } echo '<div class="forumolddiscuss">'; echo '<a href="'.$CFG->wwwroot.'/mod/forum/view.php?f='.$forum->id.'&showall=1">'; echo $strolder.'</a> ...</div>'; } if ($page != -1) { ///Show the paging bar echo $OUTPUT->paging_bar($numdiscussions, $page, $perpage, "view.php?f=$forum->id"); } }
/** * Is current user allowed to access this report * * @access private defined in lib.php for performance reasons * @global stdClass $USER * @param stdClass $user * @param stdClass $course * @return array with two elements $all, $today */ function report_courselog_can_access_user_report($user, $course) { global $USER; $coursecontext = context_course::instance($course->id); $personalcontext = context_user::instance($user->id); $today = false; $all = false; if (has_capability('report/log:view', $coursecontext)) { $today = true; } if (has_capability('report/log:viewtoday', $coursecontext)) { $all = true; } if ($today and $all) { return array(true, true); } if (has_capability('moodle/user:viewuseractivitiesreport', $personalcontext)) { if ($course->showreports and (is_viewing($coursecontext, $user) or is_enrolled($coursecontext, $user))) { return array(true, true); } } else { if ($user->id == $USER->id) { if ($course->showreports and (is_viewing($coursecontext, $USER) or is_enrolled($coursecontext, $USER))) { return array(true, true); } } } return array($all, $today); }
$node->add(format_string($post->subject), $PAGE->url); } $PAGE->set_title("{$course->shortname}: " . format_string($discussion->name)); $PAGE->set_heading($course->fullname); $PAGE->set_button($searchform); echo $OUTPUT->header(); echo $OUTPUT->heading(format_string($forum->name), 2); /// Check to see if groups are being used in this forum /// If so, make sure the current person is allowed to see this discussion /// Also, if we know they should be able to reply, then explicitly set $canreply for performance reasons $canreply = forum_user_can_post($forum, $discussion, $USER, $cm, $course, $modcontext); if (!$canreply and $forum->type !== 'news') { if (isguestuser() or !isloggedin()) { $canreply = true; } if (!is_enrolled($modcontext) and !is_viewing($modcontext)) { // allow guests and not-logged-in to see the link - they are prompted to log in after clicking the link // normal users with temporary guest access see this link too, they are asked to enrol instead $canreply = enrol_selfenrol_available($course->id); } } /// Print the controls across the top echo '<div class="discussioncontrols clearfix">'; if (!empty($CFG->enableportfolios) && has_capability('mod/forum:exportdiscussion', $modcontext)) { require_once $CFG->libdir . '/portfoliolib.php'; $button = new portfolio_add_button(); $button->set_callback_options('forum_portfolio_caller', array('discussionid' => $discussion->id), 'mod_forum'); $button = $button->to_html(PORTFOLIO_ADD_FULL_FORM, get_string('exportdiscussion', 'mod_forum')); $buttonextraclass = ''; if (empty($button)) { // no portfolio plugin available.
function validation($data, $files) { global $CFG, $DB, $USER; $errors = array(); $sitecontext = get_context_instance(CONTEXT_SYSTEM); // validate course association if (!empty($data['courseassoc']) && has_capability('moodle/blog:associatecourse', $sitecontext)) { $coursecontext = $DB->get_record('context', array('id' => $data['courseassoc'], 'contextlevel' => CONTEXT_COURSE)); if ($coursecontext) { if (!is_enrolled($coursecontext) and !is_viewing($coursecontext)) { $errors['courseassoc'] = get_string('studentnotallowed', '', fullname($USER, true)); } } else { $errors['courseassoc'] = get_string('invalidcontextid', 'blog'); } } // validate mod association if (!empty($data['modassoc'])) { $modcontextid = $data['modassoc']; $modcontext = $DB->get_record('context', array('id' => $modcontextid, 'contextlevel' => CONTEXT_MODULE)); if ($modcontext) { // get context of the mod's course $path = explode('/', $modcontext->path); $coursecontext = $DB->get_record('context', array('id' => $path[count($path) - 2])); // ensure only one course is associated if (!empty($data['courseassoc'])) { if ($data['courseassoc'] != $coursecontext->id) { $errors['modassoc'] = get_string('onlyassociateonecourse', 'blog'); } } else { $data['courseassoc'] = $coursecontext->id; } // ensure the user has access to each mod's course if (!is_enrolled($modcontext) and !is_viewing($modcontext)) { $errors['modassoc'] = get_string('studentnotallowed', '', fullname($USER, true)); } } else { $errors['modassoc'] = get_string('invalidcontextid', 'blog'); } } if ($errors) { return $errors; } return true; }
/** * Returns true if the user is able to access the course. * * This function is in no way, shape, or form a substitute for require_login. * It should only be used in circumstances where it is not possible to call require_login * such as the navigation. * * This function checks many of the methods of access to a course such as the view * capability, enrollments, and guest access. It also makes use of the cache * generated by require_login for guest access. * * The flags within the $USER object that are used here should NEVER be used outside * of this function can_access_course and require_login. Doing so WILL break future * versions. * * @param stdClass $course record * @param stdClass|int|null $user user record or id, current user if null * @param string $withcapability Check for this capability as well. * @param bool $onlyactive consider only active enrolments in enabled plugins and time restrictions * @return boolean Returns true if the user is able to access the course */ function can_access_course(stdClass $course, $user = null, $withcapability = '', $onlyactive = false) { global $DB, $USER; // this function originally accepted $coursecontext parameter if ($course instanceof context) { if ($course instanceof context_course) { debugging('deprecated context parameter, please use $course record'); $coursecontext = $course; $course = $DB->get_record('course', array('id' => $coursecontext->instanceid)); } else { debugging('Invalid context parameter, please use $course record'); return false; } } else { $coursecontext = context_course::instance($course->id); } if (!isset($USER->id)) { // should never happen $USER->id = 0; } // make sure there is a user specified if ($user === null) { $userid = $USER->id; } else { $userid = is_object($user) ? $user->id : $user; } unset($user); if ($withcapability and !has_capability($withcapability, $coursecontext, $userid)) { return false; } if ($userid == $USER->id) { if (!empty($USER->access['rsw'][$coursecontext->path])) { // the fact that somebody switched role means they can access the course no matter to what role they switched return true; } } if (!$course->visible and !has_capability('moodle/course:viewhiddencourses', $coursecontext, $userid)) { return false; } if (is_viewing($coursecontext, $userid)) { return true; } if ($userid != $USER->id) { // for performance reasons we do not verify temporary guest access for other users, sorry... return is_enrolled($coursecontext, $userid, '', $onlyactive); } // === from here we deal only with $USER === $coursecontext->reload_if_dirty(); if (isset($USER->enrol['enrolled'][$course->id])) { if ($USER->enrol['enrolled'][$course->id] > time()) { return true; } } if (isset($USER->enrol['tempguest'][$course->id])) { if ($USER->enrol['tempguest'][$course->id] > time()) { return true; } } if (is_enrolled($coursecontext, $USER, '', $onlyactive)) { return true; } // if not enrolled try to gain temporary guest access $instances = $DB->get_records('enrol', array('courseid' => $course->id, 'status' => ENROL_INSTANCE_ENABLED), 'sortorder, id ASC'); $enrols = enrol_get_plugins(true); foreach ($instances as $instance) { if (!isset($enrols[$instance->enrol])) { continue; } // Get a duration for the guest access, a timestamp in the future, 0 (always) or false. $until = $enrols[$instance->enrol]->try_guestaccess($instance); if ($until !== false and $until > time()) { $USER->enrol['tempguest'][$course->id] = $until; return true; } } if (isset($USER->enrol['tempguest'][$course->id])) { unset($USER->enrol['tempguest'][$course->id]); remove_temp_course_roles($coursecontext); } return false; }
} break; } redirect($url); } else if ($data = $editform->get_data()) { // process data if submitted if (empty($course->id)) { // In creating the course $course = create_course($data, $editoroptions); // Get the context of the newly created course $context = get_context_instance(CONTEXT_COURSE, $course->id, MUST_EXIST); if (!empty($CFG->creatornewroleid) and !is_viewing($context, NULL, 'moodle/role:assign') and !is_enrolled($context, NULL, 'moodle/role:assign')) { // deal with course creators - enrol them internally with default role enrol_try_internal_enrol($course->id, $USER->id, $CFG->creatornewroleid); } if (!is_enrolled($context)) { // Redirect to manual enrolment page if possible $instances = enrol_get_instances($course->id, true); foreach($instances as $instance) { if ($plugin = enrol_get_plugin($instance->enrol)) { if ($plugin->get_manual_enrol_link($instance)) { // we know that the ajax enrol UI will have an option to enrol redirect(new moodle_url('/enrol/users.php', array('id'=>$course->id))); } } }