Note:

If you want to create a new page for developers, you should create it on the Moodle Developer Resource site.

Enrolment plugins: Difference between revisions

From MoodleDocs
(38 intermediate revisions by 9 users not shown)
Line 1: Line 1:
==How to write an Enrolment plugin in Moodle 1.9==
Since Moodle 2.0 all enrolment plugins must extend [https://github.com/moodle/moodle/blob/master/lib/enrollib.php enrol_plugin] base class which is defined at the end of lib/enrollib.php. This base class contains all standard methods together with developer documentation.


Create a new directory called <code>/enrol/</code>'''<code>PLUGINNAME</code>'''. Within this directory, create a file <code>/enrol/</code>'''<code>PLUGINNAME</code>'''<code>/enrol.php</code> which contains the declaration for a class called <code>enrolment_plugin_</code>'''<code>PLUGINNAME</code>'''.
Course enrolment information is stored in tables <code>enrol</code> and <code>user_enrolments</code> and optionally other custom database tables defined by individual enrolment plugins. Each plugin has complete total over own instance record and user enrolments, by defaults user enrolments are protected and can not be modified manually by teachers.


<code php>
Enrolment gives users following privileges:
class enrolment_plugin_PLUGINNAME {
* User with active enrolment may enter course, other users need either temporary guest access right or moodle/course:view capability.
    // Functions go here
* "My courses" shows list of active enrolments for current user.
    // ...
* Course participation - some activities restrict participation to enrolled users only. The behaviour is defined independently by each activity, for example only enrolled users with submit capability may submit assignments, the capability alone is not enough.
}
* Only enrolled users may be members of groups.
</code>
* Gradebook tracks grades of all enrolled users, visibility of grades is controlled by role membership.


=== Mandatory functions ===
Enrolments and role assignments are now separate concepts, you may be enrolled and not have any role and you may have a role in course and not be enrolled. Roles at course context level and below may be controlled by enrolment plugins.


Your enrolment plugin class is required to define these two functions, which print and process a configuration form.
==User enrolment process==


<code php>
Manual enrolment plugins are the simplest way to handle user enrolments. This simplest plugin is enrol_manual, users with necessary permissions may enrol or unenrol users manually. enrol_flatfile plugin allows automation of enrolment and unenrolment actions.
    /**
    * Prints out the configuration form for this plugin. All we need
    * to provide is the form fields. The <form> tags and submit button will
    * be provided for us by Moodle.
    *
    * @param object $formdata Equal to the global $CFG variable, or if
    *      process_config() returned false, the form contents
    * @return void
    */
    public function config_form( $formdata ){
        return;
    }


    /**
Fully automatic plugins are configured at the system level, they synchronise user enrolments with information stored in external systems (ex.: enrol_ldap, enrol_database and enrol_category). Some non-interactive plugins may require configuration of enrolment instances (ex.: enrol_cohort and enrol_meta).
    * Process the data from the configuration form.
    *
    * @param object $formdata
    * @return boolean True if configuration was successful, False if the user
    *      should be kicked back to config_form() again.
    */
    public function process_config( $formdata ){
        return true;
    }
</code>


=== Automated enrolment ===
Interactive enrolment plugins require user interaction during enrolment (ex.: enrol_self and enrol_paypal). These plugins need to override <code>enrol_plugin::show_enrolme_link()</code>, <code>enrol_plugin::enrol_page_hook()</code> and to implement adding and editing of enrol instance.


To handle automated enrolment, your function may contain a <code>setup_enrolments($user)</code> function. This will be called each time a user logs in, to allow the plugin to make any changes to their enrolments.
==Enrolment expiration and suspending==
User has active enrolment if all following conditions are met:
* user has record in <code>user_enrolments</code> table,
* user enrolment already started,
* user enrolment is not past timeend,
* user enrolment has active status,
* enrol instance has active status in <code>enrol</code> table,
* enrol plugin is enabled.


<code php>
Most synchronisation plugins include a setting called ''External unenrol action''. It is used to decide what happens when previously enrolled user is not supposed to be enrolled any more. Synchronisation is usually executed from cli/sync.php or as part of standard cron.
    /**
    * OPTIONAL: Set up non-interactive enrolments for user. This is the most
    * important function for non-interactive enrolment plugins (such as LDAP
    * and external database). It is called each time a user logs in.
    *
    * @param object $user
    * @return void
    */
    public function setup_enrolments( $user ){
        // Note that when you're setting up role assignments, you should use the
        // mdl_role_assignment.enrol column to indicate which role assignments
        // are from this plugin.
        role_assign($someroleid, $user->id, null, $somecontextid, 0, 0, 0, 'PLUGINNAME');
        role_unassign($someroleid, $user->id, null, $somecontextid, 'PLUGINNAME');
       
        return;
    }
</code>


=== Interactive enrolment ===
Time based expiration was implemented in Moodle 2.5. Plugins that set timeend in user_enrolments table may want to specify expiration action and optional expiration notification, see <code>enrol_plugin::process_expirations()</code> and <code>enrol_plugin::send_expiry_notifications()</code>.


Your plugin can handle interactive enrolment (i.e. self-enrolment) by implementing these four functions. (See the manual enrolment plugin <code>enrol/manual/enrol.php</code> for an example that uses all of these.)
==Manual enrolment modifications==


<code php>
The standard user enrolment UI does not use the following methods directly, so developers need to describe all possible UI enrolments actions via <code>enrol_plugin::get_user_enrolment_actions()</code>. It is very important to obey these restrictions in all externallib methods!
    /**
    * OPTIONAL: Prints the entry form/page for interactive enrolment into a course.
    *
    * This is only called from course/enrol.php. Most plugins will probably
    * override this to print payment forms, etc, or even just a notice to say
    * that manual enrollment is disabled.
    *
    * @param object $course
    * @return void
    */
    public function print_entry(){
    }


    /**
The following methods describe the allowed modifications for each enrolment instance:
    * OPTIONAL: The other half to print_entry(), this checks the form data.
    *
    * This function checks that the user has completed the task on the enrollment
    * entry page and enrolls them.
    *
    * @param object $form
    * @param object $course
    * @return void
    */
    public function check_entry( $form, $course ){
        // some logic
        // some role_assign();
    }


    /**
* <code>enrol_plugin::roles_protected()</code> - True means that protected roles (nonempty component+itemid) cannot be modified by any other plugin. Return false if you want to allow users to remove all roles assigned by this plugin. Since Moodle 2.5 it is allowed to assign roles with component+itemid even if roles are not protected.
    * OPTIONAL: Check if the given enrolment key matches a group enrolment key for
* <code>enrol_plugin::allow_enrol()</code> - True means other code may call <code>enrol_plugin::enrol_user()</code>, false means only plugin may enrol users. Each plugin is responsible for implementing its own UI for enrolment. See <code>enrol_plugin::get_manual_enrol_link()</code>.
    * the given course.
* <code>enrol_plugin::allow_unenrol()</code> and <code>enrol_plugin::allow_unenrol_user()</code> - Is other code allowed to unenrol everybody from one instance or one specific user? True is required for course reset and manual user unenrolment.
    *
* <code>enrol_plugin:allow_manage()</code> - Return true if plugin allows manual modification of user enrolments from other code. False is usually returned from plugins that synchronise data with external systems, otherwise the manual changes would be reverted immediately upon synchronisation.
    * @param int $courseid
    * @param string $enrolmentkey
    * @return mixed The group id of the group which the key matches, or false
    *      if it matches none
    */
    public function check_group_entry( $courseid, $password ){
        // some logic
        if ( $itlooksgood ){
            return $groupid;
        } else {
            return false;
        }
    }


    /**
    * OPTIONAL: Return a string with icons that give enrolment information
    * for this course.
    *
    * @param object $course
    * @return string
    */
    public function get_access_icons( $course ){
        return 'put icons here';
    }
</code>
=== Cron ===


Your plugin can perform cron tasks if it contains a <code>cron()</code> function:
{{Moodle 3.4}}
From Moodle 3.4 onwards, enrolment plugins don't have to override '''''enrol_plugin::get_user_enrolment_actions()''''', unless your enrolment plugin provides other enrolment actions in addition to editing enrolment and user unenrolment.


To support editing enrolment for your plugin, simply override ''enrol_plugin::allow_manage()'' to return true. To support unenrolment, be sure to override ''enrol_plugin::allow_unenrol_user()'' or ''enrol_plugin::allow_unenrol()'' to return true. For example:
<code php>
<code php>
     /**
class enrol_my_awesome_plugin extends enrol_plugin {
    * OPTIONAL: If this function exists, it will be called each time
     public function allow_manage(stdClass $instance) {
    * admin/cron.php runs. It takes no arguments and returns no values,
        // Simply making this function return true will render the edit enrolment action in the participants list if the user has the 'enrol/pluginname:manage' capability.
    * but anything written to $this->log will be printed to the cron output.
        return true;
    *
    }
    * @return void
     public function allow_unenrol(stdClass $instance) {
    */
         // Simply making this function return true will render the unenrolment action in the participants list if the user has the 'enrol/pluginname:unenrol' capability.
     public function cron(){
        return true;
         $this->log = 'Print this in the cron log!';
     }
     }
}
</code>
</code>


=== Database ===
Should your enrolment plugin provide other enrolment actions aside from editing enrolment and unenrolment, you may override ''enrol_plugin::get_user_enrolment_actions()''. For example:
<code php>
public function get_user_enrolment_actions(course_enrolment_manager $manager, $ue) {
    // Get the standard user enrolment actions.
    $actions = parent::get_user_enrolment_actions();


If your plugin needs to have its own Moodle database tables, create a file called <code>enrol/PLUGINNAME/version.php</code> like this:
    // Add your custom user enrolment actions here...
    $actions[] = ...;
    ...
    return $actions;
}
</code>


<code php><?php
==Standard capabilities==
$plugin->version = 2010091600; // Version of your plugin
$plugin->requires = 2007101000; // Required Moodle version (from /version.php)
?></code>


Then create a directory <code>enrol/PLUGINNAME/db</code>, and use the [[XMLDB editor]] to set up your tables.
* '''enrol/xxx:enrol''' - Must be defined when <code>enrol_plugin::allow_enrol()</code> returns true.
* '''enrol/xxx:unenrol''' - Must be implemented when <code>enrol_plugin::allow_unenrol()</code> or <code>enrol_plugin::allow_unenrol_user()</code> returns true.
* '''enrol/xxx:manage''' - Must be implemented when <code>enrol_plugin::allow_manage()</code> returns true.
* '''enrol/xxx:unenrolself''' - Usually implemented when plugin support self-unenrolment.
* '''enrol/xxx:config''' - Implemented when plugin allows user to modify instance properties. Automatic synchronisation plugins do not usually need this capability.


==Testing paypal using the paypal developer sandbox==
==Standard Editing UI==


=== For moodle 1.4 - 1.8 ===
In Moodle 3.1 changes were made to the enrolment plugin base class so that plugins do not have to define their own add/edit interface. In order to use this new logic, the enrolment plugin class must override and return true from this function:


If you follow these steps, you can test paypal payments using the paypal developer sandbox instead of the real paypal site.  No money is actually charged to any account.  All other actions are the same as if you were using the real paypal site.
<code>
* create a paypal developer account at https://developer.paypal.com/cgi-bin/devscr?cmd=_home
    /**                                                                                                                           
* change the address being used to send data to paypal to use the sandbox. in enrol/paypal/enrol.html:
    * We are a good plugin and don't invent our own UI/validation code path.                                                      
** change the form post action to be https://www.sandbox.paypal.com/cgi-bin/webscr instead of https://www.paypal.com/cgi-bin/webscr
    *                                                                                                                            
* change the address that is used to check the acknowledgment from paypal.  in enrol/paypal/ipn.php, change:
    * @return boolean                                                                                                             
** $fp = fsockopen ('www.paypal.com', 80, $errno, $errstr, 30);
    */                                                                                                                            
* to
    public function use_standard_editing_ui() {                                                                                   
** $fp = fsockopen ('www.sandbox.paypal.com', 80, $errno, $errstr, 30);
        return true;                                                                                                              
* create a couple of user accounts in the paypal sandbox and test enrolling in a course that requires payment (note that you need to be logged into the paypal sandbox while doing this testing)
    }
* under the "business" sandbox account you created, log in, go to "Profile", "Instant Payment Notification", and enter the full web-visible HTTPS URL to ../enrol/paypal/ipn.php. Failing to do this is a common mistake, and the cause of most headaches with this plugin.
</code>


=== For moodle 1.8.2 - 1.9.x ===
This means that the following functions from the plugin will be called to build the add/edit form, perform validation of the data and add standard navigation links to the manage enrolments page and course navigation.


The above changes to the code were made part of the release starting with version 1.8.2
<code>
    /**                                                                                                                           
    * 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) {
</code>


If you follow these steps, you can test paypal payments using the paypal developer sandbox instead of the real paypal site.  No money is actually charged to any account.  All other actions are the same as if you were using the real paypal site.
<code>
* create a paypal developer account at https://developer.paypal.com/cgi-bin/devscr?cmd=_home
    /**                                                                                                                           
* create a couple of user accounts in the paypal sandbox and test enrolling in a course that requires payment (note that you need to be logged into the paypal sandbox while doing this testing)
    * Perform custom validation of the data used to edit the instance.                                                            
* under the "business" sandbox account you created, log in, go to "Profile", "Instant Payment Notification", and enter the full web-visible HTTPS URL to ../enrol/paypal/ipn.php. Failing to do this is a common mistake, and the cause of most headaches with this plugin.
    *                                                                                                                            
* add the following line to config.php located in the root directory of your installation (where you installed Moodle).
    * @param array $data array of ("fieldname"=>value) of submitted data                                                         
** $CFG->usepaypalsandbox = 'TRUE';
    * @param array $files array of uploaded files "element_name"=>tmp_file_path                                                   
* Add the business account email address from "business" account you created to the paypal module settings (in 1.9.x - Site Administration>Courses>Enrolments>Paypal>Edit)
    * @param object $instance The instance loaded from the DB                                                                     
* You should be ready to test
    * @param context $context The context of the instance we are editing                                                         
* When finished be sure to remove the line that was added to config.php in your root directory.
    * @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) {
</code>


=== Note about Paypal Sandbox ===
<code>
 
    /**                                                                                                                            
Only implement these changes if the above is not working and Moodle is returning the "...Unfortunately your payment..." message after returning from Paypal Sandbox.
    * Return true if we can add a new instance to this course.                                                                    
 
    *                                                                                                                             
At the time of this writing (14 June 2008) some changes are necessary to test successfully in the Paypal Sandbox. Details can be found [http://www.pdncommunity.com/pdn/board/message?board.id=sandbox&view=by_date_ascending&message.id=9802#M9802 here]. This could change at any time at which point this may become unnecessary. For now do the following (only tested in 1.9.x so far):
    * @param int $courseid                                                                                                       
 
    * @return boolean                                                                                                             
* Locate ipn.php in your installation on your server by migrating to to ../enrol/paypal/ipn.php
    */                                                                                                                            
* Create a backup copy of ipn.php and give it a name something like ipn.php-backup
    public function can_add_instance($courseid) {                                                                                 
* Return to ipn.php and locate the following code :<br />
</code>
$header = '';<br />
$header .= "POST /cgi-bin/webscr HTTP/1.0\r\n";<br />
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";<br />
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";<br />
$paypaladdr = empty($CFG->usepaypalsandbox) ? 'www.paypal.com' : 'www.sandbox.paypal.com';<br />
$fp = fsockopen ($paypaladdr, 80, $errno, $errstr, 30);
* Change that code to :<br />
$header = '';<br />
$header .= "POST /cgi-bin/webscr HTTP/1.0\r\n";<br />
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";<br />
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";<br />
$paypaladdr = empty($CFG->usepaypalsandbox) ? 'www.paypal.com' : 'ssl://www.sandbox.paypal.com';<br />
$fp = fsockopen ($paypaladdr, 443, $errno, $errstr, 30);<br />
* Try the course purchase again.
 
If the above still is not working you will need to seek help in the [http://moodle.org/mod/forum/view.php?id=2981 Enrolment Plugins] Forum.
 
==Enrolment plugins 1.7==
 
===Background===
# isteacher(), isstudent(), isadmin(), iscoursecreator() are all deprecated and should be replaced with checks on has_capability instead.
# enrol_student() and add_teacher() are obsolete, so use the generic role_assign() or the convenience function for "students" called enrol_into_course() instead.
# unenrol_student() and remove_teacher() are obsolete, so use the generic role_unassign() instead.
# All the roles have a "shortname", so by default we can refer to them using "teacher", "student", "editingteacher" etc.  Note that new roles may have different names.  Enrolment plugins can use these to map outside data onto the inside roles without needing to know internal role id numbers.  For example, it would be really handy for the flatfile plugin to refer to roles directly like this.
# Each plugin used to implement get_student_courses() and get_teacher_courses() for use at login time.  These now need to be converted to one new function called $enrol->setup_enrolments($user) which looks up sets all enrolments for a given user (using role_assign and role_unassign).
# All the session arrays like $USER->student[] and $USER->teacher[] are gone and should not be relied on.  You can check what roles a user already has by calling get_user_roles() on that course context.
 
===What's been done===
 
#enrol/manual has been converted to use the new functions
#enrol/imsenterprise has been converted - testing needed though
 
===What still needs to be done===


#enrol/authorize
In future - only plugins using this standard ui code path will provide a useful API for e.g. tool_uploadcourse to add/edit enrolment instances with complete validation of the submitted data.
#enrol/database
#enrol/flatfile
#enrol/ldap
#enrol/paypal


==See also==
==See also==
*[[Enrolment plugins|Enrolment plugins (administrator)]]
* [[Enrolment API]]
*Using Moodle [http://moodle.org/mod/forum/view.php?id=2981 Enrolment Plugins] forum
* [[Enrolment usage overview]]
* [[New enrolments in 2.0]]
* Using Moodle [http://moodle.org/mod/forum/view.php?id=2981 Enrolment Plugins] forum


[[Category:Enrolment plugins]]
[[Category:Enrolment]]
[[Category:Enrolment]]
[[Category:Plugins]]

Revision as of 06:34, 13 November 2017

Since Moodle 2.0 all enrolment plugins must extend enrol_plugin base class which is defined at the end of lib/enrollib.php. This base class contains all standard methods together with developer documentation.

Course enrolment information is stored in tables enrol and user_enrolments and optionally other custom database tables defined by individual enrolment plugins. Each plugin has complete total over own instance record and user enrolments, by defaults user enrolments are protected and can not be modified manually by teachers.

Enrolment gives users following privileges:

  • User with active enrolment may enter course, other users need either temporary guest access right or moodle/course:view capability.
  • "My courses" shows list of active enrolments for current user.
  • Course participation - some activities restrict participation to enrolled users only. The behaviour is defined independently by each activity, for example only enrolled users with submit capability may submit assignments, the capability alone is not enough.
  • Only enrolled users may be members of groups.
  • Gradebook tracks grades of all enrolled users, visibility of grades is controlled by role membership.

Enrolments and role assignments are now separate concepts, you may be enrolled and not have any role and you may have a role in course and not be enrolled. Roles at course context level and below may be controlled by enrolment plugins.

User enrolment process

Manual enrolment plugins are the simplest way to handle user enrolments. This simplest plugin is enrol_manual, users with necessary permissions may enrol or unenrol users manually. enrol_flatfile plugin allows automation of enrolment and unenrolment actions.

Fully automatic plugins are configured at the system level, they synchronise user enrolments with information stored in external systems (ex.: enrol_ldap, enrol_database and enrol_category). Some non-interactive plugins may require configuration of enrolment instances (ex.: enrol_cohort and enrol_meta).

Interactive enrolment plugins require user interaction during enrolment (ex.: enrol_self and enrol_paypal). These plugins need to override enrol_plugin::show_enrolme_link(), enrol_plugin::enrol_page_hook() and to implement adding and editing of enrol instance.

Enrolment expiration and suspending

User has active enrolment if all following conditions are met:

  • user has record in user_enrolments table,
  • user enrolment already started,
  • user enrolment is not past timeend,
  • user enrolment has active status,
  • enrol instance has active status in enrol table,
  • enrol plugin is enabled.

Most synchronisation plugins include a setting called External unenrol action. It is used to decide what happens when previously enrolled user is not supposed to be enrolled any more. Synchronisation is usually executed from cli/sync.php or as part of standard cron.

Time based expiration was implemented in Moodle 2.5. Plugins that set timeend in user_enrolments table may want to specify expiration action and optional expiration notification, see enrol_plugin::process_expirations() and enrol_plugin::send_expiry_notifications().

Manual enrolment modifications

The standard user enrolment UI does not use the following methods directly, so developers need to describe all possible UI enrolments actions via enrol_plugin::get_user_enrolment_actions(). It is very important to obey these restrictions in all externallib methods!

The following methods describe the allowed modifications for each enrolment instance:

  • enrol_plugin::roles_protected() - True means that protected roles (nonempty component+itemid) cannot be modified by any other plugin. Return false if you want to allow users to remove all roles assigned by this plugin. Since Moodle 2.5 it is allowed to assign roles with component+itemid even if roles are not protected.
  • enrol_plugin::allow_enrol() - True means other code may call enrol_plugin::enrol_user(), false means only plugin may enrol users. Each plugin is responsible for implementing its own UI for enrolment. See enrol_plugin::get_manual_enrol_link().
  • enrol_plugin::allow_unenrol() and enrol_plugin::allow_unenrol_user() - Is other code allowed to unenrol everybody from one instance or one specific user? True is required for course reset and manual user unenrolment.
  • enrol_plugin:allow_manage() - Return true if plugin allows manual modification of user enrolments from other code. False is usually returned from plugins that synchronise data with external systems, otherwise the manual changes would be reverted immediately upon synchronisation.


Moodle 3.4

From Moodle 3.4 onwards, enrolment plugins don't have to override enrol_plugin::get_user_enrolment_actions(), unless your enrolment plugin provides other enrolment actions in addition to editing enrolment and user unenrolment.

To support editing enrolment for your plugin, simply override enrol_plugin::allow_manage() to return true. To support unenrolment, be sure to override enrol_plugin::allow_unenrol_user() or enrol_plugin::allow_unenrol() to return true. For example: class enrol_my_awesome_plugin extends enrol_plugin {

   public function allow_manage(stdClass $instance) {
       // Simply making this function return true will render the edit enrolment action in the participants list if the user has the 'enrol/pluginname:manage' capability.
       return true;
   }
   public function allow_unenrol(stdClass $instance) {
       // Simply making this function return true will render the unenrolment action in the participants list if the user has the 'enrol/pluginname:unenrol' capability.
       return true;
   }

}

Should your enrolment plugin provide other enrolment actions aside from editing enrolment and unenrolment, you may override enrol_plugin::get_user_enrolment_actions(). For example: public function get_user_enrolment_actions(course_enrolment_manager $manager, $ue) {

   // Get the standard user enrolment actions.
   $actions = parent::get_user_enrolment_actions();
   // Add your custom user enrolment actions here...
   $actions[] = ...;
   ...
   return $actions;

}

Standard capabilities

  • enrol/xxx:enrol - Must be defined when enrol_plugin::allow_enrol() returns true.
  • enrol/xxx:unenrol - Must be implemented when enrol_plugin::allow_unenrol() or enrol_plugin::allow_unenrol_user() returns true.
  • enrol/xxx:manage - Must be implemented when enrol_plugin::allow_manage() returns true.
  • enrol/xxx:unenrolself - Usually implemented when plugin support self-unenrolment.
  • enrol/xxx:config - Implemented when plugin allows user to modify instance properties. Automatic synchronisation plugins do not usually need this capability.

Standard Editing UI

In Moodle 3.1 changes were made to the enrolment plugin base class so that plugins do not have to define their own add/edit interface. In order to use this new logic, the enrolment plugin class must override and return true from this function:

   /**                                                                                                                            
    * 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;                                                                                                                
   }

This means that the following functions from the plugin will be called to build the add/edit form, perform validation of the data and add standard navigation links to the manage enrolments page and course navigation.

   /**                                                                                                                             
    * 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) {

   /**                                                                                                                             
    * 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) {

   /**                                                                                                                             
    * Return true if we can add a new instance to this course.                                                                     
    *                                                                                                                              
    * @param int $courseid                                                                                                         
    * @return boolean                                                                                                              
    */                                                                                                                             
   public function can_add_instance($courseid) {                                                                                   

In future - only plugins using this standard ui code path will provide a useful API for e.g. tool_uploadcourse to add/edit enrolment instances with complete validation of the submitted data.

See also