$string['enrolcandidatesmatching'] = 'Matching not enrolled users';
$string['enrolcohort'] = 'Enrol cohort';
$string['enrolcohortusers'] = 'Enrol users';
+$string['enroldetails'] = 'Enrolment details';
$string['eventenrolinstancecreated'] = 'Enrolment instance created';
$string['eventenrolinstancedeleted'] = 'Enrolment instance deleted';
$string['eventenrolinstanceupdated'] = 'Enrolment instance updated';
$string['enrolmentinstances'] = 'Enrolment methods';
$string['enrolmentnew'] = 'New enrolment in {$a}';
$string['enrolmentnewuser'] = '{$a->user} has enrolled in course "{$a->course}"';
+$string['enrolmentmethod'] = 'Enrolment method';
$string['enrolments'] = 'Enrolments';
$string['enrolmentoptions'] = 'Enrolment options';
$string['enrolnotpermitted'] = 'You do not have permission or are not allowed to enrol someone in this course';
--- /dev/null
+// 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/>.
+
+/**
+ * AMD module for the user enrolment status field in the course participants page.
+ *
+ * @module core_user/status_field
+ * @copyright 2017 Jun Pataleta
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+define(['core/templates',
+ 'jquery',
+ 'core/str',
+ 'core/config',
+ 'core/notification',
+ 'core/modal_factory',
+ 'core/modal_events',
+ 'core/fragment',
+ 'core/ajax'
+ ],
+ function(Template, $, Str, Config, Notification, ModalFactory, ModalEvents, Fragment, Ajax) {
+
+ /**
+ * Action selectors.
+ *
+ * @access private
+ * @type {{EDIT_ENROLMENT: string, SHOW_DETAILS: string, UNENROL: string}}
+ */
+ var SELECTORS = {
+ EDIT_ENROLMENT: '[data-action="editenrolment"]',
+ SHOW_DETAILS: '[data-action="showdetails"]',
+ UNENROL: '[data-action="unenrol"]'
+ };
+
+ /**
+ * Constructor
+ *
+ * @param {Object} options Object containing options. The only valid option at this time is contextid.
+ * Each call to templates.render gets it's own instance of this class.
+ */
+ var StatusFieldActions = function(options) {
+ this.contextid = options.contextid;
+ this.courseid = options.courseid;
+
+ // Bind click event to editenrol buttons.
+ this.bindEditEnrol();
+
+ // Bind click event to unenrol buttons.
+ this.bindUnenrol();
+
+ // Bind click event to status details buttons.
+ this.bindStatusDetails();
+ };
+ // Class variables and functions.
+
+ /** @var {number} courseid The course ID. */
+ StatusFieldActions.prototype.courseid = 0;
+
+ /**
+ * Private method
+ *
+ * @method initModal
+ * @private
+ */
+ StatusFieldActions.prototype.bindEditEnrol = function() {
+ var statusFieldInstsance = this;
+
+ $(SELECTORS.EDIT_ENROLMENT).click(function(e) {
+ e.preventDefault();
+
+ // The particular edit button that was clicked.
+ var clickedEditTrigger = $(this);
+ // Get the parent container (it contains the data attributes associated with the status field).
+ var parentContainer = clickedEditTrigger.parent();
+ // Get the name of the user whose enrolment status is being edited.
+ var fullname = parentContainer.data('fullname');
+ // Get the user enrolment ID.
+ var ueid = clickedEditTrigger.attr('rel');
+
+ $.when(Str.get_string('edituserenrolment', 'enrol', fullname)).then(function(modalTitle) {
+ return ModalFactory.create({
+ large: true,
+ title: modalTitle,
+ type: ModalFactory.types.SAVE_CANCEL
+ });
+ }).done(function(modal) {
+ // Handle save event.
+ modal.getRoot().on(ModalEvents.save, function(e) {
+ // Don't close the modal yet.
+ e.preventDefault();
+ // Submit form data.
+ statusFieldInstsance.submitEditFormAjax(modal);
+ });
+
+ // Handle hidden event.
+ modal.getRoot().on(ModalEvents.hidden, function() {
+ // Destroy when hidden.
+ modal.destroy();
+ });
+
+ // Set the modal body.
+ modal.setBody(statusFieldInstsance.getBody(ueid));
+
+ // Show the modal!
+ modal.show();
+ }).fail(Notification.exception);
+ });
+ };
+
+ /**
+ * Private method
+ *
+ * @method bindUnenrol
+ * @private
+ */
+ StatusFieldActions.prototype.bindUnenrol = function() {
+ $(SELECTORS.UNENROL).click(function(e) {
+ e.preventDefault();
+ var unenrolLink = $(this);
+ var parentContainer = unenrolLink.parent();
+ var strings = [
+ {
+ key: 'unenrol',
+ component: 'enrol'
+ },
+ {
+ key: 'unenrolconfirm',
+ component: 'enrol',
+ param: {
+ user: parentContainer.data('fullname'),
+ course: parentContainer.data('coursename')
+ }
+ }
+ ];
+
+ $.when(Str.get_strings(strings)).then(function(results) {
+ var title = results[0];
+ var confirmMessage = results[1];
+ return ModalFactory.create({
+ body: confirmMessage,
+ large: true,
+ title: title,
+ type: ModalFactory.types.CONFIRM
+ });
+ }).done(function(modal) {
+ // Handle confirm event.
+ modal.getRoot().on(ModalEvents.yes, function() {
+ // Build params.
+ var unenrolParams = {
+ confirm: 1,
+ sesskey: Config.sesskey,
+ ue: $(unenrolLink).attr('rel')
+ };
+ // Send data to unenrol page (which will redirect back to the participants page after unenrol).
+ window.location.href = Config.wwwroot + '/enrol/unenroluser.php?' + $.param(unenrolParams);
+ });
+
+ // Handle hidden event.
+ modal.getRoot().on(ModalEvents.hidden, function() {
+ // Destroy when hidden.
+ modal.destroy();
+ });
+
+ // Display the delete confirmation modal.
+ modal.show();
+ }).fail(Notification.exception);
+ });
+ };
+
+ /**
+ * Private method
+ *
+ * @method bindStatusDetails
+ * @private
+ */
+ StatusFieldActions.prototype.bindStatusDetails = function() {
+ $(SELECTORS.SHOW_DETAILS).click(function(e) {
+ e.preventDefault();
+
+ var detailsButton = $(this);
+ var parentContainer = detailsButton.parent();
+ var context = {
+ "fullname": parentContainer.data('fullname'),
+ "coursename": parentContainer.data('coursename'),
+ "enrolinstancename": parentContainer.data('enrolinstancename'),
+ "status": parentContainer.data('status'),
+ "timestart": parentContainer.data('timestart'),
+ "timeend": parentContainer.data('timeend')
+ };
+
+ var modalTitlePromise = Str.get_string('enroldetails', 'enrol');
+ var modalPromise = ModalFactory.create({large: true, type: ModalFactory.types.CANCEL});
+ $.when(modalTitlePromise, modalPromise).done(function(modalTitle, modal) {
+ var modalBodyPromise = Template.render('core_user/status_details', context);
+ modal.setTitle(modalTitle);
+ modal.setBody(modalBodyPromise);
+ modal.show();
+
+ // Handle hidden event.
+ modal.getRoot().on(ModalEvents.hidden, function() {
+ // Destroy when hidden.
+ modal.destroy();
+ });
+ }).fail(Notification.exception);
+ });
+ };
+
+ /**
+ * Private method
+ *
+ * @method submitEditFormAjax
+ * @param {Object} modal The the AMD modal object containing the form.
+ * @private
+ */
+ StatusFieldActions.prototype.submitEditFormAjax = function(modal) {
+ var statusFieldInstsance = this;
+ var form = modal.getRoot().find('form');
+
+ // User enrolment ID.
+ var ueid = $(form).find('[name="ue"]').val();
+ // Status.
+ var status = $(form).find('[name="status"]').val();
+
+ var params = {
+ 'courseid': this.courseid,
+ 'ueid': ueid,
+ 'status': status
+ };
+
+ // Enrol time start.
+ var timeStartEnabled = $(form).find('[name="timestart[enabled]"]');
+ if (timeStartEnabled.is(':checked')) {
+ var timeStartYear = $(form).find('[name="timestart[year]"]').val();
+ var timeStartMonth = $(form).find('[name="timestart[month]"]').val() - 1;
+ var timeStartDay = $(form).find('[name="timestart[day]"]').val();
+ var timeStartHour = $(form).find('[name="timestart[hour]"]').val();
+ var timeStartMinute = $(form).find('[name="timestart[minute]"]').val();
+ var timeStart = new Date(timeStartYear, timeStartMonth, timeStartDay, timeStartHour, timeStartMinute);
+ params.timestart = timeStart.getTime() / 1000;
+ }
+
+ // Enrol time end.
+ var timeEndEnabled = $(form).find('[name="timeend[enabled]"]');
+ if (timeEndEnabled.is(':checked')) {
+ var timeEndYear = $(form).find('[name="timeend[year]"]').val();
+ var timeEndMonth = $(form).find('[name="timeend[month]"]').val() - 1;
+ var timeEndDay = $(form).find('[name="timeend[day]"]').val();
+ var timeEndHour = $(form).find('[name="timeend[hour]"]').val();
+ var timeEndMinute = $(form).find('[name="timeend[minute]"]').val();
+ var timeEnd = new Date(timeEndYear, timeEndMonth, timeEndDay, timeEndHour, timeEndMinute);
+ params.timeend = timeEnd.getTime() / 1000;
+ }
+
+ var request = {
+ methodname: 'core_enrol_edit_user_enrolment',
+ args: params
+ };
+
+ Ajax.call([request])[0].done(function(data) {
+ if (data.result) {
+ // Dismiss the modal.
+ modal.hide();
+
+ // Reload the page, don't show changed data warnings.
+ if (typeof window.M.core_formchangechecker !== "undefined") {
+ window.M.core_formchangechecker.reset_form_dirty_state();
+ }
+ window.location.reload();
+
+ } else {
+ // Serialise the form data and reload the form fragment to show validation errors.
+ var formData = JSON.stringify(form.serialize());
+ modal.setBody(statusFieldInstsance.getBody(ueid, formData));
+ }
+ }).fail(Notification.exception);
+ };
+
+ /**
+ * Private method
+ *
+ * @method getBody
+ * @private
+ * @param {Number} ueid The user enrolment ID associated with the user.
+ * @param {string} formData Serialized string of the edit enrolment form data.
+ * @return {Promise}
+ */
+ StatusFieldActions.prototype.getBody = function(ueid, formData) {
+ var params = {
+ 'ueid': ueid
+ };
+ if (typeof formData !== 'undefined') {
+ params.formdata = formData;
+ }
+ return Fragment.loadFragment('enrol', 'user_enrolment_form', this.contextid, params).fail(Notification.exception);
+ };
+
+ return /** @alias module:core_user/editenrolment */ {
+ // Public variables and functions.
+ /**
+ * Every call to init creates a new instance of the class with it's own event listeners etc.
+ *
+ * @method init
+ * @public
+ * @param {object} config - config variables for the module.
+ */
+ init: function(config) {
+ (new StatusFieldActions(config));
+ }
+ };
+ });
\ No newline at end of file
use context;
use DateTime;
-use html_writer;
defined('MOODLE_INTERNAL') || die;
$this->assignableroles = get_assignable_roles($this->context, ROLENAME_ALIAS, false);
}
+ /**
+ * Render the participants table.
+ *
+ * @param int $pagesize Size of page for paginated displayed table.
+ * @param bool $useinitialsbar Whether to use the initials bar which will only be used if there is a fullname column defined.
+ * @param string $downloadhelpbutton
+ */
+ public function out($pagesize, $useinitialsbar, $downloadhelpbutton = '') {
+ global $PAGE;
+
+ parent::out($pagesize, $useinitialsbar, $downloadhelpbutton);
+
+ if (has_capability('moodle/course:enrolreview', $this->context)) {
+ $params = ['contextid' => $this->context->id, 'courseid' => $this->course->id];
+ $PAGE->requires->js_call_amd('core_user/status_field', 'init', [$params]);
+ }
+ }
+
/**
* Generate the select column.
*
/**
* Generate the status column.
*
- * @param stdClass $data The data object.
+ * @param \stdClass $data The data object.
* @return string
*/
public function col_status($data) {
$canreviewenrol = has_capability('moodle/course:enrolreview', $this->context);
if ($canreviewenrol) {
$fullname = fullname($data);
+ $coursename = $this->course->fullname;
require_once($CFG->dirroot . '/enrol/locallib.php');
$manager = new \course_enrolment_manager($PAGE, $this->course);
$userenrolments = $manager->get_user_enrolments($data->id);
foreach ($userenrolments as $ue) {
- $enrolactions = $ue->enrolmentplugin->get_user_enrolment_actions($manager, $ue);
$timestart = $ue->timestart;
$timeend = $ue->timeend;
$status = '';
- $dimmed = '';
switch ($ue->status) {
case ENROL_USER_ACTIVE:
$currentdate = new DateTime();
$status = get_string('participationactive', 'enrol');
} else {
$status = get_string('participationnotcurrent', 'enrol');
- $dimmed = 'dimmed_text';
}
break;
case ENROL_USER_SUSPENDED:
$status = get_string('participationsuspended', 'enrol');
- $dimmed = 'dimmed_text';
break;
}
- $statusout = html_writer::span($status, $dimmed, ['title' => "{$ue->enrolmentinstancename}: {$status}"]);
- $enrolactionsout = '';
- foreach ($enrolactions as $action) {
- $icon = $OUTPUT->render($action->get_icon());
- $attributes = $action->get_attributes();
- $attributes['data-fullname'] = $fullname;
- $attributes['data-coursename'] = $this->course->fullname;
- $enrolactionsout .= html_writer::link($action->get_url(), $icon, $attributes);
- }
- $enrolstatusoutput .= html_writer::div($statusout . $enrolactionsout);
+ $actions = $ue->enrolmentplugin->get_user_enrolment_actions($manager, $ue);
+ $instancename = $ue->enrolmentinstancename;
+ $statusfield = new status_field($instancename, $coursename, $fullname, $status, $timestart, $timeend, $actions);
+ $statusfielddata = $statusfield->export_for_template($OUTPUT);
+ $enrolstatusoutput .= $OUTPUT->render_from_template('core_user/status_field', $statusfielddata);
}
}
return $enrolstatusoutput;
--- /dev/null
+<?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/>.
+
+/**
+ * Class containing the data necessary for rendering the status field in the course participants page.
+ *
+ * @package core_user
+ * @copyright 2017 Jun Pataleta
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+namespace core_user;
+
+defined('MOODLE_INTERNAL') || die();
+
+use renderable;
+use renderer_base;
+use stdClass;
+use templatable;
+use user_enrolment_action;
+
+/**
+ * Class containing the data for the status field.
+ *
+ * @package core_user
+ * @copyright 2017 Jun Pataleta
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class status_field implements renderable, templatable {
+
+ /** @var string $enrolinstancename The enrolment instance name. */
+ protected $enrolinstancename;
+
+ /** @var string $coursename The course's full name. */
+ protected $coursename;
+
+ /** @var string $fullname The user's full name. */
+ protected $fullname;
+
+ /** @var string $status The user enrolment status. */
+ protected $status;
+
+ /** @var int $timestart The timestamp when the user's enrolment starts. */
+ protected $timestart;
+
+ /** @var int $timeend The timestamp when the user's enrolment ends. */
+ protected $timeend;
+
+ /** @var user_enrolment_action[] $enrolactions Array of enrol action objects for the given enrolment method. */
+ protected $enrolactions;
+
+ /**
+ * status_field constructor.
+ *
+ * @param string $enrolinstancename The enrolment instance name.
+ * @param string $coursename The course's full name.
+ * @param string $fullname The user's full name.
+ * @param string $status The user enrolment status.
+ * @param int|null $timestart The timestamp when the user's enrolment starts.
+ * @param int|null $timeend The timestamp when the user's enrolment ends.
+ * @param user_enrolment_action[] $enrolactions Array of enrol action objects for the given enrolment method.
+ */
+ public function __construct($enrolinstancename, $coursename, $fullname, $status,
+ $timestart = null, $timeend = null, $enrolactions = []) {
+ $this->enrolinstancename = $enrolinstancename;
+ $this->coursename = $coursename;
+ $this->fullname = $fullname;
+ $this->status = $status;
+ $this->timestart = $timestart;
+ $this->timeend = $timeend;
+ $this->enrolactions = $enrolactions;
+ }
+
+ /**
+ * Function to export the renderer data in a format that is suitable for a
+ * mustache template. This means:
+ * 1. No complex types - only stdClass, array, int, string, float, bool
+ * 2. Any additional info that is required for the template is pre-calculated (e.g. capability checks).
+ *
+ * @param renderer_base $output Used to do a final render of any components that need to be rendered for export.
+ * @return stdClass|array
+ */
+ public function export_for_template(renderer_base $output) {
+ $data = new stdClass();
+ $data->enrolinstancename = $this->enrolinstancename;
+ $data->coursename = $this->coursename;
+ $data->fullname = $this->fullname;
+ $data->status = $this->status;
+ if ($this->timestart) {
+ $data->timestart = userdate($this->timestart);
+ }
+ if ($this->timeend) {
+ $data->timeend = userdate($this->timeend);
+ }
+ $data->enrolactions = [];
+
+ foreach ($this->enrolactions as $enrolaction) {
+ $action = new stdClass();
+ $action->url = $enrolaction->get_url()->out(false);
+ $action->icon = $output->render($enrolaction->get_icon());
+ $action->attributes = [];
+ foreach ($enrolaction->get_attributes() as $name => $value) {
+ $attribute = (object) [
+ 'name' => $name,
+ 'value' => $value
+ ];
+ $action->attributes[] = $attribute;
+ }
+ $data->enrolactions[] = $action;
+ }
+
+ return $data;
+ }
+}
--- /dev/null
+{{!
+ 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/>.
+}}
+{{!
+ @template core_user/status_details
+
+ Template for the user enrolment status details.
+
+ Context variables required for this template:
+ * fullname string - The user's full name.
+ * coursename string - The course name.
+ * enrolinstancename string - The enrolment instance name.
+ * status string - The enrolment status.
+ * timestart string - Optional. The enrolment time start.
+ * timeend string - Optional. The enrolment time end.
+
+ Example context (json):
+ {
+ "fullname": "Student John",
+ "coursename": "TC 1",
+ "enrolinstancename": "Manual enrolment",
+ "status": "Active",
+ "timestart": "1 January 2017",
+ "timeend": "31 January 2018"
+ }
+}}
+<table class="table user-enrol-details">
+ <tr>
+ <th>
+ {{#str}}fullname{{/str}}
+ </th>
+ <td class="user-fullname">
+ {{fullname}}
+ </td>
+ </tr>
+ <tr>
+ <th>
+ {{#str}}course{{/str}}
+ </th>
+ <td class="user-course">
+ {{coursename}}
+ </td>
+ </tr>
+ <tr>
+ <th>
+ {{#str}}enrolmentmethod, enrol{{/str}}
+ </th>
+ <td class="user-enrol-instance">
+ {{enrolinstancename}}
+ </td>
+ </tr>
+ <tr>
+ <th>
+ {{#str}}participationstatus, enrol{{/str}}
+ </th>
+ <td class="user-enrol-status">
+ {{status}}
+ </td>
+ </tr>
+ {{#timestart}}
+ <tr>
+ <th>
+ {{#str}}enroltimestart, enrol{{/str}}
+ </th>
+ <td class="user-enrol-timestart">
+ {{timestart}}
+ </td>
+ </tr>
+ {{/timestart}}
+ {{#timeend}}
+ <tr>
+ <th>
+ {{#str}}enroltimeend, enrol{{/str}}
+ </th>
+ <td class="user-enrol-timeend">
+ {{timeend}}
+ </td>
+ </tr>
+ {{/timeend}}
+</table>
--- /dev/null
+{{!
+ 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/>.
+}}
+{{!
+ @template core_user/status_field
+
+ Template for the enrolment status field.
+
+ Context variables required for this template:
+ * fullname string - The user's full name.
+ * coursename string - The course name.
+ * enrolinstancename string - The enrolment instance name.
+ * status string - The enrolment status.
+ * timestart string - Optional. The enrolment time start.
+ * timeend string - Optional. The enrolment time end.
+ * enrolactions array - Optional. Array of enrol actions consisting of:
+ * url string - The URL of the enrol action link.
+ * attributes array - The array of attributes for the enrol action link.
+ * icon string - The HTML output for the enrol action icon.
+
+ Example context (json):
+ {
+ "fullname": "Student John",
+ "coursename": "TC 1",
+ "enrolinstancename": "Manual enrolment",
+ "status": "Active",
+ "timestart": "1 January 2017",
+ "timeend": "31 January 2018",
+ "enrolactions": [
+ {
+ "url": "#",
+ "attributes": [
+ {
+ "name": "class",
+ "value": "action-class"
+ }
+ ],
+ "icon": "<i class=\"icon fa fa-cog fa-fw\" aria-hidden=\"true\" title=\"Edit enrolment\" aria-label=\"\"></i>"
+ }
+ ]
+ }
+}}
+<div data-fullname="{{fullname}}" data-coursename="{{coursename}}" data-enrolinstancename="{{enrolinstancename}}"
+ data-status="{{status}}" data-timestart="{{timestart}}" data-timeend="{{timeend}}">
+ <span>{{status}}</span>
+ <a data-action="showdetails" role="button" tabindex="0">
+ {{#pix}}docs, core, {{#str}}enroldetails, enrol{{/str}}{{/pix}}
+ </a>
+ {{#enrolactions}}
+ <a href="{{url}}" role="button" {{#attributes}}{{name}}="{{value}}" {{/attributes}}>
+ {{{icon}}}
+ </a>
+ {{/enrolactions}}
+</div>