diff --git a/course/externallib.php b/course/externallib.php index ec6f7c9d34c82..8b5025695e3de 100644 --- a/course/externallib.php +++ b/course/externallib.php @@ -2611,4 +2611,160 @@ public static function get_activities_overview_returns() { ); } + /** + * Returns description of method parameters + * + * @return external_function_parameters + * @since Moodle 3.2 + */ + public static function get_user_navigation_options_parameters() { + return new external_function_parameters( + array( + 'courseids' => new external_multiple_structure(new external_value(PARAM_INT, 'Course id.')), + ) + ); + } + + /** + * Return a list of navigation options in a set of courses that are avaialable or not for the current user. + * + * @param array $courseids a list of course ids + * @return array of warnings and the options availability + * @since Moodle 3.2 + * @throws moodle_exception + */ + public static function get_user_navigation_options($courseids) { + global $CFG; + require_once($CFG->dirroot . '/course/lib.php'); + + // Parameter validation. + $params = self::validate_parameters(self::get_user_navigation_options_parameters(), array('courseids' => $courseids)); + $courseoptions = array(); + + list($courses, $warnings) = external_util::validate_courses($params['courseids'], array(), true); + + if (!empty($courses)) { + foreach ($courses as $course) { + // Fix the context for the frontpage. + if ($course->id == SITEID) { + $course->context = context_system::instance(); + } + $navoptions = course_get_user_navigation_options($course->context, $course); + $options = array(); + foreach ($navoptions as $name => $available) { + $options[] = array( + 'name' => $name, + 'available' => $available, + ); + } + + $courseoptions[] = array( + 'id' => $course->id, + 'options' => $options + ); + } + } + + $result = array( + 'courses' => $courseoptions, + 'warnings' => $warnings + ); + return $result; + } + + /** + * Returns description of method result value + * + * @return external_description + * @since Moodle 3.2 + */ + public static function get_user_navigation_options_returns() { + return new external_single_structure( + array( + 'courses' => new external_multiple_structure( + new external_single_structure( + array( + 'id' => new external_value(PARAM_INT, 'Course id'), + 'options' => new external_multiple_structure( + new external_single_structure( + array( + 'name' => new external_value(PARAM_ALPHANUMEXT, 'Option name'), + 'available' => new external_value(PARAM_BOOL, 'Whether the option is available or not'), + ) + ) + ) + ) + ), 'List of courses' + ), + 'warnings' => new external_warnings() + ) + ); + } + + /** + * Returns description of method parameters + * + * @return external_function_parameters + * @since Moodle 3.2 + */ + public static function get_user_administration_options_parameters() { + return new external_function_parameters( + array( + 'courseids' => new external_multiple_structure(new external_value(PARAM_INT, 'Course id.')), + ) + ); + } + + /** + * Return a list of administration options in a set of courses that are available or not for the current user. + * + * @param array $courseids a list of course ids + * @return array of warnings and the options availability + * @since Moodle 3.2 + * @throws moodle_exception + */ + public static function get_user_administration_options($courseids) { + global $CFG; + require_once($CFG->dirroot . '/course/lib.php'); + + // Parameter validation. + $params = self::validate_parameters(self::get_user_administration_options_parameters(), array('courseids' => $courseids)); + $courseoptions = array(); + + list($courses, $warnings) = external_util::validate_courses($params['courseids'], array(), true); + + if (!empty($courses)) { + foreach ($courses as $course) { + $adminoptions = course_get_user_administration_options($course, $course->context); + $options = array(); + foreach ($adminoptions as $name => $available) { + $options[] = array( + 'name' => $name, + 'available' => $available, + ); + } + + $courseoptions[] = array( + 'id' => $course->id, + 'options' => $options + ); + } + } + + $result = array( + 'courses' => $courseoptions, + 'warnings' => $warnings + ); + return $result; + } + + /** + * Returns description of method result value + * + * @return external_description + * @since Moodle 3.2 + */ + public static function get_user_administration_options_returns() { + return self::get_user_navigation_options_returns(); + } } diff --git a/course/lib.php b/course/lib.php index a8ac69b2645e9..ea6827af2d266 100644 --- a/course/lib.php +++ b/course/lib.php @@ -4073,3 +4073,107 @@ function course_get_tagged_course_modules($tag, $exclusivemode = false, $fromcon $exclusivemode, $fromcontextid, $contextid, $recursivecontext, $page, $totalpages); } } + +/** + * Return an object with the list of navigation options in a course that are avaialable or not for the current user. + * This function also handles the frontpage course. + * + * @param stdClass $context context object (it can be a course context or the system context for frontpage settings) + * @param stdClass $course the course where the settings are being rendered (only used when $context is set to frontpage) + * @return stdClass the navigation options in a course and their availability status + * @since Moodle 3.2 + */ +function course_get_user_navigation_options($context, $course = null) { + global $CFG; + + $isloggedin = isloggedin(); + $isguestuser = isguestuser(); + $isfrontpage = $context->contextlevel == CONTEXT_SYSTEM; + + if ($isfrontpage) { + $sitecontext = $context; + } else { + $sitecontext = context_system::instance(); + } + + $options = new stdClass; + $options->blogs = !empty($CFG->enableblogs) && + ($CFG->bloglevel == BLOG_GLOBAL_LEVEL || + ($CFG->bloglevel == BLOG_SITE_LEVEL and ($isloggedin and !$isguestuser))) + && has_capability('moodle/blog:view', $sitecontext); + + $options->notes = !empty($CFG->enablenotes) && has_any_capability(array('moodle/notes:manage', 'moodle/notes:view'), $context); + + // Frontpage settings? + if ($isfrontpage) { + if ($course->id == SITEID) { + $options->participants = has_capability('moodle/site:viewparticipants', $sitecontext); + } else { + $options->participants = has_capability('moodle/course:viewparticipants', context_course::instance($course->id)); + } + + $options->badges = !empty($CFG->enablebadges) && has_capability('moodle/badges:viewbadges', $sitecontext); + $options->tags = !empty($CFG->usetags) && $isloggedin; + $options->search = !empty($CFG->enableglobalsearch) && has_capability('moodle/search:query', $sitecontext); + $options->calendar = $isloggedin; + } else { + $options->participants = has_capability('moodle/course:viewparticipants', $context); + $options->badges = !empty($CFG->enablebadges) && !empty($CFG->badges_allowcoursebadges) && + has_capability('moodle/badges:viewbadges', $context); + } + return $options; +} + +/** + * Return an object with the list of administration options in a course that are available or not for the current user. + * This function also handles the frontpage settings. + * + * @param stdClass $course course object (for frontpage it should be a clone of $SITE) + * @param stdClass $context context object (course context) + * @return stdClass the administration options in a course and their availability status + * @since Moodle 3.2 + */ +function course_get_user_administration_options($course, $context) { + global $CFG; + $isfrontpage = $course->id == SITEID; + + $options = new stdClass; + $options->update = has_capability('moodle/course:update', $context); + $options->filters = has_capability('moodle/filter:manage', $context) && + count(filter_get_available_in_context($context)) > 0; + $options->reports = has_capability('moodle/site:viewreports', $context); + $options->backup = has_capability('moodle/backup:backupcourse', $context); + $options->restore = has_capability('moodle/restore:restorecourse', $context); + $options->files = $course->legacyfiles == 2 and has_capability('moodle/course:managefiles', $context); + + if (!$isfrontpage) { + $options->tags = has_capability('moodle/course:tag', $context); + $options->gradebook = has_capability('moodle/grade:manage', $context); + $options->outcomes = !empty($CFG->enableoutcomes) && has_capability('moodle/course:update', $context); + $options->badges = !empty($CFG->enablebadges); + $options->import = has_capability('moodle/restore:restoretargetimport', $context); + $options->publish = has_capability('moodle/course:publish', $context); + $options->reset = has_capability('moodle/course:reset', $context); + $options->roles = has_capability('moodle/role:switchroles', $context); + + // Add view grade report is permitted. + $grades = false; + if (has_capability('moodle/grade:viewall', $context)) { + $grades = true; + } else if (!empty($course->showgrades)) { + $reports = core_component::get_plugin_list('gradereport'); + if (is_array($reports) && count($reports) > 0) { // Get all installed reports. + arsort($reports); // User is last, we want to test it first. + foreach ($reports as $plugin => $plugindir) { + if (has_capability('gradereport/'.$plugin.':view', $context)) { + // Stop when the first visible plugin is found. + $grades = true; + break; + } + } + } + } + $options->grades = $grades; + } + return $options; +} diff --git a/course/tests/courselib_test.php b/course/tests/courselib_test.php index 4c9ed7396d6fa..a7fdc316aff54 100644 --- a/course/tests/courselib_test.php +++ b/course/tests/courselib_test.php @@ -2920,4 +2920,208 @@ public function test_course_get_tagged_course_modules() { $this->assertNotEmpty($res->prevpageurl); $this->assertEmpty($res->nextpageurl); } + + /** + * Test course_get_user_navigation_options for frontpage. + */ + public function test_course_get_user_navigation_options_for_frontpage() { + global $CFG, $SITE, $DB; + $this->resetAfterTest(); + $context = context_system::instance(); + $course = clone $SITE; + $this->setAdminUser(); + + $navoptions = course_get_user_navigation_options($context, $course); + $this->assertTrue($navoptions->blogs); + $this->assertTrue($navoptions->notes); + $this->assertTrue($navoptions->participants); + $this->assertTrue($navoptions->badges); + $this->assertTrue($navoptions->tags); + $this->assertFalse($navoptions->search); + $this->assertTrue($navoptions->calendar); + + // Enable global search now. + $CFG->enableglobalsearch = 1; + $navoptions = course_get_user_navigation_options($context, $course); + $this->assertTrue($navoptions->search); + + // Now try with a standard user. + $user = $this->getDataGenerator()->create_user(); + $this->setUser($user); + $navoptions = course_get_user_navigation_options($context, $course); + $this->assertTrue($navoptions->blogs); + $this->assertFalse($navoptions->notes); + $this->assertFalse($navoptions->participants); + $this->assertTrue($navoptions->badges); + $this->assertTrue($navoptions->tags); + $this->assertTrue($navoptions->search); + $this->assertTrue($navoptions->calendar); + + // Standar using viewing frontpage settings from a course where is enrolled. + $course = self::getDataGenerator()->create_course(); + // Create a viewer user. + $viewer = self::getDataGenerator()->create_user(); + $studentrole = $DB->get_record('role', array('shortname' => 'student')); + $this->getDataGenerator()->enrol_user($viewer->id, $course->id, $studentrole->id); + $this->setUser($viewer); + + $navoptions = course_get_user_navigation_options($context, $course); + $this->assertTrue($navoptions->blogs); + $this->assertFalse($navoptions->notes); + $this->assertTrue($navoptions->participants); + $this->assertTrue($navoptions->badges); + $this->assertTrue($navoptions->tags); + $this->assertTrue($navoptions->search); + $this->assertTrue($navoptions->calendar); + } + + /** + * Test course_get_user_navigation_options for managers in a normal course. + */ + public function test_course_get_user_navigation_options_for_managers() { + global $CFG; + $this->resetAfterTest(); + $course = $this->getDataGenerator()->create_course(); + $context = context_course::instance($course->id); + $this->setAdminUser(); + + $navoptions = course_get_user_navigation_options($context); + $this->assertTrue($navoptions->blogs); + $this->assertTrue($navoptions->notes); + $this->assertTrue($navoptions->participants); + $this->assertTrue($navoptions->badges); + } + + /** + * Test course_get_user_navigation_options for students in a normal course. + */ + public function test_course_get_user_navigation_options_for_students() { + global $DB, $CFG; + $this->resetAfterTest(); + $course = $this->getDataGenerator()->create_course(); + $context = context_course::instance($course->id); + + $user = $this->getDataGenerator()->create_user(); + $roleid = $DB->get_field('role', 'id', array('shortname' => 'student')); + $this->getDataGenerator()->enrol_user($user->id, $course->id, $roleid); + + $this->setUser($user); + + $navoptions = course_get_user_navigation_options($context); + $this->assertTrue($navoptions->blogs); + $this->assertFalse($navoptions->notes); + $this->assertTrue($navoptions->participants); + $this->assertTrue($navoptions->badges); + + // Disable some options. + $CFG->badges_allowcoursebadges = 0; + $CFG->enableblogs = 0; + // Disable view participants capability. + assign_capability('moodle/course:viewparticipants', CAP_PROHIBIT, $roleid, $context); + $context->mark_dirty(); + + $navoptions = course_get_user_navigation_options($context); + $this->assertFalse($navoptions->blogs); + $this->assertFalse($navoptions->notes); + $this->assertFalse($navoptions->participants); + $this->assertFalse($navoptions->badges); + } + + /** + * Test course_get_user_administration_options for frontpage. + */ + public function test_course_get_user_administration_options_for_frontpage() { + global $CFG, $SITE; + $this->resetAfterTest(); + $course = clone $SITE; + $context = context_course::instance($course->id); + $this->setAdminUser(); + + $adminoptions = course_get_user_administration_options($course, $context); + $this->assertTrue($adminoptions->update); + $this->assertTrue($adminoptions->filters); + $this->assertTrue($adminoptions->reports); + $this->assertTrue($adminoptions->backup); + $this->assertTrue($adminoptions->restore); + $this->assertFalse($adminoptions->files); + $this->assertTrue(!isset($adminoptions->tags)); + + // Now try with a standard user. + $user = $this->getDataGenerator()->create_user(); + $this->setUser($user); + $adminoptions = course_get_user_administration_options($course, $context); + $this->assertFalse($adminoptions->update); + $this->assertFalse($adminoptions->filters); + $this->assertFalse($adminoptions->reports); + $this->assertFalse($adminoptions->backup); + $this->assertFalse($adminoptions->restore); + $this->assertFalse($adminoptions->files); + $this->assertTrue(!isset($adminoptions->tags)); + + } + + /** + * Test course_get_user_administration_options for managers in a normal course. + */ + public function test_course_get_user_administration_options_for_managers() { + global $CFG; + $this->resetAfterTest(); + $course = $this->getDataGenerator()->create_course(); + $context = context_course::instance($course->id); + $this->setAdminUser(); + + $adminoptions = course_get_user_administration_options($course, $context); + $this->assertTrue($adminoptions->update); + $this->assertTrue($adminoptions->filters); + $this->assertTrue($adminoptions->reports); + $this->assertTrue($adminoptions->backup); + $this->assertTrue($adminoptions->restore); + $this->assertFalse($adminoptions->files); + $this->assertTrue($adminoptions->tags); + $this->assertTrue($adminoptions->gradebook); + $this->assertFalse($adminoptions->outcomes); + $this->assertTrue($adminoptions->badges); + $this->assertTrue($adminoptions->import); + $this->assertTrue($adminoptions->publish); + $this->assertTrue($adminoptions->reset); + $this->assertTrue($adminoptions->roles); + $this->assertTrue($adminoptions->grades); + } + + /** + * Test course_get_user_administration_options for students in a normal course. + */ + public function test_course_get_user_administration_options_for_students() { + global $DB, $CFG; + $this->resetAfterTest(); + $course = $this->getDataGenerator()->create_course(); + $context = context_course::instance($course->id); + + $user = $this->getDataGenerator()->create_user(); + $roleid = $DB->get_field('role', 'id', array('shortname' => 'student')); + $this->getDataGenerator()->enrol_user($user->id, $course->id, $roleid); + + $this->setUser($user); + $adminoptions = course_get_user_administration_options($course, $context); + + $this->assertFalse($adminoptions->update); + $this->assertFalse($adminoptions->filters); + $this->assertFalse($adminoptions->reports); + $this->assertFalse($adminoptions->backup); + $this->assertFalse($adminoptions->restore); + $this->assertFalse($adminoptions->files); + $this->assertFalse($adminoptions->tags); + $this->assertFalse($adminoptions->gradebook); + $this->assertFalse($adminoptions->outcomes); + $this->assertTrue($adminoptions->badges); + $this->assertFalse($adminoptions->import); + $this->assertFalse($adminoptions->publish); + $this->assertFalse($adminoptions->reset); + $this->assertFalse($adminoptions->roles); + $this->assertTrue($adminoptions->grades); + + $CFG->enablebadges = false; + $adminoptions = course_get_user_administration_options($course, $context); + $this->assertFalse($adminoptions->badges); + } } diff --git a/course/tests/externallib_test.php b/course/tests/externallib_test.php index 0e07018336a41..552e509c6e546 100644 --- a/course/tests/externallib_test.php +++ b/course/tests/externallib_test.php @@ -1755,4 +1755,111 @@ public function test_get_activities_overview() { $this->assertEquals('forum', $result['courses'][0]['overviews'][0]['module']); $this->assertContains('1 total unread', $result['courses'][0]['overviews'][0]['overviewtext']); } + + /** + * Test get_user_navigation_options + */ + public function test_get_user_navigation_options() { + global $USER; + + $this->resetAfterTest(); + $course1 = self::getDataGenerator()->create_course(); + $course2 = self::getDataGenerator()->create_course(); + + // Create a viewer user. + $viewer = self::getDataGenerator()->create_user(); + $this->getDataGenerator()->enrol_user($viewer->id, $course1->id); + $this->getDataGenerator()->enrol_user($viewer->id, $course2->id); + + $this->setUser($viewer->id); + $courses = array($course1->id , $course2->id, SITEID); + + $result = core_course_external::get_user_navigation_options($courses); + $result = external_api::clean_returnvalue(core_course_external::get_user_navigation_options_returns(), $result); + + $this->assertCount(0, $result['warnings']); + $this->assertCount(3, $result['courses']); + + foreach ($result['courses'] as $course) { + $navoptions = new stdClass; + foreach ($course['options'] as $option) { + $navoptions->{$option['name']} = $option['available']; + } + if ($course['id'] == SITEID) { + $this->assertCount(7, $course['options']); + $this->assertTrue($navoptions->blogs); + $this->assertFalse($navoptions->notes); + $this->assertFalse($navoptions->participants); + $this->assertTrue($navoptions->badges); + $this->assertTrue($navoptions->tags); + $this->assertFalse($navoptions->search); + $this->assertTrue($navoptions->calendar); + } else { + $this->assertCount(4, $course['options']); + $this->assertTrue($navoptions->blogs); + $this->assertFalse($navoptions->notes); + $this->assertTrue($navoptions->participants); + $this->assertTrue($navoptions->badges); + } + } + } + + /** + * Test get_user_administration_options + */ + public function test_get_user_administration_options() { + global $USER; + + $this->resetAfterTest(); + $course1 = self::getDataGenerator()->create_course(); + $course2 = self::getDataGenerator()->create_course(); + + // Create a viewer user. + $viewer = self::getDataGenerator()->create_user(); + $this->getDataGenerator()->enrol_user($viewer->id, $course1->id); + $this->getDataGenerator()->enrol_user($viewer->id, $course2->id); + + $this->setUser($viewer->id); + $courses = array($course1->id , $course2->id, SITEID); + + $result = core_course_external::get_user_administration_options($courses); + $result = external_api::clean_returnvalue(core_course_external::get_user_administration_options_returns(), $result); + + $this->assertCount(0, $result['warnings']); + $this->assertCount(3, $result['courses']); + + foreach ($result['courses'] as $course) { + $adminoptions = new stdClass; + foreach ($course['options'] as $option) { + $adminoptions->{$option['name']} = $option['available']; + } + if ($course['id'] == SITEID) { + $this->assertCount(6, $course['options']); + $this->assertFalse($adminoptions->update); + $this->assertFalse($adminoptions->filters); + $this->assertFalse($adminoptions->reports); + $this->assertFalse($adminoptions->backup); + $this->assertFalse($adminoptions->restore); + $this->assertFalse($adminoptions->files); + $this->assertTrue(!isset($adminoptions->tags)); + } else { + $this->assertCount(15, $course['options']); + $this->assertFalse($adminoptions->update); + $this->assertFalse($adminoptions->filters); + $this->assertFalse($adminoptions->reports); + $this->assertFalse($adminoptions->backup); + $this->assertFalse($adminoptions->restore); + $this->assertFalse($adminoptions->files); + $this->assertFalse($adminoptions->tags); + $this->assertFalse($adminoptions->gradebook); + $this->assertFalse($adminoptions->outcomes); + $this->assertTrue($adminoptions->badges); + $this->assertFalse($adminoptions->import); + $this->assertFalse($adminoptions->publish); + $this->assertFalse($adminoptions->reset); + $this->assertFalse($adminoptions->roles); + $this->assertTrue($adminoptions->grades); + } + } + } } diff --git a/lib/db/services.php b/lib/db/services.php index 8694520ec1239..8fc5595d5e4f4 100644 --- a/lib/db/services.php +++ b/lib/db/services.php @@ -302,6 +302,23 @@ 'type' => 'read', 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE), ), + 'core_course_get_user_navigation_options' => array( + 'classname' => 'core_course_external', + 'methodname' => 'get_user_navigation_options', + 'classpath' => 'course/externallib.php', + 'description' => 'Return a list of navigation options in a set of courses that are avaialable or not for the current user.', + 'type' => 'read', + 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE), + ), + 'core_course_get_user_administration_options' => array( + 'classname' => 'core_course_external', + 'methodname' => 'get_user_administration_options', + 'classpath' => 'course/externallib.php', + 'description' => 'Return a list of administration options in a set of courses that are avaialable or not for the current + user.', + 'type' => 'read', + 'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE), + ), 'core_enrol_get_course_enrolment_methods' => array( 'classname' => 'core_enrol_external', 'methodname' => 'get_course_enrolment_methods', diff --git a/lib/externallib.php b/lib/externallib.php index ab3346c48be07..c05009da85e1d 100644 --- a/lib/externallib.php +++ b/lib/externallib.php @@ -1098,9 +1098,10 @@ class external_util { * * @param array $courseids A list of course ids * @param array $courses An array of courses already pre-fetched, indexed by course id. + * @param bool $addcontext True if the returned course object should include the full context object. * @return array An array of courses and the validation warnings */ - public static function validate_courses($courseids, $courses = array()) { + public static function validate_courses($courseids, $courses = array(), $addcontext = false) { // Delete duplicates. $courseids = array_unique($courseids); $warnings = array(); @@ -1117,6 +1118,9 @@ public static function validate_courses($courseids, $courses = array()) { if (!isset($courses[$cid])) { $courses[$cid] = get_course($cid); } + if ($addcontext) { + $courses[$cid]->context = $context; + } } catch (Exception $e) { unset($courses[$cid]); $warnings[] = array( diff --git a/lib/navigationlib.php b/lib/navigationlib.php index ec308c6bf87d0..6cc7a258720db 100644 --- a/lib/navigationlib.php +++ b/lib/navigationlib.php @@ -2536,6 +2536,7 @@ protected function is_category_fully_loaded($categoryid) { */ public function add_course_essentials($coursenode, stdClass $course) { global $CFG, $SITE; + require_once($CFG->dirroot . '/course/lib.php'); if ($course->id == $SITE->id) { return $this->add_front_page_course_essentials($coursenode, $course); @@ -2545,22 +2546,23 @@ public function add_course_essentials($coursenode, stdClass $course) { return true; } + $navoptions = course_get_user_navigation_options($this->page->context); + //Participants - if (has_capability('moodle/course:viewparticipants', $this->page->context)) { + if ($navoptions->participants) { $participants = $coursenode->add(get_string('participants'), new moodle_url('/user/index.php?id='.$course->id), self::TYPE_CONTAINER, get_string('participants'), 'participants'); - if (!empty($CFG->enableblogs)) { - if (($CFG->bloglevel == BLOG_GLOBAL_LEVEL or ($CFG->bloglevel == BLOG_SITE_LEVEL and (isloggedin() and !isguestuser()))) - and has_capability('moodle/blog:view', context_system::instance())) { - $blogsurls = new moodle_url('/blog/index.php'); - if ($currentgroup = groups_get_course_group($course, true)) { - $blogsurls->param('groupid', $currentgroup); - } else { - $blogsurls->param('courseid', $course->id); - } - $participants->add(get_string('blogscourse', 'blog'), $blogsurls->out(), self::TYPE_SETTING, null, 'courseblogs'); + + if ($navoptions->blogs) { + $blogsurls = new moodle_url('/blog/index.php'); + if ($currentgroup = groups_get_course_group($course, true)) { + $blogsurls->param('groupid', $currentgroup); + } else { + $blogsurls->param('courseid', $course->id); } + $participants->add(get_string('blogscourse', 'blog'), $blogsurls->out(), self::TYPE_SETTING, null, 'courseblogs'); } - if (!empty($CFG->enablenotes) && (has_capability('moodle/notes:manage', $this->page->context) || has_capability('moodle/notes:view', $this->page->context))) { + + if ($navoptions->notes) { $participants->add(get_string('notes', 'notes'), new moodle_url('/notes/index.php', array('filtertype' => 'course', 'filterselect' => $course->id)), self::TYPE_SETTING, null, 'currentcoursenotes'); } } else if (count($this->extendforuser) > 0 || $this->page->course->id == $course->id) { @@ -2568,8 +2570,7 @@ public function add_course_essentials($coursenode, stdClass $course) { } // Badges. - if (!empty($CFG->enablebadges) && !empty($CFG->badges_allowcoursebadges) && - has_capability('moodle/badges:viewbadges', $this->page->context)) { + if ($navoptions->badges) { $url = new moodle_url('/badges/view.php', array('type' => 2, 'id' => $course->id)); $coursenode->add(get_string('coursebadges', 'badges'), null, @@ -2594,30 +2595,26 @@ public function add_course_essentials($coursenode, stdClass $course) { */ public function add_front_page_course_essentials(navigation_node $coursenode, stdClass $course) { global $CFG; + require_once($CFG->dirroot . '/course/lib.php'); if ($coursenode == false || $coursenode->get('frontpageloaded', navigation_node::TYPE_CUSTOM)) { return true; } $sitecontext = context_system::instance(); - $isfrontpage = ($course->id == SITEID); + $navoptions = course_get_user_navigation_options($sitecontext, $course); // Hidden node that we use to determine if the front page navigation is loaded. // This required as there are not other guaranteed nodes that may be loaded. $coursenode->add('frontpageloaded', null, self::TYPE_CUSTOM, null, 'frontpageloaded')->display = false; // Participants. - // If this is the site course, they need to have moodle/site:viewparticipants at the site level. - // If no, then they need to have moodle/course:viewparticipants at the course level. - if (($isfrontpage && has_capability('moodle/site:viewparticipants', $sitecontext)) || - (!$isfrontpage && has_capability('moodle/course:viewparticipants', context_course::instance($course->id)))) { + if ($navoptions->participants) { $coursenode->add(get_string('participants'), new moodle_url('/user/index.php?id='.$course->id), self::TYPE_CUSTOM, get_string('participants'), 'participants'); } // Blogs. - if (!empty($CFG->enableblogs) - and ($CFG->bloglevel == BLOG_GLOBAL_LEVEL or ($CFG->bloglevel == BLOG_SITE_LEVEL and (isloggedin() and !isguestuser()))) - and has_capability('moodle/blog:view', $sitecontext)) { + if ($navoptions->blogs) { $blogsurls = new moodle_url('/blog/index.php'); $coursenode->add(get_string('blogssite', 'blog'), $blogsurls->out(), self::TYPE_SYSTEM, null, 'siteblog'); } @@ -2625,30 +2622,30 @@ public function add_front_page_course_essentials(navigation_node $coursenode, st $filterselect = 0; // Badges. - if (!empty($CFG->enablebadges) && has_capability('moodle/badges:viewbadges', $sitecontext)) { + if ($navoptions->badges) { $url = new moodle_url($CFG->wwwroot . '/badges/view.php', array('type' => 1)); $coursenode->add(get_string('sitebadges', 'badges'), $url, navigation_node::TYPE_CUSTOM); } // Notes. - if (!empty($CFG->enablenotes) && has_any_capability(array('moodle/notes:manage', 'moodle/notes:view'), $sitecontext)) { + if ($navoptions->notes) { $coursenode->add(get_string('notes', 'notes'), new moodle_url('/notes/index.php', array('filtertype' => 'course', 'filterselect' => $filterselect)), self::TYPE_SETTING, null, 'notes'); } // Tags - if (!empty($CFG->usetags) && isloggedin()) { + if ($navoptions->tags) { $node = $coursenode->add(get_string('tags', 'tag'), new moodle_url('/tag/search.php'), self::TYPE_SETTING, null, 'tags'); } // Search. - if (!empty($CFG->enableglobalsearch) && has_capability('moodle/search:query', $sitecontext)) { + if ($navoptions->search) { $node = $coursenode->add(get_string('search', 'search'), new moodle_url('/search/index.php'), self::TYPE_SETTING, null, 'search'); } - if (isloggedin()) { + if ($navoptions->calendar) { // Calendar $calendarurl = new moodle_url('/calendar/view.php', array('view' => 'month')); $coursenode->add(get_string('calendar', 'calendar'), $calendarurl, self::TYPE_CUSTOM, null, 'calendar'); @@ -3770,9 +3767,11 @@ protected function get_by_path(array $path) { */ protected function load_course_settings($forceopen = false) { global $CFG; + require_once($CFG->dirroot . '/course/lib.php'); $course = $this->page->course; $coursecontext = context_course::instance($course->id); + $adminoptions = course_get_user_administration_options($course, $coursecontext); // note: do not test if enrolled or viewing here because we need the enrol link in Course administration section @@ -3804,7 +3803,7 @@ protected function load_course_settings($forceopen = false) { $coursenode->add($editstring, $editurl, self::TYPE_SETTING, null, 'turneditingonoff', new pix_icon('i/edit', '')); } - if (has_capability('moodle/course:update', $coursecontext)) { + if ($adminoptions->update) { // Add the course settings link $url = new moodle_url('/course/edit.php', array('id'=>$course->id)); $coursenode->add(get_string('editsettings'), $url, self::TYPE_SETTING, null, 'editsettings', new pix_icon('i/settings', '')); @@ -3814,7 +3813,7 @@ protected function load_course_settings($forceopen = false) { $url = new moodle_url('/course/completion.php', array('id'=>$course->id)); $coursenode->add(get_string('coursecompletion', 'completion'), $url, self::TYPE_SETTING, null, null, new pix_icon('i/settings', '')); } - } else if (has_capability('moodle/course:tag', $coursecontext)) { + } else if ($adminoptions->tags) { $url = new moodle_url('/course/tags.php', array('id' => $course->id)); $coursenode->add(get_string('coursetags', 'tag'), $url, self::TYPE_SETTING, null, 'coursetags', new pix_icon('i/settings', '')); } @@ -3823,13 +3822,13 @@ protected function load_course_settings($forceopen = false) { enrol_add_course_navigation($coursenode, $course); // Manage filters - if (has_capability('moodle/filter:manage', $coursecontext) && count(filter_get_available_in_context($coursecontext))>0) { + if ($adminoptions->filters) { $url = new moodle_url('/filter/manage.php', array('contextid'=>$coursecontext->id)); $coursenode->add(get_string('filters', 'admin'), $url, self::TYPE_SETTING, null, null, new pix_icon('i/filter', '')); } // View course reports. - if (has_capability('moodle/site:viewreports', $coursecontext)) { // Basic capability for listing of reports. + if ($adminoptions->reports) { $reportnav = $coursenode->add(get_string('reports'), null, self::TYPE_CONTAINER, null, 'coursereports', new pix_icon('i/stats', '')); $coursereports = core_component::get_plugin_list('coursereport'); @@ -3850,73 +3849,56 @@ protected function load_course_settings($forceopen = false) { } } - // Add view grade report is permitted - $reportavailable = false; - if (has_capability('moodle/grade:viewall', $coursecontext)) { - $reportavailable = true; - } else if (!empty($course->showgrades)) { - $reports = core_component::get_plugin_list('gradereport'); - if (is_array($reports) && count($reports)>0) { // Get all installed reports - arsort($reports); // user is last, we want to test it first - foreach ($reports as $plugin => $plugindir) { - if (has_capability('gradereport/'.$plugin.':view', $coursecontext)) { - //stop when the first visible plugin is found - $reportavailable = true; - break; - } - } - } - } - if ($reportavailable) { + if ($adminoptions->grades) { $url = new moodle_url('/grade/report/index.php', array('id'=>$course->id)); $gradenode = $coursenode->add(get_string('grades'), $url, self::TYPE_SETTING, null, 'grades', new pix_icon('i/grades', '')); } // Check if we can view the gradebook's setup page. - if (has_capability('moodle/grade:manage', $coursecontext)) { + if ($adminoptions->gradebook) { $url = new moodle_url('/grade/edit/tree/index.php', array('id' => $course->id)); $coursenode->add(get_string('gradebooksetup', 'grades'), $url, self::TYPE_SETTING, null, 'gradebooksetup', new pix_icon('i/settings', '')); } // Add outcome if permitted - if (!empty($CFG->enableoutcomes) && has_capability('moodle/course:update', $coursecontext)) { + if ($adminoptions->outcomes) { $url = new moodle_url('/grade/edit/outcome/course.php', array('id'=>$course->id)); $coursenode->add(get_string('outcomes', 'grades'), $url, self::TYPE_SETTING, null, 'outcomes', new pix_icon('i/outcomes', '')); } //Add badges navigation - if (!empty($CFG->enablebadges)) { + if ($adminoptions->badges) { require_once($CFG->libdir .'/badgeslib.php'); badges_add_course_navigation($coursenode, $course); } // Backup this course - if (has_capability('moodle/backup:backupcourse', $coursecontext)) { + if ($adminoptions->backup) { $url = new moodle_url('/backup/backup.php', array('id'=>$course->id)); $coursenode->add(get_string('backup'), $url, self::TYPE_SETTING, null, 'backup', new pix_icon('i/backup', '')); } // Restore to this course - if (has_capability('moodle/restore:restorecourse', $coursecontext)) { + if ($adminoptions->restore) { $url = new moodle_url('/backup/restorefile.php', array('contextid'=>$coursecontext->id)); $coursenode->add(get_string('restore'), $url, self::TYPE_SETTING, null, 'restore', new pix_icon('i/restore', '')); } // Import data from other courses - if (has_capability('moodle/restore:restoretargetimport', $coursecontext)) { + if ($adminoptions->import) { $url = new moodle_url('/backup/import.php', array('id'=>$course->id)); $coursenode->add(get_string('import'), $url, self::TYPE_SETTING, null, 'import', new pix_icon('i/import', '')); } // Publish course on a hub - if (has_capability('moodle/course:publish', $coursecontext)) { + if ($adminoptions->publish) { $url = new moodle_url('/course/publish/index.php', array('id'=>$course->id)); $coursenode->add(get_string('publish'), $url, self::TYPE_SETTING, null, 'publish', new pix_icon('i/publish', '')); } // Reset this course - if (has_capability('moodle/course:reset', $coursecontext)) { + if ($adminoptions->reset) { $url = new moodle_url('/course/reset.php', array('id'=>$course->id)); $coursenode->add(get_string('reset'), $url, self::TYPE_SETTING, null, 'reset', new pix_icon('i/return', '')); } @@ -3925,7 +3907,7 @@ protected function load_course_settings($forceopen = false) { require_once($CFG->libdir . '/questionlib.php'); question_extend_settings_navigation($coursenode, $coursecontext)->trim_if_empty(); - if (has_capability('moodle/course:update', $coursecontext)) { + if ($adminoptions->update) { // Repository Instances if (!$this->cache->cached('contexthasrepos'.$coursecontext->id)) { require_once($CFG->dirroot . '/repository/lib.php'); @@ -3943,7 +3925,7 @@ protected function load_course_settings($forceopen = false) { } // Manage files - if ($course->legacyfiles == 2 and has_capability('moodle/course:managefiles', $coursecontext)) { + if ($adminoptions->files) { // hidden in new courses and courses where legacy files were turned off $url = new moodle_url('/files/index.php', array('contextid'=>$coursecontext->id)); $coursenode->add(get_string('courselegacyfiles'), $url, self::TYPE_SETTING, null, 'coursefiles', new pix_icon('i/folder', '')); @@ -3956,7 +3938,7 @@ protected function load_course_settings($forceopen = false) { if ($assumedrole !== false) { $roles[0] = get_string('switchrolereturn'); } - if (has_capability('moodle/role:switchroles', $coursecontext)) { + if ($adminoptions->roles) { $availableroles = get_switchable_roles($coursecontext); if (is_array($availableroles)) { foreach ($availableroles as $key=>$role) { @@ -4737,9 +4719,11 @@ protected function in_alternative_role() { */ protected function load_front_page_settings($forceopen = false) { global $SITE, $CFG; + require_once($CFG->dirroot . '/course/lib.php'); $course = clone($SITE); $coursecontext = context_course::instance($course->id); // Course context + $adminoptions = course_get_user_administration_options($course, $coursecontext); $frontpage = $this->add(get_string('frontpagesettings'), null, self::TYPE_SETTING, null, 'frontpage'); if ($forceopen) { @@ -4761,7 +4745,7 @@ protected function load_front_page_settings($forceopen = false) { $frontpage->add($editstring, $url, self::TYPE_SETTING, null, null, new pix_icon('i/edit', '')); } - if (has_capability('moodle/course:update', $coursecontext)) { + if ($adminoptions->update) { // Add the course settings link $url = new moodle_url('/admin/settings.php', array('section'=>'frontpagesettings')); $frontpage->add(get_string('editsettings'), $url, self::TYPE_SETTING, null, null, new pix_icon('i/settings', '')); @@ -4771,13 +4755,13 @@ protected function load_front_page_settings($forceopen = false) { enrol_add_course_navigation($frontpage, $course); // Manage filters - if (has_capability('moodle/filter:manage', $coursecontext) && count(filter_get_available_in_context($coursecontext))>0) { + if ($adminoptions->filters) { $url = new moodle_url('/filter/manage.php', array('contextid'=>$coursecontext->id)); $frontpage->add(get_string('filters', 'admin'), $url, self::TYPE_SETTING, null, null, new pix_icon('i/filter', '')); } // View course reports. - if (has_capability('moodle/site:viewreports', $coursecontext)) { // Basic capability for listing of reports. + if ($adminoptions->reports) { $frontpagenav = $frontpage->add(get_string('reports'), null, self::TYPE_CONTAINER, null, 'frontpagereports', new pix_icon('i/stats', '')); $coursereports = core_component::get_plugin_list('coursereport'); @@ -4799,13 +4783,13 @@ protected function load_front_page_settings($forceopen = false) { } // Backup this course - if (has_capability('moodle/backup:backupcourse', $coursecontext)) { + if ($adminoptions->backup) { $url = new moodle_url('/backup/backup.php', array('id'=>$course->id)); $frontpage->add(get_string('backup'), $url, self::TYPE_SETTING, null, null, new pix_icon('i/backup', '')); } // Restore to this course - if (has_capability('moodle/restore:restorecourse', $coursecontext)) { + if ($adminoptions->restore) { $url = new moodle_url('/backup/restorefile.php', array('contextid'=>$coursecontext->id)); $frontpage->add(get_string('restore'), $url, self::TYPE_SETTING, null, null, new pix_icon('i/restore', '')); } @@ -4815,7 +4799,7 @@ protected function load_front_page_settings($forceopen = false) { question_extend_settings_navigation($frontpage, $coursecontext)->trim_if_empty(); // Manage files - if ($course->legacyfiles == 2 and has_capability('moodle/course:managefiles', $this->context)) { + if ($adminoptions->files) { //hiden in new installs $url = new moodle_url('/files/index.php', array('contextid'=>$coursecontext->id)); $frontpage->add(get_string('sitelegacyfiles'), $url, self::TYPE_SETTING, null, null, new pix_icon('i/folder', ''));