MDL-55415 course: Move admin options permission check to API
authorJuan Leyva <juanleyvadelgado@gmail.com>
Tue, 2 Aug 2016 13:17:14 +0000 (15:17 +0200)
committerJuan Leyva <juanleyvadelgado@gmail.com>
Mon, 5 Sep 2016 14:42:47 +0000 (15:42 +0100)
course/lib.php
course/tests/courselib_test.php
lib/navigationlib.php

index 6fb01fb..e9a0060 100644 (file)
@@ -4111,3 +4111,57 @@ function course_get_user_navigation_options($context, $course = null) {
     }
     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;
+}
index 444929e..a7fdc31 100644 (file)
@@ -3026,4 +3026,102 @@ class core_course_courselib_testcase extends advanced_testcase {
         $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);
+    }
 }
index 5059a85..6cc7a25 100644 (file)
@@ -3767,9 +3767,11 @@ class settings_navigation extends navigation_node {
      */
     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
 
@@ -3801,7 +3803,7 @@ class settings_navigation extends navigation_node {
             $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', ''));
@@ -3811,7 +3813,7 @@ class settings_navigation extends navigation_node {
                 $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', ''));
         }
@@ -3820,13 +3822,13 @@ class settings_navigation extends navigation_node {
         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');
@@ -3847,73 +3849,56 @@ class settings_navigation extends navigation_node {
             }
         }
 
-        // 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', ''));
         }
@@ -3922,7 +3907,7 @@ class settings_navigation extends navigation_node {
         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');
@@ -3940,7 +3925,7 @@ class settings_navigation extends navigation_node {
         }
 
         // 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', ''));
@@ -3953,7 +3938,7 @@ class settings_navigation extends navigation_node {
         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) {
@@ -4734,9 +4719,11 @@ class settings_navigation extends navigation_node {
      */
     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) {
@@ -4758,7 +4745,7 @@ class settings_navigation extends navigation_node {
             $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', ''));
@@ -4768,13 +4755,13 @@ class settings_navigation extends navigation_node {
         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');
@@ -4796,13 +4783,13 @@ class settings_navigation extends navigation_node {
         }
 
         // 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', ''));
         }
@@ -4812,7 +4799,7 @@ class settings_navigation extends navigation_node {
         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', ''));