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
No edit summary
Line 1: Line 1:
==Enrolment plugins in Moodle 2.x==
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 available methods and developer documentation.
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 available methods and developer documentation.


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


Enrolment gives user following privileges:
Enrolment gives user following privileges:
* User with active enrolment may enter course, without enrolment user needs either temporary guest access right or moodle/course:view capability.
* User with active enrolment may enter course, without enrolment user needs either temporary guest access right or moodle/course:view capability.
* "My courses" shows list of active enrolments for current user
* "My courses" shows list of active enrolments for current user
* User participates in course - 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.
* 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.
* Only enrolled users may be members of groups.
 
* Gradebook tracks grades of all enrolled users.
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 context level and bellow may be linked to user enrolments.
 
===Creating new plugin===
====Create required files====
====Alter enrolment and role protection====
 
====Implement synchronisation or enrol form====
 
====Implement notifications====
 
====Implement backup/restore====
 
 
TODO... (skodak)
 
==Enrolment plugins in Moodle 1.9==
 
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>'''. Note that PLUGINNAME must be letters only as it is passed through PARAM_ALPHA.
 
<code php>
class enrolment_plugin_PLUGINNAME {
    // Functions go here
    // ...
}
</code>
 
=== Mandatory functions ===
 
Your enrolment plugin class is required to define these two functions, which print and process a configuration form.
 
<code php>
    /**
    * 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;
    }
 
    /**
    * 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>
 
=== Optional functions ===
 
==== Automated enrolment ====
 
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.
 
<code php>
    /**
    * 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 ====
 
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.)
 
<code php>
    /**
    * 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(){
    }
 
    /**
    * 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();
    }
 
    /**
    * OPTIONAL: Check if the given enrolment key matches a group enrolment key for
    * the given course.
    *
    * @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:
 
<code php>
    /**
    * OPTIONAL: If this function exists, it will be called each time
    * admin/cron.php runs. It takes no arguments and returns no values,
    * but anything written to $this->log will be printed to the cron output.
    *
    * @return void
    */
    public function cron(){
        $this->log = 'Print this in the cron log!';
    }
</code>
 
=== Language Strings ===
 
Create a lang directory and file under your plugin's directory, like this '''<code>enrol/PLUGINNAME/lang/en_utf8/enrol_PLUGINNAME.php</code>'''. Plugins are expected to provide at least these two strings:
 
<code php><?php
 
// The name of your plugin. Displayed on admin menus.
$string['enrolname'] = 'My plugin';
 
// Description of your plugin. Shown on the plugin's configuration screen.
$string['description'] = 'This is what my plugin does.';
 
?></code>
 
Those two strings will be accessed automatically by Moodle in various situations. You can (and should) of course include other [[Places to search for lang strings|language strings]] in your plugin's lang file(s). These can be accessed like normal language strings, using "enrol_PLUGINNAME" as the module name, e.g. <code>get_string('anotherstring', 'enrol_PLUGINNAME')</code>.
 
=== Database ===
 
If your plugin needs to have its own Moodle database tables, create a file called <code>enrol/PLUGINNAME/version.php</code> like this:
 
<code php><?php
$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.
 
==Testing paypal using the paypal developer sandbox==


=== For moodle 1.4 - 1.8 ===
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 bellow may be attached to user enrolments.


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.
==User enrolment process==
* 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:
** 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:
** $fp = fsockopen ('www.paypal.com', 80, $errno, $errstr, 30);
* to
** $fp = fsockopen ('www.sandbox.paypal.com', 80, $errno, $errstr, 30);
* 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.


=== For moodle 1.8.2 - 1.9.x ===
Manual enrolment plugins are the simplest way to handle user enrolments. enrol_flatfile plugin allows automation of enrolment and unernolment actions.


The above changes to the code were made part of the release starting with version 1.8.2
Fully automatic plugins are configured at the system level, they usually synchronise user enrolments with information stored in external systems (ex.: enrol_ldap and enrol_database). Some non-interactive plugins require only configuration of instance (ex.: enrol_cohort).  


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.
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 also implement adding and editing of enrol instance.
* 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)
* 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).
** $CFG->usepaypalsandbox = 'TRUE';
* 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)
* You should be ready to test
* When finished be sure to remove the line that was added to config.php in your root directory.


=== Note about Paypal Sandbox ===
==Enrolment expiration and suspending==
Active user enrolment is defined as condition: user has record in user_enrolments AND user enrolment already started AND user enrolment is not past timeend AND user enrolment has active status AND enrol_instance has active status AND enrol plugin is enabled.


Only implement these changes if the above is not working and Moodle is returning the "...Unfortunately your payment..." message after returning from Paypal Sandbox.
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 using cli/sync.php and as part of standard cron.


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):
Time based expiration was fully 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().


* Locate ipn.php in your installation on your server by migrating to to ../enrol/paypal/ipn.php
==Standard capabilities==
* Create a backup copy of ipn.php and give it a name something like ipn.php-backup
* Return to ipn.php and locate the following code :<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' : '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.
; 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.


==Enrolment plugins 1.7==
==Manual enrolment modifications==


===Background===
; enrol_plugin::roles_protected()
# isteacher(), isstudent(), isadmin(), iscoursecreator() are all deprecated and should be replaced with checks on has_capability instead.
: Protected roles cannot be modified manually by users. Return false if you want to allow users to remove all roles assigned by plugin. Since Moodle 2.5 it is possible to assign roles with component+itemid even if roles are not protected.
# enrol_student() and add_teacher() are obsolete, so use the generic role_assign() or the convenience function for "students" called enrol_into_course() instead.
; enrol_plugin::allow_enrol()
# unenrol_student() and remove_teacher() are obsolete, so use the generic role_unassign() instead.
: Each plugin is responsible for implementing own UI for enrolment see enrol_plugin::get_manual_enrol_link().  externallib methods must respect this property.
# 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.
; enrol_plugin::allow_unenrol() and enrol_plugin::allow_unenrol_user()
# 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).
: Is user allowed to unenrol everybody from one instance or one specific user? True is required for course reset and manual user unenrolment. externallib methods must respect this property.
# 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.
; enrol_plugin:allow_manage()
: Return true if plugin allows manual modification of user enrolments. False is usually returned from plugin that synchronise data with external systems, otherwise the manual changes would be immediately reverted. externallib methods must respect this property.  


===What's been done===
Standard user enrolment UI does not use these methods directly, developer needs to describe all possible UI enrolments actions via enrol_plugin::get_user_enrolment_actions().


#enrol/manual has been converted to use the new functions
==Restore support==
#enrol/imsenterprise has been converted - testing needed though


===What still needs to be done===
Enrolment and role restore is supported since Moodle 2.4, earlier versions can restore only manual and self enrolments.


#enrol/authorize
Plugins with automatic synchronisation may use enrol_plugin:restore_sync_course() hook to synchronise enrolments in newly crated courses. The restore process starts with instance restore which must set mapping information enrol_plugin::restore_instance() (plugins may decide to map enrolments to other plugin type), then plugin must restore users enrolments enrol_plugin::restore_user_enrolment(), protected roles enrol_plugin::restore_role_assignment() and protected group membership enrol_plugin::restore_group_member().
#enrol/database
#enrol/flatfile
#enrol/ldap
#enrol/paypal


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


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

Revision as of 14:59, 26 January 2013

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 available methods and developer documentation.

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

Enrolment gives user following privileges:

  • User with active enrolment may enter course, without enrolment user needs 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.

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 bellow may be attached to user enrolments.

User enrolment process

Manual enrolment plugins are the simplest way to handle user enrolments. enrol_flatfile plugin allows automation of enrolment and unernolment actions.

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

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 also implement adding and editing of enrol instance.

Enrolment expiration and suspending

Active user enrolment is defined as condition: user has record in user_enrolments AND user enrolment already started AND user enrolment is not past timeend AND user enrolment has active status AND enrol_instance has active status AND enrol plugin is enabled.

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 using cli/sync.php and as part of standard cron.

Time based expiration was fully 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().

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.

Manual enrolment modifications

enrol_plugin
:roles_protected()
Protected roles cannot be modified manually by users. Return false if you want to allow users to remove all roles assigned by plugin. Since Moodle 2.5 it is possible to assign roles with component+itemid even if roles are not protected.
enrol_plugin
:allow_enrol()
Each plugin is responsible for implementing own UI for enrolment see enrol_plugin::get_manual_enrol_link(). externallib methods must respect this property.
enrol_plugin
:allow_unenrol() and enrol_plugin::allow_unenrol_user()
Is user allowed to unenrol everybody from one instance or one specific user? True is required for course reset and manual user unenrolment. externallib methods must respect this property.
enrol_plugin
allow_manage()
Return true if plugin allows manual modification of user enrolments. False is usually returned from plugin that synchronise data with external systems, otherwise the manual changes would be immediately reverted. externallib methods must respect this property.

Standard user enrolment UI does not use these methods directly, developer needs to describe all possible UI enrolments actions via enrol_plugin::get_user_enrolment_actions().

Restore support

Enrolment and role restore is supported since Moodle 2.4, earlier versions can restore only manual and self enrolments.

Plugins with automatic synchronisation may use enrol_plugin:restore_sync_course() hook to synchronise enrolments in newly crated courses. The restore process starts with instance restore which must set mapping information enrol_plugin::restore_instance() (plugins may decide to map enrolments to other plugin type), then plugin must restore users enrolments enrol_plugin::restore_user_enrolment(), protected roles enrol_plugin::restore_role_assignment() and protected group membership enrol_plugin::restore_group_member().

See also