Skip to content

Commit

Permalink
MDL-26770 enrol - Added support for bulk operations by enrol plugins
Browse files Browse the repository at this point in the history
  • Loading branch information
Sam Hemelryk committed Apr 21, 2011
1 parent 884faff commit 75ee207
Show file tree
Hide file tree
Showing 13 changed files with 743 additions and 5 deletions.
94 changes: 94 additions & 0 deletions enrol/bulkchange.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<?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/>.

/**
* Bulk user enrolment processing.
*
* @package core
* @subpackage enrol
* @copyright 2011 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

require('../config.php');
require_once("$CFG->dirroot/enrol/locallib.php");
require_once("$CFG->dirroot/enrol/users_forms.php");
require_once("$CFG->dirroot/enrol/renderer.php");
require_once("$CFG->dirroot/group/lib.php");

$id = required_param('id', PARAM_INT); // course id
$bulkuserop = required_param('bulkuserop', PARAM_ALPHANUMEXT);
$userids = required_param('bulkuser', PARAM_INT);
$action = optional_param('action', '', PARAM_ACTION);
$filter = optional_param('ifilter', 0, PARAM_INT);

$course = $DB->get_record('course', array('id'=>$id), '*', MUST_EXIST);
$context = get_context_instance(CONTEXT_COURSE, $course->id, MUST_EXIST);

if ($course->id == SITEID) {
redirect(new moodle_url('/'));
}

require_login($course);
require_capability('moodle/course:enrolreview', $context);
$PAGE->set_pagelayout('admin');

$manager = new course_enrolment_manager($PAGE, $course, $filter);
$table = new course_enrolment_users_table($manager, $PAGE);
$returnurl = new moodle_url('/enrol/users.php', $table->get_combined_url_params());
$actionurl = new moodle_url('/enrol/bulkchange.php', $table->get_combined_url_params()+array('bulkuserop' => $bulkuserop));

$PAGE->set_url($actionurl);
navigation_node::override_active_url(new moodle_url('/enrol/users.php', array('id' => $id)));

$ops = $table->get_bulk_user_enrolment_operations();
if (!array_key_exists($bulkuserop, $ops)) {
throw new moodle_exception('invalidbulkenrolop');
}
$operation = $ops[$bulkuserop];

// Prepare the properties of the form
$users = $manager->get_users_enrolments($userids);

// Get the form for the bulk operation
$mform = $operation->get_form($actionurl, array('users' => $users));
// If the mform is false then attempt an immediate process. This may be an immediate action that
// doesn't require user input OR confirmation.... who know what but maybe one day
if ($mform === false) {
if ($operation->process($manager, $users, new stdClass)) {
redirect($returnurl);
} else {
print_error('errorwithbulkoperation', 'enrol');
}
}
// Check if the bulk operation has been cancelled
if ($mform->is_cancelled()) {
redirect($returnurl);
}
if ($mform->is_submitted() && $mform->is_validated() && confirm_sesskey()) {
if ($operation->process($manager, $users, $mform->get_data())) {
redirect($returnurl);
}
}

$pagetitle = get_string('bulkuseroperation', 'enrol');

$PAGE->set_title($pagetitle);
$PAGE->set_heading($pagetitle);
echo $OUTPUT->header();
echo $OUTPUT->heading($operation->get_title());
$mform->display();
echo $OUTPUT->footer();
118 changes: 118 additions & 0 deletions enrol/bulkchange_forms.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
<?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/>.

/**
* This file contains form for bulk changing user enrolments.
*
* @package core
* @subpackage enrol
* @copyright 2011 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

defined('MOODLE_INTERNAL') || die();

require_once("$CFG->libdir/formslib.php");

/**
* A base class that can be used to easily construct a form for use with bulk operations
*
* @copyright 2011 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
abstract class enrol_bulk_enrolment_change_form extends moodleform {

/**
* Defines the standard structure of the form
*/
protected function definition() {
$form = $this->_form;
$users = $this->_customdata['users'];

$statusoptions = $this->get_status_options();
$form->addElement('html', $this->get_users_table($users, $statusoptions));
$form->addElement('select', 'status', get_string('alterstatus', 'enrol_manual'), $statusoptions, array('optional' => true));
$form->addElement('date_selector', 'timestart', get_string('altertimestart', 'enrol_manual'), array('optional' => true));
$form->addElement('date_selector', 'timeend', get_string('altertimeend', 'enrol_manual'), array('optional' => true));

$this->add_action_buttons();
}

/**
* Returns an array of status options
* @return array
*/
protected function get_status_options() {
return array(-1 => get_string('nochange', 'enrol'),
ENROL_USER_ACTIVE => get_string('participationactive', 'enrol'),
ENROL_USER_SUSPENDED => get_string('participationsuspended', 'enrol'));
}

/**
* Generates an HTML table to display the users being affected by the bulk change.
*
* @param array $users
* @param array $statusoptions
* @return string
*/
protected function get_users_table(array $users, array $statusoptions) {
$table = new html_table();
$table->head = array(
get_string('name'),
get_string('participationstatus', 'enrol'),
get_string('enroltimestart', 'enrol'),
get_string('enroltimeend', 'enrol'),
);
$table->data = array();
foreach ($users as $user) {
foreach ($user->enrolments as $enrolment) {
$input = html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'bulkuser[]', 'value' => $user->id));
$table->data[] = array(
fullname($user).$input,
$statusoptions[$enrolment->status],
(!empty($enrolment->timestart))?userdate($enrolment->timestart):'',
(!empty($enrolment->timeend))?userdate($enrolment->timeend):'',
);
}
}
return html_writer::table($table);
}
}

/**
* A convenience class to allow the quick generation of a confirmation form for a bulk operation.
* @copyright 2011 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
abstract class enrol_bulk_enrolment_confirm_form extends enrol_bulk_enrolment_change_form {

/**
* Defines the standard structure of the form
*/
protected function definition() {
$form = $this->_form;
$users = $this->_customdata['users'];
$title = $this->_customdata['title'];
$message = $this->_customdata['message'];
$button = $this->_customdata['button'];

$form->addElement('html', $this->get_users_table($users, $this->get_status_options()));
$form->addElement('header', 'ebecf_header', $title);
$form->addElement('html', html_writer::tag('p', $message));
$this->add_action_buttons(true, $button);
}
}
140 changes: 140 additions & 0 deletions enrol/locallib.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

defined('MOODLE_INTERNAL') || die();

/**
* This class provides a targeted tied together means of interfacing the enrolment
* tasks together with a course.
Expand Down Expand Up @@ -913,6 +915,76 @@ public function has_instance($enrolpluginname) {
}
return false;
}

/**
* Returns the enrolment plugin that the course manager was being filtered to.
*
* If no filter was being applied then this function returns false.
*
* @return enrol_plugin
*/
public function get_filtered_enrolment_plugin() {
$instances = $this->get_enrolment_instances();
$plugins = $this->get_enrolment_plugins();

if (empty($this->instancefilter) || !array_key_exists($this->instancefilter, $instances)) {
return false;
}

$instance = $instances[$this->instancefilter];
return $plugins[$instance->enrol];
}

/**
* Returns and array of users + enrolment details.
*
* Given an array of user id's this function returns and array of user enrolments for those users
* as well as enough user information to display the users name and picture for each enrolment.
*
* @global moodle_database $DB
* @param array $userids
* @return array
*/
public function get_users_enrolments(array $userids) {
global $DB;

$instances = $this->get_enrolment_instances();
$plugins = $this->get_enrolment_plugins();

if (!empty($this->instancefilter)) {
$instancesql = ' = :instanceid';
$instanceparams = array('instanceid' => $this->instancefilter);
} else {
list($instancesql, $instanceparams) = $DB->get_in_or_equal(array_keys($instances), SQL_PARAMS_NAMED, 'instanceid0000');
}

$userfields = user_picture::fields('u');
list($idsql, $idparams) = $DB->get_in_or_equal($userids, SQL_PARAMS_NAMED, 'userid0000');

$sql = "SELECT ue.id AS ueid, ue.status, ue.enrolid, ue.userid, ue.timestart, ue.timeend, ue.modifierid, ue.timecreated, ue.timemodified, $userfields
FROM {user_enrolments} ue
LEFT JOIN {user} u ON u.id = ue.userid
WHERE ue.enrolid $instancesql AND
u.id $idsql
ORDER BY u.firstname ASC, u.lastname ASC";

$rs = $DB->get_recordset_sql($sql, $idparams + $instanceparams);
$users = array();
foreach ($rs as $ue) {
$user = user_picture::unalias($ue);
$ue->id = $ue->ueid;
unset($ue->ueid);
if (!array_key_exists($user->id, $users)) {
$user->enrolments = array();
$users[$user->id] = $user;
}
$ue->enrolmentinstance = $instances[$ue->enrolid];
$ue->enrolmentplugin = $plugins[$ue->enrolmentinstance->enrol];
$users[$user->id]->enrolments[$ue->id] = $ue;
}
$rs->close();
return $users;
}
}

/**
Expand Down Expand Up @@ -1123,4 +1195,72 @@ class enrol_ajax_exception extends moodle_exception {
public function __construct($errorcode, $link = '', $a = NULL, $debuginfo = null) {
parent::__construct($errorcode, 'enrol', $link, $a, $debuginfo);
}
}

/**
* This class is used to manage a bulk operations for enrolment plugins.
*
* @copyright 2011 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
abstract class enrol_bulk_enrolment_operation {

/**
* The course enrolment manager
* @var course_enrolment_manager
*/
protected $manager;

/**
* The enrolment plugin to which this operation belongs
* @var enrol_plugin
*/
protected $plugin;

/**
* Contructor
* @param course_enrolment_manager $manager
* @param stdClass $plugin
*/
public function __construct(course_enrolment_manager $manager, enrol_plugin $plugin = null) {
$this->manager = $manager;
$this->plugin = $plugin;
}

/**
* Returns a moodleform used for this operation, or false if no form is required and the action
* should be immediatly processed.
*
* @param moodle_url|string $defaultaction
* @param mixed $defaultcustomdata
* @return enrol_bulk_enrolment_change_form|moodleform|false
*/
public function get_form($defaultaction = null, $defaultcustomdata = null) {
return false;
}

/**
* Returns the title to use for this bulk operation
*
* @return string
*/
abstract public function get_title();

/**
* Returns the identifier for this bulk operation.
* This should be the same identifier used by the plugins function when returning
* all of its bulk operations.
*
* @return string
*/
abstract public function get_identifier();

/**
* Processes the bulk operation on the given users
*
* @param course_enrolment_manager $manager
* @param array $users
* @param stdClass $properties
*/
abstract public function process(course_enrolment_manager $manager, array $users, stdClass $properties);
}
3 changes: 1 addition & 2 deletions enrol/manual/ajax.php
Original file line number Diff line number Diff line change
Expand Up @@ -128,5 +128,4 @@
throw new enrol_ajax_exception('unknowajaxaction');
}

echo json_encode($outcome);
die();
echo json_encode($outcome);
Loading

0 comments on commit 75ee207

Please sign in to comment.