Example #1
0
/**
 * This function extends the course navigation
 *
 * @param navigation_node $navigation The navigation node to extend
 * @param stdClass $course The course to object for the tool
 * @param context $coursecontext The context of the course
 */
function tool_lp_extend_navigation_course($navigation, $course, $coursecontext)
{
    if (!get_config('core_competency', 'enabled')) {
        return;
    }
    // Check access to the course and competencies page.
    $capabilities = array('moodle/competency:coursecompetencyview', 'moodle/competency:coursecompetencymanage');
    $context = context_course::instance($course->id);
    if (!has_any_capability($capabilities, $context) || !can_access_course($course)) {
        return;
    }
    // Just a link to course competency.
    $title = get_string('competencies', 'core_competency');
    $path = new moodle_url("/admin/tool/lp/coursecompetencies.php", array('courseid' => $course->id));
    $settingsnode = navigation_node::create($title, $path, navigation_node::TYPE_SETTING, null, null, new pix_icon('i/competencies', ''));
    if (isset($settingsnode)) {
        $navigation->add_node($settingsnode);
    }
}
Example #2
0
 /**
  * Initialise the navigation given the type and id for the branch to expand.
  *
  * @return array An array of the expandable nodes
  */
 public function initialise()
 {
     global $DB, $SITE;
     if ($this->initialised || during_initial_install()) {
         return $this->expandable;
     }
     $this->initialised = true;
     $this->rootnodes = array();
     $this->rootnodes['site'] = $this->add_course($SITE);
     $this->rootnodes['mycourses'] = $this->add(get_string('mycourses'), new moodle_url('/my'), self::TYPE_ROOTNODE, null, 'mycourses');
     $this->rootnodes['courses'] = $this->add(get_string('courses'), null, self::TYPE_ROOTNODE, null, 'courses');
     // The courses branch is always displayed, and is always expandable (although may be empty).
     // This mimicks what is done during {@link global_navigation::initialise()}.
     $this->rootnodes['courses']->isexpandable = true;
     // Branchtype will be one of navigation_node::TYPE_*
     switch ($this->branchtype) {
         case 0:
             if ($this->instanceid === 'mycourses') {
                 $this->load_courses_enrolled();
             } else {
                 if ($this->instanceid === 'courses') {
                     $this->load_courses_other();
                 }
             }
             break;
         case self::TYPE_CATEGORY:
             $this->load_category($this->instanceid);
             break;
         case self::TYPE_MY_CATEGORY:
             $this->load_category($this->instanceid, self::TYPE_MY_CATEGORY);
             break;
         case self::TYPE_COURSE:
             $course = $DB->get_record('course', array('id' => $this->instanceid), '*', MUST_EXIST);
             if (!can_access_course($course, null, '', true)) {
                 // Thats OK all courses are expandable by default. We don't need to actually expand it we can just
                 // add the course node and break. This leads to an empty node.
                 $this->add_course($course);
                 break;
             }
             require_course_login($course, true, null, false, true);
             $this->page->set_context(context_course::instance($course->id));
             $coursenode = $this->add_course($course);
             $this->add_course_essentials($coursenode, $course);
             $this->load_course_sections($course, $coursenode);
             break;
         case self::TYPE_SECTION:
             $sql = 'SELECT c.*, cs.section AS sectionnumber
                     FROM {course} c
                     LEFT JOIN {course_sections} cs ON cs.course = c.id
                     WHERE cs.id = ?';
             $course = $DB->get_record_sql($sql, array($this->instanceid), MUST_EXIST);
             require_course_login($course, true, null, false, true);
             $this->page->set_context(context_course::instance($course->id));
             $coursenode = $this->add_course($course);
             $this->add_course_essentials($coursenode, $course);
             $this->load_course_sections($course, $coursenode, $course->sectionnumber);
             break;
         case self::TYPE_ACTIVITY:
             $sql = "SELECT c.*\n                          FROM {course} c\n                          JOIN {course_modules} cm ON cm.course = c.id\n                         WHERE cm.id = :cmid";
             $params = array('cmid' => $this->instanceid);
             $course = $DB->get_record_sql($sql, $params, MUST_EXIST);
             $modinfo = get_fast_modinfo($course);
             $cm = $modinfo->get_cm($this->instanceid);
             require_course_login($course, true, $cm, false, true);
             $this->page->set_context(context_module::instance($cm->id));
             $coursenode = $this->load_course($course);
             $this->load_course_sections($course, $coursenode, null, $cm);
             $activitynode = $coursenode->find($cm->id, self::TYPE_ACTIVITY);
             if ($activitynode) {
                 $modulenode = $this->load_activity($cm, $course, $activitynode);
             }
             break;
         default:
             throw new Exception('Unknown type');
             return $this->expandable;
     }
     if ($this->page->context->contextlevel == CONTEXT_COURSE && $this->page->context->instanceid != $SITE->id) {
         $this->load_for_user(null, true);
     }
     $this->find_expandable($this->expandable);
     return $this->expandable;
 }
 /**
  * Returns true if the current user can access this course.
  * @return bool
  */
 public function can_access()
 {
     if ($this->canaccess === null) {
         $this->canaccess = can_access_course($this->record);
     }
     return $this->canaccess;
 }
Example #4
0
 /**
  * Whether the user can access the document or not.
  *
  * @param int $id The course instance id.
  * @return int
  */
 public function check_access($id)
 {
     global $DB;
     $course = $DB->get_record('course', array('id' => $id));
     if (!$course) {
         return \core_search\manager::ACCESS_DELETED;
     }
     if (can_access_course($course)) {
         return \core_search\manager::ACCESS_GRANTED;
     }
     return \core_search\manager::ACCESS_DENIED;
 }
Example #5
0
/**
 * Adds module specific settings to the settings block
 *
 * @param settings_navigation $settings The settings navigation object
 * @param navigation_node $glossarynode The node to add module settings to
 */
function glossary_extend_settings_navigation(settings_navigation $settings, navigation_node $glossarynode) {
    global $PAGE, $DB, $CFG, $USER;

    $mode = optional_param('mode', '', PARAM_ALPHA);
    $hook = optional_param('hook', 'ALL', PARAM_CLEAN);

    if (has_capability('mod/glossary:import', $PAGE->cm->context)) {
        $glossarynode->add(get_string('importentries', 'glossary'), new moodle_url('/mod/glossary/import.php', array('id'=>$PAGE->cm->id)));
    }

    if (has_capability('mod/glossary:export', $PAGE->cm->context)) {
        $glossarynode->add(get_string('exportentries', 'glossary'), new moodle_url('/mod/glossary/export.php', array('id'=>$PAGE->cm->id, 'mode'=>$mode, 'hook'=>$hook)));
    }

    if (has_capability('mod/glossary:approve', $PAGE->cm->context) && ($hiddenentries = $DB->count_records('glossary_entries', array('glossaryid'=>$PAGE->cm->instance, 'approved'=>0)))) {
        $glossarynode->add(get_string('waitingapproval', 'glossary'), new moodle_url('/mod/glossary/view.php', array('id'=>$PAGE->cm->id, 'mode'=>'approval')));
    }

    if (has_capability('mod/glossary:write', $PAGE->cm->context)) {
        $glossarynode->add(get_string('addentry', 'glossary'), new moodle_url('/mod/glossary/edit.php', array('cmid'=>$PAGE->cm->id)));
    }

    $glossary = $DB->get_record('glossary', array("id" => $PAGE->cm->instance));

    if (!empty($CFG->enablerssfeeds) && !empty($CFG->glossary_enablerssfeeds) && $glossary->rsstype && $glossary->rssarticles  && can_access_course($PAGE->course, $USER)) {
        require_once("$CFG->libdir/rsslib.php");

        $string = get_string('rsstype','forum');

        $url = new moodle_url(rss_get_url($PAGE->cm->context->id, $USER->id, 'mod_glossary', $glossary->id));
        $glossarynode->add($string, $url, settings_navigation::TYPE_SETTING, null, null, new pix_icon('i/rss', ''));
    }
}
        }
        if (isset($SESSION->bigbluebuttonbn_bbbsession) && !is_null($SESSION->bigbluebuttonbn_bbbsession)) {
            $bbbsession = $SESSION->bigbluebuttonbn_bbbsession;
        } else {
            $error = bigbluebuttonbn_bbb_broker_add_error($error, "No session variable set");
        }
    }
}
header('Content-Type: application/javascript; charset=utf-8');
if (empty($error)) {
    if (!isloggedin() && $PAGE->course->id == SITEID) {
        $userid = guest_user()->id;
    } else {
        $userid = $USER->id;
    }
    $hascourseaccess = $PAGE->course->id == SITEID || can_access_course($PAGE->course, $userid);
    if (!$hascourseaccess) {
        header("HTTP/1.0 401 Unauthorized");
        return;
    } else {
        try {
            switch (strtolower($params['action'])) {
                case 'meeting_info':
                    $meeting_info = bigbluebuttonbn_bbb_broker_get_meeting_info($params['id'], $bbbsession['modPW']);
                    $meeting_running = bigbluebuttonbn_bbb_broker_is_meeting_running($meeting_info);
                    $status_can_end = '';
                    $status_can_tag = '';
                    if ($meeting_running) {
                        $join_button_text = get_string('view_conference_action_join', 'bigbluebuttonbn');
                        if ($bbbsession['userlimit'] == 0 || $meeting_info->participantCount < $bbbsession['userlimit']) {
                            $initial_message = get_string('view_message_conference_in_progress', 'bigbluebuttonbn');
Example #7
0
    /**
     * Loads user specific information into the navigation in the appropriate place.
     *
     * If no user is provided the current user is assumed.
     *
     * @param stdClass $user
     * @param bool $forceforcontext probably force something to be loaded somewhere (ask SamH if not sure what this means)
     * @return bool
     */
    protected function load_for_user($user=null, $forceforcontext=false) {
        global $DB, $CFG, $USER, $SITE;

        if ($user === null) {
            // We can't require login here but if the user isn't logged in we don't
            // want to show anything
            if (!isloggedin() || isguestuser()) {
                return false;
            }
            $user = $USER;
        } else if (!is_object($user)) {
            // If the user is not an object then get them from the database
            $select = context_helper::get_preload_record_columns_sql('ctx');
            $sql = "SELECT u.*, $select
                      FROM {user} u
                      JOIN {context} ctx ON u.id = ctx.instanceid
                     WHERE u.id = :userid AND
                           ctx.contextlevel = :contextlevel";
            $user = $DB->get_record_sql($sql, array('userid' => (int)$user, 'contextlevel' => CONTEXT_USER), MUST_EXIST);
            context_helper::preload_from_record($user);
        }

        $iscurrentuser = ($user->id == $USER->id);

        $usercontext = context_user::instance($user->id);

        // Get the course set against the page, by default this will be the site
        $course = $this->page->course;
        $baseargs = array('id'=>$user->id);
        if ($course->id != $SITE->id && (!$iscurrentuser || $forceforcontext)) {
            $coursenode = $this->add_course($course, false, self::COURSE_CURRENT);
            $baseargs['course'] = $course->id;
            $coursecontext = context_course::instance($course->id);
            $issitecourse = false;
        } else {
            // Load all categories and get the context for the system
            $coursecontext = context_system::instance();
            $issitecourse = true;
        }

        // Create a node to add user information under.
        if ($iscurrentuser && !$forceforcontext) {
            // If it's the current user the information will go under the profile root node
            $usernode = $this->rootnodes['myprofile'];
            $course = get_site();
            $coursecontext = context_course::instance($course->id);
            $issitecourse = true;
        } else {
            if (!$issitecourse) {
                // Not the current user so add it to the participants node for the current course
                $usersnode = $coursenode->get('participants', navigation_node::TYPE_CONTAINER);
                $userviewurl = new moodle_url('/user/view.php', $baseargs);
            } else {
                // This is the site so add a users node to the root branch
                $usersnode = $this->rootnodes['users'];
                if (has_capability('moodle/course:viewparticipants', $coursecontext)) {
                    $usersnode->action = new moodle_url('/user/index.php', array('id'=>$course->id));
                }
                $userviewurl = new moodle_url('/user/profile.php', $baseargs);
            }
            if (!$usersnode) {
                // We should NEVER get here, if the course hasn't been populated
                // with a participants node then the navigaiton either wasn't generated
                // for it (you are missing a require_login or set_context call) or
                // you don't have access.... in the interests of no leaking informatin
                // we simply quit...
                return false;
            }
            // Add a branch for the current user
            $canseefullname = has_capability('moodle/site:viewfullnames', $coursecontext);
            $usernode = $usersnode->add(fullname($user, $canseefullname), $userviewurl, self::TYPE_USER, null, $user->id);

            if ($this->page->context->contextlevel == CONTEXT_USER && $user->id == $this->page->context->instanceid) {
                $usernode->make_active();
            }
        }

        // If the user is the current user or has permission to view the details of the requested
        // user than add a view profile link.
        if ($iscurrentuser || has_capability('moodle/user:viewdetails', $coursecontext) || has_capability('moodle/user:viewdetails', $usercontext)) {
            if ($issitecourse || ($iscurrentuser && !$forceforcontext)) {
                $usernode->add(get_string('viewprofile'), new moodle_url('/user/profile.php',$baseargs));
            } else {
                $usernode->add(get_string('viewprofile'), new moodle_url('/user/view.php',$baseargs));
            }
        }

        if (!empty($CFG->navadduserpostslinks)) {
            // Add nodes for forum posts and discussions if the user can view either or both
            // There are no capability checks here as the content of the page is based
            // purely on the forums the current user has access too.
            $forumtab = $usernode->add(get_string('forumposts', 'forum'));
            $forumtab->add(get_string('posts', 'forum'), new moodle_url('/mod/forum/user.php', $baseargs));
            $forumtab->add(get_string('discussions', 'forum'), new moodle_url('/mod/forum/user.php', array_merge($baseargs, array('mode'=>'discussions'))));
        }

        // Add blog nodes
        if (!empty($CFG->enableblogs)) {
            if (!$this->cache->cached('userblogoptions'.$user->id)) {
                require_once($CFG->dirroot.'/blog/lib.php');
                // Get all options for the user
                $options = blog_get_options_for_user($user);
                $this->cache->set('userblogoptions'.$user->id, $options);
            } else {
                $options = $this->cache->{'userblogoptions'.$user->id};
            }

            if (count($options) > 0) {
                $blogs = $usernode->add(get_string('blogs', 'blog'), null, navigation_node::TYPE_CONTAINER);
                foreach ($options as $type => $option) {
                    if ($type == "rss") {
                        $blogs->add($option['string'], $option['link'], settings_navigation::TYPE_SETTING, null, null, new pix_icon('i/rss', ''));
                    } else {
                        $blogs->add($option['string'], $option['link']);
                    }
                }
            }
        }

        if (!empty($CFG->messaging)) {
            $messageargs = array('user1' => $USER->id);
            if ($USER->id != $user->id) {
                $messageargs['user2'] = $user->id;
            }
            if ($course->id != $SITE->id) {
                $messageargs['viewing'] = MESSAGE_VIEW_COURSE. $course->id;
            }
            $url = new moodle_url('/message/index.php',$messageargs);
            $usernode->add(get_string('messages', 'message'), $url, self::TYPE_SETTING, null, 'messages');
        }

        if ($iscurrentuser && has_capability('moodle/user:manageownfiles', context_user::instance($USER->id))) {
            $url = new moodle_url('/user/files.php');
            $usernode->add(get_string('myfiles'), $url, self::TYPE_SETTING);
        }

        if (!empty($CFG->enablebadges) && $iscurrentuser &&
                has_capability('moodle/badges:manageownbadges', context_user::instance($USER->id))) {
            $url = new moodle_url('/badges/mybadges.php');
            $usernode->add(get_string('mybadges', 'badges'), $url, self::TYPE_SETTING);
        }

        // Add a node to view the users notes if permitted
        if (!empty($CFG->enablenotes) && has_any_capability(array('moodle/notes:manage', 'moodle/notes:view'), $coursecontext)) {
            $url = new moodle_url('/notes/index.php',array('user'=>$user->id));
            if ($coursecontext->instanceid) {
                $url->param('course', $coursecontext->instanceid);
            }
            $usernode->add(get_string('notes', 'notes'), $url);
        }

        // If the user is the current user add the repositories for the current user
        $hiddenfields = array_flip(explode(',', $CFG->hiddenuserfields));
        if ($iscurrentuser) {
            if (!$this->cache->cached('contexthasrepos'.$usercontext->id)) {
                require_once($CFG->dirroot . '/repository/lib.php');
                $editabletypes = repository::get_editable_types($usercontext);
                $haseditabletypes = !empty($editabletypes);
                unset($editabletypes);
                $this->cache->set('contexthasrepos'.$usercontext->id, $haseditabletypes);
            } else {
                $haseditabletypes = $this->cache->{'contexthasrepos'.$usercontext->id};
            }
            if ($haseditabletypes) {
                $usernode->add(get_string('repositories', 'repository'), new moodle_url('/repository/manage_instances.php', array('contextid' => $usercontext->id)));
            }
        } else if ($course->id == $SITE->id && has_capability('moodle/user:viewdetails', $usercontext) && (!in_array('mycourses', $hiddenfields) || has_capability('moodle/user:viewhiddendetails', $coursecontext))) {

            // Add view grade report is permitted
            $reports = core_component::get_plugin_list('gradereport');
            arsort($reports); // user is last, we want to test it first

            $userscourses = enrol_get_users_courses($user->id);
            $userscoursesnode = $usernode->add(get_string('courses'));

            foreach ($userscourses as $usercourse) {
                $usercoursecontext = context_course::instance($usercourse->id);
                $usercourseshortname = format_string($usercourse->shortname, true, array('context' => $usercoursecontext));
                $usercoursenode = $userscoursesnode->add($usercourseshortname, new moodle_url('/user/view.php', array('id'=>$user->id, 'course'=>$usercourse->id)), self::TYPE_CONTAINER);

                $gradeavailable = has_capability('moodle/grade:viewall', $usercoursecontext);
                if (!$gradeavailable && !empty($usercourse->showgrades) && is_array($reports) && !empty($reports)) {
                    foreach ($reports as $plugin => $plugindir) {
                        if (has_capability('gradereport/'.$plugin.':view', $usercoursecontext)) {
                            //stop when the first visible plugin is found
                            $gradeavailable = true;
                            break;
                        }
                    }
                }

                if ($gradeavailable) {
                    $url = new moodle_url('/grade/report/index.php', array('id'=>$usercourse->id));
                    $usercoursenode->add(get_string('grades'), $url, self::TYPE_SETTING, null, null, new pix_icon('i/grades', ''));
                }

                // Add a node to view the users notes if permitted
                if (!empty($CFG->enablenotes) && has_any_capability(array('moodle/notes:manage', 'moodle/notes:view'), $usercoursecontext)) {
                    $url = new moodle_url('/notes/index.php',array('user'=>$user->id, 'course'=>$usercourse->id));
                    $usercoursenode->add(get_string('notes', 'notes'), $url, self::TYPE_SETTING);
                }

                if (can_access_course($usercourse, $user->id)) {
                    $usercoursenode->add(get_string('entercourse'), new moodle_url('/course/view.php', array('id'=>$usercourse->id)), self::TYPE_SETTING, null, null, new pix_icon('i/course', ''));
                }

                $reporttab = $usercoursenode->add(get_string('activityreports'));

                $reports = get_plugin_list_with_function('report', 'extend_navigation_user', 'lib.php');
                foreach ($reports as $reportfunction) {
                    $reportfunction($reporttab, $user, $usercourse);
                }

                $reporttab->trim_if_empty();
            }
        }
        return true;
    }
Example #8
0
function glossary_rss_get_feed($context, $args)
{
    global $CFG, $DB, $COURSE, $USER;
    $status = true;
    if (empty($CFG->glossary_enablerssfeeds)) {
        debugging("DISABLED (module configuration)");
        return null;
    }
    $glossaryid = clean_param($args[3], PARAM_INT);
    $cm = get_coursemodule_from_instance('glossary', $glossaryid, 0, false, MUST_EXIST);
    if ($cm) {
        $modcontext = get_context_instance(CONTEXT_MODULE, $cm->id);
        if ($COURSE->id == $cm->course) {
            $course = $COURSE;
        } else {
            $course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST);
        }
        $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id, MUST_EXIST);
        //context id from db should match the submitted one
        //no specific capability required to view glossary entries so just check user is enrolled
        if ($context->id != $modcontext->id || !can_access_course($coursecontext, $USER)) {
            return null;
        }
    }
    $glossary = $DB->get_record('glossary', array('id' => $glossaryid), '*', MUST_EXIST);
    if (!rss_enabled_for_mod('glossary', $glossary)) {
        return null;
    }
    $sql = glossary_rss_get_sql($glossary);
    //get the cache file info
    $filename = rss_get_file_name($glossary, $sql);
    $cachedfilepath = rss_get_file_full_name('mod_glossary', $filename);
    //Is the cache out of date?
    $cachedfilelastmodified = 0;
    if (file_exists($cachedfilepath)) {
        $cachedfilelastmodified = filemtime($cachedfilepath);
    }
    //if the cache is more than 60 seconds old and there's new stuff
    $dontrecheckcutoff = time() - 60;
    if ($dontrecheckcutoff > $cachedfilelastmodified && glossary_rss_newstuff($glossary, $cachedfilelastmodified)) {
        if (!($recs = $DB->get_records_sql($sql, array(), 0, $glossary->rssarticles))) {
            return null;
        }
        $items = array();
        $formatoptions = new stdClass();
        $formatoptions->trusttext = true;
        foreach ($recs as $rec) {
            $item = new stdClass();
            $user = new stdClass();
            $item->title = $rec->entryconcept;
            if ($glossary->rsstype == 1) {
                //With author
                $user->firstname = $rec->userfirstname;
                $user->lastname = $rec->userlastname;
                $item->author = fullname($user);
            }
            $item->pubdate = $rec->entrytimecreated;
            $item->link = $CFG->wwwroot . "/mod/glossary/showentry.php?courseid=" . $glossary->course . "&eid=" . $rec->entryid;
            $item->description = format_text($rec->entrydefinition, $rec->entryformat, $formatoptions, $glossary->course);
            $items[] = $item;
        }
        //First all rss feeds common headers
        $header = rss_standard_header(format_string($glossary->name, true), $CFG->wwwroot . "/mod/glossary/view.php?g=" . $glossary->id, format_string($glossary->intro, true));
        //Now all the rss items
        if (!empty($header)) {
            $articles = rss_add_items($items);
        }
        //Now all rss feeds common footers
        if (!empty($header) && !empty($articles)) {
            $footer = rss_standard_footer();
        }
        //Now, if everything is ok, concatenate it
        if (!empty($header) && !empty($articles) && !empty($footer)) {
            $rss = $header . $articles . $footer;
            //Save the XML contents to file.
            $status = rss_save_file('mod_glossary', $filename, $rss);
        }
    }
    if (!$status) {
        $cachedfilepath = null;
    }
    return $cachedfilepath;
}
Example #9
0
 /**
  * Gets a list of groups that the user is allowed to access within the specified activity.
  *
  * @throws moodle_exception
  * @param int $cmid course module id
  * @param int $userid id of user.
  * @return array of group objects (id, name, description, format) and possible warnings.
  * @since Moodle 3.0
  */
 public static function get_activity_allowed_groups($cmid, $userid = 0)
 {
     global $USER;
     // Warnings array, it can be empty at the end but is mandatory.
     $warnings = array();
     $params = array('cmid' => $cmid, 'userid' => $userid);
     $params = self::validate_parameters(self::get_activity_allowed_groups_parameters(), $params);
     $cmid = $params['cmid'];
     $userid = $params['userid'];
     $cm = get_coursemodule_from_id(null, $cmid, 0, false, MUST_EXIST);
     // Security checks.
     $context = context_module::instance($cm->id);
     $coursecontext = context_course::instance($cm->course);
     self::validate_context($context);
     if (empty($userid)) {
         $userid = $USER->id;
     }
     $user = core_user::get_user($userid, '*', MUST_EXIST);
     core_user::require_active_user($user);
     // Check if we have permissions for retrieve the information.
     if ($user->id != $USER->id) {
         if (!has_capability('moodle/course:managegroups', $context)) {
             throw new moodle_exception('accessdenied', 'admin');
         }
         // Validate if the user is enrolled in the course.
         $course = get_course($cm->course);
         if (!can_access_course($course, $user, '', true)) {
             // We return a warning because the function does not fail for not enrolled users.
             $warning = array();
             $warning['item'] = 'course';
             $warning['itemid'] = $cm->course;
             $warning['warningcode'] = '1';
             $warning['message'] = "User {$user->id} cannot access course {$cm->course}";
             $warnings[] = $warning;
         }
     }
     $usergroups = array();
     if (empty($warnings)) {
         $groups = groups_get_activity_allowed_groups($cm, $user->id);
         foreach ($groups as $group) {
             list($group->description, $group->descriptionformat) = external_format_text($group->description, $group->descriptionformat, $coursecontext->id, 'group', 'description', $group->id);
             $group->courseid = $cm->course;
             $usergroups[] = $group;
         }
     }
     $results = array('groups' => $usergroups, 'warnings' => $warnings);
     return $results;
 }
Example #10
0
 /**
  * Checks if current user has access to the course
  *
  * This method calls global function {@link can_access_course} and caches results
  *
  * @param int $courseid
  * @return bool
  */
 public function can_access_course($courseid)
 {
     $this->init_course_access();
     if (!array_key_exists($courseid, $this->courseaccess)) {
         $this->courseaccess[$courseid] = can_access_course($this->get_course($courseid)) ? 1 : 0;
         $this->cachechangedcourse = true;
     }
     return $this->courseaccess[$courseid];
 }
Example #11
0
 /**
  * Determines a user's access to a course with a given capability, using cached results where possible.
  *
  * @since 3.2.0
  * @param \stdClass $user the user record.
  * @param \stdClass $course the course record.
  * @param string $capability the capability to check.
  * @return bool true if the user can access the course with the specified capability, false otherwise.
  */
 protected function user_can_access_course($user, $course, $capability)
 {
     if (!isset($this->courseaccesscache[$course->id][$user->id][$capability])) {
         $this->courseaccesscache[$course->id][$user->id][$capability] = can_access_course($course, $user, $capability, true);
     }
     return $this->courseaccesscache[$course->id][$user->id][$capability];
 }
 /**
  * Print  table of contents for a course
  *
  * @Author: Stuart Lamour
  */
 public function print_course_toc()
 {
     global $COURSE;
     // No access to course, return nothing.
     if (!can_access_course($COURSE)) {
         return '';
     }
     $format = course_get_format($this->page->course);
     $course = $format->get_course();
     // We don't want to display the toc if the current course is the site.
     if ($COURSE->id == SITEID) {
         return;
     }
     // If course does not have any sections then exit - it can't be a course without sections!!!
     if (!isset($course->numsections)) {
         return;
     }
     $singlepage = true;
     if ($COURSE->format === 'folderview') {
         $singlepage = false;
     }
     $contents = get_string('contents', 'theme_snap');
     $o = '<nav id="course-toc">
     <div>
     <h2 id="toc-desktop-menu-heading">
     <span class=sr-only>Page</span>' . $contents . '</h2>
     <form id="toc-search" onSubmit="return false;">
     <input id="toc-search-input" type="search" title="' . get_string("search") . '" placeholder="' . get_string("search") . '" aria-autocomplete="list" aria-haspopup="true" aria-activedescendant="toc-search-results" autocomplete="off" />
     ' . $this->modulesearch() . '
     </form>
     <a id="toc-mobile-menu-toggle" title="' . $contents . '" href="#course-toc"><i class="icon icon-office-52"></i></a>
     </div>';
     $listlarge = '';
     if ($course->numsections > 9) {
         $listlarge = "list-large";
     }
     $toc = '<ol id="chapters" class="chapters ' . $listlarge . '" start="0">';
     course_create_sections_if_missing($course, range(0, $course->numsections));
     $canviewhidden = has_capability('moodle/course:viewhiddensections', context_course::instance($course->id));
     $modinfo = get_fast_modinfo($course);
     foreach ($modinfo->get_section_info_all() as $section => $thissection) {
         if ($section > $course->numsections) {
             continue;
         }
         // Students - If course hidden sections completely invisible & section is hidden, and you cannot
         // see hidden things, bale out.
         if ($course->hiddensections && !$thissection->visible && !$canviewhidden) {
             continue;
         }
         $linkinfo = '';
         $outputlink = true;
         $conditional = $this->is_section_conditional($thissection);
         if ($canviewhidden) {
             // Teachers.
             if ($conditional) {
                 $linkinfo .= $this->toc_linkinfo(get_string('conditional', 'theme_snap'));
             }
             if (!$thissection->visible) {
                 $linkinfo .= $this->toc_linkinfo(get_string('notpublished', 'theme_snap'));
             }
         } else {
             // Students.
             if ($conditional && $thissection->availableinfo) {
                 // Conditional section, with text explaining conditions.
                 $linkinfo .= $this->toc_linkinfo(get_string('conditional', 'theme_snap'));
             }
             if ($conditional && !$thissection->uservisible && !$thissection->availableinfo) {
                 // Conditional section, totally hidden from user so skip.
                 continue;
             }
             if (!$conditional && !$thissection->visible) {
                 // Hidden section collapsed, so show as text in TOC.
                 $outputlink = false;
                 // Top trump - if not clickable, replace linkinfo.
                 $linkinfo = $this->toc_linkinfo(get_string('notavailable'));
             }
         }
         /*
         // fun understanding what all these vars mean //
         $linkinfo .= $course->hiddensections;
         // visible - shows on conditionals when not completely hidden
         if($thissection->visible){
            $linkinfo .= " section->visible ";
         }
         // uservisible - shows while conditions are met?
         if($thissection->uservisible){
             $linkinfo .= " section->uservisible ";
         }
         // available - shown on hidden when 'colapsed'
         if($thissection->available){
             $linkinfo .= " section->available ";
         }
         // availability info - shown on conditional when not hidden or met
         if($thissection->availableinfo){
             $linkinfo .= " section->availableinfo ";
         }
         */
         $sectionstring = get_section_name($course, $section);
         if ($sectionstring == get_string('general')) {
             $sectionstring = get_string('introduction', 'theme_snap');
         }
         $sectionclass = '';
         $highlight = '';
         if (course_get_format($course)->is_section_current($section)) {
             $sectionclass = 'current';
             $highlight = ' <small class=highlight-tag>' . get_string('current', 'theme_snap') . '</small>';
         }
         if ($outputlink) {
             if ($singlepage) {
                 $url = '#section-' . $section;
             } else {
                 if ($section > 0) {
                     $url = course_get_url($course, $section, array('navigation' => true, 'sr' => $section));
                 } else {
                     // We need to create the url for section 0, or a hash will get returned.
                     $url = new moodle_url('/course/view.php', array('id' => $course->id, 'section' => $section));
                 }
             }
             $link = "<a class='{$sectionclass}' href='{$url}'>{$sectionstring}</a>";
         } else {
             $link = "<span class='{$sectionclass}' >{$sectionstring}</a>";
         }
         $progress = $this->toc_progress($thissection, $course);
         $li = '<li>' . $link . $highlight . $progress . ' ' . $linkinfo . '</li>';
         $toc .= $li;
     }
     $coursetools = get_string('coursetools', 'theme_snap');
     $url = "#coursetools";
     if ($COURSE->format == 'folderview') {
         $url = new moodle_url('/course/view.php', ['id' => $course->id, 'section' => 0], 'coursetools');
     }
     $link = html_writer::link($url, $coursetools);
     $toc .= "<li>{$link}</li>";
     $toc .= "</ol>";
     $toc .= "</nav>";
     $o .= $toc;
     return $o;
 }
Example #13
0
 /**
  * Simulates the web interface view of notes/index.php: trigger events
  *
  * @param int $courseid id of the course
  * @param int $userid id of the user
  * @return array of warnings and status result
  * @since Moodle 2.9
  * @throws moodle_exception
  */
 public static function view_notes($courseid, $userid = 0)
 {
     global $CFG;
     require_once $CFG->dirroot . "/notes/lib.php";
     if (empty($CFG->enablenotes)) {
         throw new moodle_exception('notesdisabled', 'notes');
     }
     $warnings = array();
     $arrayparams = array('courseid' => $courseid, 'userid' => $userid);
     $params = self::validate_parameters(self::view_notes_parameters(), $arrayparams);
     if (empty($params['courseid'])) {
         $params['courseid'] = SITEID;
     }
     $course = get_course($params['courseid']);
     if ($course->id == SITEID) {
         $context = context_system::instance();
     } else {
         $context = context_course::instance($course->id);
     }
     // First of all, validate the context before do further permission checks.
     self::validate_context($context);
     require_capability('moodle/notes:view', $context);
     if (!empty($params['userid'])) {
         $user = core_user::get_user($params['userid'], 'id, deleted', MUST_EXIST);
         if ($user->deleted) {
             throw new moodle_exception('userdeleted');
         }
         if (isguestuser($user)) {
             throw new moodle_exception('invaliduserid');
         }
         if ($course->id != SITEID and !can_access_course($course, $user, '', true)) {
             throw new moodle_exception('notenrolledprofile');
         }
     }
     note_view($context, $params['userid']);
     $result = array();
     $result['status'] = true;
     $result['warnings'] = $warnings;
     return $result;
 }
Example #14
0
/**
 * 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;
}
Example #15
0
 /**
  * Simulate the /user/index.php and /user/profile.php web interface page triggering events
  *
  * @param int $userid id of user
  * @param int $courseid id of course
  * @return array of warnings and status result
  * @since Moodle 2.9
  * @throws moodle_exception
  */
 public static function view_user_profile($userid, $courseid = 0)
 {
     global $CFG, $USER;
     require_once $CFG->dirroot . "/user/profile/lib.php";
     $params = self::validate_parameters(self::view_user_profile_parameters(), array('userid' => $userid, 'courseid' => $courseid));
     $warnings = array();
     if (empty($params['userid'])) {
         $params['userid'] = $USER->id;
     }
     if (empty($params['courseid'])) {
         $params['courseid'] = SITEID;
     }
     $course = get_course($params['courseid']);
     $user = core_user::get_user($params['userid'], '*', MUST_EXIST);
     if ($user->deleted) {
         throw new moodle_exception('userdeleted');
     }
     if (isguestuser($user)) {
         // Can not view profile of guest - thre is nothing to see there.
         throw new moodle_exception('invaliduserid');
     }
     if ($course->id == SITEID) {
         $coursecontext = context_system::instance();
     } else {
         $coursecontext = context_course::instance($course->id);
     }
     self::validate_context($coursecontext);
     $currentuser = $USER->id == $user->id;
     $usercontext = context_user::instance($user->id);
     if (!$currentuser and !has_capability('moodle/user:viewdetails', $coursecontext) and !has_capability('moodle/user:viewdetails', $usercontext)) {
         throw new moodle_exception('cannotviewprofile');
     }
     // Case like user/profile.php.
     if ($course->id == SITEID) {
         profile_view($user, $usercontext);
     } else {
         // Case like user/view.php.
         if (!$currentuser and !can_access_course($course, $user, '', true)) {
             throw new moodle_exception('notenrolledprofile');
         }
         profile_view($user, $coursecontext, $course);
     }
     $result = array();
     $result['status'] = true;
     $result['warnings'] = $warnings;
     return $result;
 }
 /**
  * This function gets called by {@link settings_navigation::load_user_settings()} and actually works out
  * what can be shown/done
  *
  * @param int $courseid The current course' id
  * @param int $userid The user id to load for
  * @param string $gstitle The string to pass to get_string for the branch title
  * @return navigation_node|false
  */
 protected function generate_user_settings($courseid, $userid, $gstitle = 'usercurrentsettings')
 {
     global $DB, $CFG, $USER, $SITE;
     if ($courseid != $SITE->id) {
         if (!empty($this->page->course->id) && $this->page->course->id == $courseid) {
             $course = $this->page->course;
         } else {
             $select = context_helper::get_preload_record_columns_sql('ctx');
             $sql = "SELECT c.*, {$select}\n                          FROM {course} c\n                          JOIN {context} ctx ON c.id = ctx.instanceid\n                         WHERE c.id = :courseid AND ctx.contextlevel = :contextlevel";
             $params = array('courseid' => $courseid, 'contextlevel' => CONTEXT_COURSE);
             $course = $DB->get_record_sql($sql, $params, MUST_EXIST);
             context_helper::preload_from_record($course);
         }
     } else {
         $course = $SITE;
     }
     $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id);
     // Course context
     $systemcontext = get_system_context();
     $currentuser = $USER->id == $userid;
     if ($currentuser) {
         $user = $USER;
         $usercontext = get_context_instance(CONTEXT_USER, $user->id);
         // User context
     } else {
         $select = context_helper::get_preload_record_columns_sql('ctx');
         $sql = "SELECT u.*, {$select}\n                      FROM {user} u\n                      JOIN {context} ctx ON u.id = ctx.instanceid\n                     WHERE u.id = :userid AND ctx.contextlevel = :contextlevel";
         $params = array('userid' => $userid, 'contextlevel' => CONTEXT_USER);
         $user = $DB->get_record_sql($sql, $params, IGNORE_MISSING);
         if (!$user) {
             return false;
         }
         context_helper::preload_from_record($user);
         // Check that the user can view the profile
         $usercontext = get_context_instance(CONTEXT_USER, $user->id);
         // User context
         $canviewuser = has_capability('moodle/user:viewdetails', $usercontext);
         if ($course->id == $SITE->id) {
             if ($CFG->forceloginforprofiles && !has_coursecontact_role($user->id) && !$canviewuser) {
                 // Reduce possibility of "browsing" userbase at site level
                 // Teachers can browse and be browsed at site level. If not forceloginforprofiles, allow access (bug #4366)
                 return false;
             }
         } else {
             $canviewusercourse = has_capability('moodle/user:viewdetails', $coursecontext);
             $canaccessallgroups = has_capability('moodle/site:accessallgroups', $coursecontext);
             if (!$canviewusercourse && !$canviewuser || !can_access_course($course, $user->id)) {
                 return false;
             }
             if (!$canaccessallgroups && groups_get_course_groupmode($course) == SEPARATEGROUPS) {
                 // If groups are in use, make sure we can see that group
                 return false;
             }
         }
     }
     $fullname = fullname($user, has_capability('moodle/site:viewfullnames', $this->page->context));
     $key = $gstitle;
     if ($gstitle != 'usercurrentsettings') {
         $key .= $userid;
     }
     // Add a user setting branch
     $usersetting = $this->add(get_string($gstitle, 'moodle', $fullname), null, self::TYPE_CONTAINER, null, $key);
     $usersetting->id = 'usersettings';
     if ($this->page->context->contextlevel == CONTEXT_USER && $this->page->context->instanceid == $user->id) {
         // Automatically start by making it active
         $usersetting->make_active();
     }
     // Check if the user has been deleted
     if ($user->deleted) {
         if (!has_capability('moodle/user:update', $coursecontext)) {
             // We can't edit the user so just show the user deleted message
             $usersetting->add(get_string('userdeleted'), null, self::TYPE_SETTING);
         } else {
             // We can edit the user so show the user deleted message and link it to the profile
             if ($course->id == $SITE->id) {
                 $profileurl = new moodle_url('/user/profile.php', array('id' => $user->id));
             } else {
                 $profileurl = new moodle_url('/user/view.php', array('id' => $user->id, 'course' => $course->id));
             }
             $usersetting->add(get_string('userdeleted'), $profileurl, self::TYPE_SETTING);
         }
         return true;
     }
     $userauthplugin = false;
     if (!empty($user->auth)) {
         $userauthplugin = get_auth_plugin($user->auth);
     }
     // Add the profile edit link
     if (isloggedin() && !isguestuser($user) && !is_mnet_remote_user($user)) {
         if (($currentuser || is_siteadmin($USER) || !is_siteadmin($user)) && has_capability('moodle/user:update', $systemcontext)) {
             $url = new moodle_url('/user/editadvanced.php', array('id' => $user->id, 'course' => $course->id));
             $usersetting->add(get_string('editmyprofile'), $url, self::TYPE_SETTING);
         } else {
             if (has_capability('moodle/user:editprofile', $usercontext) && !is_siteadmin($user) || $currentuser && has_capability('moodle/user:editownprofile', $systemcontext)) {
                 if ($userauthplugin && $userauthplugin->can_edit_profile()) {
                     $url = $userauthplugin->edit_profile_url();
                     if (empty($url)) {
                         $url = new moodle_url('/user/edit.php', array('id' => $user->id, 'course' => $course->id));
                     }
                     $usersetting->add(get_string('editmyprofile'), $url, self::TYPE_SETTING);
                 }
             }
         }
     }
     // Change password link
     if ($userauthplugin && $currentuser && !session_is_loggedinas() && !isguestuser() && has_capability('moodle/user:changeownpassword', $systemcontext) && $userauthplugin->can_change_password()) {
         $passwordchangeurl = $userauthplugin->change_password_url();
         if (empty($passwordchangeurl)) {
             $passwordchangeurl = new moodle_url('/login/change_password.php', array('id' => $course->id));
         }
         $usersetting->add(get_string("changepassword"), $passwordchangeurl, self::TYPE_SETTING);
     }
     // View the roles settings
     if (has_any_capability(array('moodle/role:assign', 'moodle/role:safeoverride', 'moodle/role:override', 'moodle/role:manage'), $usercontext)) {
         $roles = $usersetting->add(get_string('roles'), null, self::TYPE_SETTING);
         $url = new moodle_url('/admin/roles/usersroles.php', array('userid' => $user->id, 'courseid' => $course->id));
         $roles->add(get_string('thisusersroles', 'role'), $url, self::TYPE_SETTING);
         $assignableroles = get_assignable_roles($usercontext, ROLENAME_BOTH);
         if (!empty($assignableroles)) {
             $url = new moodle_url('/admin/roles/assign.php', array('contextid' => $usercontext->id, 'userid' => $user->id, 'courseid' => $course->id));
             $roles->add(get_string('assignrolesrelativetothisuser', 'role'), $url, self::TYPE_SETTING);
         }
         if (has_capability('moodle/role:review', $usercontext) || count(get_overridable_roles($usercontext, ROLENAME_BOTH)) > 0) {
             $url = new moodle_url('/admin/roles/permissions.php', array('contextid' => $usercontext->id, 'userid' => $user->id, 'courseid' => $course->id));
             $roles->add(get_string('permissions', 'role'), $url, self::TYPE_SETTING);
         }
         $url = new moodle_url('/admin/roles/check.php', array('contextid' => $usercontext->id, 'userid' => $user->id, 'courseid' => $course->id));
         $roles->add(get_string('checkpermissions', 'role'), $url, self::TYPE_SETTING);
     }
     // Portfolio
     if ($currentuser && !empty($CFG->enableportfolios) && has_capability('moodle/portfolio:export', $systemcontext)) {
         require_once $CFG->libdir . '/portfoliolib.php';
         if (portfolio_instances(true, false)) {
             $portfolio = $usersetting->add(get_string('portfolios', 'portfolio'), null, self::TYPE_SETTING);
             $url = new moodle_url('/user/portfolio.php', array('courseid' => $course->id));
             $portfolio->add(get_string('configure', 'portfolio'), $url, self::TYPE_SETTING);
             $url = new moodle_url('/user/portfoliologs.php', array('courseid' => $course->id));
             $portfolio->add(get_string('logs', 'portfolio'), $url, self::TYPE_SETTING);
         }
     }
     $enablemanagetokens = false;
     if (!empty($CFG->enablerssfeeds)) {
         $enablemanagetokens = true;
     } else {
         if (!is_siteadmin($USER->id) && !empty($CFG->enablewebservices) && has_capability('moodle/webservice:createtoken', get_system_context())) {
             $enablemanagetokens = true;
         }
     }
     // Security keys
     if ($currentuser && $enablemanagetokens) {
         $url = new moodle_url('/user/managetoken.php', array('sesskey' => sesskey()));
         $usersetting->add(get_string('securitykeys', 'webservice'), $url, self::TYPE_SETTING);
     }
     // Repository
     if (!$currentuser && $usercontext->contextlevel == CONTEXT_USER) {
         if (!$this->cache->cached('contexthasrepos' . $usercontext->id)) {
             require_once $CFG->dirroot . '/repository/lib.php';
             $editabletypes = repository::get_editable_types($usercontext);
             $haseditabletypes = !empty($editabletypes);
             unset($editabletypes);
             $this->cache->set('contexthasrepos' . $usercontext->id, $haseditabletypes);
         } else {
             $haseditabletypes = $this->cache->{'contexthasrepos' . $usercontext->id};
         }
         if ($haseditabletypes) {
             $url = new moodle_url('/repository/manage_instances.php', array('contextid' => $usercontext->id));
             $usersetting->add(get_string('repositories', 'repository'), $url, self::TYPE_SETTING);
         }
     }
     // Messaging
     if ($currentuser && has_capability('moodle/user:editownmessageprofile', $systemcontext) || !isguestuser($user) && has_capability('moodle/user:editmessageprofile', $usercontext) && !is_primary_admin($user->id)) {
         $url = new moodle_url('/message/edit.php', array('id' => $user->id));
         $usersetting->add(get_string('editmymessage', 'message'), $url, self::TYPE_SETTING);
     }
     // Blogs
     if ($currentuser && !empty($CFG->bloglevel)) {
         $blog = $usersetting->add(get_string('blogs', 'blog'), null, navigation_node::TYPE_CONTAINER, null, 'blogs');
         $blog->add(get_string('preferences', 'blog'), new moodle_url('/blog/preferences.php'), navigation_node::TYPE_SETTING);
         if (!empty($CFG->useexternalblogs) && $CFG->maxexternalblogsperuser > 0 && has_capability('moodle/blog:manageexternal', get_context_instance(CONTEXT_SYSTEM))) {
             $blog->add(get_string('externalblogs', 'blog'), new moodle_url('/blog/external_blogs.php'), navigation_node::TYPE_SETTING);
             $blog->add(get_string('addnewexternalblog', 'blog'), new moodle_url('/blog/external_blog_edit.php'), navigation_node::TYPE_SETTING);
         }
     }
     // Login as ...
     if (!$user->deleted and !$currentuser && !session_is_loggedinas() && has_capability('moodle/user:loginas', $coursecontext) && !is_siteadmin($user->id)) {
         $url = new moodle_url('/course/loginas.php', array('id' => $course->id, 'user' => $user->id, 'sesskey' => sesskey()));
         $usersetting->add(get_string('loginas'), $url, self::TYPE_SETTING);
     }
     return $usersetting;
 }
 private static function can_access_course($courseid)
 {
     global $DB;
     static $cache = array();
     if (!array_key_exists($courseid, $cache)) {
         $course = $DB->get_record('course', array('id' => $courseid));
         $cache[$courseid] = can_access_course($course);
     }
     return $cache[$courseid];
 }