Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

issue #96: implement restriction by enrolment methods #105

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions classes/local/restrictions/base.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?php
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.

namespace local_recompletion\local\restrictions;

use admin_settingpage;
use MoodleQuickForm;
use stdClass;

/**
* Base restriction class.
*
* @package local_recompletion
* @author Dmitrii Metelkin <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
abstract class base {

/**
* Check if needs to reset completion for a given user.
*
* @param int $userid - user id.
* @param stdClass $course - course record.
* @param stdClass $config - recompletion config.
*/
abstract public static function should_reset(int $userid, stdClass $course, stdClass $config): bool;

/**
* Add params to form.
*
* @param MoodleQuickForm $mform
*/
public static function editingform(MoodleQuickForm $mform): void {
}

/**
* Set form data after submitting.
*
* @param stdClass $data
*/
public static function set_form_data(stdClass $data): void {
}

/**
* Add site level settings for this plugin.
*
* @param admin_settingpage $settings
*/
public static function settings(admin_settingpage $settings): void {
}

/**
* Get restriction reason.
* @return string
*/
public static function get_restriction_reason(): string {
return get_string('restricted', 'local_recompletion');
}
}
134 changes: 134 additions & 0 deletions classes/local/restrictions/enrol.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
<?php
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.

namespace local_recompletion\local\restrictions;

use admin_settingpage;
use core_component;
use MoodleQuickForm;
use stdClass;

/**
* Enrolment method restriction class.
*
* @package local_recompletion
* @author Dmitrii Metelkin <[email protected]>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class enrol extends base {

/**
* Add params to form.
*
* @param MoodleQuickForm $mform
*/
public static function editingform(MoodleQuickForm $mform): void {
$config = get_config('local_recompletion');
$options = [
'multiple' => true,
'noselectionstring' => get_string('all'),
];

$plugins = array_keys(core_component::get_plugin_list('enrol'));
$enrolplugins = array_map(function($plugin) {
return get_string('pluginname', 'enrol_' . $plugin);
}, array_combine($plugins, $plugins));

$mform->addElement(
'autocomplete',
'restrictenrol',
get_string('restrictenrol', 'local_recompletion'),
$enrolplugins,
$options
);

$mform->setDefault('restrictenrol', $config->restrictenrol);
$mform->addHelpButton('restrictenrol', 'restrictenrol', 'local_recompletion');
}

/**
* Set form data after submitting.
* @param stdClass $data
*/
public static function set_form_data(stdClass $data): void {
if (isset($data->restrictenrol) && is_array($data->restrictenrol)) {
$data->restrictenrol = implode(',', $data->restrictenrol);
}
}

/**
* Add site level settings for this plugin.
*
* @param admin_settingpage $settings
*/
public static function settings(admin_settingpage $settings): void {
$enrolplugins = array_keys(core_component::get_plugin_list('enrol'));
$options = array_map(function($plugin) {
return get_string('pluginname', 'enrol_' . $plugin);
}, array_combine($enrolplugins, $enrolplugins));

$settings->add(new \admin_setting_configmulticheckbox(
'local_recompletion/restrictenrol',
get_string('restrictenrol', 'local_recompletion'),
get_string('restrictenrol_help', 'local_recompletion'),
[],
$options
));
}

/**
* Check if needs to reset completion for a given user.
*
* @param int $userid - user id.
* @param stdClass $course - course record.
* @param stdClass $config - recompletion config.
*/
public static function should_reset(int $userid, stdClass $course, stdClass $config): bool {
global $DB;

// Not restricted to any enrol methods.
if (empty($config->restrictenrol) || !is_string($config->restrictenrol)) {
return true;
}

$allowedenrols = explode(',', $config->restrictenrol);
$courseinstances = enrol_get_instances($course->id, false);

$courseallowedinstances = array_filter($courseinstances, function ($courseinstance) use ($allowedenrols){
return in_array($courseinstance->enrol, $allowedenrols);
});

// Course doesn't have allowed enrolment methods.
if (empty($courseallowedinstances)) {
return false;
}

// Check if a user is enrolled using one of the allowed instances.
list($sql, $params) = $DB->get_in_or_equal(array_keys($courseallowedinstances), SQL_PARAMS_NAMED);
$params['userid'] = $userid;
$userenrolments = $DB->get_records_select('user_enrolments', "enrolid $sql AND userid = :userid", $params);

return !empty($userenrolments);
}

/**
* Get restriction reason.
* @return string
*/
public static function get_restriction_reason(): string {
return get_string('restrictedbyenrol', 'local_recompletion');
}
}
6 changes: 6 additions & 0 deletions classes/recompletion_form.php
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,12 @@ public function definition() {
$fqn::editingform($mform);
}

$mform->addElement('header', 'restrictionsheader', get_string('restrictionsheader', 'local_recompletion'));
$restrictions = local_recompletion_get_supported_restrictions();
foreach ($restrictions as $plugin) {
$fqn = 'local_recompletion\\local\\restrictions\\' . $plugin;
$fqn::editingform($mform);
}
$mform->disabledIf('deletegradedata', 'recompletiontype', 'eq', '');
$mform->disabledIf('archivecompletiondata', 'recompletiontype', 'eq', '');
$mform->disabledIf('archivecompletiondata', 'forcearchive', 'eq');
Expand Down
14 changes: 13 additions & 1 deletion classes/task/check_recompletion.php
Original file line number Diff line number Diff line change
Expand Up @@ -182,13 +182,26 @@ protected function notify_user($userid, $course, $config) {
*/
public function reset_user($userid, $course, $config = null) {
global $CFG, $DB;

$errors = [];

if (empty($config)) {
$config = (object) $DB->get_records_menu('local_recompletion_config',
['course' => $course->id], '', 'name, value');
}
if (empty($config->recompletiontype)) {
throw new \moodle_exception('recompletionnotenabled', 'local_recompletion');
}

$restrictions = local_recompletion_get_supported_restrictions();
foreach ($restrictions as $plugin) {
$fqn = 'local_recompletion\\local\\restrictions\\' . $plugin;
if (!$fqn::should_reset($userid, $course, $config)) {
$errors[] = $fqn::get_restriction_reason();
return $errors;
}
}

// Archive and delete course completion.
$this->reset_completions($userid, $course, $config);

Expand All @@ -206,7 +219,6 @@ public function reset_user($userid, $course, $config = null) {
}

$plugins = local_recompletion_get_supported_plugins();
$errors = [];
foreach ($plugins as $plugin) {
$fqn = 'local_recompletion\\plugins\\' . $plugin;
$error = $fqn::reset($userid, $course, $config);
Expand Down
7 changes: 7 additions & 0 deletions lang/en/local_recompletion.php
Original file line number Diff line number Diff line change
Expand Up @@ -196,3 +196,10 @@
$string['h5pattempts'] = 'H5P attempts (mod_h5pactivity)';
$string['h5pattempts_help'] = 'How to handle H5P attempts within the course. If archive is selected, the old H5P attempts will be archived in the local_recompletion_h5p and local_recompletion_h5pr tables.';
$string['archiveh5p'] = 'Archive old H5P attempts (mod_h5pactivity)';
$string['pluginssettings'] = 'Plugins settings';
$string['restrictionsettings'] = 'Restrictions settings';
$string['restrictenrol'] = 'Enrol method';
$string['restrictenrol_help'] = 'Ony users enrolled with selected enrol methods will be included in resetting completion data. If none selected, that means no restrictions on enrolment method for users.';
$string['restrictionsheader'] = 'Restrictions';
$string['restricted'] = 'Resetting completion for a given user is restricted';
$string['restrictedbyenrol'] = 'Resetting completion for a given user is restricted by enrolment method';
26 changes: 26 additions & 0 deletions locallib.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,39 @@ function local_recompletion_get_supported_plugins() {
return $plugins;
}

/**
* Get list of supported restriction classes.
* @return array
*/
function local_recompletion_get_supported_restrictions(): array {
global $CFG;

$restrictions = [];
$files = scandir($CFG->dirroot. '/local/recompletion/classes/local/restrictions');
foreach ($files as $file) {
$class = clean_param(str_replace('.php', '', $file), PARAM_ALPHANUMEXT);
if (!empty($class) && $class !== 'base') {
$restrictions[] = $class;
}
}

return $restrictions;
}

/**
* Loads form data.
*
* @param string[] $mformdata
* @return object
*/
function local_recompletion_set_form_data($mformdata) {

$restrictions = local_recompletion_get_supported_restrictions();
foreach ($restrictions as $plugin) {
$fqn = 'local_recompletion\\local\\restrictions\\' . $plugin;
$fqn::set_form_data($mformdata);
}

$data = (array)$mformdata;
if (key_exists('recompletionemailbody', $data)) {
$recompletionemailbody = $data['recompletionemailbody'];
Expand Down
7 changes: 6 additions & 1 deletion recompletion.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@
$setnames[] = 'archive'.$plugin;
}

$restrictions = local_recompletion_get_supported_restrictions();
foreach ($restrictions as $plugin) {
$setnames[] = 'restrict' . $plugin;
}

// Create the settings form instance.
$form = new local_recompletion_recompletion_form('recompletion.php?id='.$id, array('course' => $course));

Expand Down Expand Up @@ -121,7 +126,7 @@
}
}
// Redirect to the course main page.
$url = new moodle_url('/course/view.php', array('id' => $course->id));
$url = new moodle_url('/local/recompletion/recompletion.php', array('id' => $course->id));
redirect($url, get_string('recompletionsettingssaved', 'local_recompletion'));
} else if (!empty($config)) {
$form->set_data(local_recompletion_get_data($config));
Expand Down
5 changes: 3 additions & 2 deletions resetcompletion.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,11 @@

$context = context_course::instance($course->id);
if ($USER->id <> $userid) {
$cancelurl = new moodle_url('/local/recompletion/participants.php', array('id' => $course->id));
require_capability('local/recompletion:manage', $context);
$user = $DB->get_record('user', array('id' => $userid));
} else {
$cancelurl = course_get_url($course);
require_capability('local/recompletion:resetmycompletion', $context);
$user = $USER;
}
Expand All @@ -63,7 +65,7 @@
$returnurl = course_get_url($course);
}
if (!empty($errors)) {
redirect($returnurl, explode(',', $errors), '', \core\output\notification::NOTIFY_WARNING);
redirect($returnurl, implode(', ', $errors), '', \core\output\notification::NOTIFY_WARNING);
} else {
redirect($returnurl, get_string('completionresetuser', 'local_recompletion', fullname($user)));
}
Expand All @@ -80,7 +82,6 @@
echo $OUTPUT->header();
echo $OUTPUT->heading(get_string("resetcompletionfor", "local_recompletion", fullname($user)));

$cancelurl = course_get_url($course);
$confirmurl = $PAGE->url;
$confirmurl->param('confirm', 1);
$confirmurl->param('user', $userid);
Expand Down
17 changes: 17 additions & 0 deletions settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,26 @@
new lang_string('forcearchivecompletiondata', 'local_recompletion'),
new lang_string('forcearchivecompletiondata_help', 'local_recompletion'), 0));

$settings->add(new admin_setting_heading('local_recompletion/pluginsettings',
get_string('pluginssettings', 'local_recompletion'),
''
));

$plugins = local_recompletion_get_supported_plugins();
foreach ($plugins as $plugin) {
$fqn = 'local_recompletion\\plugins\\' . $plugin;
$fqn::settings($settings);
}

$settings->add(new admin_setting_heading('local_recompletion/restrictionsettings',
get_string('restrictionsettings', 'local_recompletion'),
''
));

$restrictions = local_recompletion_get_supported_restrictions();
foreach ($restrictions as $plugin) {
$fqn = 'local_recompletion\\local\\restrictions\\' . $plugin;
$fqn::settings($settings);
}

}
Loading
Loading