diff --git a/enrol/cohort/edit.php b/enrol/cohort/edit.php deleted file mode 100644 index 3affaa9fcfa..00000000000 --- a/enrol/cohort/edit.php +++ /dev/null @@ -1,130 +0,0 @@ -. - -/** - * Adds new instance of enrol_cohort to specified course. - * - * @package enrol_cohort - * @copyright 2010 Petr Skoda {@link http://skodak.org} - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -require('../../config.php'); -require_once("$CFG->dirroot/enrol/cohort/edit_form.php"); -require_once("$CFG->dirroot/enrol/cohort/locallib.php"); -require_once("$CFG->dirroot/group/lib.php"); - -$courseid = required_param('courseid', PARAM_INT); -$instanceid = optional_param('id', 0, PARAM_INT); -$message = optional_param('message', null, PARAM_TEXT); - -$course = $DB->get_record('course', array('id'=>$courseid), '*', MUST_EXIST); -$context = context_course::instance($course->id, MUST_EXIST); - -require_login($course); -require_capability('moodle/course:enrolconfig', $context); -require_capability('enrol/cohort:config', $context); - -$PAGE->set_url('/enrol/cohort/edit.php', array('courseid'=>$course->id, 'id'=>$instanceid)); -$PAGE->set_pagelayout('admin'); - -$returnurl = new moodle_url('/enrol/instances.php', array('id'=>$course->id)); -if (!enrol_is_enabled('cohort')) { - redirect($returnurl); -} - -$enrol = enrol_get_plugin('cohort'); - -if ($instanceid) { - $instance = $DB->get_record('enrol', array('courseid'=>$course->id, 'enrol'=>'cohort', 'id'=>$instanceid), '*', MUST_EXIST); - -} else { - // No instance yet, we have to add new instance. - if (!$enrol->get_newinstance_link($course->id)) { - redirect($returnurl); - } - navigation_node::override_active_url(new moodle_url('/enrol/instances.php', array('id'=>$course->id))); - $instance = new stdClass(); - $instance->id = null; - $instance->courseid = $course->id; - $instance->enrol = 'cohort'; - $instance->customint1 = ''; // Cohort id. - $instance->customint2 = 0; // Optional group id. -} - -// Try and make the manage instances node on the navigation active. -$courseadmin = $PAGE->settingsnav->get('courseadmin'); -if ($courseadmin && $courseadmin->get('users') && $courseadmin->get('users')->get('manageinstances')) { - $courseadmin->get('users')->get('manageinstances')->make_active(); -} - - -$mform = new enrol_cohort_edit_form(null, array($instance, $enrol, $course)); - -if ($mform->is_cancelled()) { - redirect($returnurl); - -} else if ($data = $mform->get_data()) { - if ($data->id) { - // NOTE: no cohort changes here!!! - if ($data->roleid != $instance->roleid) { - // The sync script can only add roles, for perf reasons it does not modify them. - role_unassign_all(array('contextid'=>$context->id, 'roleid'=>$instance->roleid, 'component'=>'enrol_cohort', 'itemid'=>$instance->id)); - } - $instance->name = $data->name; - $instance->status = $data->status; - $instance->roleid = $data->roleid; - $instance->customint2 = $data->customint2; - $instance->timemodified = time(); - // Create a new group for the cohort if requested. - if ($data->customint2 == COHORT_CREATE_GROUP) { - require_capability('moodle/course:managegroups', $context); - $groupid = enrol_cohort_create_new_group($course->id, $data->customint1); - $instance->customint2 = $groupid; - } - $DB->update_record('enrol', $instance); - \core\event\enrol_instance_updated::create_from_record($instance)->trigger(); - } else { - // Create a new group for the cohort if requested. - if ($data->customint2 == COHORT_CREATE_GROUP) { - require_capability('moodle/course:managegroups', $context); - $groupid = enrol_cohort_create_new_group($course->id, $data->customint1); - $enrol->add_instance($course, array('name' => $data->name, 'status' => $data->status, - 'customint1' => $data->customint1, 'roleid' => $data->roleid, 'customint2' => $groupid)); - } else { - $enrol->add_instance($course, array('name' => $data->name, 'status' => $data->status, - 'customint1' => $data->customint1, 'roleid' => $data->roleid, 'customint2' => $data->customint2)); - } - if (!empty($data->submitbuttonnext)) { - $returnurl = new moodle_url($PAGE->url); - $returnurl->param('message', 'added'); - } - } - $trace = new null_progress_trace(); - enrol_cohort_sync($trace, $course->id); - $trace->finished(); - redirect($returnurl); -} - -$PAGE->set_heading($course->fullname); -$PAGE->set_title(get_string('pluginname', 'enrol_cohort')); - -echo $OUTPUT->header(); -if ($message === 'added') { - echo $OUTPUT->notification(get_string('instanceadded', 'enrol'), 'notifysuccess'); -} -$mform->display(); -echo $OUTPUT->footer(); diff --git a/enrol/cohort/edit_form.php b/enrol/cohort/edit_form.php deleted file mode 100644 index 2a02a29dd98..00000000000 --- a/enrol/cohort/edit_form.php +++ /dev/null @@ -1,134 +0,0 @@ -. - -/** - * Adds instance form - * - * @package enrol_cohort - * @copyright 2010 Petr Skoda {@link http://skodak.org} - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -defined('MOODLE_INTERNAL') || die(); - -require_once("$CFG->libdir/formslib.php"); - -class enrol_cohort_edit_form extends moodleform { - - function definition() { - global $CFG, $DB; - - $mform = $this->_form; - - list($instance, $plugin, $course) = $this->_customdata; - $coursecontext = context_course::instance($course->id); - - $enrol = enrol_get_plugin('cohort'); - - $groups = array(0 => get_string('none')); - if (has_capability('moodle/course:managegroups', $coursecontext)) { - $groups[COHORT_CREATE_GROUP] = get_string('creategroup', 'enrol_cohort'); - } - - foreach (groups_get_all_groups($course->id) as $group) { - $groups[$group->id] = format_string($group->name, true, array('context'=>$coursecontext)); - } - - $mform->addElement('header','general', get_string('pluginname', 'enrol_cohort')); - - $mform->addElement('text', 'name', get_string('custominstancename', 'enrol')); - $mform->setType('name', PARAM_TEXT); - - $options = array(ENROL_INSTANCE_ENABLED => get_string('yes'), - ENROL_INSTANCE_DISABLED => get_string('no')); - $mform->addElement('select', 'status', get_string('status', 'enrol_cohort'), $options); - - if ($instance->id) { - if ($cohort = $DB->get_record('cohort', array('id'=>$instance->customint1))) { - $cohorts = array($instance->customint1=>format_string($cohort->name, true, array('context'=>context::instance_by_id($cohort->contextid)))); - } else { - $cohorts = array($instance->customint1=>get_string('error')); - } - $mform->addElement('select', 'customint1', get_string('cohort', 'cohort'), $cohorts); - $mform->setConstant('customint1', $instance->customint1); - $mform->hardFreeze('customint1', $instance->customint1); - - } else { - $cohorts = array('' => get_string('choosedots')); - $allcohorts = cohort_get_available_cohorts($coursecontext, 0, 0, 0); - foreach ($allcohorts as $c) { - $cohorts[$c->id] = format_string($c->name); - } - $mform->addElement('select', 'customint1', get_string('cohort', 'cohort'), $cohorts); - $mform->addRule('customint1', get_string('required'), 'required', null, 'client'); - } - - $roles = get_assignable_roles($coursecontext); - $roles[0] = get_string('none'); - $roles = array_reverse($roles, true); // Descending default sortorder. - $mform->addElement('select', 'roleid', get_string('assignrole', 'enrol_cohort'), $roles); - $mform->setDefault('roleid', $enrol->get_config('roleid')); - if ($instance->id and !isset($roles[$instance->roleid])) { - if ($role = $DB->get_record('role', array('id'=>$instance->roleid))) { - $roles = role_fix_names($roles, $coursecontext, ROLENAME_ALIAS, true); - $roles[$instance->roleid] = role_get_name($role, $coursecontext); - } else { - $roles[$instance->roleid] = get_string('error'); - } - } - $mform->addElement('select', 'customint2', get_string('addgroup', 'enrol_cohort'), $groups); - - $mform->addElement('hidden', 'courseid', null); - $mform->setType('courseid', PARAM_INT); - - $mform->addElement('hidden', 'id', null); - $mform->setType('id', PARAM_INT); - - if ($instance->id) { - $this->add_action_buttons(true); - } else { - $this->add_add_buttons(); - } - - $this->set_data($instance); - } - - /** - * Adds buttons on create new method form - */ - protected function add_add_buttons() { - $mform = $this->_form; - $buttonarray = array(); - $buttonarray[0] = $mform->createElement('submit', 'submitbutton', get_string('addinstance', 'enrol')); - $buttonarray[1] = $mform->createElement('submit', 'submitbuttonnext', get_string('addinstanceanother', 'enrol')); - $buttonarray[2] = $mform->createElement('cancel'); - $mform->addGroup($buttonarray, 'buttonar', '', array(' '), false); - $mform->closeHeaderBefore('buttonar'); - } - - function validation($data, $files) { - global $DB; - - $errors = parent::validation($data, $files); - - $params = array('roleid'=>$data['roleid'], 'customint1'=>$data['customint1'], 'courseid'=>$data['courseid'], 'id'=>$data['id']); - if ($DB->record_exists_select('enrol', "roleid = :roleid AND customint1 = :customint1 AND courseid = :courseid AND enrol = 'cohort' AND id <> :id", $params)) { - $errors['roleid'] = get_string('instanceexists', 'enrol_cohort'); - } - - return $errors; - } -} diff --git a/enrol/cohort/lib.php b/enrol/cohort/lib.php index 61be2ad145f..f30fd9dff75 100644 --- a/enrol/cohort/lib.php +++ b/enrol/cohort/lib.php @@ -79,19 +79,6 @@ class enrol_cohort_plugin extends enrol_plugin { } } - /** - * Returns link to page which may be used to add new instance of enrolment plugin in course. - * @param int $courseid - * @return moodle_url page url - */ - public function get_newinstance_link($courseid) { - if (!$this->can_add_new_instances($courseid)) { - return NULL; - } - // Multiple instances supported - multiple parent courses linked. - return new moodle_url('/enrol/cohort/edit.php', array('courseid'=>$courseid)); - } - /** * Given a courseid this function returns true if the user is able to enrol or configure cohorts. * AND there are cohorts that the user can view. @@ -99,7 +86,7 @@ class enrol_cohort_plugin extends enrol_plugin { * @param int $courseid * @return bool */ - protected function can_add_new_instances($courseid) { + public function can_add_instance($courseid) { global $CFG; require_once($CFG->dirroot . '/cohort/lib.php'); $coursecontext = context_course::instance($courseid); @@ -109,6 +96,54 @@ class enrol_cohort_plugin extends enrol_plugin { return cohort_get_available_cohorts($coursecontext, 0, 0, 1) ? true : false; } + /** + * Add new instance of enrol plugin. + * @param object $course + * @param array $fields instance fields + * @return int id of new instance, null if can not be created + */ + public function add_instance($course, array $fields = null) { + + if (!empty($fields['customint2']) && $fields['customint2'] == COHORT_CREATE_GROUP) { + // Create a new group for the cohort if requested. + $context = context_course::instance($course->id); + require_capability('moodle/course:managegroups', $context); + $groupid = enrol_cohort_create_new_group($course->id, $fields['customint1']); + $fields['customint2'] = $groupid; + } + + return parent::add_instance($course, $fields); + } + + /** + * Update instance of enrol plugin. + * @param stdClass $instance + * @param stdClass $data modified instance fields + * @return boolean + */ + public function update_instance($instance, $data) { + // NOTE: no cohort changes here!!! + $context = context_course::instance($instance->courseid); + if ($data->roleid != $instance->roleid) { + // The sync script can only add roles, for perf reasons it does not modify them. + $params = array( + 'contextid' => $context->id, + 'roleid' => $instance->roleid, + 'component' => 'enrol_cohort', + 'itemid' => $instance->id + ); + role_unassign_all($params); + } + // Create a new group for the cohort if requested. + if ($data->customint2 == COHORT_CREATE_GROUP) { + require_capability('moodle/course:managegroups', $context); + $groupid = enrol_cohort_create_new_group($instance->courseid, $data->customint1); + $data->customint2 = $groupid; + } + + return parent::update_instance($instance, $data); + } + /** * Returns edit icons for the page with list of instances. * @param stdClass $instance @@ -125,7 +160,8 @@ class enrol_cohort_plugin extends enrol_plugin { $icons = array(); if (has_capability('enrol/cohort:config', $context)) { - $editlink = new moodle_url("/enrol/cohort/edit.php", array('courseid'=>$instance->courseid, 'id'=>$instance->id)); + $linkparams = array('courseid' => $instance->courseid, 'id' => $instance->id, 'type' => 'cohort'); + $editlink = new moodle_url("/enrol/editinstance.php", $linkparams); $icons[] = $OUTPUT->action_icon($editlink, new pix_icon('t/edit', get_string('edit'), 'core', array('class' => 'iconsmall'))); } @@ -316,6 +352,176 @@ class enrol_cohort_plugin extends enrol_plugin { $context = context_course::instance($instance->courseid); return has_capability('enrol/cohort:config', $context); } + + /** + * Return an array of valid options for the status. + * + * @return array + */ + protected function get_status_options() { + $options = array(ENROL_INSTANCE_ENABLED => get_string('yes'), + ENROL_INSTANCE_DISABLED => get_string('no')); + return $options; + } + + /** + * Return an array of valid options for the cohorts. + * + * @param stdClass $instance + * @param context $context + * @return array + */ + protected function get_cohort_options($instance, $context) { + global $DB, $CFG; + + require_once($CFG->dirroot . '/cohort/lib.php'); + + $cohorts = array(); + + if ($instance->id) { + if ($cohort = $DB->get_record('cohort', array('id' => $instance->customint1))) { + $name = format_string($cohort->name, true, array('context' => context::instance_by_id($cohort->contextid))); + $cohorts = array($instance->customint1 => $name); + } else { + $cohorts = array($instance->customint1 => get_string('error')); + } + } else { + $cohorts = array('' => get_string('choosedots')); + $allcohorts = cohort_get_available_cohorts($context, 0, 0, 0); + foreach ($allcohorts as $c) { + $cohorts[$c->id] = format_string($c->name); + } + } + return $cohorts; + } + + /** + * Return an array of valid options for the roles. + * + * @param stdClass $instance + * @param context $coursecontext + * @return array + */ + protected function get_role_options($instance, $coursecontext) { + global $DB; + + $roles = get_assignable_roles($coursecontext); + $roles[0] = get_string('none'); + $roles = array_reverse($roles, true); // Descending default sortorder. + if ($instance->id and !isset($roles[$instance->roleid])) { + if ($role = $DB->get_record('role', array('id' => $instance->roleid))) { + $roles = role_fix_names($roles, $coursecontext, ROLENAME_ALIAS, true); + $roles[$instance->roleid] = role_get_name($role, $coursecontext); + } else { + $roles[$instance->roleid] = get_string('error'); + } + } + + return $roles; + } + + /** + * Return an array of valid options for the groups. + * + * @param context $coursecontext + * @return array + */ + protected function get_group_options($coursecontext) { + $groups = array(0 => get_string('none')); + if (has_capability('moodle/course:managegroups', $coursecontext)) { + $groups[COHORT_CREATE_GROUP] = get_string('creategroup', 'enrol_cohort'); + } + + foreach (groups_get_all_groups($coursecontext->instanceid) as $group) { + $groups[$group->id] = format_string($group->name, true, array('context' => $coursecontext)); + } + + return $groups; + } + + /** + * We are a good plugin and don't invent our own UI/validation code path. + * + * @return boolean + */ + public function use_standard_editing_ui() { + return true; + } + + /** + * Add elements to the edit instance form. + * + * @param stdClass $instance + * @param MoodleQuickForm $mform + * @param context $coursecontext + * @return bool + */ + public function edit_instance_form($instance, MoodleQuickForm $mform, $coursecontext) { + global $DB; + + $mform->addElement('text', 'name', get_string('custominstancename', 'enrol')); + $mform->setType('name', PARAM_TEXT); + + $options = $this->get_status_options(); + $mform->addElement('select', 'status', get_string('status', 'enrol_cohort'), $options); + + $options = $this->get_cohort_options($instance, $coursecontext); + $mform->addElement('select', 'customint1', get_string('cohort', 'cohort'), $options); + if ($instance->id) { + $mform->setConstant('customint1', $instance->customint1); + $mform->hardFreeze('customint1', $instance->customint1); + } else { + $mform->addRule('customint1', get_string('required'), 'required', null, 'client'); + } + + $roles = $this->get_role_options($instance, $coursecontext); + $mform->addElement('select', 'roleid', get_string('assignrole', 'enrol_cohort'), $roles); + $mform->setDefault('roleid', $this->get_config('roleid')); + $groups = $this->get_group_options($coursecontext); + $mform->addElement('select', 'customint2', get_string('addgroup', 'enrol_cohort'), $groups); + } + + /** + * Perform custom validation of the data used to edit the instance. + * + * @param array $data array of ("fieldname" => value) of submitted data + * @param array $files array of uploaded files "element_name" => tmp_file_path + * @param object $instance The instance loaded from the DB + * @param context $context The context of the instance we are editing + * @return array of "element_name" => "error_description" if there are errors, + * or an empty array if everything is OK. + * @return void + */ + public function edit_instance_validation($data, $files, $instance, $context) { + global $DB; + $errors = array(); + + $params = array( + 'roleid' => $data['roleid'], + 'customint1' => $data['customint1'], + 'courseid' => $data['courseid'], + 'id' => $data['id'] + ); + $sql = "roleid = :roleid AND customint1 = :customint1 AND courseid = :courseid AND enrol = 'cohort' AND id <> :id"; + if ($DB->record_exists_select('enrol', $sql, $params)) { + $errors['roleid'] = get_string('instanceexists', 'enrol_cohort'); + } + $validstatus = array_keys($this->get_status_options()); + $validcohorts = array_keys($this->get_cohort_options($instance, $context)); + $validroles = array_keys($this->get_role_options($instance, $context)); + $validgroups = array_keys($this->get_group_options($context)); + $tovalidate = array( + 'name' => PARAM_TEXT, + 'status' => $validstatus, + 'customint1' => $validcohorts, + 'roleid' => $validroles, + 'customint2' => $validgroups + ); + $typeerrors = $this->validate_param_types($data, $tovalidate); + $errors = array_merge($errors, $typeerrors); + + return $errors; + } } /** @@ -337,7 +543,9 @@ function enrol_cohort_allow_group_member_remove($itemid, $groupid, $userid) { * @return int $groupid Group ID for this cohort. */ function enrol_cohort_create_new_group($courseid, $cohortid) { - global $DB; + global $DB, $CFG; + + require_once($CFG->dirroot . '/group/lib.php'); $groupname = $DB->get_field('cohort', 'name', array('id' => $cohortid), MUST_EXIST); $a = new stdClass(); diff --git a/enrol/editinstance.php b/enrol/editinstance.php new file mode 100644 index 00000000000..38d3ae77508 --- /dev/null +++ b/enrol/editinstance.php @@ -0,0 +1,104 @@ +. + +/** + * Adds new instance of an enrolment plugin to specified course or edits current instance. + * + * @package core_enrol + * @copyright 2015 Damyon Wiese + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +require('../config.php'); +require_once('editinstance_form.php'); + +$courseid = required_param('courseid', PARAM_INT); +$type = required_param('type', PARAM_COMPONENT); +$instanceid = optional_param('id', 0, PARAM_INT); + +$course = $DB->get_record('course', array('id' => $courseid), '*', MUST_EXIST); +$context = context_course::instance($course->id, MUST_EXIST); + +$plugin = enrol_get_plugin($type); +if (!$plugin) { + throw new moodle_exception('invaliddata', 'error'); +} + +require_login($course); +require_capability('enrol/' . $type . ':config', $context); + +$PAGE->set_url('/enrol/editinstance.php', array('courseid' => $course->id, 'id' => $instanceid, 'type' => $type)); +$PAGE->set_pagelayout('admin'); + +$return = new moodle_url('/enrol/instances.php', array('id' => $course->id)); +if (!enrol_is_enabled($type)) { + redirect($return); +} + +if ($instanceid) { + $instance = $DB->get_record('enrol', array('courseid' => $course->id, 'enrol' => $type, 'id' => $instanceid), '*', MUST_EXIST); + +} else { + require_capability('moodle/course:enrolconfig', $context); + // No instance yet, we have to add new instance. + navigation_node::override_active_url(new moodle_url('/enrol/instances.php', array('id' => $course->id))); + + $instance = (object)$plugin->get_instance_defaults(); + $instance->id = null; + $instance->courseid = $course->id; + $instance->status = ENROL_INSTANCE_ENABLED; // Do not use default for automatically created instances here. +} + +$mform = new enrol_instance_edit_form(null, array($instance, $plugin, $context, $type)); + +if ($mform->is_cancelled()) { + redirect($return); + +} else if ($data = $mform->get_data()) { + + if ($instance->id) { + $reset = false; + if (isset($data->status)) { + $reset = ($instance->status != $data->status); + } + + foreach ($data as $key => $value) { + $instance->$key = $value; + } + + $instance->timemodified = time(); + + $plugin->update_instance($instance, $data); + + if ($reset) { + $context->mark_dirty(); + } + + } else { + $fields = (array) $data; + $plugin->add_instance($course, $fields); + } + + redirect($return); +} + +$PAGE->set_heading($course->fullname); +$PAGE->set_title(get_string('pluginname', 'enrol_' . $type)); + +echo $OUTPUT->header(); +echo $OUTPUT->heading(get_string('pluginname', 'enrol_' . $type)); +$mform->display(); +echo $OUTPUT->footer(); diff --git a/enrol/editinstance_form.php b/enrol/editinstance_form.php new file mode 100644 index 00000000000..728a7e8926d --- /dev/null +++ b/enrol/editinstance_form.php @@ -0,0 +1,87 @@ +. + +/** + * Adds new instance of enrol_plugin to specified course or edits current instance. + * + * @package core_enrol + * @copyright 2015 Damyon Wiese + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +require_once($CFG->libdir.'/formslib.php'); + +/** + * Standard edit form shared by all enrol plugins. + * + * @package core_enrol + * @copyright 2015 Damyon Wiese + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class enrol_instance_edit_form extends moodleform { + + /** + * Called to define this moodle form + * + * @return void + */ + public function definition() { + global $DB; + + $mform = $this->_form; + + list($instance, $plugin, $context, $type) = $this->_customdata; + + $mform->addElement('header', 'header', get_string('pluginname', 'enrol_' . $type)); + + $plugin->edit_instance_form($instance, $mform, $context); + + $mform->addElement('hidden', 'id'); + $mform->setType('id', PARAM_INT); + $mform->addElement('hidden', 'courseid'); + $mform->setType('courseid', PARAM_INT); + + $mform->addElement('hidden', 'type'); + $mform->setType('type', PARAM_COMPONENT); + $instance->type = $type; + + $this->add_action_buttons(true, ($instance->id ? null : get_string('addinstance', 'enrol'))); + + $this->set_data($instance); + } + + /** + * Validate this form. Calls plugin validation method. + * + * @param array $data + * @param array $files + * @return array + */ + public function validation($data, $files) { + $errors = parent::validation($data, $files); + + list($instance, $plugin, $context, $type) = $this->_customdata; + + $pluginerrors = $plugin->edit_instance_validation($data, $files, $instance, $context); + + $errors = array_merge($errors, $pluginerrors); + + return $errors; + } + +} diff --git a/enrol/instances.php b/enrol/instances.php index ec95e755383..52b5142e5b1 100644 --- a/enrol/instances.php +++ b/enrol/instances.php @@ -277,10 +277,19 @@ echo html_writer::table($table); // access security is in each plugin $candidates = array(); foreach (enrol_get_plugins(true) as $name=>$plugin) { - if (!$link = $plugin->get_newinstance_link($course->id)) { - continue; + if ($plugin->use_standard_editing_ui()) { + if ($plugin->can_add_instance($course->id)) { + // Standard add/edit UI. + $params = array('type' => $name, 'courseid' => $course->id); + $url = new moodle_url('/enrol/editinstance.php', $params); + $link = $url->out(false); + $candidates[$link] = get_string('pluginname', 'enrol_'.$name); + } + } else if ($url = $plugin->get_newinstance_link($course->id)) { + // Old custom UI. + $link = $url->out(false); + $candidates[$link] = get_string('pluginname', 'enrol_'.$name); } - $candidates[$link->out(false)] = get_string('pluginname', 'enrol_'.$name); } if ($candidates) { diff --git a/enrol/manual/edit.php b/enrol/manual/edit.php deleted file mode 100644 index 27e1de79567..00000000000 --- a/enrol/manual/edit.php +++ /dev/null @@ -1,125 +0,0 @@ -. - -/** - * Adds new instance of enrol_manual to specified course - * or edits current instance. - * - * @package enrol_manual - * @copyright 2010 Petr Skoda {@link http://skodak.org} - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -require('../../config.php'); -require_once('edit_form.php'); - -$courseid = required_param('courseid', PARAM_INT); - -$course = $DB->get_record('course', array('id'=>$courseid), '*', MUST_EXIST); -$context = context_course::instance($course->id, MUST_EXIST); - -require_login($course); -require_capability('enrol/manual:config', $context); - -$PAGE->set_url('/enrol/manual/edit.php', array('courseid'=>$course->id)); -$PAGE->set_pagelayout('admin'); - -$return = new moodle_url('/enrol/instances.php', array('id'=>$course->id)); -if (!enrol_is_enabled('manual')) { - redirect($return); -} - -$plugin = enrol_get_plugin('manual'); - -if ($instances = $DB->get_records('enrol', array('courseid'=>$course->id, 'enrol'=>'manual'), 'id ASC')) { - $instance = array_shift($instances); - if ($instances) { - // Oh - we allow only one instance per course!! - foreach ($instances as $del) { - $plugin->delete_instance($del); - } - } - // Merge these two settings to one value for the single selection element. - if ($instance->notifyall and $instance->expirynotify) { - $instance->expirynotify = 2; - } - unset($instance->notifyall); - -} else { - require_capability('moodle/course:enrolconfig', $context); - // No instance yet, we have to add new instance. - navigation_node::override_active_url(new moodle_url('/enrol/instances.php', array('id'=>$course->id))); - $instance = new stdClass(); - $instance->id = null; - $instance->courseid = $course->id; - $instance->expirynotify = $plugin->get_config('expirynotify'); - $instance->expirythreshold = $plugin->get_config('expirythreshold'); -} - -$mform = new enrol_manual_edit_form(null, array($instance, $plugin, $context)); - -if ($mform->is_cancelled()) { - redirect($return); - -} else if ($data = $mform->get_data()) { - if ($data->expirynotify == 2) { - $data->expirynotify = 1; - $data->notifyall = 1; - } else { - $data->notifyall = 0; - } - if (!$data->expirynotify) { - // Keep previous/default value of disabled expirythreshold option. - $data->expirythreshold = $instance->expirythreshold; - } - if ($instance->id) { - $instance->roleid = $data->roleid; - $instance->enrolperiod = $data->enrolperiod; - $instance->expirynotify = $data->expirynotify; - $instance->notifyall = $data->notifyall; - $instance->expirythreshold = $data->expirythreshold; - $instance->timemodified = time(); - $markdirty = ($instance->status != $data->status); - $instance->status = $data->status; - - $DB->update_record('enrol', $instance); - \core\event\enrol_instance_updated::create_from_record($instance)->trigger(); - - if ($markdirty) { - $context->mark_dirty(); - } - - } else { - $fields = array( - 'status' => $data->status, - 'roleid' => $data->roleid, - 'enrolperiod' => $data->enrolperiod, - 'expirynotify' => $data->expirynotify, - 'notifyall' => $data->notifyall, - 'expirythreshold' => $data->expirythreshold); - $plugin->add_instance($course, $fields); - } - - redirect($return); -} - -$PAGE->set_title(get_string('pluginname', 'enrol_manual')); -$PAGE->set_heading($course->fullname); - -echo $OUTPUT->header(); -echo $OUTPUT->heading(get_string('pluginname', 'enrol_manual')); -$mform->display(); -echo $OUTPUT->footer(); diff --git a/enrol/manual/edit_form.php b/enrol/manual/edit_form.php deleted file mode 100644 index bfc09a7848f..00000000000 --- a/enrol/manual/edit_form.php +++ /dev/null @@ -1,88 +0,0 @@ -. - -/** - * Adds new instance of enrol_manual to specified course - * or edits current instance. - * - * @package enrol_manual - * @copyright 2010 Petr Skoda {@link http://skodak.org} - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -defined('MOODLE_INTERNAL') || die(); - -require_once($CFG->libdir.'/formslib.php'); - -class enrol_manual_edit_form extends moodleform { - - function definition() { - $mform = $this->_form; - - list($instance, $plugin, $context) = $this->_customdata; - - $mform->addElement('header', 'header', get_string('pluginname', 'enrol_manual')); - - $options = array(ENROL_INSTANCE_ENABLED => get_string('yes'), - ENROL_INSTANCE_DISABLED => get_string('no')); - $mform->addElement('select', 'status', get_string('status', 'enrol_manual'), $options); - $mform->addHelpButton('status', 'status', 'enrol_manual'); - $mform->setDefault('status', $plugin->get_config('status')); - - if ($instance->id) { - $roles = get_default_enrol_roles($context, $instance->roleid); - } else { - $roles = get_default_enrol_roles($context, $plugin->get_config('roleid')); - } - $mform->addElement('select', 'roleid', get_string('defaultrole', 'role'), $roles); - $mform->setDefault('roleid', $plugin->get_config('roleid')); - - $mform->addElement('duration', 'enrolperiod', get_string('defaultperiod', 'enrol_manual'), array('optional' => true, 'defaultunit' => 86400)); - $mform->setDefault('enrolperiod', $plugin->get_config('enrolperiod')); - $mform->addHelpButton('enrolperiod', 'defaultperiod', 'enrol_manual'); - - $options = array(0 => get_string('no'), 1 => get_string('expirynotifyenroller', 'core_enrol'), 2 => get_string('expirynotifyall', 'core_enrol')); - $mform->addElement('select', 'expirynotify', get_string('expirynotify', 'core_enrol'), $options); - $mform->addHelpButton('expirynotify', 'expirynotify', 'core_enrol'); - - $mform->addElement('duration', 'expirythreshold', get_string('expirythreshold', 'core_enrol'), array('optional' => false, 'defaultunit' => 86400)); - $mform->addHelpButton('expirythreshold', 'expirythreshold', 'core_enrol'); - $mform->disabledIf('expirythreshold', 'expirynotify', 'eq', 0); - - $mform->addElement('hidden', 'courseid'); - $mform->setType('courseid', PARAM_INT); - - if (enrol_accessing_via_instance($instance)) { - $mform->addElement('static', 'selfwarn', get_string('instanceeditselfwarning', 'core_enrol'), get_string('instanceeditselfwarningtext', 'core_enrol')); - } - - $this->add_action_buttons(true, ($instance->id ? null : get_string('addinstance', 'enrol'))); - - $this->set_data($instance); - } - - function validation($data, $files) { - global $DB; - - $errors = parent::validation($data, $files); - - if ($data['expirynotify'] > 0 and $data['expirythreshold'] < 86400) { - $errors['expirythreshold'] = get_string('errorthresholdlow', 'core_enrol'); - } - - return $errors; - } -} diff --git a/enrol/manual/lib.php b/enrol/manual/lib.php index b50e3cc1a0d..30b045b547a 100644 --- a/enrol/manual/lib.php +++ b/enrol/manual/lib.php @@ -93,11 +93,27 @@ class enrol_manual_plugin extends enrol_plugin { $context = context_course::instance($instance->courseid); if (has_capability('enrol/manual:config', $context)) { - $managelink = new moodle_url('/enrol/manual/edit.php', array('courseid'=>$instance->courseid)); + $managelink = new moodle_url('/enrol/editinstance.php', array('courseid' => $instance->courseid, 'type' => 'manual')); $instancesnode->add($this->get_instance_name($instance), $managelink, navigation_node::TYPE_SETTING); } } + /** + * Return true if we can add a new instance to this course. + * + * @param int $courseid + * @return boolean + */ + public function can_add_instance($courseid) { + $context = context_course::instance($courseid, MUST_EXIST); + if (!has_capability('moodle/course:enrolconfig', $context) or !has_capability('enrol/manual:config', $context)) { + return false; + } + // Multiple instances supported - multiple parent courses linked. + return true; + } + + /** * Returns edit icons for the page with list of instances. * @param stdClass $instance @@ -118,7 +134,8 @@ class enrol_manual_plugin extends enrol_plugin { $icons[] = $OUTPUT->action_icon($managelink, new pix_icon('t/enrolusers', get_string('enrolusers', 'enrol_manual'), 'core', array('class'=>'iconsmall'))); } if (has_capability('enrol/manual:config', $context)) { - $editlink = new moodle_url("/enrol/manual/edit.php", array('courseid'=>$instance->courseid)); + $urlparams = array('courseid' => $instance->courseid, 'type' => 'manual', 'id' => $instance->id); + $editlink = new moodle_url("/enrol/editinstance.php", $urlparams); $icons[] = $OUTPUT->action_icon($editlink, new pix_icon('t/edit', get_string('edit'), 'core', array('class' => 'iconsmall'))); } @@ -126,27 +143,6 @@ class enrol_manual_plugin extends enrol_plugin { return $icons; } - /** - * Returns link to page which may be used to add new instance of enrolment plugin in course. - * @param int $courseid - * @return moodle_url page url - */ - public function get_newinstance_link($courseid) { - global $DB; - - $context = context_course::instance($courseid, MUST_EXIST); - - if (!has_capability('moodle/course:enrolconfig', $context) or !has_capability('enrol/manual:config', $context)) { - return NULL; - } - - if ($DB->record_exists('enrol', array('courseid'=>$courseid, 'enrol'=>'manual'))) { - return NULL; - } - - return new moodle_url('/enrol/manual/edit.php', array('courseid'=>$courseid)); - } - /** * Add new instance of enrol plugin with default settings. * @param stdClass $course @@ -188,6 +184,26 @@ class enrol_manual_plugin extends enrol_plugin { return parent::add_instance($course, $fields); } + /** + * Update instance of enrol plugin. + * @param stdClass $instance + * @param stdClass $data modified instance fields + * @return boolean + */ + public function update_instance($instance, $data) { + global $DB; + + // Delete all other instances, leaving only one. + if ($instances = $DB->get_records('enrol', array('courseid' => $instance->courseid, 'enrol' => 'manual'), 'id ASC')) { + foreach ($instances as $anotherinstance) { + if ($anotherinstance->id != $instance->id) { + $this->delete_instance($anotherinstance); + } + } + } + return parent::update_instance($instance, $data); + } + /** * Returns a button to manually enrol users through the manual enrolment plugin. * @@ -610,4 +626,130 @@ class enrol_manual_plugin extends enrol_plugin { $this->enrol_user($instance, $userid, $roleid, $timestart, $timeend, $status, $recovergrades); } } + + /** + * We are a good plugin and don't invent our own UI/validation code path. + * + * @return boolean + */ + public function use_standard_editing_ui() { + return true; + } + + /** + * Return an array of valid options for the status. + * + * @return array + */ + protected function get_status_options() { + $options = array(ENROL_INSTANCE_ENABLED => get_string('yes'), + ENROL_INSTANCE_DISABLED => get_string('no')); + return $options; + } + + /** + * Return an array of valid options for the roleid. + * + * @param stdClass $instance + * @param context $context + * @return array + */ + protected function get_roleid_options($instance, $context) { + if ($instance->id) { + $roles = get_default_enrol_roles($context, $instance->roleid); + } else { + $roles = get_default_enrol_roles($context, $this->get_config('roleid')); + } + return $roles; + } + + /** + * Return an array of valid options for the expirynotify. + * + * @return array + */ + protected function get_expirynotify_options() { + $options = array( + 0 => get_string('no'), + 1 => get_string('expirynotifyenroller', 'core_enrol'), + 2 => get_string('expirynotifyall', 'core_enrol') + ); + return $options; + } + + /** + * Add elements to the edit instance form. + * + * @param stdClass $instance + * @param MoodleQuickForm $mform + * @param context $context + * @return bool + */ + public function edit_instance_form($instance, MoodleQuickForm $mform, $context) { + + $options = $this->get_status_options(); + $mform->addElement('select', 'status', get_string('status', 'enrol_manual'), $options); + $mform->addHelpButton('status', 'status', 'enrol_manual'); + $mform->setDefault('status', $this->get_config('status')); + + $roles = $this->get_roleid_options($instance, $context); + $mform->addElement('select', 'roleid', get_string('defaultrole', 'role'), $roles); + $mform->setDefault('roleid', $this->get_config('roleid')); + + $options = array('optional' => true, 'defaultunit' => 86400); + $mform->addElement('duration', 'enrolperiod', get_string('defaultperiod', 'enrol_manual'), $options); + $mform->setDefault('enrolperiod', $this->get_config('enrolperiod')); + $mform->addHelpButton('enrolperiod', 'defaultperiod', 'enrol_manual'); + + $options = $this->get_expirynotify_options(); + $mform->addElement('select', 'expirynotify', get_string('expirynotify', 'core_enrol'), $options); + $mform->addHelpButton('expirynotify', 'expirynotify', 'core_enrol'); + + $options = array('optional' => false, 'defaultunit' => 86400); + $mform->addElement('duration', 'expirythreshold', get_string('expirythreshold', 'core_enrol'), $options); + $mform->addHelpButton('expirythreshold', 'expirythreshold', 'core_enrol'); + $mform->disabledIf('expirythreshold', 'expirynotify', 'eq', 0); + + if (enrol_accessing_via_instance($instance)) { + $warntext = get_string('instanceeditselfwarningtext', 'core_enrol'); + $mform->addElement('static', 'selfwarn', get_string('instanceeditselfwarning', 'core_enrol'), $warntext); + } + } + + /** + * Perform custom validation of the data used to edit the instance. + * + * @param array $data array of ("fieldname"=>value) of submitted data + * @param array $files array of uploaded files "element_name"=>tmp_file_path + * @param object $instance The instance loaded from the DB + * @param context $context The context of the instance we are editing + * @return array of "element_name"=>"error_description" if there are errors, + * or an empty array if everything is OK. + * @return void + */ + public function edit_instance_validation($data, $files, $instance, $context) { + $errors = array(); + + if ($data['expirynotify'] > 0 and $data['expirythreshold'] < 86400) { + $errors['expirythreshold'] = get_string('errorthresholdlow', 'core_enrol'); + } + + $validstatus = array_keys($this->get_status_options()); + $validroles = array_keys($this->get_roleid_options($instance, $context)); + $validexpirynotify = array_keys($this->get_expirynotify_options()); + + $tovalidate = array( + 'status' => $validstatus, + 'roleid' => $validroles, + 'enrolperiod' => PARAM_INT, + 'expirynotify' => $validexpirynotify, + 'expirythreshold' => PARAM_INT + ); + + $typeerrors = $this->validate_param_types($data, $tovalidate); + $errors = array_merge($errors, $typeerrors); + + return $errors; + } + } diff --git a/enrol/meta/addinstance.php b/enrol/meta/addinstance.php deleted file mode 100644 index aea6adbfc98..00000000000 --- a/enrol/meta/addinstance.php +++ /dev/null @@ -1,94 +0,0 @@ -. - -/** - * Adds new instance of enrol_meta to specified course. - * - * @package enrol_meta - * @copyright 2010 Petr Skoda {@link http://skodak.org} - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -require('../../config.php'); -require_once("$CFG->dirroot/enrol/meta/addinstance_form.php"); -require_once("$CFG->dirroot/enrol/meta/locallib.php"); - -$id = required_param('id', PARAM_INT); // course id -$message = optional_param('message', null, PARAM_TEXT); -$instanceid = optional_param('enrolid', 0, PARAM_INT); - -$course = $DB->get_record('course', array('id'=>$id), '*', MUST_EXIST); -$context = context_course::instance($course->id, MUST_EXIST); - -$PAGE->set_url('/enrol/meta/addinstance.php', array('id'=>$course->id)); -$PAGE->set_pagelayout('admin'); - -navigation_node::override_active_url(new moodle_url('/enrol/instances.php', array('id'=>$course->id))); - -require_login($course); -require_capability('moodle/course:enrolconfig', $context); - -$enrol = enrol_get_plugin('meta'); -if ($instanceid) { - require_capability('enrol/meta:config', $context); - $instance = $DB->get_record('enrol', array('courseid' => $course->id, 'enrol' => 'meta', - 'id' => $instanceid), '*', MUST_EXIST); - -} else { - if (!$enrol->get_newinstance_link($course->id)) { - redirect(new moodle_url('/enrol/instances.php', array('id' => $course->id))); - } - $instance = null; -} - -$mform = new enrol_meta_addinstance_form(null, array('course' => $course, 'instance' => $instance)); - -if ($mform->is_cancelled()) { - redirect(new moodle_url('/enrol/instances.php', array('id'=>$course->id))); - -} else if ($data = $mform->get_data()) { - if (!empty($data->customint2) && $data->customint2 == ENROL_META_CREATE_GROUP) { - $data->customint2 = enrol_meta_create_new_group($course->id, $data->link); - } - if ($instance) { - if ($data->customint2 != $instance->customint2) { - $DB->update_record('enrol', array('id' => $instance->id, 'customint2' => $data->customint2)); - enrol_meta_sync($course->id); - } - } else { - $eid = $enrol->add_instance($course, array('customint1' => $data->link, - 'customint2' => $data->customint2)); - enrol_meta_sync($course->id); - if (!empty($data->submitbuttonnext)) { - redirect(new moodle_url('/enrol/meta/addinstance.php', - array('id' => $course->id, 'message' => 'added'))); - } - } - redirect(new moodle_url('/enrol/instances.php', array('id' => $course->id))); -} - -$PAGE->set_heading($course->fullname); -$PAGE->set_title(get_string('pluginname', 'enrol_meta')); - -echo $OUTPUT->header(); - -if ($message === 'added') { - echo $OUTPUT->notification(get_string('instanceadded', 'enrol'), 'notifysuccess'); -} - -$mform->display(); - -echo $OUTPUT->footer(); diff --git a/enrol/meta/addinstance_form.php b/enrol/meta/addinstance_form.php deleted file mode 100644 index c28a762d250..00000000000 --- a/enrol/meta/addinstance_form.php +++ /dev/null @@ -1,152 +0,0 @@ -. - -/** - * Adds instance form - * - * @package enrol_meta - * @copyright 2010 Petr Skoda {@link http://skodak.org} - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -defined('MOODLE_INTERNAL') || die(); - -require_once("$CFG->libdir/formslib.php"); - -class enrol_meta_addinstance_form extends moodleform { - protected $course; - - function definition() { - global $CFG, $DB; - - $mform = $this->_form; - $course = $this->_customdata['course']; - $instance = $this->_customdata['instance']; - $this->course = $course; - - if ($instance) { - $where = 'WHERE c.id = :courseid'; - $params = array('courseid' => $instance->customint1); - $existing = array(); - } else { - $where = ''; - $params = array(); - $existing = $DB->get_records('enrol', array('enrol' => 'meta', 'courseid' => $course->id), '', 'customint1, id'); - } - - // TODO: this has to be done via ajax or else it will fail very badly on large sites! - $courses = array('' => get_string('choosedots')); - $select = ', ' . context_helper::get_preload_record_columns_sql('ctx'); - $join = "LEFT JOIN {context} ctx ON (ctx.instanceid = c.id AND ctx.contextlevel = :contextlevel)"; - - $plugin = enrol_get_plugin('meta'); - $sortorder = 'c.' . $plugin->get_config('coursesort', 'sortorder') . ' ASC'; - - $sql = "SELECT c.id, c.fullname, c.shortname, c.visible $select FROM {course} c $join $where ORDER BY $sortorder"; - $rs = $DB->get_recordset_sql($sql, array('contextlevel' => CONTEXT_COURSE) + $params); - foreach ($rs as $c) { - if ($c->id == SITEID or $c->id == $course->id or isset($existing[$c->id])) { - continue; - } - context_helper::preload_from_record($c); - $coursecontext = context_course::instance($c->id); - if (!$c->visible and !has_capability('moodle/course:viewhiddencourses', $coursecontext)) { - continue; - } - if (!has_capability('enrol/meta:selectaslinked', $coursecontext)) { - continue; - } - $courses[$c->id] = $coursecontext->get_context_name(false); - } - $rs->close(); - - $groups = array(0 => get_string('none')); - if (has_capability('moodle/course:managegroups', context_course::instance($course->id))) { - $groups[ENROL_META_CREATE_GROUP] = get_string('creategroup', 'enrol_meta'); - } - foreach (groups_get_all_groups($course->id) as $group) { - $groups[$group->id] = format_string($group->name, true, array('context' => context_course::instance($course->id))); - } - - $mform->addElement('header','general', get_string('pluginname', 'enrol_meta')); - - $mform->addElement('select', 'link', get_string('linkedcourse', 'enrol_meta'), $courses); - $mform->addRule('link', get_string('required'), 'required', null, 'client'); - - $mform->addElement('select', 'customint2', get_string('addgroup', 'enrol_meta'), $groups); - - $mform->addElement('hidden', 'id', null); - $mform->setType('id', PARAM_INT); - - $mform->addElement('hidden', 'enrolid'); - $mform->setType('enrolid', PARAM_INT); - - $data = array('id' => $course->id); - if ($instance) { - $data['link'] = $instance->customint1; - $data['enrolid'] = $instance->id; - $data['customint2'] = $instance->customint2; - $mform->freeze('link'); - $this->add_action_buttons(); - } else { - $this->add_add_buttons(); - } - $this->set_data($data); - } - - /** - * Adds buttons on create new method form - */ - protected function add_add_buttons() { - $mform = $this->_form; - $buttonarray = array(); - $buttonarray[0] = $mform->createElement('submit', 'submitbutton', get_string('addinstance', 'enrol')); - $buttonarray[1] = $mform->createElement('submit', 'submitbuttonnext', get_string('addinstanceanother', 'enrol')); - $buttonarray[2] = $mform->createElement('cancel'); - $mform->addGroup($buttonarray, 'buttonar', '', array(' '), false); - $mform->closeHeaderBefore('buttonar'); - } - - function validation($data, $files) { - global $DB, $CFG; - - $errors = parent::validation($data, $files); - - if ($this->_customdata['instance']) { - // Nothing to validate in case of editing. - return $errors; - } - - // TODO: this is duplicated here because it may be necessary once we implement ajax course selection element - - if (!$c = $DB->get_record('course', array('id'=>$data['link']))) { - $errors['link'] = get_string('required'); - } else { - $coursecontext = context_course::instance($c->id); - $existing = $DB->get_records('enrol', array('enrol'=>'meta', 'courseid'=>$this->course->id), '', 'customint1, id'); - if (!$c->visible and !has_capability('moodle/course:viewhiddencourses', $coursecontext)) { - $errors['link'] = get_string('error'); - } else if (!has_capability('enrol/meta:selectaslinked', $coursecontext)) { - $errors['link'] = get_string('error'); - } else if ($c->id == SITEID or $c->id == $this->course->id or isset($existing[$c->id])) { - $errors['link'] = get_string('error'); - } - } - - return $errors; - } -} - diff --git a/enrol/meta/lib.php b/enrol/meta/lib.php index 538fd1fd3ff..bfd4c67e9bb 100644 --- a/enrol/meta/lib.php +++ b/enrol/meta/lib.php @@ -64,17 +64,18 @@ class enrol_meta_plugin extends enrol_plugin { } /** - * Returns link to page which may be used to add new instance of enrolment plugin in course. + * Returns true if we can add a new instance to this course. + * * @param int $courseid - * @return moodle_url page url + * @return boolean */ - public function get_newinstance_link($courseid) { + public function can_add_instance($courseid) { $context = context_course::instance($courseid, MUST_EXIST); if (!has_capability('moodle/course:enrolconfig', $context) or !has_capability('enrol/meta:config', $context)) { - return NULL; + return false; } - // multiple instances supported - multiple parent courses linked - return new moodle_url('/enrol/meta/addinstance.php', array('id'=>$courseid)); + // Multiple instances supported - multiple parent courses linked. + return true; } /** @@ -127,6 +128,56 @@ class enrol_meta_plugin extends enrol_plugin { // We should probably add some sync button to the course enrol methods overview page. } + /** + * Add new instance of enrol plugin. + * @param object $course + * @param array $fields instance fields + * @return int id of new instance, null if can not be created + */ + public function add_instance($course, array $fields = null) { + global $CFG; + + require_once("$CFG->dirroot/enrol/meta/locallib.php"); + + if (!empty($fields['customint2']) && $fields['customint2'] == ENROL_META_CREATE_GROUP) { + $context = context_course::instance($course->id); + require_capability('moodle/course:managegroups', $context); + $groupid = enrol_meta_create_new_group($course->id, $fields['customint1']); + $fields['customint2'] = $groupid; + } + + $result = parent::add_instance($course, $fields); + + enrol_meta_sync($course->id); + + return $result; + } + + /** + * Update instance of enrol plugin. + * @param stdClass $instance + * @param stdClass $data modified instance fields + * @return boolean + */ + public function update_instance($instance, $data) { + global $CFG; + + require_once("$CFG->dirroot/enrol/meta/locallib.php"); + + if (!empty($data->customint2) && $data->customint2 == ENROL_META_CREATE_GROUP) { + $context = context_course::instance($instance->courseid); + require_capability('moodle/course:managegroups', $context); + $groupid = enrol_meta_create_new_group($instance->courseid, $data->customint1); + $data->customint2 = $groupid; + } + + $result = parent::update_instance($instance, $data); + + enrol_meta_sync($instance->courseid); + + return $result; + } + /** * Update instance status * @@ -176,6 +227,153 @@ class enrol_meta_plugin extends enrol_plugin { return has_capability('enrol/meta:config', $context); } + /** + * We are a good plugin and don't invent our own UI/validation code path. + * + * @return boolean + */ + public function use_standard_editing_ui() { + return true; + } + + /** + * Return an array of valid options for the courses. + * + * @param stdClass $instance + * @param context $coursecontext + * @return array + */ + protected function get_course_options($instance, $coursecontext) { + global $DB; + + if ($instance->id) { + $where = 'WHERE c.id = :courseid'; + $params = array('courseid' => $instance->customint1); + $existing = array(); + } else { + $where = ''; + $params = array(); + $instanceparams = array('enrol' => 'meta', 'courseid' => $instance->courseid); + $existing = $DB->get_records('enrol', $instanceparams, '', 'customint1, id'); + } + + // TODO: this has to be done via ajax or else it will fail very badly on large sites! + $courses = array('' => get_string('choosedots')); + $select = ', ' . context_helper::get_preload_record_columns_sql('ctx'); + $join = "LEFT JOIN {context} ctx ON (ctx.instanceid = c.id AND ctx.contextlevel = :contextlevel)"; + + $sortorder = 'c.' . $this->get_config('coursesort', 'sortorder') . ' ASC'; + + $sql = "SELECT c.id, c.fullname, c.shortname, c.visible $select FROM {course} c $join $where ORDER BY $sortorder"; + $rs = $DB->get_recordset_sql($sql, array('contextlevel' => CONTEXT_COURSE) + $params); + foreach ($rs as $c) { + if ($c->id == SITEID or $c->id == $instance->courseid or isset($existing[$c->id])) { + continue; + } + context_helper::preload_from_record($c); + $coursecontext = context_course::instance($c->id); + if (!$c->visible and !has_capability('moodle/course:viewhiddencourses', $coursecontext)) { + continue; + } + if (!has_capability('enrol/meta:selectaslinked', $coursecontext)) { + continue; + } + $courses[$c->id] = $coursecontext->get_context_name(false); + } + $rs->close(); + return $courses; + } + + /** + * Return an array of valid options for the groups. + * + * @param context $coursecontext + * @return array + */ + protected function get_group_options($coursecontext) { + $groups = array(0 => get_string('none')); + $courseid = $coursecontext->instanceid; + if (has_capability('moodle/course:managegroups', $coursecontext)) { + $groups[ENROL_META_CREATE_GROUP] = get_string('creategroup', 'enrol_meta'); + } + foreach (groups_get_all_groups($courseid) as $group) { + $groups[$group->id] = format_string($group->name, true, array('context' => $coursecontext)); + } + return $groups; + } + + /** + * Add elements to the edit instance form. + * + * @param stdClass $instance + * @param MoodleQuickForm $mform + * @param context $coursecontext + * @return bool + */ + public function edit_instance_form($instance, MoodleQuickForm $mform, $coursecontext) { + global $DB; + + $courses = $this->get_course_options($instance, $coursecontext); + $groups = $this->get_group_options($coursecontext); + + $mform->addElement('select', 'customint1', get_string('linkedcourse', 'enrol_meta'), $courses); + $mform->addRule('customint1', get_string('required'), 'required', null, 'client'); + if (!empty($instance->id)) { + $mform->freeze('customint1'); + } + + $mform->addElement('select', 'customint2', get_string('addgroup', 'enrol_meta'), $groups); + } + + /** + * Perform custom validation of the data used to edit the instance. + * + * @param array $data array of ("fieldname"=>value) of submitted data + * @param array $files array of uploaded files "element_name"=>tmp_file_path + * @param object $instance The instance loaded from the DB + * @param context $context The context of the instance we are editing + * @return array of "element_name"=>"error_description" if there are errors, + * or an empty array if everything is OK. + * @return void + */ + public function edit_instance_validation($data, $files, $instance, $context) { + global $DB; + $errors = array(); + $thiscourseid = $context->instanceid; + $c = false; + + if (!empty($data['customint1'])) { + $c = $DB->get_record('course', array('id' => $data['customint1'])); + } + + if (!$c) { + $errors['customint1'] = get_string('required'); + } else { + $coursecontext = context_course::instance($c->id); + $existing = $DB->get_records('enrol', array('enrol' => 'meta', 'courseid' => $thiscourseid), '', 'customint1, id'); + if (!$c->visible and !has_capability('moodle/course:viewhiddencourses', $coursecontext)) { + $errors['customint1'] = get_string('error'); + } else if (!has_capability('enrol/meta:selectaslinked', $coursecontext)) { + $errors['customint1'] = get_string('error'); + } else if ($c->id == SITEID or $c->id == $thiscourseid or isset($existing[$c->id])) { + $errors['customint1'] = get_string('error'); + } + } + + $validcourses = array_keys($this->get_course_options($instance, $context)); + $validgroups = array_keys($this->get_group_options($context)); + + $tovalidate = array( + 'customint1' => $validcourses, + 'customint2' => $validgroups + ); + $typeerrors = $this->validate_param_types($data, $tovalidate); + $errors = array_merge($errors, $typeerrors); + + return $errors; + } + + /** * Restore instance and map settings. * @@ -270,8 +468,8 @@ class enrol_meta_plugin extends enrol_plugin { $icons = array(); if (has_capability('enrol/meta:config', $context)) { - $editlink = new moodle_url("/enrol/meta/addinstance.php", - array('id' => $instance->courseid, 'enrolid' => $instance->id)); + $editlink = new moodle_url("/enrol/editinstance.php", + array('courseid' => $instance->courseid, 'id' => $instance->id, 'type' => 'meta')); $icons[] = $OUTPUT->action_icon($editlink, new pix_icon('t/edit', get_string('edit'), 'core', array('class' => 'iconsmall'))); } diff --git a/enrol/meta/tests/behat/enrol_meta.feature b/enrol/meta/tests/behat/enrol_meta.feature index 6566759e6f0..b3ca8829b57 100644 --- a/enrol/meta/tests/behat/enrol_meta.feature +++ b/enrol/meta/tests/behat/enrol_meta.feature @@ -51,7 +51,9 @@ Feature: Enrolments are synchronised with meta courses And I set the following fields to these values: | Link course | Course 1 | | Add to group | Groupcourse 1 | - And I press "Add method and create another" + And I press "Add method" + And I set the field "Add method" to "Course meta link" + And I press "Go" And I set the following fields to these values: | Link course | Course 2 | | Add to group | Groupcourse 2 | @@ -91,7 +93,9 @@ Feature: Enrolments are synchronised with meta courses And I set the following fields to these values: | Link course | Course 1 | | Add to group | Groupcourse 1 | - And I press "Add method and create another" + And I press "Add method" + And I set the field "Add method" to "Course meta link" + And I press "Go" And I set the following fields to these values: | Link course | Course 2 | And I press "Add method" diff --git a/enrol/meta/tests/plugin_test.php b/enrol/meta/tests/plugin_test.php index 9f0fb8a0e24..5f292e5b6db 100644 --- a/enrol/meta/tests/plugin_test.php +++ b/enrol/meta/tests/plugin_test.php @@ -128,12 +128,15 @@ class enrol_meta_plugin_testcase extends advanced_testcase { $this->assertEquals(7, $DB->count_records('user_enrolments')); $this->assertEquals(6, $DB->count_records('role_assignments')); + // Disable the plugin to prevent add_instance from calling enrol_meta_sync. + $this->disable_plugin(); $e1 = $metalplugin->add_instance($course3, array('customint1'=>$course1->id)); $e2 = $metalplugin->add_instance($course3, array('customint1'=>$course2->id)); $e3 = $metalplugin->add_instance($course4, array('customint1'=>$course2->id)); $enrol1 = $DB->get_record('enrol', array('id'=>$e1)); $enrol2 = $DB->get_record('enrol', array('id'=>$e2)); $enrol3 = $DB->get_record('enrol', array('id'=>$e3)); + $this->enable_plugin(); enrol_meta_sync($course4->id, false); $this->assertEquals(9, $DB->count_records('user_enrolments')); diff --git a/enrol/mnet/addinstance.php b/enrol/mnet/addinstance.php deleted file mode 100644 index 9678b400bf5..00000000000 --- a/enrol/mnet/addinstance.php +++ /dev/null @@ -1,67 +0,0 @@ -. - -/** - * Adds new instance of enrol_mnet into the specified course - * - * @package enrol_mnet - * @copyright 2010 David Mudrak - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -require(dirname(dirname(dirname(__FILE__))).'/config.php'); -require_once($CFG->dirroot.'/enrol/mnet/addinstance_form.php'); -require_once($CFG->dirroot.'/mnet/service/enrol/locallib.php'); - -$id = required_param('id', PARAM_INT); // course id - -$course = $DB->get_record('course', array('id'=>$id), '*', MUST_EXIST); -$context = context_course::instance($course->id, MUST_EXIST); - -require_login($course); -require_capability('moodle/course:enrolconfig', $context); - -$PAGE->set_url('/enrol/mnet/addinstance.php', array('id'=>$course->id)); -$PAGE->set_pagelayout('standard'); - -// Try and make the manage instances node on the navigation active -$courseadmin = $PAGE->settingsnav->get('courseadmin'); -if ($courseadmin && $courseadmin->get('users') && $courseadmin->get('users')->get('manageinstances')) { - $courseadmin->get('users')->get('manageinstances')->make_active(); -} - -$enrol = enrol_get_plugin('mnet'); -// make sure we were allowed to get here form the Enrolment methods page -if (!$enrol->get_newinstance_link($course->id)) { - redirect(new moodle_url('/enrol/instances.php', array('id'=>$course->id))); -} -$service = mnetservice_enrol::get_instance(); -$mform = new enrol_mnet_addinstance_form(null, array('course'=>$course, 'enrol'=>$enrol, 'service'=>$service)); - -if ($mform->is_cancelled()) { - redirect(new moodle_url('/enrol/instances.php', array('id'=>$course->id))); - -} else if ($data = $mform->get_data()) { - $enrol->add_instance($course, array('customint1'=>$data->hostid, 'roleid'=>$data->roleid, 'name'=>$data->name)); - redirect(new moodle_url('/enrol/instances.php', array('id'=>$course->id))); -} - -$PAGE->set_heading($course->fullname); -$PAGE->set_title(get_string('pluginname', 'enrol_mnet')); - -echo $OUTPUT->header(); -$mform->display(); -echo $OUTPUT->footer(); diff --git a/enrol/mnet/addinstance_form.php b/enrol/mnet/addinstance_form.php deleted file mode 100644 index 436e92b0cf4..00000000000 --- a/enrol/mnet/addinstance_form.php +++ /dev/null @@ -1,87 +0,0 @@ -. - -/** - * Form to add an instance of enrol_mnet plugin - * - * @package enrol_mnet - * @copyright 2010 David Mudrak - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -defined('MOODLE_INTERNAL') || die(); - -require_once("$CFG->libdir/formslib.php"); - -class enrol_mnet_addinstance_form extends moodleform { - function definition() { - global $CFG, $DB; - - $mform = $this->_form; - $course = $this->_customdata['course']; - $enrol = $this->_customdata['enrol']; - $service = $this->_customdata['service']; - $coursecontext = context_course::instance($course->id); - - $subscribers = $service->get_remote_subscribers(); - $hosts = array(0 => get_string('remotesubscribersall', 'enrol_mnet')); - foreach ($subscribers as $hostid => $subscriber) { - $hosts[$hostid] = $subscriber->appname.': '.$subscriber->hostname.' ('.$subscriber->hosturl.')'; - } - $roles = get_assignable_roles($coursecontext); - - $mform->addElement('header','general', get_string('pluginname', 'enrol_mnet')); - - $mform->addElement('select', 'hostid', get_string('remotesubscriber', 'enrol_mnet'), $hosts); - $mform->addHelpButton('hostid', 'remotesubscriber', 'enrol_mnet'); - $mform->addRule('hostid', get_string('required'), 'required', null, 'client'); - - $mform->addElement('select', 'roleid', get_string('roleforremoteusers', 'enrol_mnet'), $roles); - $mform->addHelpButton('roleid', 'roleforremoteusers', 'enrol_mnet'); - $mform->addRule('roleid', get_string('required'), 'required', null, 'client'); - $mform->setDefault('roleid', $enrol->get_config('roleid')); - - $mform->addElement('text', 'name', get_string('instancename', 'enrol_mnet')); - $mform->addHelpButton('name', 'instancename', 'enrol_mnet'); - $mform->setType('name', PARAM_TEXT); - - $mform->addElement('hidden', 'id', null); - $mform->setType('id', PARAM_INT); - - $this->add_action_buttons(); - - $this->set_data(array('id'=>$course->id)); - } - - /** - * Do not allow multiple instances for single remote host - * - * @param array $data raw form data - * @param array $files - * @return array of errors - */ - function validation($data, $files) { - global $DB; - - $errors = array(); - - if ($DB->record_exists('enrol', array('enrol' => 'mnet', 'courseid' => $data['id'], 'customint1' => $data['hostid']))) { - $errors['hostid'] = get_string('error_multiplehost', 'enrol_mnet'); - } - - return $errors; - } -} diff --git a/enrol/mnet/lib.php b/enrol/mnet/lib.php index 419228b6cc5..bc33fe4db6e 100644 --- a/enrol/mnet/lib.php +++ b/enrol/mnet/lib.php @@ -62,31 +62,31 @@ class enrol_mnet_plugin extends enrol_plugin { } /** - * Returns link to page which may be used to add new instance of enrolment plugin into the course + * Returns true if a new instance can be added to this course. * * The link is returned only if there are some MNet peers that we publish enrolment service to. * * @param int $courseid id of the course to add the instance to - * @return moodle_url|null page url or null if instance can not be created + * @return boolean */ - public function get_newinstance_link($courseid) { + public function can_add_instance($courseid) { global $CFG, $DB; require_once($CFG->dirroot.'/mnet/service/enrol/locallib.php'); $service = mnetservice_enrol::get_instance(); if (!$service->is_available()) { - return null; + return false; } $coursecontext = context_course::instance($courseid); if (!has_capability('moodle/course:enrolconfig', $coursecontext)) { - return null; + return false; } $subscribers = $service->get_remote_subscribers(); if (empty($subscribers)) { - return null; + return false; } - return new moodle_url('/enrol/mnet/addinstance.php', array('id'=>$courseid)); + return true; } /** @@ -110,4 +110,104 @@ class enrol_mnet_plugin extends enrol_plugin { $context = context_course::instance($instance->courseid); return has_capability('enrol/mnet:config', $context); } + + /** + * Return an array of valid options for the hosts property. + * + * @return array + */ + protected function get_valid_hosts_options() { + global $CFG; + require_once($CFG->dirroot.'/mnet/service/enrol/locallib.php'); + + $service = mnetservice_enrol::get_instance(); + + $subscribers = $service->get_remote_subscribers(); + $hosts = array(0 => get_string('remotesubscribersall', 'enrol_mnet')); + foreach ($subscribers as $hostid => $subscriber) { + $hosts[$hostid] = $subscriber->appname.': '.$subscriber->hostname.' ('.$subscriber->hosturl.')'; + } + return $hosts; + } + + /** + * Return an array of valid options for the roles property. + * + * @param context $context + * @return array + */ + protected function get_valid_roles_options($context) { + $roles = get_assignable_roles($context); + return $roles; + } + + /** + * Add elements to the edit instance form. + * + * @param stdClass $instance + * @param MoodleQuickForm $mform + * @param context $context + * @return bool + */ + public function edit_instance_form($instance, MoodleQuickForm $mform, $context) { + global $CFG; + + $hosts = $this->get_valid_hosts_options(); + $mform->addElement('select', 'customint1', get_string('remotesubscriber', 'enrol_mnet'), $hosts); + $mform->addHelpButton('customint1', 'remotesubscriber', 'enrol_mnet'); + $mform->addRule('customint1', get_string('required'), 'required', null, 'client'); + + $roles = $this->get_valid_roles_options($context); + $mform->addElement('select', 'roleid', get_string('roleforremoteusers', 'enrol_mnet'), $roles); + $mform->addHelpButton('roleid', 'roleforremoteusers', 'enrol_mnet'); + $mform->addRule('roleid', get_string('required'), 'required', null, 'client'); + $mform->setDefault('roleid', $this->get_config('roleid')); + + $mform->addElement('text', 'name', get_string('instancename', 'enrol_mnet')); + $mform->addHelpButton('name', 'instancename', 'enrol_mnet'); + $mform->setType('name', PARAM_TEXT); + } + + /** + * We are a good plugin and don't invent our own UI/validation code path. + * + * @return boolean + */ + public function use_standard_editing_ui() { + return true; + } + + /** + * Perform custom validation of the data used to edit the instance. + * + * @param array $data array of ("fieldname"=>value) of submitted data + * @param array $files array of uploaded files "element_name"=>tmp_file_path + * @param object $instance The instance loaded from the DB + * @param context $context The context of the instance we are editing + * @return array of "element_name"=>"error_description" if there are errors, + * or an empty array if everything is OK. + * @return void + */ + public function edit_instance_validation($data, $files, $instance, $context) { + global $DB; + $errors = array(); + + $validroles = array_keys($this->get_valid_roles_options($context)); + $validhosts = array_keys($this->get_valid_hosts_options()); + + $params = array('enrol' => 'mnet', 'courseid' => $instance->courseid, 'customint1' => $data['customint1']); + if ($DB->record_exists('enrol', $params)) { + $errors['customint1'] = get_string('error_multiplehost', 'enrol_mnet'); + } + + $tovalidate = array( + 'customint1' => $validhosts, + 'roleid' => $validroles, + 'name' => PARAM_TEXT + ); + $typeerrors = $this->validate_param_types($data, $tovalidate); + $errors = array_merge($errors, $typeerrors); + + return $errors; + } } diff --git a/enrol/paypal/edit.php b/enrol/paypal/edit.php deleted file mode 100644 index 9c0541a4d49..00000000000 --- a/enrol/paypal/edit.php +++ /dev/null @@ -1,100 +0,0 @@ -. - -/** - * Adds new instance of enrol_paypal to specified course - * or edits current instance. - * - * @package enrol_paypal - * @copyright 2010 Petr Skoda {@link http://skodak.org} - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -require('../../config.php'); -require_once('edit_form.php'); - -$courseid = required_param('courseid', PARAM_INT); -$instanceid = optional_param('id', 0, PARAM_INT); // instanceid - -$course = $DB->get_record('course', array('id'=>$courseid), '*', MUST_EXIST); -$context = context_course::instance($course->id, MUST_EXIST); - -require_login($course); -require_capability('enrol/paypal:config', $context); - -$PAGE->set_url('/enrol/paypal/edit.php', array('courseid'=>$course->id, 'id'=>$instanceid)); -$PAGE->set_pagelayout('admin'); - -$return = new moodle_url('/enrol/instances.php', array('id'=>$course->id)); -if (!enrol_is_enabled('paypal')) { - redirect($return); -} - -$plugin = enrol_get_plugin('paypal'); - -if ($instanceid) { - $instance = $DB->get_record('enrol', array('courseid'=>$course->id, 'enrol'=>'paypal', 'id'=>$instanceid), '*', MUST_EXIST); - $instance->cost = format_float($instance->cost, 2, true); -} else { - require_capability('moodle/course:enrolconfig', $context); - // no instance yet, we have to add new instance - navigation_node::override_active_url(new moodle_url('/enrol/instances.php', array('id'=>$course->id))); - $instance = new stdClass(); - $instance->id = null; - $instance->courseid = $course->id; -} - -$mform = new enrol_paypal_edit_form(NULL, array($instance, $plugin, $context)); - -if ($mform->is_cancelled()) { - redirect($return); - -} else if ($data = $mform->get_data()) { - if ($instance->id) { - $reset = ($instance->status != $data->status); - - $instance->status = $data->status; - $instance->name = $data->name; - $instance->cost = unformat_float($data->cost); - $instance->currency = $data->currency; - $instance->roleid = $data->roleid; - $instance->enrolperiod = $data->enrolperiod; - $instance->enrolstartdate = $data->enrolstartdate; - $instance->enrolenddate = $data->enrolenddate; - $instance->timemodified = time(); - $DB->update_record('enrol', $instance); - \core\event\enrol_instance_updated::create_from_record($instance)->trigger(); - - if ($reset) { - $context->mark_dirty(); - } - - } else { - $fields = array('status'=>$data->status, 'name'=>$data->name, 'cost'=>unformat_float($data->cost), 'currency'=>$data->currency, 'roleid'=>$data->roleid, - 'enrolperiod'=>$data->enrolperiod, 'enrolstartdate'=>$data->enrolstartdate, 'enrolenddate'=>$data->enrolenddate); - $plugin->add_instance($course, $fields); - } - - redirect($return); -} - -$PAGE->set_heading($course->fullname); -$PAGE->set_title(get_string('pluginname', 'enrol_paypal')); - -echo $OUTPUT->header(); -echo $OUTPUT->heading(get_string('pluginname', 'enrol_paypal')); -$mform->display(); -echo $OUTPUT->footer(); diff --git a/enrol/paypal/edit_form.php b/enrol/paypal/edit_form.php deleted file mode 100644 index 8aa8059be26..00000000000 --- a/enrol/paypal/edit_form.php +++ /dev/null @@ -1,108 +0,0 @@ -. - -/** - * Adds new instance of enrol_paypal to specified course - * or edits current instance. - * - * @package enrol_paypal - * @copyright 2010 Petr Skoda {@link http://skodak.org} - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -defined('MOODLE_INTERNAL') || die(); - -require_once($CFG->libdir.'/formslib.php'); - -class enrol_paypal_edit_form extends moodleform { - - function definition() { - $mform = $this->_form; - - list($instance, $plugin, $context) = $this->_customdata; - - $mform->addElement('header', 'header', get_string('pluginname', 'enrol_paypal')); - - $mform->addElement('text', 'name', get_string('custominstancename', 'enrol')); - $mform->setType('name', PARAM_TEXT); - - $options = array(ENROL_INSTANCE_ENABLED => get_string('yes'), - ENROL_INSTANCE_DISABLED => get_string('no')); - $mform->addElement('select', 'status', get_string('status', 'enrol_paypal'), $options); - $mform->setDefault('status', $plugin->get_config('status')); - - $mform->addElement('text', 'cost', get_string('cost', 'enrol_paypal'), array('size'=>4)); - $mform->setType('cost', PARAM_RAW); // Use unformat_float to get real value. - $mform->setDefault('cost', format_float($plugin->get_config('cost'), 2, true)); - - $paypalcurrencies = $plugin->get_currencies(); - $mform->addElement('select', 'currency', get_string('currency', 'enrol_paypal'), $paypalcurrencies); - $mform->setDefault('currency', $plugin->get_config('currency')); - - if ($instance->id) { - $roles = get_default_enrol_roles($context, $instance->roleid); - } else { - $roles = get_default_enrol_roles($context, $plugin->get_config('roleid')); - } - $mform->addElement('select', 'roleid', get_string('assignrole', 'enrol_paypal'), $roles); - $mform->setDefault('roleid', $plugin->get_config('roleid')); - - - $mform->addElement('duration', 'enrolperiod', get_string('enrolperiod', 'enrol_paypal'), array('optional' => true, 'defaultunit' => 86400)); - $mform->setDefault('enrolperiod', $plugin->get_config('enrolperiod')); - $mform->addHelpButton('enrolperiod', 'enrolperiod', 'enrol_paypal'); - - $mform->addElement('date_time_selector', 'enrolstartdate', get_string('enrolstartdate', 'enrol_paypal'), array('optional' => true)); - $mform->setDefault('enrolstartdate', 0); - $mform->addHelpButton('enrolstartdate', 'enrolstartdate', 'enrol_paypal'); - - $mform->addElement('date_time_selector', 'enrolenddate', get_string('enrolenddate', 'enrol_paypal'), array('optional' => true)); - $mform->setDefault('enrolenddate', 0); - $mform->addHelpButton('enrolenddate', 'enrolenddate', 'enrol_paypal'); - - $mform->addElement('hidden', 'id'); - $mform->setType('id', PARAM_INT); - - $mform->addElement('hidden', 'courseid'); - $mform->setType('courseid', PARAM_INT); - - if (enrol_accessing_via_instance($instance)) { - $mform->addElement('static', 'selfwarn', get_string('instanceeditselfwarning', 'core_enrol'), get_string('instanceeditselfwarningtext', 'core_enrol')); - } - - $this->add_action_buttons(true, ($instance->id ? null : get_string('addinstance', 'enrol'))); - - $this->set_data($instance); - } - - function validation($data, $files) { - global $DB, $CFG; - $errors = parent::validation($data, $files); - - list($instance, $plugin, $context) = $this->_customdata; - - if (!empty($data['enrolenddate']) and $data['enrolenddate'] < $data['enrolstartdate']) { - $errors['enrolenddate'] = get_string('enrolenddaterror', 'enrol_paypal'); - } - - $cost = str_replace(get_string('decsep', 'langconfig'), '.', $data['cost']); - if (!is_numeric($cost)) { - $errors['cost'] = get_string('costerror', 'enrol_paypal'); - } - - return $errors; - } -} diff --git a/enrol/paypal/lib.php b/enrol/paypal/lib.php index 845e2e4e3b9..f536ab2aa77 100644 --- a/enrol/paypal/lib.php +++ b/enrol/paypal/lib.php @@ -109,7 +109,8 @@ class enrol_paypal_plugin extends enrol_plugin { $context = context_course::instance($instance->courseid); if (has_capability('enrol/paypal:config', $context)) { - $managelink = new moodle_url('/enrol/paypal/edit.php', array('courseid'=>$instance->courseid, 'id'=>$instance->id)); + $params = array('courseid' => $instance->courseid, 'id' => $instance->id, 'type' => 'paypal'); + $managelink = new moodle_url('/enrol/editinstance.php', $params); $instancesnode->add($this->get_instance_name($instance), $managelink, navigation_node::TYPE_SETTING); } } @@ -139,19 +140,54 @@ class enrol_paypal_plugin extends enrol_plugin { } /** - * Returns link to page which may be used to add new instance of enrolment plugin in course. + * Returns true if the user can add a new instance in this course. * @param int $courseid - * @return moodle_url page url + * @return boolean */ - public function get_newinstance_link($courseid) { + public function can_add_instance($courseid) { $context = context_course::instance($courseid, MUST_EXIST); if (!has_capability('moodle/course:enrolconfig', $context) or !has_capability('enrol/paypal:config', $context)) { - return NULL; + return false; } // multiple instances supported - different cost for different roles - return new moodle_url('/enrol/paypal/edit.php', array('courseid'=>$courseid)); + return true; + } + + /** + * We are a good plugin and don't invent our own UI/validation code path. + * + * @return boolean + */ + public function use_standard_editing_ui() { + return true; + } + + /** + * Add new instance of enrol plugin. + * @param object $course + * @param array $fields instance fields + * @return int id of new instance, null if can not be created + */ + public function add_instance($course, array $fields = null) { + if ($fields && !empty($fields['cost'])) { + $fields['cost'] = unformat_float($fields['cost']); + } + return parent::add_instance($course, $fields); + } + + /** + * Update instance of enrol plugin. + * @param stdClass $instance + * @param stdClass $data modified instance fields + * @return boolean + */ + public function update_instance($instance, $data) { + if ($data) { + $data->cost = unformat_float($data->cost); + } + return parent::update_instance($instance, $data); } /** @@ -312,6 +348,126 @@ class enrol_paypal_plugin extends enrol_plugin { $this->process_expirations($trace); } + /** + * Return an array of valid options for the status. + * + * @return array + */ + protected function get_status_options() { + $options = array(ENROL_INSTANCE_ENABLED => get_string('yes'), + ENROL_INSTANCE_DISABLED => get_string('no')); + return $options; + } + + /** + * Return an array of valid options for the roleid. + * + * @param stdClass $instance + * @param context $context + * @return array + */ + protected function get_roleid_options($instance, $context) { + if ($instance->id) { + $roles = get_default_enrol_roles($context, $instance->roleid); + } else { + $roles = get_default_enrol_roles($context, $this->get_config('roleid')); + } + return $roles; + } + + + /** + * Add elements to the edit instance form. + * + * @param stdClass $instance + * @param MoodleQuickForm $mform + * @param context $context + * @return bool + */ + public function edit_instance_form($instance, MoodleQuickForm $mform, $context) { + + $mform->addElement('text', 'name', get_string('custominstancename', 'enrol')); + $mform->setType('name', PARAM_TEXT); + + $options = $this->get_status_options(); + $mform->addElement('select', 'status', get_string('status', 'enrol_paypal'), $options); + $mform->setDefault('status', $this->get_config('status')); + + $mform->addElement('text', 'cost', get_string('cost', 'enrol_paypal'), array('size' => 4)); + $mform->setType('cost', PARAM_RAW); + $mform->setDefault('cost', format_float($this->get_config('cost'), 2, true)); + + $paypalcurrencies = $this->get_currencies(); + $mform->addElement('select', 'currency', get_string('currency', 'enrol_paypal'), $paypalcurrencies); + $mform->setDefault('currency', $this->get_config('currency')); + + $roles = $this->get_roleid_options($instance, $context); + $mform->addElement('select', 'roleid', get_string('assignrole', 'enrol_paypal'), $roles); + $mform->setDefault('roleid', $this->get_config('roleid')); + + $options = array('optional' => true, 'defaultunit' => 86400); + $mform->addElement('duration', 'enrolperiod', get_string('enrolperiod', 'enrol_paypal'), $options); + $mform->setDefault('enrolperiod', $this->get_config('enrolperiod')); + $mform->addHelpButton('enrolperiod', 'enrolperiod', 'enrol_paypal'); + + $options = array('optional' => true); + $mform->addElement('date_time_selector', 'enrolstartdate', get_string('enrolstartdate', 'enrol_paypal'), $options); + $mform->setDefault('enrolstartdate', 0); + $mform->addHelpButton('enrolstartdate', 'enrolstartdate', 'enrol_paypal'); + + $options = array('optional' => true); + $mform->addElement('date_time_selector', 'enrolenddate', get_string('enrolenddate', 'enrol_paypal'), $options); + $mform->setDefault('enrolenddate', 0); + $mform->addHelpButton('enrolenddate', 'enrolenddate', 'enrol_paypal'); + + if (enrol_accessing_via_instance($instance)) { + $warningtext = get_string('instanceeditselfwarningtext', 'core_enrol'); + $mform->addElement('static', 'selfwarn', get_string('instanceeditselfwarning', 'core_enrol'), $warningtext); + } + } + + /** + * Perform custom validation of the data used to edit the instance. + * + * @param array $data array of ("fieldname"=>value) of submitted data + * @param array $files array of uploaded files "element_name"=>tmp_file_path + * @param object $instance The instance loaded from the DB + * @param context $context The context of the instance we are editing + * @return array of "element_name"=>"error_description" if there are errors, + * or an empty array if everything is OK. + * @return void + */ + public function edit_instance_validation($data, $files, $instance, $context) { + $errors = array(); + + if (!empty($data['enrolenddate']) and $data['enrolenddate'] < $data['enrolstartdate']) { + $errors['enrolenddate'] = get_string('enrolenddaterror', 'enrol_paypal'); + } + + $cost = str_replace(get_string('decsep', 'langconfig'), '.', $data['cost']); + if (!is_numeric($cost)) { + $errors['cost'] = get_string('costerror', 'enrol_paypal'); + } + + $validstatus = array_keys($this->get_status_options()); + $validcurrency = array_keys($this->get_currencies()); + $validroles = array_keys($this->get_roleid_options($instance, $context)); + $tovalidate = array( + 'name' => PARAM_TEXT, + 'status' => $validstatus, + 'currency' => $validcurrency, + 'roleid' => $validroles, + 'enrolperiod' => PARAM_INT, + 'enrolstartdate' => PARAM_INT, + 'enrolenddate' => PARAM_INT + ); + + $typeerrors = $this->validate_param_types($data, $tovalidate); + $errors = array_merge($errors, $typeerrors); + + return $errors; + } + /** * Execute synchronisation. * @param progress_trace $trace diff --git a/enrol/self/edit.php b/enrol/self/edit.php deleted file mode 100644 index f429c394508..00000000000 --- a/enrol/self/edit.php +++ /dev/null @@ -1,149 +0,0 @@ -. - -/** - * Adds new instance of enrol_self to specified course - * or edits current instance. - * - * @package enrol_self - * @copyright 2010 Petr Skoda {@link http://skodak.org} - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -require('../../config.php'); -require_once('edit_form.php'); - -$courseid = required_param('courseid', PARAM_INT); -$instanceid = optional_param('id', 0, PARAM_INT); - -$course = $DB->get_record('course', array('id'=>$courseid), '*', MUST_EXIST); -$context = context_course::instance($course->id, MUST_EXIST); - -require_login($course); -require_capability('enrol/self:config', $context); - -$PAGE->set_url('/enrol/self/edit.php', array('courseid'=>$course->id, 'id'=>$instanceid)); -$PAGE->set_pagelayout('admin'); - -$return = new moodle_url('/enrol/instances.php', array('id'=>$course->id)); -if (!enrol_is_enabled('self')) { - redirect($return); -} - -/** @var enrol_self_plugin $plugin */ -$plugin = enrol_get_plugin('self'); - -if ($instanceid) { - $instance = $DB->get_record('enrol', array('courseid'=>$course->id, 'enrol'=>'self', 'id'=>$instanceid), '*', MUST_EXIST); - -} else { - require_capability('moodle/course:enrolconfig', $context); - // No instance yet, we have to add new instance. - navigation_node::override_active_url(new moodle_url('/enrol/instances.php', array('id'=>$course->id))); - - $instance = (object)$plugin->get_instance_defaults(); - $instance->id = null; - $instance->courseid = $course->id; - $instance->status = ENROL_INSTANCE_ENABLED; // Do not use default for automatically created instances here. -} - -// Merge these two settings to one value for the single selection element. -if ($instance->notifyall and $instance->expirynotify) { - $instance->expirynotify = 2; -} -unset($instance->notifyall); - -$mform = new enrol_self_edit_form(NULL, array($instance, $plugin, $context)); - -if ($mform->is_cancelled()) { - redirect($return); - -} else if ($data = $mform->get_data()) { - if ($data->expirynotify == 2) { - $data->expirynotify = 1; - $data->notifyall = 1; - } else { - $data->notifyall = 0; - } - if (!$data->expirynotify) { - // Keep previous/default value of disabled expirythreshold option. - $data->expirythreshold = $instance->expirythreshold; - } - if (!isset($data->customint6)) { - // Add previous value of newenrols if disabled. - $data->customint6 = $instance->customint6; - } - - if ($instance->id) { - $reset = ($instance->status != $data->status); - - $instance->status = $data->status; - $instance->name = $data->name; - $instance->password = $data->password; - $instance->customint1 = $data->customint1; - $instance->customint2 = $data->customint2; - $instance->customint3 = $data->customint3; - $instance->customint4 = $data->customint4; - $instance->customint5 = $data->customint5; - $instance->customint6 = $data->customint6; - $instance->customtext1 = $data->customtext1; - $instance->roleid = $data->roleid; - $instance->enrolperiod = $data->enrolperiod; - $instance->expirynotify = $data->expirynotify; - $instance->notifyall = $data->notifyall; - $instance->expirythreshold = $data->expirythreshold; - $instance->enrolstartdate = $data->enrolstartdate; - $instance->enrolenddate = $data->enrolenddate; - $instance->timemodified = time(); - $DB->update_record('enrol', $instance); - \core\event\enrol_instance_updated::create_from_record($instance)->trigger(); - - if ($reset) { - $context->mark_dirty(); - } - - } else { - $fields = array( - 'status' => $data->status, - 'name' => $data->name, - 'password' => $data->password, - 'customint1' => $data->customint1, - 'customint2' => $data->customint2, - 'customint3' => $data->customint3, - 'customint4' => $data->customint4, - 'customint5' => $data->customint5, - 'customint6' => $data->customint6, - 'customtext1' => $data->customtext1, - 'roleid' => $data->roleid, - 'enrolperiod' => $data->enrolperiod, - 'expirynotify' => $data->expirynotify, - 'notifyall' => $data->notifyall, - 'expirythreshold' => $data->expirythreshold, - 'enrolstartdate' => $data->enrolstartdate, - 'enrolenddate' => $data->enrolenddate); - $plugin->add_instance($course, $fields); - } - - redirect($return); -} - -$PAGE->set_heading($course->fullname); -$PAGE->set_title(get_string('pluginname', 'enrol_self')); - -echo $OUTPUT->header(); -echo $OUTPUT->heading(get_string('pluginname', 'enrol_self')); -$mform->display(); -echo $OUTPUT->footer(); diff --git a/enrol/self/edit_form.php b/enrol/self/edit_form.php deleted file mode 100644 index af10050e54f..00000000000 --- a/enrol/self/edit_form.php +++ /dev/null @@ -1,223 +0,0 @@ -. - -/** - * Adds new instance of enrol_self to specified course - * or edits current instance. - * - * @package enrol_self - * @copyright 2010 Petr Skoda {@link http://skodak.org} - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -defined('MOODLE_INTERNAL') || die(); - -require_once($CFG->libdir.'/formslib.php'); -require_once($CFG->dirroot.'/cohort/lib.php'); - -class enrol_self_edit_form extends moodleform { - - function definition() { - global $DB; - - $mform = $this->_form; - - list($instance, $plugin, $context) = $this->_customdata; - - $mform->addElement('header', 'header', get_string('pluginname', 'enrol_self')); - - $nameattribs = array('size' => '20', 'maxlength' => '255'); - $mform->addElement('text', 'name', get_string('custominstancename', 'enrol'), $nameattribs); - $mform->setType('name', PARAM_TEXT); - $mform->addRule('name', get_string('maximumchars', '', 255), 'maxlength', 255, 'server'); - - $options = array(ENROL_INSTANCE_ENABLED => get_string('yes'), - ENROL_INSTANCE_DISABLED => get_string('no')); - $mform->addElement('select', 'status', get_string('status', 'enrol_self'), $options); - $mform->addHelpButton('status', 'status', 'enrol_self'); - - $options = array(1 => get_string('yes'), 0 => get_string('no')); - $mform->addElement('select', 'customint6', get_string('newenrols', 'enrol_self'), $options); - $mform->addHelpButton('customint6', 'newenrols', 'enrol_self'); - $mform->disabledIf('customint6', 'status', 'eq', ENROL_INSTANCE_DISABLED); - - $passattribs = array('size' => '20', 'maxlength' => '50'); - $mform->addElement('passwordunmask', 'password', get_string('password', 'enrol_self'), $passattribs); - $mform->addHelpButton('password', 'password', 'enrol_self'); - if (empty($instance->id) and $plugin->get_config('requirepassword')) { - $mform->addRule('password', get_string('required'), 'required', null, 'client'); - } - $mform->addRule('password', get_string('maximumchars', '', 50), 'maxlength', 50, 'server'); - - $options = array(1 => get_string('yes'), - 0 => get_string('no')); - $mform->addElement('select', 'customint1', get_string('groupkey', 'enrol_self'), $options); - $mform->addHelpButton('customint1', 'groupkey', 'enrol_self'); - - $roles = $this->extend_assignable_roles($context, $instance->roleid); - $mform->addElement('select', 'roleid', get_string('role', 'enrol_self'), $roles); - - $mform->addElement('duration', 'enrolperiod', get_string('enrolperiod', 'enrol_self'), array('optional' => true, 'defaultunit' => 86400)); - $mform->addHelpButton('enrolperiod', 'enrolperiod', 'enrol_self'); - - $options = array(0 => get_string('no'), 1 => get_string('expirynotifyenroller', 'core_enrol'), 2 => get_string('expirynotifyall', 'core_enrol')); - $mform->addElement('select', 'expirynotify', get_string('expirynotify', 'core_enrol'), $options); - $mform->addHelpButton('expirynotify', 'expirynotify', 'core_enrol'); - - $mform->addElement('duration', 'expirythreshold', get_string('expirythreshold', 'core_enrol'), array('optional' => false, 'defaultunit' => 86400)); - $mform->addHelpButton('expirythreshold', 'expirythreshold', 'core_enrol'); - $mform->disabledIf('expirythreshold', 'expirynotify', 'eq', 0); - - $mform->addElement('date_time_selector', 'enrolstartdate', get_string('enrolstartdate', 'enrol_self'), array('optional' => true)); - $mform->setDefault('enrolstartdate', 0); - $mform->addHelpButton('enrolstartdate', 'enrolstartdate', 'enrol_self'); - - $mform->addElement('date_time_selector', 'enrolenddate', get_string('enrolenddate', 'enrol_self'), array('optional' => true)); - $mform->setDefault('enrolenddate', 0); - $mform->addHelpButton('enrolenddate', 'enrolenddate', 'enrol_self'); - - $options = array(0 => get_string('never'), - 1800 * 3600 * 24 => get_string('numdays', '', 1800), - 1000 * 3600 * 24 => get_string('numdays', '', 1000), - 365 * 3600 * 24 => get_string('numdays', '', 365), - 180 * 3600 * 24 => get_string('numdays', '', 180), - 150 * 3600 * 24 => get_string('numdays', '', 150), - 120 * 3600 * 24 => get_string('numdays', '', 120), - 90 * 3600 * 24 => get_string('numdays', '', 90), - 60 * 3600 * 24 => get_string('numdays', '', 60), - 30 * 3600 * 24 => get_string('numdays', '', 30), - 21 * 3600 * 24 => get_string('numdays', '', 21), - 14 * 3600 * 24 => get_string('numdays', '', 14), - 7 * 3600 * 24 => get_string('numdays', '', 7)); - $mform->addElement('select', 'customint2', get_string('longtimenosee', 'enrol_self'), $options); - $mform->addHelpButton('customint2', 'longtimenosee', 'enrol_self'); - - $mform->addElement('text', 'customint3', get_string('maxenrolled', 'enrol_self')); - $mform->addHelpButton('customint3', 'maxenrolled', 'enrol_self'); - $mform->setType('customint3', PARAM_INT); - - $cohorts = array(0 => get_string('no')); - $allcohorts = cohort_get_available_cohorts($context, 0, 0, 0); - if ($instance->customint5 && !isset($allcohorts[$instance->customint5]) && - ($c = $DB->get_record('cohort', array('id' => $instance->customint5), 'id, name, idnumber, contextid, visible', IGNORE_MISSING))) { - // Current cohort was not found because current user can not see it. Still keep it. - $allcohorts[$instance->customint5] = $c; - } - foreach ($allcohorts as $c) { - $cohorts[$c->id] = format_string($c->name, true, array('context' => context::instance_by_id($c->contextid))); - if ($c->idnumber) { - $cohorts[$c->id] .= ' ['.s($c->idnumber).']'; - } - } - if ($instance->customint5 && !isset($allcohorts[$instance->customint5])) { - // Somebody deleted a cohort, better keep the wrong value so that random ppl can not enrol. - $cohorts[$instance->customint5] = get_string('unknowncohort', 'cohort', $instance->customint5); - } - if (count($cohorts) > 1) { - $mform->addElement('select', 'customint5', get_string('cohortonly', 'enrol_self'), $cohorts); - $mform->addHelpButton('customint5', 'cohortonly', 'enrol_self'); - } else { - $mform->addElement('hidden', 'customint5'); - $mform->setType('customint5', PARAM_INT); - $mform->setConstant('customint5', 0); - } - - $mform->addElement('advcheckbox', 'customint4', get_string('sendcoursewelcomemessage', 'enrol_self')); - $mform->addHelpButton('customint4', 'sendcoursewelcomemessage', 'enrol_self'); - - $mform->addElement('textarea', 'customtext1', get_string('customwelcomemessage', 'enrol_self'), array('cols'=>'60', 'rows'=>'8')); - $mform->addHelpButton('customtext1', 'customwelcomemessage', 'enrol_self'); - - $mform->addElement('hidden', 'id'); - $mform->setType('id', PARAM_INT); - $mform->addElement('hidden', 'courseid'); - $mform->setType('courseid', PARAM_INT); - - if (enrol_accessing_via_instance($instance)) { - $mform->addElement('static', 'selfwarn', get_string('instanceeditselfwarning', 'core_enrol'), get_string('instanceeditselfwarningtext', 'core_enrol')); - } - - $this->add_action_buttons(true, ($instance->id ? null : get_string('addinstance', 'enrol'))); - - $this->set_data($instance); - } - - function validation($data, $files) { - global $DB, $CFG; - $errors = parent::validation($data, $files); - - list($instance, $plugin, $context) = $this->_customdata; - $checkpassword = false; - - if ($instance->id) { - // Check the password if we are enabling the plugin again. - if (($instance->status == ENROL_INSTANCE_DISABLED) && ($data['status'] == ENROL_INSTANCE_ENABLED)) { - $checkpassword = true; - } - - // Check the password if the instance is enabled and the password has changed. - if (($data['status'] == ENROL_INSTANCE_ENABLED) && ($instance->password !== $data['password'])) { - $checkpassword = true; - } - } else { - $checkpassword = true; - } - - if ($checkpassword) { - $require = $plugin->get_config('requirepassword'); - $policy = $plugin->get_config('usepasswordpolicy'); - if ($require and trim($data['password']) === '') { - $errors['password'] = get_string('required'); - } else if (!empty($data['password']) && $policy) { - $errmsg = ''; - if (!check_password_policy($data['password'], $errmsg)) { - $errors['password'] = $errmsg; - } - } - } - - if ($data['status'] == ENROL_INSTANCE_ENABLED) { - if (!empty($data['enrolenddate']) and $data['enrolenddate'] < $data['enrolstartdate']) { - $errors['enrolenddate'] = get_string('enrolenddaterror', 'enrol_self'); - } - } - - if ($data['expirynotify'] > 0 and $data['expirythreshold'] < 86400) { - $errors['expirythreshold'] = get_string('errorthresholdlow', 'core_enrol'); - } - - return $errors; - } - - /** - * Gets a list of roles that this user can assign for the course as the default for self-enrolment. - * - * @param context $context the context. - * @param integer $defaultrole the id of the role that is set as the default for self-enrolment - * @return array index is the role id, value is the role name - */ - function extend_assignable_roles($context, $defaultrole) { - global $DB; - - $roles = get_assignable_roles($context, ROLENAME_BOTH); - if (!isset($roles[$defaultrole])) { - if ($role = $DB->get_record('role', array('id'=>$defaultrole))) { - $roles[$defaultrole] = role_get_name($role, $context, ROLENAME_BOTH); - } - } - return $roles; - } -} diff --git a/enrol/self/lib.php b/enrol/self/lib.php index fef3f6f4f5a..fe71c131345 100644 --- a/enrol/self/lib.php +++ b/enrol/self/lib.php @@ -131,7 +131,8 @@ class enrol_self_plugin extends enrol_plugin { $context = context_course::instance($instance->courseid); if (has_capability('enrol/self:config', $context)) { - $managelink = new moodle_url('/enrol/self/edit.php', array('courseid'=>$instance->courseid, 'id'=>$instance->id)); + $linkparams = array('courseid' => $instance->courseid, 'id' => $instance->id, 'type' => 'self'); + $managelink = new moodle_url('/enrol/editinstance.php', $linkparams); $instancesnode->add($this->get_instance_name($instance), $managelink, navigation_node::TYPE_SETTING); } } @@ -152,7 +153,8 @@ class enrol_self_plugin extends enrol_plugin { $icons = array(); if (has_capability('enrol/self:config', $context)) { - $editlink = new moodle_url("/enrol/self/edit.php", array('courseid'=>$instance->courseid, 'id'=>$instance->id)); + $linkparams = array('courseid' => $instance->courseid, 'id' => $instance->id, 'type' => 'self'); + $editlink = new moodle_url("/enrol/editinstance.php", $linkparams); $icons[] = $OUTPUT->action_icon($editlink, new pix_icon('t/edit', get_string('edit'), 'core', array('class' => 'iconsmall'))); } @@ -161,18 +163,19 @@ class enrol_self_plugin extends enrol_plugin { } /** - * Returns link to page which may be used to add new instance of enrolment plugin in course. + * Return true if we can add a new instance to this course. + * * @param int $courseid - * @return moodle_url page url + * @return boolean */ - public function get_newinstance_link($courseid) { + public function can_add_instance($courseid) { $context = context_course::instance($courseid, MUST_EXIST); if (!has_capability('moodle/course:enrolconfig', $context) or !has_capability('enrol/self:config', $context)) { - return NULL; + return false; } - // Multiple instances supported - different roles with different password. - return new moodle_url('/enrol/self/edit.php', array('courseid'=>$courseid)); + + return true; } /** @@ -236,7 +239,7 @@ class enrol_self_plugin extends enrol_plugin { if (true === $enrolstatus) { // This user can self enrol using this instance. - $form = new enrol_self_enrol_form(NULL, $instance); + $form = new enrol_self_enrol_form(null, $instance); $instanceid = optional_param('instance', 0, PARAM_INT); if ($instance->id == $instanceid) { if ($data = $form->get_data()) { @@ -708,4 +711,357 @@ class enrol_self_plugin extends enrol_plugin { return true; } + + /** + * Return an array of valid options for the status. + * + * @return array + */ + protected function get_status_options() { + $options = array(ENROL_INSTANCE_ENABLED => get_string('yes'), + ENROL_INSTANCE_DISABLED => get_string('no')); + return $options; + } + + /** + * Return an array of valid options for the newenrols property. + * + * @return array + */ + protected function get_newenrols_options() { + $options = array(1 => get_string('yes'), 0 => get_string('no')); + return $options; + } + + /** + * Return an array of valid options for the groupkey property. + * + * @return array + */ + protected function get_groupkey_options() { + $options = array(1 => get_string('yes'), 0 => get_string('no')); + return $options; + } + + /** + * Return an array of valid options for the expirynotify property. + * + * @return array + */ + protected function get_expirynotify_options() { + $options = array(0 => get_string('no'), + 1 => get_string('expirynotifyenroller', 'core_enrol'), + 2 => get_string('expirynotifyall', 'core_enrol')); + return $options; + } + + /** + * Return an array of valid options for the longtimenosee property. + * + * @return array + */ + protected function get_longtimenosee_options() { + $options = array(0 => get_string('never'), + 1800 * 3600 * 24 => get_string('numdays', '', 1800), + 1000 * 3600 * 24 => get_string('numdays', '', 1000), + 365 * 3600 * 24 => get_string('numdays', '', 365), + 180 * 3600 * 24 => get_string('numdays', '', 180), + 150 * 3600 * 24 => get_string('numdays', '', 150), + 120 * 3600 * 24 => get_string('numdays', '', 120), + 90 * 3600 * 24 => get_string('numdays', '', 90), + 60 * 3600 * 24 => get_string('numdays', '', 60), + 30 * 3600 * 24 => get_string('numdays', '', 30), + 21 * 3600 * 24 => get_string('numdays', '', 21), + 14 * 3600 * 24 => get_string('numdays', '', 14), + 7 * 3600 * 24 => get_string('numdays', '', 7)); + return $options; + } + + /** + * Add elements to the edit instance form. + * + * @param stdClass $instance + * @param MoodleQuickForm $mform + * @param context $context + * @return bool + */ + public function edit_instance_form($instance, MoodleQuickForm $mform, $context) { + global $CFG; + + // Merge these two settings to one value for the single selection element. + if ($instance->notifyall and $instance->expirynotify) { + $instance->expirynotify = 2; + } + unset($instance->notifyall); + + $nameattribs = array('size' => '20', 'maxlength' => '255'); + $mform->addElement('text', 'name', get_string('custominstancename', 'enrol'), $nameattribs); + $mform->setType('name', PARAM_TEXT); + $mform->addRule('name', get_string('maximumchars', '', 255), 'maxlength', 255, 'server'); + + $options = $this->get_status_options(); + $mform->addElement('select', 'status', get_string('status', 'enrol_self'), $options); + $mform->addHelpButton('status', 'status', 'enrol_self'); + + $options = $this->get_newenrols_options(); + $mform->addElement('select', 'customint6', get_string('newenrols', 'enrol_self'), $options); + $mform->addHelpButton('customint6', 'newenrols', 'enrol_self'); + $mform->disabledIf('customint6', 'status', 'eq', ENROL_INSTANCE_DISABLED); + + $passattribs = array('size' => '20', 'maxlength' => '50'); + $mform->addElement('passwordunmask', 'password', get_string('password', 'enrol_self'), $passattribs); + $mform->addHelpButton('password', 'password', 'enrol_self'); + if (empty($instance->id) and $this->get_config('requirepassword')) { + $mform->addRule('password', get_string('required'), 'required', null, 'client'); + } + $mform->addRule('password', get_string('maximumchars', '', 50), 'maxlength', 50, 'server'); + + $options = $this->get_groupkey_options(); + $mform->addElement('select', 'customint1', get_string('groupkey', 'enrol_self'), $options); + $mform->addHelpButton('customint1', 'groupkey', 'enrol_self'); + + $roles = $this->extend_assignable_roles($context, $instance->roleid); + $mform->addElement('select', 'roleid', get_string('role', 'enrol_self'), $roles); + + $options = array('optional' => true, 'defaultunit' => 86400); + $mform->addElement('duration', 'enrolperiod', get_string('enrolperiod', 'enrol_self'), $options); + $mform->addHelpButton('enrolperiod', 'enrolperiod', 'enrol_self'); + + $options = $this->get_expirynotify_options(); + $mform->addElement('select', 'expirynotify', get_string('expirynotify', 'core_enrol'), $options); + $mform->addHelpButton('expirynotify', 'expirynotify', 'core_enrol'); + + $options = array('optional' => false, 'defaultunit' => 86400); + $mform->addElement('duration', 'expirythreshold', get_string('expirythreshold', 'core_enrol'), $options); + $mform->addHelpButton('expirythreshold', 'expirythreshold', 'core_enrol'); + $mform->disabledIf('expirythreshold', 'expirynotify', 'eq', 0); + + $options = array('optional' => true); + $mform->addElement('date_time_selector', 'enrolstartdate', get_string('enrolstartdate', 'enrol_self'), $options); + $mform->setDefault('enrolstartdate', 0); + $mform->addHelpButton('enrolstartdate', 'enrolstartdate', 'enrol_self'); + + $options = array('optional' => true); + $mform->addElement('date_time_selector', 'enrolenddate', get_string('enrolenddate', 'enrol_self'), $options); + $mform->setDefault('enrolenddate', 0); + $mform->addHelpButton('enrolenddate', 'enrolenddate', 'enrol_self'); + + $options = $this->get_longtimenosee_options(); + $mform->addElement('select', 'customint2', get_string('longtimenosee', 'enrol_self'), $options); + $mform->addHelpButton('customint2', 'longtimenosee', 'enrol_self'); + + $mform->addElement('text', 'customint3', get_string('maxenrolled', 'enrol_self')); + $mform->addHelpButton('customint3', 'maxenrolled', 'enrol_self'); + $mform->setType('customint3', PARAM_INT); + + require_once($CFG->dirroot.'/cohort/lib.php'); + + $cohorts = array(0 => get_string('no')); + $allcohorts = cohort_get_available_cohorts($context, 0, 0, 0); + if ($instance->customint5 && !isset($allcohorts[$instance->customint5])) { + $c = $DB->get_record('cohort', + array('id' => $instance->customint5), + 'id, name, idnumber, contextid, visible', + IGNORE_MISSING); + if ($c) { + // Current cohort was not found because current user can not see it. Still keep it. + $allcohorts[$instance->customint5] = $c; + } + } + foreach ($allcohorts as $c) { + $cohorts[$c->id] = format_string($c->name, true, array('context' => context::instance_by_id($c->contextid))); + if ($c->idnumber) { + $cohorts[$c->id] .= ' ['.s($c->idnumber).']'; + } + } + if ($instance->customint5 && !isset($allcohorts[$instance->customint5])) { + // Somebody deleted a cohort, better keep the wrong value so that random ppl can not enrol. + $cohorts[$instance->customint5] = get_string('unknowncohort', 'cohort', $instance->customint5); + } + if (count($cohorts) > 1) { + $mform->addElement('select', 'customint5', get_string('cohortonly', 'enrol_self'), $cohorts); + $mform->addHelpButton('customint5', 'cohortonly', 'enrol_self'); + } else { + $mform->addElement('hidden', 'customint5'); + $mform->setType('customint5', PARAM_INT); + $mform->setConstant('customint5', 0); + } + + $mform->addElement('advcheckbox', 'customint4', get_string('sendcoursewelcomemessage', 'enrol_self')); + $mform->addHelpButton('customint4', 'sendcoursewelcomemessage', 'enrol_self'); + + $options = array('cols' => '60', 'rows' => '8'); + $mform->addElement('textarea', 'customtext1', get_string('customwelcomemessage', 'enrol_self'), $options); + $mform->addHelpButton('customtext1', 'customwelcomemessage', 'enrol_self'); + + if (enrol_accessing_via_instance($instance)) { + $warntext = get_string('instanceeditselfwarningtext', 'core_enrol'); + $mform->addElement('static', 'selfwarn', get_string('instanceeditselfwarning', 'core_enrol'), $warntext); + } + } + + /** + * We are a good plugin and don't invent our own UI/validation code path. + * + * @return boolean + */ + public function use_standard_editing_ui() { + return true; + } + + /** + * Perform custom validation of the data used to edit the instance. + * + * @param array $data array of ("fieldname"=>value) of submitted data + * @param array $files array of uploaded files "element_name"=>tmp_file_path + * @param object $instance The instance loaded from the DB + * @param context $context The context of the instance we are editing + * @return array of "element_name"=>"error_description" if there are errors, + * or an empty array if everything is OK. + * @return void + */ + public function edit_instance_validation($data, $files, $instance, $context) { + $errors = array(); + + $checkpassword = false; + + if ($instance->id) { + // Check the password if we are enabling the plugin again. + if (($instance->status == ENROL_INSTANCE_DISABLED) && ($data['status'] == ENROL_INSTANCE_ENABLED)) { + $checkpassword = true; + } + + // Check the password if the instance is enabled and the password has changed. + if (($data['status'] == ENROL_INSTANCE_ENABLED) && ($instance->password !== $data['password'])) { + $checkpassword = true; + } + } else { + $checkpassword = true; + } + + if ($checkpassword) { + $require = $this->get_config('requirepassword'); + $policy = $this->get_config('usepasswordpolicy'); + if ($require and trim($data['password']) === '') { + $errors['password'] = get_string('required'); + } else if (!empty($data['password']) && $policy) { + $errmsg = ''; + if (!check_password_policy($data['password'], $errmsg)) { + $errors['password'] = $errmsg; + } + } + } + + if ($data['status'] == ENROL_INSTANCE_ENABLED) { + if (!empty($data['enrolenddate']) and $data['enrolenddate'] < $data['enrolstartdate']) { + $errors['enrolenddate'] = get_string('enrolenddaterror', 'enrol_self'); + } + } + + if ($data['expirynotify'] > 0 and $data['expirythreshold'] < 86400) { + $errors['expirythreshold'] = get_string('errorthresholdlow', 'core_enrol'); + } + + // Now these ones are checked by quickforms, but we may be called by the upload enrolments tool, or a webservive. + if (core_text::strlen($data['name']) > 255) { + $errors['name'] = get_string('err_maxlength', 'form', 255); + } + $validstatus = array_keys($this->get_status_options()); + $validnewenrols = array_keys($this->get_newenrols_options()); + if (core_text::strlen($data['password']) > 50) { + $errors['name'] = get_string('err_maxlength', 'form', 50); + } + $validgroupkey = array_keys($this->get_groupkey_options()); + $context = context_course::instance($instance->courseid); + $validroles = array_keys($this->extend_assignable_roles($context, $instance->roleid)); + $validexpirynotify = array_keys($this->get_expirynotify_options()); + $validlongtimenosee = array_keys($this->get_longtimenosee_options()); + $tovalidate = array( + 'enrolstartdate' => PARAM_INT, + 'enrolenddate' => PARAM_INT, + 'name' => PARAM_TEXT, + 'customint1' => $validgroupkey, + 'customint2' => $validlongtimenosee, + 'customint3' => PARAM_INT, + 'customint4' => PARAM_BOOL, + 'customint5' => PARAM_INT, + 'customint6' => $validnewenrols, + 'status' => $validstatus, + 'enrolperiod' => PARAM_INT, + 'expirynotify' => $validexpirynotify, + 'roleid' => $validroles + ); + if ($data['expirynotify'] != 0) { + $tovalidate['expirythreshold'] = PARAM_INT; + } + $typeerrors = $this->validate_param_types($data, $tovalidate); + $errors = array_merge($errors, $typeerrors); + + return $errors; + } + + /** + * Add new instance of enrol plugin. + * @param object $course + * @param array $fields instance fields + * @return int id of new instance, null if can not be created + */ + public function add_instance($course, array $fields = null) { + // In the form we are representing 2 db columns with one field. + if (!empty($fields) && !empty($fields['expirynotify'])) { + if ($fields['expirynotify'] == 2) { + $fields['expirynotify'] = 1; + $fields['notifyall'] = 1; + } else { + $fields['notifyall'] = 0; + } + } + + return parent::add_instance($course, $fields); + } + + /** + * Update instance of enrol plugin. + * @param stdClass $instance + * @param stdClass $data modified instance fields + * @return boolean + */ + public function update_instance($instance, $data) { + // In the form we are representing 2 db columns with one field. + if ($data->expirynotify == 2) { + $data->expirynotify = 1; + $data->notifyall = 1; + } else { + $data->notifyall = 0; + } + // Keep previous/default value of disabled expirythreshold option. + if (!$data->expirynotify) { + $data->expirythreshold = $instance->expirythreshold; + } + // Add previous value of newenrols if disabled. + if (!isset($data->customint6)) { + $data->customint6 = $instance->customint6; + } + + return parent::update_instance($instance, $data); + } + + /** + * Gets a list of roles that this user can assign for the course as the default for self-enrolment. + * + * @param context $context the context. + * @param integer $defaultrole the id of the role that is set as the default for self-enrolment + * @return array index is the role id, value is the role name + */ + public function extend_assignable_roles($context, $defaultrole) { + global $DB; + + $roles = get_assignable_roles($context, ROLENAME_BOTH); + if (!isset($roles[$defaultrole])) { + if ($role = $DB->get_record('role', array('id' => $defaultrole))) { + $roles[$defaultrole] = role_get_name($role, $context, ROLENAME_BOTH); + } + } + return $roles; + } } diff --git a/enrol/upgrade.txt b/enrol/upgrade.txt index 38a41e110c4..b00c6edd006 100644 --- a/enrol/upgrade.txt +++ b/enrol/upgrade.txt @@ -1,5 +1,9 @@ This files describes API changes in /enrol/* - plugins, information provided here is intended especially for developers. +=== 3.0 === +Enrolment plugins UI have been consolidated. Plugins can implement use_standard_editing_ui() function +and add edit_instance_form() and edit_instance_validation() methods instead of providing their own edit.php and form. In future +this will mean they can be called by webservices/user upload tools because they can validate their data. === 3.1 === * core_enrol_external::get_enrolled_users now supports two additional parameters for ordering: sortby and sortdirection. diff --git a/lib/enrollib.php b/lib/enrollib.php index 426c9a26c92..161f5126d95 100644 --- a/lib/enrollib.php +++ b/lib/enrollib.php @@ -1539,6 +1539,30 @@ abstract class enrol_plugin { // override if necessary } + /** + * This returns false for backwards compatibility, but it is really recommended. + * + * @since Moodle 3.1 + * @return boolean + */ + public function use_standard_editing_ui() { + return false; + } + + /** + * Return whether or not, given the current state, it is possible to add a new instance + * of this enrolment plugin to the course. + * + * Default implementation is just for backwards compatibility. + * + * @param int $courseid + * @return boolean + */ + public function can_add_instance($courseid) { + $link = $this->get_newinstance_link($courseid); + return !empty($link); + } + /** * Returns link to page which may be used to add new instance of enrolment plugin in course. * @param int $courseid @@ -1645,6 +1669,36 @@ abstract class enrol_plugin { // override - usually at least enable/disable switch, has to add own form header } + /** + * Adds form elements to add/edit instance form. + * + * @since Moodle 3.1 + * @param object $instance enrol instance or null if does not exist yet + * @param MoodleQuickForm $mform + * @param context $context + * @return void + */ + public function edit_instance_form($instance, MoodleQuickForm $mform, $context) { + // Do nothing by default. + } + + /** + * Perform custom validation of the data used to edit the instance. + * + * @since Moodle 3.1 + * @param array $data array of ("fieldname"=>value) of submitted data + * @param array $files array of uploaded files "element_name"=>tmp_file_path + * @param object $instance The instance data loaded from the DB. + * @param context $context The context of the instance we are editing + * @return array of "element_name"=>"error_description" if there are errors, + * or an empty array if everything is OK. + */ + public function edit_instance_validation($data, $files, $instance, $context) { + // No errors by default. + debugging('enrol_plugin::edit_instance_validation() is missing. This plugin has no validation!', DEBUG_DEVELOPER); + return array(); + } + /** * Validates course edit form data * @@ -1711,6 +1765,37 @@ abstract class enrol_plugin { return $instance->id; } + /** + * Update instance of enrol plugin. + * + * @since Moodle 3.1 + * @param stdClass $instance + * @param stdClass $data modified instance fields + * @return boolean + */ + public function update_instance($instance, $data) { + global $DB; + $properties = array('status', 'name', 'password', 'customint1', 'customint2', 'customint3', + 'customint4', 'customint5', 'customint6', 'customint7', 'customint8', + 'customchar1', 'customchar2', 'customchar3', 'customdec1', 'customdec2', + 'customtext1', 'customtext2', 'customtext3', 'customtext4', 'roleid', + 'enrolperiod', 'expirynotify', 'notifyall', 'expirythreshold', + 'enrolstartdate', 'enrolenddate', 'cost', 'currency'); + + foreach ($properties as $key) { + if (isset($data->$key)) { + $instance->$key = $data->$key; + } + } + $instance->timemodified = time(); + + $update = $DB->update_record('enrol', $instance); + if ($update) { + \core\event\enrol_instance_updated::create_from_record($instance)->trigger(); + } + return $update; + } + /** * Add new instance of enrol plugin with default settings, * called when adding new instance manually or when adding new course. @@ -2359,4 +2444,39 @@ abstract class enrol_plugin { // Implement if you want to restore protected group memberships, // usually this is not necessary because plugins should be able to recreate the memberships automatically. } + + /** + * Returns defaults for new instances. + * @since Moodle 3.1 + * @return array + */ + public function get_instance_defaults() { + return array(); + } + + /** + * Validate a list of parameter names and types. + * @since Moodle 3.1 + * + * @param array $data array of ("fieldname"=>value) of submitted data + * @param array $rules array of ("fieldname"=>PARAM_X types - or "fieldname"=>array( list of valid options ) + * @return array of "element_name"=>"error_description" if there are errors, + * or an empty array if everything is OK. + */ + public function validate_param_types($data, $rules) { + $errors = array(); + $invalidstr = get_string('invaliddata', 'error'); + foreach ($rules as $fieldname => $rule) { + if (is_array($rule)) { + if (!in_array($data[$fieldname], $rule)) { + $errors[$fieldname] = $invalidstr; + } + } else { + if ($data[$fieldname] != clean_param($data[$fieldname], $rule)) { + $errors[$fieldname] = $invalidstr; + } + } + } + return $errors; + } }