Merge branch 'MDL-48362-master' of git://github.com/damyon/moodle
authorAndrew Nicols <andrew@nicols.co.uk>
Mon, 29 Feb 2016 06:46:20 +0000 (14:46 +0800)
committerAndrew Nicols <andrew@nicols.co.uk>
Mon, 29 Feb 2016 06:46:20 +0000 (14:46 +0800)
28 files changed:
enrol/cohort/edit.php [deleted file]
enrol/cohort/edit_form.php [deleted file]
enrol/cohort/lib.php
enrol/editinstance.php [moved from enrol/guest/edit.php with 59% similarity]
enrol/editinstance_form.php [new file with mode: 0644]
enrol/guest/classes/enrol_guest_edit_form.php [deleted file]
enrol/guest/lib.php
enrol/guest/locallib.php
enrol/instances.php
enrol/manual/edit.php [deleted file]
enrol/manual/edit_form.php [deleted file]
enrol/manual/lib.php
enrol/meta/addinstance.php [deleted file]
enrol/meta/addinstance_form.php [deleted file]
enrol/meta/lib.php
enrol/meta/tests/behat/enrol_meta.feature
enrol/meta/tests/plugin_test.php
enrol/mnet/addinstance.php [deleted file]
enrol/mnet/addinstance_form.php [deleted file]
enrol/mnet/lib.php
enrol/paypal/edit.php [deleted file]
enrol/paypal/edit_form.php [deleted file]
enrol/paypal/lib.php
enrol/self/edit.php [deleted file]
enrol/self/edit_form.php [deleted file]
enrol/self/lib.php
enrol/upgrade.txt
lib/enrollib.php

diff --git a/enrol/cohort/edit.php b/enrol/cohort/edit.php
deleted file mode 100644 (file)
index 3affaa9..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * 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 (file)
index 2a02a29..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * 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;
-    }
-}
index 61be2ad..da38760 100644 (file)
@@ -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);
@@ -110,27 +97,51 @@ class enrol_cohort_plugin extends enrol_plugin {
     }
 
     /**
-     * Returns edit icons for the page with list of instances.
-     * @param stdClass $instance
-     * @return array
+     * 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 get_action_icons(stdClass $instance) {
-        global $OUTPUT;
-
-        if ($instance->enrol !== 'cohort') {
-            throw new coding_exception('invalid enrol instance!');
+    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;
         }
-        $context = context_course::instance($instance->courseid);
 
-        $icons = array();
+        return parent::add_instance($course, $fields);
+    }
 
-        if (has_capability('enrol/cohort:config', $context)) {
-            $editlink = new moodle_url("/enrol/cohort/edit.php", array('courseid'=>$instance->courseid, 'id'=>$instance->id));
-            $icons[] = $OUTPUT->action_icon($editlink, new pix_icon('t/edit', get_string('edit'), 'core',
-                    array('class' => 'iconsmall')));
+    /**
+     * 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 $icons;
+        return parent::update_instance($instance, $data);
     }
 
     /**
@@ -316,6 +327,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 +518,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();
similarity index 59%
rename from enrol/guest/edit.php
rename to enrol/editinstance.php
index 975f250..38d3ae7 100644 (file)
 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 
 /**
- * Edit instance of enrol_guest.
+ * Adds new instance of an enrolment plugin to specified course or edits current instance.
  *
- * Adds new instance of enrol_guest to specified course
- * or edits current instance.
- *
- * @package    enrol_guest
- * @copyright  2015 Andrew Hancox <andrewdchancox@googlemail.com>
+ * @package    core_enrol
+ * @copyright  2015 Damyon Wiese
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
-require('../../config.php');
+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/guest:config', $context);
+require_capability('enrol/' . $type . ':config', $context);
 
-$PAGE->set_url('/enrol/guest/edit.php', array('courseid' => $course->id, 'id' => $instanceid));
+$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('guest')) {
+if (!enrol_is_enabled($type)) {
     redirect($return);
 }
 
-$plugin = enrol_get_plugin('guest');
-
 if ($instanceid) {
-    $conditions = array('courseid' => $course->id, 'enrol' => 'guest', 'id' => $instanceid);
-    $instance = $DB->get_record('enrol', $conditions, '*', MUST_EXIST);
+    $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.
@@ -57,10 +59,10 @@ if ($instanceid) {
     $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_guest\enrol_guest_edit_form(null, array($instance, $plugin));
-$mform->set_data($instance);
+$mform = new enrol_instance_edit_form(null, array($instance, $plugin, $context, $type));
 
 if ($mform->is_cancelled()) {
     redirect($return);
@@ -68,22 +70,25 @@ if ($mform->is_cancelled()) {
 } else if ($data = $mform->get_data()) {
 
     if ($instance->id) {
-        $reset = ($instance->status != $data->status);
+        $reset = false;
+        if (isset($data->status)) {
+            $reset = ($instance->status != $data->status);
+        }
+
+        foreach ($data as $key => $value) {
+            $instance->$key = $value;
+        }
 
-        $instance->status         = $data->status;
-        $instance->password       = $data->password;
         $instance->timemodified   = time();
-        $DB->update_record('enrol', $instance);
+
+        $plugin->update_instance($instance, $data);
 
         if ($reset) {
             $context->mark_dirty();
         }
 
-        \core\event\enrol_instance_updated::create_from_record($instance)->trigger();
     } else {
-        $fields = array(
-            'status'          => $data->status,
-            'password'        => $data->password);
+        $fields = (array) $data;
         $plugin->add_instance($course, $fields);
     }
 
@@ -91,9 +96,9 @@ if ($mform->is_cancelled()) {
 }
 
 $PAGE->set_heading($course->fullname);
-$PAGE->set_title(get_string('pluginname', 'enrol_guest'));
+$PAGE->set_title(get_string('pluginname', 'enrol_' . $type));
 
 echo $OUTPUT->header();
-echo $OUTPUT->heading(get_string('pluginname', 'enrol_guest'));
+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 (file)
index 0000000..728a7e8
--- /dev/null
@@ -0,0 +1,87 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * 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/guest/classes/enrol_guest_edit_form.php b/enrol/guest/classes/enrol_guest_edit_form.php
deleted file mode 100644 (file)
index 4eb6ef1..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * Guest access plugin.
- *
- * Adds new instance of enrol_guest to specified course
- * or edits current instance.
- *
- * @package    enrol_guest
- * @copyright  2015 Andrew Hancox <andrewdchancox@googlemail.com>
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-namespace enrol_guest;
-use moodleform;
-
-defined('MOODLE_INTERNAL') || die();
-
-require_once($CFG->libdir.'/formslib.php');
-
-/**
- * Class enrol_guest_edit_form
- * @copyright  2015 Andrew Hancox <andrewdchancox@googlemail.com>
- * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class enrol_guest_edit_form extends moodleform {
-    /**
-     * Form definition
-     */
-    public function definition() {
-
-        $mform = $this->_form;
-
-        list($instance, $plugin) = $this->_customdata;
-
-        $mform->addElement('header', 'header', get_string('pluginname', 'enrol_guest'));
-
-        $options = array(ENROL_INSTANCE_ENABLED  => get_string('yes'),
-                         ENROL_INSTANCE_DISABLED => get_string('no'));
-        $mform->addElement('select', 'status', get_string('status', 'enrol_guest'), $options);
-        $mform->addHelpButton('status', 'status', 'enrol_guest');
-        $mform->setDefault('status', $plugin->get_config('status'));
-        $mform->setAdvanced('status', $plugin->get_config('status_adv'));
-
-        $mform->addElement('passwordunmask', 'password', get_string('password', 'enrol_guest'));
-        $mform->addHelpButton('password', 'password', 'enrol_guest');
-
-        // If we have a new instance and the password is required - make sure it is set. For existing
-        // instances we do not force the password to be required as it may have been set to empty before
-        // the password was required. We check in the validation function whether this check is required
-        // for existing instances.
-        if (empty($instance->id) && $plugin->get_config('requirepassword')) {
-            $mform->addRule('password', get_string('required'), 'required', null);
-        }
-
-        $mform->addElement('hidden', 'id');
-        $mform->setType('id', PARAM_INT);
-        $mform->addElement('hidden', 'courseid');
-        $mform->setType('courseid', PARAM_INT);
-
-        $this->add_action_buttons(true, ($instance->id ? null : get_string('addinstance', 'enrol')));
-    }
-
-    /**
-     * Form validation
-     *
-     * @param array $data
-     * @param array $files
-     * @return array
-     */
-    public function validation($data, $files) {
-        $errors = parent::validation($data, $files);
-
-        list($instance, $plugin) = $this->_customdata;
-        $checkpassword = false;
-
-        if ($data['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 && 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;
-                }
-            }
-        }
-
-        return $errors;
-    }
-}
index 0c69877..696ae6b 100644 (file)
@@ -84,51 +84,6 @@ class enrol_guest_plugin extends enrol_plugin {
         return;
     }
 
-    /**
-     * Sets up navigation entries.
-     *
-     * @param stdClass $instancesnode
-     * @param stdClass $instance
-     * @return void
-     * @throws coding_exception
-     */
-    public function add_course_navigation($instancesnode, stdClass $instance) {
-        if ($instance->enrol !== 'guest') {
-             throw new coding_exception('Invalid enrol instance type!');
-        }
-
-        $context = context_course::instance($instance->courseid);
-        if (has_capability('enrol/guest:config', $context)) {
-            $managelink = new moodle_url('/enrol/guest/edit.php', array('courseid' => $instance->courseid, 'id' => $instance->id));
-            $instancesnode->add($this->get_instance_name($instance), $managelink, navigation_node::TYPE_SETTING);
-        }
-    }
-
-    /**
-     * Returns edit icons for the page with list of instances
-     * @param stdClass $instance
-     * @return array
-     * @throws coding_exception
-     */
-    public function get_action_icons(stdClass $instance) {
-        global $OUTPUT;
-
-        if ($instance->enrol !== 'guest') {
-            throw new coding_exception('invalid enrol instance!');
-        }
-        $context = context_course::instance($instance->courseid);
-
-        $icons = array();
-
-        if (has_capability('enrol/guest:config', $context)) {
-            $editlink = new moodle_url("/enrol/guest/edit.php", array('courseid' => $instance->courseid, 'id' => $instance->id));
-            $icons[] = $OUTPUT->action_icon($editlink, new pix_icon('t/edit', get_string('edit'), 'core',
-                array('class' => 'iconsmall')));
-        }
-
-        return $icons;
-    }
-
     /**
      * Attempt to automatically gain temporary guest access to course,
      * calling code has to make sure the plugin and instance are active.
@@ -161,24 +116,24 @@ class enrol_guest_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 current user can add a new instance of enrolment plugin in course.
      * @param int $courseid
-     * @return moodle_url page url
+     * @return boolean
      */
-    public function get_newinstance_link($courseid) {
+    public function can_add_instance($courseid) {
         global $DB;
 
         $context = context_course::instance($courseid, MUST_EXIST);
 
         if (!has_capability('moodle/course:enrolconfig', $context) or !has_capability('enrol/guest:config', $context)) {
-            return NULL;
+            return false;
         }
 
         if ($DB->record_exists('enrol', array('courseid'=>$courseid, 'enrol'=>'guest'))) {
-            return NULL;
+            return false;
         }
 
-        return new moodle_url('/enrol/guest/edit.php', array('courseid' => $courseid));
+        return true;
     }
 
     /**
@@ -420,4 +375,108 @@ class enrol_guest_plugin extends enrol_plugin {
         }
         return $instanceinfo;
     }
+
+    /**
+     * 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;
+    }
+
+    /**
+     * 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;
+
+        $options = $this->get_status_options();
+        $mform->addElement('select', 'status', get_string('status', 'enrol_guest'), $options);
+        $mform->addHelpButton('status', 'status', 'enrol_guest');
+        $mform->setDefault('status', $this->get_config('status'));
+        $mform->setAdvanced('status', $this->get_config('status_adv'));
+
+        $mform->addElement('passwordunmask', 'password', get_string('password', 'enrol_guest'));
+        $mform->addHelpButton('password', 'password', 'enrol_guest');
+
+        // If we have a new instance and the password is required - make sure it is set. For existing
+        // instances we do not force the password to be required as it may have been set to empty before
+        // the password was required. We check in the validation function whether this check is required
+        // for existing instances.
+        if (empty($instance->id) && $this->get_config('requirepassword')) {
+            $mform->addRule('password', get_string('required'), 'required', null);
+        }
+    }
+
+    /**
+     * 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 ($data['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 && 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;
+                }
+            }
+        }
+
+        $validstatus = array_keys($this->get_status_options());
+        $tovalidate = array(
+            'status' => $validstatus
+        );
+        $typeerrors = $this->validate_param_types($data, $tovalidate);
+        $errors = array_merge($errors, $typeerrors);
+
+        return $errors;
+    }
+
+
 }
index 2fecf89..b1757a7 100644 (file)
@@ -71,4 +71,4 @@ class enrol_guest_enrol_form extends moodleform {
 
         return $errors;
     }
-}
\ No newline at end of file
+}
index ec95e75..52b5142 100644 (file)
@@ -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 (file)
index 27e1de7..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * 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 (file)
index bfc09a7..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * 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;
-    }
-}
index b50e3cc..445b769 100644 (file)
@@ -78,24 +78,18 @@ class enrol_manual_plugin extends enrol_plugin {
     }
 
     /**
-     * Returns enrolment instance manage link.
+     * Return true if we can add a new instance to this course.
      *
-     * By defaults looks for manage.php file and tests for manage capability.
-     *
-     * @param navigation_node $instancesnode
-     * @param stdClass $instance
-     * @return moodle_url;
+     * @param int $courseid
+     * @return boolean
      */
-    public function add_course_navigation($instancesnode, stdClass $instance) {
-        if ($instance->enrol !== 'manual') {
-             throw new coding_exception('Invalid enrol instance type!');
-        }
-
-        $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));
-            $instancesnode->add($this->get_instance_name($instance), $managelink, navigation_node::TYPE_SETTING);
+    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;
     }
 
     /**
@@ -106,47 +100,18 @@ class enrol_manual_plugin extends enrol_plugin {
     public function get_action_icons(stdClass $instance) {
         global $OUTPUT;
 
-        if ($instance->enrol !== 'manual') {
-            throw new coding_exception('invalid enrol instance!');
-        }
         $context = context_course::instance($instance->courseid);
 
         $icons = array();
-
         if (has_capability('enrol/manual:enrol', $context) or has_capability('enrol/manual:unenrol', $context)) {
             $managelink = new moodle_url("/enrol/manual/manage.php", array('enrolid'=>$instance->id));
             $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));
-            $icons[] = $OUTPUT->action_icon($editlink, new pix_icon('t/edit', get_string('edit'), 'core',
-                    array('class' => 'iconsmall')));
-        }
+        $icons = $icons + parent::get_action_icons($instance);
 
         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 +153,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 +595,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 (file)
index aea6adb..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * 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 (file)
index c28a762..0000000
+++ /dev/null
@@ -1,152 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * 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;
-    }
-}
-
index 538fd1f..5659d9f 100644 (file)
@@ -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.
      *
@@ -254,28 +452,4 @@ class enrol_meta_plugin extends enrol_plugin {
         return;
     }
 
-    /**
-     * Returns edit icons for the page with list of instances.
-     * @param stdClass $instance
-     * @return array
-     */
-    public function get_action_icons(stdClass $instance) {
-        global $OUTPUT;
-
-        if ($instance->enrol !== 'meta') {
-            throw new coding_exception('invalid enrol instance!');
-        }
-        $context = context_course::instance($instance->courseid);
-
-        $icons = array();
-
-        if (has_capability('enrol/meta:config', $context)) {
-            $editlink = new moodle_url("/enrol/meta/addinstance.php",
-                array('id' => $instance->courseid, 'enrolid' => $instance->id));
-            $icons[] = $OUTPUT->action_icon($editlink, new pix_icon('t/edit', get_string('edit'), 'core',
-                array('class' => 'iconsmall')));
-        }
-
-        return $icons;
-    }
 }
index 6566759..b3ca882 100644 (file)
@@ -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"
index 9f0fb8a..5f292e5 100644 (file)
@@ -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 (file)
index 9678b40..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * Adds new instance of enrol_mnet into the specified course
- *
- * @package    enrol_mnet
- * @copyright  2010 David Mudrak <david@moodle.com>
- * @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 (file)
index 436e92b..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * Form to add an instance of enrol_mnet plugin
- *
- * @package    enrol_mnet
- * @copyright  2010 David Mudrak <david@moodle.com>
- * @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;
-    }
-}
index 419228b..bc33fe4 100644 (file)
@@ -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 (file)
index 9c0541a..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * 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 (file)
index 8aa8059..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * 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;
-    }
-}
index 845e2e4..87ecfe5 100644 (file)
@@ -97,61 +97,54 @@ class enrol_paypal_plugin extends enrol_plugin {
     }
 
     /**
-     * Sets up navigation entries.
-     *
-     * @param object $instance
-     * @return void
+     * Returns true if the user can add a new instance in this course.
+     * @param int $courseid
+     * @return boolean
      */
-    public function add_course_navigation($instancesnode, stdClass $instance) {
-        if ($instance->enrol !== 'paypal') {
-             throw new coding_exception('Invalid enrol instance type!');
-        }
+    public function can_add_instance($courseid) {
+        $context = context_course::instance($courseid, MUST_EXIST);
 
-        $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));
-            $instancesnode->add($this->get_instance_name($instance), $managelink, navigation_node::TYPE_SETTING);
+        if (!has_capability('moodle/course:enrolconfig', $context) or !has_capability('enrol/paypal:config', $context)) {
+            return false;
         }
+
+        // multiple instances supported - different cost for different roles
+        return true;
     }
 
     /**
-     * Returns edit icons for the page with list of instances
-     * @param stdClass $instance
-     * @return array
+     * We are a good plugin and don't invent our own UI/validation code path.
+     *
+     * @return boolean
      */
-    public function get_action_icons(stdClass $instance) {
-        global $OUTPUT;
-
-        if ($instance->enrol !== 'paypal') {
-            throw new coding_exception('invalid enrol instance!');
-        }
-        $context = context_course::instance($instance->courseid);
-
-        $icons = array();
+    public function use_standard_editing_ui() {
+        return true;
+    }
 
-        if (has_capability('enrol/paypal:config', $context)) {
-            $editlink = new moodle_url("/enrol/paypal/edit.php", array('courseid'=>$instance->courseid, 'id'=>$instance->id));
-            $icons[] = $OUTPUT->action_icon($editlink, new pix_icon('t/edit', get_string('edit'), 'core',
-                    array('class' => 'iconsmall')));
+    /**
+     * 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 $icons;
+        return parent::add_instance($course, $fields);
     }
 
     /**
-     * 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
+     * Update instance of enrol plugin.
+     * @param stdClass $instance
+     * @param stdClass $data modified instance fields
+     * @return boolean
      */
-    public function get_newinstance_link($courseid) {
-        $context = context_course::instance($courseid, MUST_EXIST);
-
-        if (!has_capability('moodle/course:enrolconfig', $context) or !has_capability('enrol/paypal:config', $context)) {
-            return NULL;
+    public function update_instance($instance, $data) {
+        if ($data) {
+            $data->cost = unformat_float($data->cost);
         }
-
-        // multiple instances supported - different cost for different roles
-        return new moodle_url('/enrol/paypal/edit.php', array('courseid'=>$courseid));
+        return parent::update_instance($instance, $data);
     }
 
     /**
@@ -312,6 +305,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 (file)
index f429c39..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * 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 (file)
index af10050..0000000
+++ /dev/null
@@ -1,223 +0,0 @@
-<?php
-// This file is part of Moodle - http://moodle.org/
-//
-// Moodle is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Moodle is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
-
-/**
- * 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;
-    }
-}
index fef3f6f..7b2827e 100644 (file)
@@ -118,61 +118,19 @@ class enrol_self_plugin extends enrol_plugin {
     }
 
     /**
-     * Sets up navigation entries.
+     * Return true if we can add a new instance to this course.
      *
-     * @param stdClass $instancesnode
-     * @param stdClass $instance
-     * @return void
-     */
-    public function add_course_navigation($instancesnode, stdClass $instance) {
-        if ($instance->enrol !== 'self') {
-             throw new coding_exception('Invalid enrol instance type!');
-        }
-
-        $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));
-            $instancesnode->add($this->get_instance_name($instance), $managelink, navigation_node::TYPE_SETTING);
-        }
-    }
-
-    /**
-     * Returns edit icons for the page with list of instances
-     * @param stdClass $instance
-     * @return array
-     */
-    public function get_action_icons(stdClass $instance) {
-        global $OUTPUT;
-
-        if ($instance->enrol !== 'self') {
-            throw new coding_exception('invalid enrol instance!');
-        }
-        $context = context_course::instance($instance->courseid);
-
-        $icons = array();
-
-        if (has_capability('enrol/self:config', $context)) {
-            $editlink = new moodle_url("/enrol/self/edit.php", array('courseid'=>$instance->courseid, 'id'=>$instance->id));
-            $icons[] = $OUTPUT->action_icon($editlink, new pix_icon('t/edit', get_string('edit'), 'core',
-                array('class' => 'iconsmall')));
-        }
-
-        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
+     * @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 +194,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 +666,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;
+    }
 }
index 38a41e1..1fb1729 100644 (file)
@@ -1,5 +1,10 @@
 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. They can
+then rely on the default implementation of get_action_icons and get_course_navigation. 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.
index 426c9a2..764dc9e 100644 (file)
@@ -1539,6 +1539,44 @@ 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);
+    }
+
+    /**
+     * Return whether or not, given the current state, it is possible to edit an instance
+     * of this enrolment plugin in the course. Used by the standard editing UI
+     * to generate a link to the edit instance form if editing is allowed.
+     *
+     * @param stdClass $instance
+     * @return boolean
+     */
+    public function can_edit_instance($instance) {
+        $context = context_course::instance($instance->courseid);
+
+        return has_capability('enrol/' . $instance->enrol . ':config', $context);
+    }
+
     /**
      * Returns link to page which may be used to add new instance of enrolment plugin in course.
      * @param int $courseid
@@ -1645,6 +1683,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 +1779,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.
@@ -1825,7 +1924,15 @@ abstract class enrol_plugin {
      * @return void
      */
     public function add_course_navigation($instancesnode, stdClass $instance) {
-        // usually adds manage users
+        if ($this->use_standard_editing_ui()) {
+            $context = context_course::instance($instance->courseid);
+            $cap = 'enrol/' . $instance->enrol . ':config';
+            if (has_capability($cap, $context)) {
+                $linkparams = array('courseid' => $instance->courseid, 'id' => $instance->id, 'type' => $instance->enrol);
+                $managelink = new moodle_url('/enrol/editinstance.php', $linkparams);
+                $instancesnode->add($this->get_instance_name($instance), $managelink, navigation_node::TYPE_SETTING);
+            }
+        }
     }
 
     /**
@@ -1834,7 +1941,16 @@ abstract class enrol_plugin {
      * @return array
      */
     public function get_action_icons(stdClass $instance) {
-        return array();
+        global $OUTPUT;
+
+        $icons = array();
+        if ($this->use_standard_editing_ui()) {
+            $linkparams = array('courseid' => $instance->courseid, 'id' => $instance->id, 'type' => $instance->enrol);
+            $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')));
+        }
+        return $icons;
     }
 
     /**
@@ -2359,4 +2475,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;
+    }
 }