Skip to content

Commit

Permalink
MDL-58140 completion: access control refinements
Browse files Browse the repository at this point in the history
Part of MDL-58138 epic
  • Loading branch information
marinaglancy authored and snake committed Apr 19, 2017
1 parent 6e60511 commit 0cbc248
Show file tree
Hide file tree
Showing 9 changed files with 113 additions and 37 deletions.
74 changes: 59 additions & 15 deletions completion/classes/manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,24 +65,45 @@ public function get_activities_and_headings() {
$sectionobject = new stdClass();
$sectionobject->sectionnumber = $sectionnumber;
$sectionobject->name = get_section_name($this->courseid, $sectioninfo);
$sectionobject->activities = [];

foreach ($section as $cmid) {
$mod = $moduleinfo->get_cm($cmid);
$moduleobject = new stdClass();
$moduleobject->cmid = $cmid;
$moduleobject->modname = $mod->get_formatted_name();
$moduleobject->icon = $mod->get_icon_url()->out();
$moduleobject->url = $mod->url;

// Get activity completion information.
$moduleobject->completionstatus = $this->get_completion_detail($mod);
$activitiesdata = $this->get_activities($section, true);
$sectionobject->activities = $activitiesdata->activities;
$data->sections[] = $sectionobject;
}
return $data;
}

$sectionobject->activities[] = $moduleobject;
/**
* Gets the data (context) to be used with the activityinstance template
*
* @param array $cmids list of course module ids
* @param bool $withcompletiondetails include completion details
* @return \stdClass
*/
public function get_activities($cmids, $withcompletiondetails = false) {
$moduleinfo = get_fast_modinfo($this->courseid);
$activities = [];
foreach ($cmids as $cmid) {
$mod = $moduleinfo->get_cm($cmid);
if (!$mod->uservisible) {
continue;
}
$moduleobject = new stdClass();
$moduleobject->cmid = $cmid;
$moduleobject->modname = $mod->get_formatted_name();
$moduleobject->icon = $mod->get_icon_url()->out();
$moduleobject->url = $mod->url;
$moduleobject->canmanage = $withcompletiondetails && self::can_edit_bulk_completion($this->courseid, $mod);

// Get activity completion information.
if ($moduleobject->canmanage) {
$moduleobject->completionstatus = $this->get_completion_detail($mod); // This is a placeholder only. Must be replaced later.
} else {
$moduleobject->completionstatus = ['icon' => null, 'string' => null];
}
$data->sections[] = $sectionobject;

$activities[] = $moduleobject;
}
return $data;
return (object)['activities' => $activities];
}

private function get_completion_detail(\cm_info $mod) {
Expand Down Expand Up @@ -137,4 +158,27 @@ public function get_activities_and_resources() {
return $data;
}

/**
* Checks if current user can edit activity completion
*
* @param int|stdClass $courseorid
* @param \cm_info|null $cm if specified capability for a given coursemodule will be check,
* if not specified capability to edit at least one activity is checked.
*/
public static function can_edit_bulk_completion($courseorid, $cm = null) {
if ($cm) {
return $cm->uservisible && has_capability('moodle/course:manageactivities', $cm->context);
}
$coursecontext = context_course::instance(is_object($courseorid) ? $courseorid->id : $courseorid);
if (has_capability('moodle/course:manageactivities', $coursecontext)) {
return true;
}
$modinfo = get_fast_modinfo($courseorid);
foreach ($modinfo->cms as $mod) {
if ($mod->uservisible && has_capability('moodle/course:manageactivities', $mod->context)) {
return true;
}
}
return false;
}
}
7 changes: 6 additions & 1 deletion course/bulkcompletion.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,21 +43,26 @@
print_error('invalidcourseid');
}
require_login($course);
require_capability('moodle/course:update', context_course::instance($course->id));

} else {
require_login();
print_error('needcourseid');
}

// Set up the page.
navigation_node::override_active_url(new moodle_url('/course/completion.php', array('id' => $course->id)));
$PAGE->set_course($course);
$PAGE->set_url('/course/bulkcompletion.php', array('id' => $course->id));
$PAGE->set_title($course->shortname);
$PAGE->set_heading($course->fullname);
$PAGE->set_pagelayout('admin');

// Get all that stuff I need for the renderer.
if (!core_completion\manager::can_edit_bulk_completion($id)) {
throw new required_capability_exception(context_course::instance($course->id),
'moodle/course:manageactivities', 'nopermission');
}

$manager = new \core_completion\manager($id);
$bulkcompletiondata = $manager->get_activities_and_headings();

Expand Down
44 changes: 28 additions & 16 deletions course/classes/output/bulk_activity_completion_renderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,25 +38,33 @@ class core_course_bulk_activity_completion_renderer extends plugin_renderer_base
public function navigation($courseid, $page) {
$tabs = [];

$tabs[] = new tabobject(
'completion',
new moodle_url('/course/completion.php', ['id' => $courseid]),
get_string('coursecompletion', 'completion')
);
if (has_capability('moodle/course:update', context_course::instance($courseid))) {
$tabs[] = new tabobject(
'completion',
new moodle_url('/course/completion.php', ['id' => $courseid]),
get_string('coursecompletion', 'completion')
);

$tabs[] = new tabobject(
'defaultcompletion',
new moodle_url('/course/defaultcompletion.php', ['id' => $courseid]),
get_string('defaultcompletion', 'completion')
);
$tabs[] = new tabobject(
'defaultcompletion',
new moodle_url('/course/defaultcompletion.php', ['id' => $courseid]),
get_string('defaultcompletion', 'completion')
);
}

$tabs[] = new tabobject(
'bulkcompletion',
new moodle_url('/course/bulkcompletion.php', ['id' => $courseid]),
get_string('bulkactivitycompletion', 'completion')
);
if (core_completion\manager::can_edit_bulk_completion($courseid)) {
$tabs[] = new tabobject(
'bulkcompletion',
new moodle_url('/course/bulkcompletion.php', ['id' => $courseid]),
get_string('bulkactivitycompletion', 'completion')
);
}

return $this->tabtree($tabs, $page);
if (count($tabs) > 1) {
return $this->tabtree($tabs, $page);
} else {
return '';
}
}


Expand All @@ -68,4 +76,8 @@ public function defaultcompletion($data) {
return parent::render_from_template('core_course/defaultactivitycompletion', $data);
}

public function activities_list($data) {
return parent::render_from_template('core_course/activityinstance', $data);
}

}
9 changes: 8 additions & 1 deletion course/completion.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,14 @@
print_error('invalidcourseid');
}
require_login($course);
require_capability('moodle/course:update', context_course::instance($course->id));
$context = context_course::instance($course->id);
if (!has_capability('moodle/course:update', $context)) {
if (core_completion\manager::can_edit_bulk_completion($course)) {
redirect(new moodle_url('/course/bulkcompletion.php', ['id' => $course->id]));
} else {
require_capability('moodle/course:update', $context);
}
}

} else {
require_login();
Expand Down
1 change: 1 addition & 0 deletions course/defaultcompletion.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
}

// Set up the page.
navigation_node::override_active_url(new moodle_url('/course/completion.php', array('id' => $course->id)));
$PAGE->set_course($course);
$PAGE->set_url('/course/bulkcompletion.php', array('id' => $course->id));
$PAGE->set_title($course->shortname);
Expand Down
1 change: 1 addition & 0 deletions course/lib.php
Original file line number Diff line number Diff line change
Expand Up @@ -3870,6 +3870,7 @@ function course_get_user_administration_options($course, $context) {

$options = new stdClass;
$options->update = has_capability('moodle/course:update', $context);
$options->editcompletion = core_completion\manager::can_edit_bulk_completion($course);
$options->filters = has_capability('moodle/filter:manage', $context) &&
count(filter_get_available_in_context($context)) > 0;
$options->reports = has_capability('moodle/site:viewreports', $context);
Expand Down
2 changes: 2 additions & 0 deletions course/templates/activityinstance.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@
<div class="activityinstance col-sm-6 span6">
<div class="mod-indent-outer"></div>
<div>
{{#canmanage}}
<input type="checkbox" class="m-r-1" name="cmid[]" data-section="{{sectionnumber}}" value="{{cmid}}" aria-label="{{#str}}checkactivity, completion, {{modname}}{{/str}}">
{{/canmanage}}
<a href={{url}}>
<img src="{{icon}}" class="iconlarge activityicon" alt=" " role="presentation" />
<span class="instancename">{{modname}}</span>
Expand Down
6 changes: 4 additions & 2 deletions course/tests/externallib_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -1942,7 +1942,7 @@ public function test_get_user_administration_options() {
$adminoptions->{$option['name']} = $option['available'];
}
if ($course['id'] == SITEID) {
$this->assertCount(15, $course['options']);
$this->assertCount(16, $course['options']);
$this->assertFalse($adminoptions->update);
$this->assertFalse($adminoptions->filters);
$this->assertFalse($adminoptions->reports);
Expand All @@ -1957,8 +1957,9 @@ public function test_get_user_administration_options() {
$this->assertFalse($adminoptions->publish);
$this->assertFalse($adminoptions->reset);
$this->assertFalse($adminoptions->roles);
$this->assertFalse($adminoptions->editcompletion);
} else {
$this->assertCount(14, $course['options']);
$this->assertCount(15, $course['options']);
$this->assertFalse($adminoptions->update);
$this->assertFalse($adminoptions->filters);
$this->assertFalse($adminoptions->reports);
Expand All @@ -1973,6 +1974,7 @@ public function test_get_user_administration_options() {
$this->assertFalse($adminoptions->publish);
$this->assertFalse($adminoptions->reset);
$this->assertFalse($adminoptions->roles);
$this->assertFalse($adminoptions->editcompletion);
}
}
}
Expand Down
6 changes: 4 additions & 2 deletions lib/navigationlib.php
Original file line number Diff line number Diff line change
Expand Up @@ -4207,14 +4207,16 @@ protected function load_course_settings($forceopen = false) {
$coursenode->add($editstring, $editurl, self::TYPE_SETTING, null, 'turneditingonoff', new pix_icon('i/edit', ''));
}

if ($adminoptions->update) {
if ($adminoptions->update || $adminoptions->editcompletion) {

// Add the course completion settings link
if ($CFG->enablecompletion && $course->enablecompletion) {
$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 ($adminoptions->tags) {
}

if (!$adminoptions->update && $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', ''));
}
Expand Down

0 comments on commit 0cbc248

Please sign in to comment.