enrol MDL-22854 New ajaxified enrolment interface

This commit is contained in:
Sam Hemelryk
2010-07-07 02:46:34 +00:00
parent 42b46a77e0
commit a70eb30fa9
16 changed files with 2662 additions and 434 deletions
+172
View File
@@ -0,0 +1,172 @@
<?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 processes AJAX enrolment actions and returns JSON
*
* @package moodlecore
* @copyright 2010 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define('AJAX_SCRIPT', true);
require('../config.php');
require_once("$CFG->dirroot/enrol/locallib.php");
require_once("$CFG->dirroot/enrol/renderer.php");
require_once("$CFG->dirroot/group/lib.php");
// Must have the sesskey
require_sesskey();
$id = required_param('id', PARAM_INT); // course id
$action = required_param('action', PARAM_ACTION);
$PAGE->set_url(new moodle_url('/enrol/ajax.php', array('id'=>$id, 'action'=>$action)));
$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);
$manager = new course_enrolment_manager($course);
$outcome = new stdClass;
$outcome->success = false;
$outcome->response = new stdClass;
$outcome->error = '';
if (!confirm_sesskey()) {
$outcome->error = 'invalidsesskey';
echo json_encode($outcome);
die();
}
switch ($action) {
case 'unenrol':
$ue = $DB->get_record('user_enrolments', array('id'=>required_param('ue', PARAM_INT)), '*', MUST_EXIST);
if ($manager->unenrol_user($ue)) {
$outcome->success = true;
} else {
$outcome->error = 'unabletounenrol';
}
break;
case 'unassign':
$role = required_param('role', PARAM_INT);
$user = required_param('user', PARAM_INT);
if ($manager->unassign_role_from_user($user, $role)) {
$outcome->success = true;
} else {
$outcome->error = 'unabletounassign';
}
break;
case 'assign':
$user = required_param('user', PARAM_INT);
$user = $DB->get_record('user', array('id'=>$user), '*', MUST_EXIST);
$roleid = required_param('roleid', PARAM_INT);
if (!is_enrolled($context, $user)) {
$outcome->error = 'mustbeenrolled';
break; // no roles without enrolments here in this script
}
if ($manager->assign_role_to_user($roleid, $user->id)) {
$outcome->success = true;
$outcome->response->roleid = $roleid;
} else {
$outcome->error = 'unabletoassign';
}
break;
case 'getassignable':
$outcome->success = true;
$outcome->response = $manager->get_assignable_roles();
break;
case 'searchusers':
$enrolid = required_param('enrolid', PARAM_INT);
$search = optional_param('search', '', PARAM_CLEAN);
$page = optional_param('page', 0, PARAM_INT);
$outcome->response = $manager->get_potential_users($enrolid, $search, false, $page);
foreach ($outcome->response['users'] as &$user) {
$user->picture = $OUTPUT->user_picture($user);
$user->fullname = fullname($user);
}
$outcome->success = true;
break;
case 'enrol':
$enrolid = required_param('enrolid', PARAM_INT);
$userid = required_param('userid', PARAM_INT);
$roleid = optional_param('role', null, PARAM_INT);
$duration = optional_param('duration', 0, PARAM_INT);
$startdate = optional_param('startdate', 0, PARAM_INT);
if (empty($roleid)) {
$roleid = null;
}
switch($startdate) {
case 2:
$timestart = $course->startdate;
break;
case 3:
default:
$today = time();
$today = make_timestamp(date('Y', $today), date('m', $today), date('d', $today), 0, 0, 0);
$timestart = $today;
break;
}
if ($duration <= 0) {
$timestart = 0;
$timeend = 0;
} else {
$timeend = $timestart + ($duration*24*60*60);
}
$user = $DB->get_record('user', array('id'=>$userid), '*', MUST_EXIST);
$instances = $manager->get_enrolment_instances();
$plugins = $manager->get_enrolment_plugins();
if (!array_key_exists($enrolid, $instances)) {
$outcome->error = 'invalidinstance';
break;
}
$instance = $instances[$enrolid];
$plugin = $plugins[$instance->enrol];
try {
$plugin->enrol_user($instance, $user->id, $roleid, $timestart, $timeend);
} catch (Exception $e) {
$outcome->error = 'unabletoenrol';
break;
}
$outcome->success = true;
break;
default:
$outcome->error = 'unknownaction';
break;
}
echo json_encode($outcome);
die();
+747
View File
@@ -0,0 +1,747 @@
<?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 the course_enrolment_manager class which is used to interface
* with the functions that exist in enrollib.php in relation to a single course.
*
* @package moodlecore
* @copyright 2010 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* This class provides a targeted tied together means of interfacing the enrolment
* tasks together with a course.
*
* It is provided as a convenience more than anything else.
*
* @copyright 2010 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class course_enrolment_manager {
/**
* The course context
* @var stdClass
*/
protected $context;
/**
* The course we are managing enrolments for
* @var stdClass
*/
protected $course = null;
/**
* Limits the focus of the manager to one enrolment plugin instance
* @var string
*/
protected $instancefilter = null;
/**
* The total number of users enrolled in the course
* Populated by course_enrolment_manager::get_total_users
* @var int
*/
protected $totalusers = null;
/**
* An array of users currently enrolled in the course
* Populated by course_enrolment_manager::get_users
* @var array
*/
protected $users = array();
/**#@+
* These variables are used to cache the information this class uses
* please never use these directly instead use thier get_ counterparts.
* @access private
* @var array
*/
private $_instancessql = null;
private $_instances = null;
private $_inames = null;
private $_plugins = null;
private $_roles = null;
private $_assignableroles = null;
private $_groups = null;
/**#@-*/
/**
* Constructs the course enrolment manager
*
* @param stdClass $course
* @param string $instancefilter
*/
public function __construct($course, $instancefilter = null) {
$this->context = get_context_instance(CONTEXT_COURSE, $course->id);
$this->course = $course;
$this->instancefilter = $instancefilter;
}
/**
* Returns the total number of enrolled users in the course.
*
* If a filter was specificed this will be the total number of users enrolled
* in this course by means of that instance.
*
* @global moodle_database $DB
* @return int
*/
public function get_total_users() {
global $DB;
if ($this->totalusers === null) {
list($instancessql, $params, $filter) = $this->get_instance_sql();
$sqltotal = "SELECT COUNT(DISTINCT u.id)
FROM {user} u
JOIN {user_enrolments} ue ON (ue.userid = u.id AND ue.enrolid $instancessql)
JOIN {enrol} e ON (e.id = ue.enrolid)";
$this->totalusers = (int)$DB->count_records_sql($sqltotal, $params);
}
return $this->totalusers;
}
/**
* Gets all of the users enrolled in this course.
*
* If a filter was specificed this will be the users who were enrolled
* in this course by means of that instance.
*
* @global moodle_database $DB
* @param string $sort
* @param string $direction ASC or DESC
* @param int $page First page should be 0
* @param int $perpage Defaults to 25
* @return array
*/
public function get_users($sort, $direction='ASC', $page=0, $perpage=25) {
global $DB;
if ($direction !== 'ASC') {
$direction = 'DESC';
}
$key = md5("$sort-$direction-$page-$perpage");
if (!array_key_exists($key, $this->users)) {
list($instancessql, $params, $filter) = $this->get_instance_sql();
$sql = "SELECT DISTINCT u.*, ul.timeaccess AS lastseen
FROM {user} u
JOIN {user_enrolments} ue ON (ue.userid = u.id AND ue.enrolid $instancessql)
JOIN {enrol} e ON (e.id = ue.enrolid)
LEFT JOIN {user_lastaccess} ul ON (ul.courseid = e.courseid AND ul.userid = u.id)";
if ($sort === 'firstname') {
$sql .= " ORDER BY u.firstname $direction, u.lastname $direction";
} else if ($sort === 'lastname') {
$sql .= " ORDER BY u.lastname $direction, u.firstname $direction";
} else if ($sort === 'email') {
$sql .= " ORDER BY u.email $direction, u.lastname $direction, u.firstname $direction";
} else if ($sort === 'lastseen') {
$sql .= " ORDER BY ul.timeaccess $direction, u.lastname $direction, u.firstname $direction";
}
$this->users[$key] = $DB->get_records_sql($sql, $params, $page*$perpage, $perpage);
}
return $this->users[$key];
}
/**
* Gets an array of the users that can be enrolled in this course.
*
* @global moodle_database $DB
* @param int $enrolid
* @param string $search
* @param bool $searchanywhere
* @param int $page Defaults to 0
* @param int $perpage Defaults to 25
* @return array Array(totalusers => int, users => array)
*/
public function get_potential_users($enrolid, $search='', $searchanywhere=false, $page=0, $perpage=25) {
global $DB;
// Add some additional sensible conditions
$tests = array("u.username <> 'guest'", 'u.deleted = 0', 'u.confirmed = 1');
$params = array();
if (!empty($search)) {
$conditions = array('u.firstname','u.lastname');
$ilike = ' ' . $DB->sql_ilike();
if ($searchanywhere) {
$searchparam = '%' . $search . '%';
} else {
$searchparam = $search . '%';
}
$i = 0;
foreach ($conditions as &$condition) {
$condition .= "$ilike :con{$i}00";
$params["con{$i}00"] = $searchparam;
$i++;
}
$tests[] = '(' . implode(' OR ', $conditions) . ')';
}
$wherecondition = implode(' AND ', $tests);
$ufields = user_picture::fields('u');
$fields = 'SELECT u.id, u.firstname, u.lastname, u.username, u.email, u.lastaccess, u.picture, u.imagealt, '.$ufields;
$countfields = 'SELECT COUNT(1)';
$sql = " FROM {user} u
WHERE $wherecondition
AND u.id NOT IN (SELECT ue.userid
FROM {user_enrolments} ue
JOIN {enrol} e ON (e.id = ue.enrolid AND e.id = :enrolid))";
$order = ' ORDER BY u.lastname ASC, u.firstname ASC';
$params['enrolid'] = $enrolid;
$totalusers = $DB->count_records_sql($countfields . $sql, $params);
$availableusers = $DB->get_records_sql($fields . $sql . $order, $params, $page*$perpage, $perpage);
return array('totalusers'=>$totalusers, 'users'=>$availableusers);
}
/**
* Gets an array containing some SQL to user for when selecting, params for
* that SQL, and the filter that was used in constructing the sql.
*
* @global moodle_database $DB
* @return string
*/
protected function get_instance_sql() {
global $DB;
if ($this->_instancessql === null) {
$instances = $this->get_enrolment_instances();
$filter = $this->get_enrolment_filter();
if ($filter && array_key_exists($filter, $instances)) {
$sql = " = :ifilter";
$params = array('ifilter'=>$filter);
} else {
$filter = 0;
if ($instances) {
list($sql, $params) = $DB->get_in_or_equal(array_keys($this->get_enrolment_instances()), SQL_PARAMS_NAMED);
} else {
// no enabled instances, oops, we should probably say something
$sql = "= :never";
$params = array('never'=>-1);
}
}
$this->instancefilter = $filter;
$this->_instancessql = array($sql, $params, $filter);
}
return $this->_instancessql;
}
/**
* Returns all of the enrolment instances for this course.
*
* @return array
*/
public function get_enrolment_instances() {
if ($this->_instances === null) {
$this->_instances = enrol_get_instances($this->course->id, true);
}
return $this->_instances;
}
/**
* Returns the names for all of the enrolment instances for this course.
*
* @return array
*/
public function get_enrolment_instance_names() {
if ($this->_inames === null) {
$instances = $this->get_enrolment_instances();
$plugins = $this->get_enrolment_plugins();
foreach ($instances as $key=>$instance) {
if (!isset($plugins[$instance->enrol])) {
// weird, some broken stuff in plugin
unset($instances[$key]);
continue;
}
$this->_inames[$key] = $plugins[$instance->enrol]->get_instance_name($instance);
}
}
return $this->_inames;
}
/**
* Gets all of the enrolment plugins that are active for this course.
*
* @return array
*/
public function get_enrolment_plugins() {
if ($this->_plugins === null) {
$this->_plugins = enrol_get_plugins(true);
}
return $this->_plugins;
}
/**
* Gets all of the roles this course can contain.
*
* @return array
*/
public function get_all_roles() {
if ($this->_roles === null) {
$this->_roles = role_fix_names(get_all_roles(), $this->context);
}
return $this->_roles;
}
/**
* Gets all of the assignable roles for this course.
*
* @return array
*/
public function get_assignable_roles() {
if ($this->_assignableroles === null) {
$this->_assignableroles = get_assignable_roles($this->context, ROLENAME_ALIAS, false); // verifies unassign access control too
}
return $this->_assignableroles;
}
/**
* Gets all of the groups for this course.
*
* @return array
*/
public function get_all_groups() {
if ($this->_groups === null) {
$this->_groups = groups_get_all_groups($this->course->id);
foreach ($this->_groups as $gid=>$group) {
$this->_groups[$gid]->name = format_string($group->name);
}
}
return $this->_groups;
}
/**
* Unenroles a user from the course given the users ue entry
*
* @global moodle_database $DB
* @param stdClass $ue
* @return bool
*/
public function unenrol_user($ue) {
global $DB;
$instances = $this->get_enrolment_instances();
$plugins = $this->get_enrolment_plugins();
$user = $DB->get_record('user', array('id'=>$ue->userid), '*', MUST_EXIST);
if (!isset($instances[$ue->enrolid])) {
return false;
}
$instance = $instances[$ue->enrolid];
$plugin = $plugins[$instance->enrol];
if (!$plugin->allow_unenrol($instance) || !has_capability("enrol/$instance->enrol:unenrol", $this->context)) {
return false;
}
$plugin->unenrol_user($instance, $ue->userid);
return true;
}
/**
* Removes an assigned role from a user.
*
* @global moodle_database $DB
* @param int $userid
* @param int $roleid
* @return bool
*/
public function unassign_role_from_user($userid, $roleid) {
global $DB;
$user = $DB->get_record('user', array('id'=>$userid), '*', MUST_EXIST);
try {
role_unassign($roleid, $user->id, $this->context->id, '', NULL);
} catch (Exception $e) {
return false;
}
return true;
}
/**
* Assigns a role to a user.
*
* @param int $roleid
* @param int $userid
* @return int|false
*/
public function assign_role_to_user($roleid, $userid) {
require_capability('moodle/role:assign', $this->context);
return role_assign($roleid, $userid, $this->context->id, '', NULL);
}
/**
* Adds a user to a group
*
* @param stdClass $user
* @param int $groupid
* @return bool
*/
public function add_user_to_group($user, $groupid) {
require_capability('moodle/course:managegroups', $this->context);
$group = $this->get_group($groupid);
if (!$group) {
return false;
}
return groups_add_member($group->id, $user->id);
}
/**
* Removes a user from a group
*
* @global moodle_database $DB
* @param StdClass $user
* @param int $groupid
* @return bool
*/
public function remove_user_from_group($user, $groupid) {
global $DB;
require_capability('moodle/course:managegroups', $this->context);
$group = $this->get_group($groupid);
if (!$group) {
return false;
}
return groups_remove_member($group, $user);
}
/**
* Gets the requested group
*
* @param int $groupid
* @return stdClass|int
*/
public function get_group($groupid) {
$groups = $this->get_all_groups();
if (!array_key_exists($groupid, $groups)) {
return false;
}
return $groups[$groupid];
}
/**
* Edits an enrolment
*
* @param stdClass $userenrolment
* @param stdClass $data
* @return bool
*/
public function edit_enrolment($userenrolment, $data) {
$instances = $this->get_enrolment_instances();
if (!array_key_exists($userenrolment->enrolid, $instances)) {
return false;
}
$instance = $instances[$userenrolment->enrolid];
$plugins = $this->get_enrolment_plugins();
$plugin = $plugins[$instance->enrol];
if (!$plugin->allow_unenrol($instance) || !has_capability("enrol/$instance->enrol:unenrol", $this->context)) {
return false;
}
if (!isset($data->status)) {
$data->status = $userenrolment->status;
}
$plugin->update_user_enrol($instance, $userenrolment->userid, $data->status, $data->timestart, $data->timeend);
return true;
}
/**
* Returns the current enrolment filter that is being applied by this class
* @return string
*/
public function get_enrolment_filter() {
return $this->instancefilter;
}
/**
* Gets the roles assigned to this user that are applicable for this course.
*
* @param int $userid
* @return array
*/
public function get_user_roles($userid) {
$roles = array();
$ras = get_user_roles($this->context, $userid, true, 'c.contextlevel DESC, r.sortorder ASC');
foreach ($ras as $ra) {
if ($ra->contextid != $this->context->id) {
if (!array_key_exists($ra->roleid, $roles)) {
$roles[$ra->roleid] = null;
}
// higher ras, course always takes precedence
continue;
}
if (array_key_exists($ra->roleid, $roles) && $roles[$ra->roleid] === false) {
continue;
}
$roles[$ra->roleid] = ($ra->itemid == 0 and $ra->component === '');
}
return $roles;
}
/**
* Gets the enrolments this user has in the course
*
* @global moodle_database $DB
* @param int $userid
* @return array
*/
public function get_user_enrolments($userid) {
global $DB;
list($instancessql, $params, $filter) = $this->get_instance_sql();
$params['userid'] = $userid;
$userenrolments = $DB->get_records_select('user_enrolments', "enrolid $instancessql AND userid = :userid", $params);
$instances = $this->get_enrolment_instances();
$plugins = $this->get_enrolment_plugins();
$inames = $this->get_enrolment_instance_names();
foreach ($userenrolments as &$ue) {
$ue->enrolmentinstance = $instances[$ue->enrolid];
$ue->enrolmentplugin = $plugins[$ue->enrolmentinstance->enrol];
$ue->enrolmentinstancename = $inames[$ue->enrolmentinstance->id];
}
return $userenrolments;
}
/**
* Gets the groups this user belongs to
*
* @param int $userid
* @return array
*/
public function get_user_groups($userid) {
return groups_get_all_groups($this->course->id, $userid, 0, 'g.id');
}
/**
* Retursn an array of params that would go into the URL to return to this
* exact page.
*
* @return array
*/
public function get_url_params() {
$args = array(
'id' => $this->course->id
);
if (!empty($this->instancefilter)) {
$args['ifilter'] = $this->instancefilter;
}
return $args;
}
/**
* Returns the course this object is managing enrolments for
*
* @return stdClass
*/
public function get_course() {
return $this->course;
}
/**
* Returns the course context
*
* @return stdClass
*/
public function get_context() {
return $this->context;
}
/**
* Gets an array of users for display, this includes minimal user information
* as well as minimal information on the users roles, groups, and enrolments.
*
* @param core_enrol_renderer $renderer
* @param moodle_url $pageurl
* @param int $sort
* @param string $direction ASC or DESC
* @param int $page
* @param int $perpage
* @return array
*/
public function get_users_for_display(core_enrol_renderer $renderer, moodle_url $pageurl, $sort, $direction, $page, $perpage) {
$users = $this->get_users($sort, $direction, $page, $perpage);
$now = time();
$strnever = get_string('never');
$straddgroup = get_string('addgroup', 'group');
$strunenrol = get_string('unenrol', 'enrol');
$stredit = get_string('edit');
$iconedit = $renderer->pix_url('t/edit');
$iconenroladd = $renderer->pix_url('t/enroladd');
$iconenrolremove = $renderer->pix_url('t/delete');
$allroles = $this->get_all_roles();
$assignable = $this->get_assignable_roles();
$allgroups = $this->get_all_groups();
$courseid = $this->get_course()->id;
$context = $this->get_context();
$canmanagegroups = has_capability('moodle/course:managegroups', $context);
$url = new moodle_url($pageurl, $this->get_url_params());
$userdetails = array();
foreach ($users as $user) {
$details = array(
'userid' => $user->id,
'courseid' => $courseid,
'picture' => new user_picture($user),
'firstname' => fullname($user, true),
'email' => $user->email,
'lastseen' => $strnever,
'roles' => array(),
'groups' => array(),
'enrolments' => array()
);
if ($user->lastseen) {
$details['lastseen'] = format_time($user->lastaccess);
}
// Roles
foreach ($this->get_user_roles($user->id) as $rid=>$rassignable) {
$details['roles'][$rid] = array('text'=>$allroles[$rid]->localname, 'unchangeable'=>(!$rassignable || !isset($assignable[$rid])));
}
// Users
$usergroups = $this->get_user_groups($user->id);
foreach($usergroups as $gid=>$unused) {
$details['groups'][$gid] = $allgroups[$gid]->name;
}
// Enrolments
foreach ($this->get_user_enrolments($user->id) as $ue) {
if ($ue->timestart and $ue->timeend) {
$period = get_string('periodstartend', 'enrol', array('start'=>userdate($ue->timestart), 'end'=>userdate($ue->timeend)));
$periodoutside = ($ue->timestart && $ue->timeend && $now < $ue->timestart && $now > $ue->timeend);
} else if ($ue->timestart) {
$period = get_string('periodstart', 'enrol', userdate($ue->timestart));
$periodoutside = ($ue->timestart && $now < $ue->timestart);
} else if ($ue->timeend) {
$period = get_string('periodend', 'enrol', userdate($ue->timeend));
$periodoutside = ($ue->timeend && $now > $ue->timeend);
} else {
$period = '';
$periodoutside = false;
}
$details['enrolments'][$ue->id] = array(
'text' => $ue->enrolmentinstancename,
'period' => $period,
'dimmed' => ($periodoutside || $ue->status != ENROL_USER_ACTIVE),
'canunenrol' => ($ue->enrolmentplugin->allow_unenrol($ue->enrolmentinstance) && has_capability("enrol/".$ue->enrolmentinstance->enrol.":unenrol", $context)),
'canmanage' => ($ue->enrolmentplugin->allow_manage($ue->enrolmentinstance) && has_capability("enrol/".$ue->enrolmentinstance->enrol.":manage", $context))
);
}
$userdetails[$user->id] = $details;
}
return $userdetails;
if (1==2){
// get list of roles
$roles = $this->get_user_roles($user->id);
foreach ($roles as $rid=>$unassignable) {
if ($unassignable && isset($assignable[$rid])) {
$icon = html_writer::empty_tag('img', array('alt'=>get_string('unassignarole', 'role', $allroles[$rid]->localname), 'src'=>$iconenrolremove));
$url = new moodle_url($url, array('action'=>'unassign', 'role'=>$rid, 'user'=>$user->id));
$roles[$rid] = html_writer::tag('div', $allroles[$rid]->localname . html_writer::link($url, $icon, array('class'=>'unassignrolelink', 'rel'=>$rid)), array('class'=>'role role_'.$rid));
} else {
$roles[$rid] = html_writer::tag('div', $allroles[$rid]->localname, array('class'=>'role unchangeable', 'rel'=>$rid));
}
}
$addrole = '';
if ($assignable) {
foreach ($assignable as $rid=>$unused) {
if (!isset($roles[$rid])) {
//candidate for role assignment
$url = new moodle_url($url, array('action'=>'assign', 'user'=>$user->id));
$icon = html_writer::empty_tag('img', array('alt'=>get_string('assignroles', 'role', $allroles[$rid]->localname), 'src'=>$iconenroladd));
$addrole .= html_writer::link($url, $icon, array('class'=>'assignrolelink'));
break;
}
}
}
$roles = html_writer::tag('div', implode('', $roles), array('class'=>'roles'));
if ($addrole) {
$roles = html_writer::tag('div', $addrole, array('class'=>'addrole')).$roles;
}
// Get list of groups
$usergroups = $this->get_user_groups($user->id);
$groups = array();
foreach($usergroups as $gid=>$unused) {
$group = $allgroups[$gid];
if ($canmanagegroups) {
$icon = html_writer::empty_tag('img', array('alt'=>get_string('removefromgroup', 'group', $group->name), 'src'=>$iconenrolremove));
$url = new moodle_url($url, array('action'=>'removemember', 'group'=>$gid, 'user'=>$user->id));
$groups[] = $group->name . html_writer::link($url, $icon);
} else {
$groups[] = $group->name;
}
}
$groups = implode(', ', $groups);
if ($canmanagegroups and (count($usergroups) < count($allgroups))) {
$icon = html_writer::empty_tag('img', array('alt'=>$straddgroup, 'src'=>$iconenroladd));
$url = new moodle_url($url, array('action'=>'addmember', 'user'=>$user->id));
$groups .= '<div>'.html_writer::link($url, $icon).'</div>';
}
// get list of enrol instances
$ues = $this->get_user_enrolments($user->id);
$edits = array();
foreach ($ues as $ue) {
$edit = $ue->enrolmentinstancename;
$dimmed = false;
if ($ue->timestart and $ue->timeend) {
$edit .= '&nbsp;('.get_string('periodstartend', 'enrol', array('start'=>userdate($ue->timestart), 'end'=>userdate($ue->timeend))).')';
$dimmed = ($now < $ue->timestart and $now > $ue->timeend);
} else if ($ue->timestart) {
$edit .= '&nbsp;('.get_string('periodstart', 'enrol', userdate($ue->timestart)).')';
$dimmed = ($now < $ue->timestart);
} else if ($ue->timeend) {
$edit .= '&nbsp;('.get_string('periodend', 'enrol', userdate($ue->timeend)).')';
$dimmed = ($now > $ue->timeend);
}
if ($dimmed or $ue->status != ENROL_USER_ACTIVE) {
$edit = html_writer::tag('span', $edit, array('class'=>'dimmed_text'));
}
if ($ue->enrolmentplugin->allow_unenrol($ue->enrolmentinstance) && has_capability("enrol/".$ue->enrolmentinstance->enrol.":unenrol", $context)) {
$icon = html_writer::empty_tag('img', array('alt'=>$strunenrol, 'src'=>$iconenrolremove));
$url = new moodle_url($url, array('action'=>'unenrol', 'ue'=>$ue->id));
$edit .= html_writer::link($url, $icon, array('class'=>'unenrollink', 'rel'=>$ue->id));
}
if ($ue->enrolmentplugin->allow_manage($ue->enrolmentinstance) && has_capability("enrol/".$ue->enrolmentinstance->enrol.":manage", $context)) {
$icon = html_writer::empty_tag('img', array('alt'=>$stredit, 'src'=>$iconedit));
$url = new moodle_url($url, array('action'=>'edit', 'ue'=>$ue->id));
$edit .= html_writer::link($url, $icon, array('class'=>'editenrollink', 'rel'=>$ue->id));
}
$edits[] = html_writer::tag('div', $edit, array('class'=>'enrolment'));
}
$edits = implode('', $edits);
$userdetails[$user->id] = array(
'picture' => $renderer->user_picture($user, array('courseid'=>$courseid)),
'firstname' => html_writer::link(new moodle_url('/user/view.php', array('id'=>$user->id, 'course'=>$courseid)), fullname($user, true)),
'email' => $user->email,
'lastseen' => $strlastaccess,
'role' => $roles,
'group' => $groups,
'enrol' => $edits
);
}
return $userdetails;
}
}
+593
View File
@@ -0,0 +1,593 @@
<?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 is the main renderer for the enrol section.
*
* @package moodlecore
* @copyright 2010 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* This is the core renderer
*
* @copyright 2010 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class core_enrol_renderer extends plugin_renderer_base {
/**
* Renders a course enrolment table
*
* @param course_enrolment_table $table
* @return string
*/
protected function render_course_enrolment_table(course_enrolment_table $table) {
$content = '';
$enrolmentselector = $table->get_enrolment_selector($this->page);
if ($enrolmentselector) {
$content .= $this->output->render($enrolmentselector);
}
$content .= $this->output->render($table->get_enrolment_type_filter());
$content .= $this->output->render($table->get_paging_bar());
$content .= html_writer::table($table);
$content .= $this->output->render($table->get_paging_bar());
$enrolmentselector = $table->get_enrolment_selector($this->page);
if ($enrolmentselector) {
$content .= $this->output->render($enrolmentselector);
}
return $content;
}
/**
* Generates HTML to display the users roles and any available actions
*
* @param int $userid
* @param array $roles
* @param array $assignableroles
* @param moodle_url $pageurl
* @return string
*/
public function user_roles_and_actions($userid, $roles, $assignableroles, $canassign, $pageurl) {
$iconenroladd = $this->output->pix_url('t/enroladd');
$iconenrolremove = $this->output->pix_url('t/delete');
// get list of roles
$rolesoutput = '';
foreach ($roles as $roleid=>$role) {
if ($canassign && !$role['unchangeable']) {
$strunassign = get_string('unassignarole', 'role', $role['text']);
$icon = html_writer::empty_tag('img', array('alt'=>$strunassign, 'src'=>$iconenrolremove));
$url = new moodle_url($pageurl, array('action'=>'unassign', 'role'=>$roleid, 'user'=>$userid));
$rolesoutput .= html_writer::tag('div', $role['text'] . html_writer::link($url, $icon, array('class'=>'unassignrolelink', 'rel'=>$roleid, 'title'=>$strunassign)), array('class'=>'role role_'.$roleid));
} else {
$rolesoutput .= html_writer::tag('div', $role['text'], array('class'=>'role unchangeable', 'rel'=>$roleid));
}
}
$output = '';
if (!empty($assignableroles) && $canassign) {
$roleids = array_keys($roles);
$hasallroles = true;
foreach (array_keys($assignableroles) as $key) {
if (!in_array($key, $roleids)) {
$hasallroles = false;
break;
}
}
if (!$hasallroles) {
$url = new moodle_url($pageurl, array('action'=>'assign', 'user'=>$userid));
$icon = html_writer::empty_tag('img', array('alt'=>get_string('assignroles', 'role'), 'src'=>$iconenroladd));
$output = html_writer::tag('div', html_writer::link($url, $icon, array('class'=>'assignrolelink', 'title'=>get_string('assignroles', 'role'))), array('class'=>'addrole'));
}
}
$output .= html_writer::tag('div', $rolesoutput, array('class'=>'roles'));
return $output;
}
/**
* Generates the HTML to view the users groups and available group actions
*
* @param int $userid
* @param array $groups
* @param array $allgroups
* @param bool $canmanagegroups
* @param moodle_url $pageurl
* @return string
*/
public function user_groups_and_actions($userid, $groups, $allgroups, $canmanagegroups, $pageurl) {
$iconenroladd = $this->output->pix_url('t/enroladd');
$iconenrolremove = $this->output->pix_url('t/delete');
$straddgroup = get_string('addgroup', 'group');
$groupoutput = '';
foreach($groups as $groupid=>$name) {
if ($canmanagegroups) {
$icon = html_writer::empty_tag('img', array('alt'=>get_string('removefromgroup', 'group', $name), 'src'=>$iconenrolremove));
$url = new moodle_url($pageurl, array('action'=>'removemember', 'group'=>$groupid, 'user'=>$userid));
$groupoutput .= html_writer::tag('div', $name . html_writer::link($url, $icon), array('class'=>'group', 'rel'=>$groupid));
} else {
$groupoutput .= html_writer::tag('div', $name, array('class'=>'group', 'rel'=>$groupid));
}
}
$groupoutput = html_writer::tag('div', $groupoutput, array('class'=>'groups'));
if ($canmanagegroups && (count($groups) < count($allgroups))) {
$icon = html_writer::empty_tag('img', array('alt'=>$straddgroup, 'src'=>$iconenroladd));
$url = new moodle_url($pageurl, array('action'=>'addmember', 'user'=>$userid));
$groupoutput .= html_writer::tag('div', html_writer::link($url, $icon), array('class'=>'addgroup'));
}
return $groupoutput;
}
/**
* Generates the HTML for the given enrolments + available actions
*
* @param int $userid
* @param array $enrolments
* @param moodle_url $pageurl
* @return string
*/
public function user_enrolments_and_actions($userid, $enrolments, $pageurl) {
$iconedit = $this->output->pix_url('t/edit');
$iconenrolremove = $this->output->pix_url('t/delete');
$strunenrol = get_string('unenrol', 'enrol');
$stredit = get_string('edit');
$output = '';
foreach ($enrolments as $ueid=>$enrolment) {
$enrolmentoutput = $enrolment['text'].' '.$enrolment['period'];
if ($enrolment['dimmed']) {
$enrolmentoutput = html_writer::tag('span', $enrolmentoutput, array('class'=>'dimmed_text'));
}
if ($enrolment['canunenrol']) {
$icon = html_writer::empty_tag('img', array('alt'=>$strunenrol, 'src'=>$iconenrolremove));
$url = new moodle_url($pageurl, array('action'=>'unenrol', 'ue'=>$ueid));
$enrolmentoutput .= html_writer::link($url, $icon, array('class'=>'unenrollink', 'rel'=>$ueid));
}
if ($enrolment['canmanage']) {
$icon = html_writer::empty_tag('img', array('alt'=>$stredit, 'src'=>$iconedit));
$url = new moodle_url($url, array('action'=>'edit', 'ue'=>$ueid));
$enrolmentoutput .= html_writer::link($url, $icon, array('class'=>'editenrollink', 'rel'=>$ueid));
}
$output .= html_writer::tag('div', $enrolmentoutput, array('class'=>'enrolment'));
}
return $output;
}
}
/**
* Main course enrolment table
*
* This table is used to display the enrolment information for a course.
* It requires that a course enrolment manager be provided during constuct with
* provides all of the information for the table.
* The control then produces the table, the paging, and the associated JS actions
* for the page.
*
* @package core
* @subpackage enrol
* @copyright 2010 Sam Hemelryk
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class course_enrolment_table extends html_table implements renderable {
/**
* The get/post variable that is used to identify the page.
* Default: page
*/
const PAGEVAR = 'page';
/**
* The get/post variable to is used to identify the number of items to display
* per page.
* Default: perpage
*/
const PERPAGEVAR = 'perpage';
/**
* The get/post variable that is used to identify the sort field for the table.
* Default: sort
*/
const SORTVAR = 'sort';
/**
* The get/post variable that is used to identify the sort direction for the table.
* Default: dir
*/
const SORTDIRECTIONVAR = 'dir';
/**
* The default number of items per page.
* Default: 20
*/
const DEFAULTPERPAGE = 20;
/**
* The default sort, options are course_enrolment_table::$sortablefields
* Default: lastname
*/
const DEFAULTSORT = 'lastname';
/**
* The default direction
* Default: ASC
*/
const DEFAULTSORTDIRECTION = 'ASC';
/**
* The current page, starting from 0
* @var int
*/
public $page = 0;
/**
* The total number of pages
* @var int
*/
public $pages = 0;
/**
* The number of items to display per page
* @var int
*/
public $perpage = 0;
/**
* The URL of the page for this table
* @var moodle_url
*/
public $pageurl;
/**
* The sort field for this table, should be one of course_enrolment_table::$sortablefields
* @var string
*/
public $sort;
/**
* The sort direction, either ASC or DESC
* @var string
*/
public $sortdirection;
/**
* The course manager this table is displaying for
* @var course_enrolment_manager
*/
protected $manager;
/**
* The paging bar that controls the paging for this table
* @var paging_bar
*/
protected $pagingbar = null;
/**
* The total number of users enrolled in the course
* @var int
*/
protected $totalusers = null;
/**
* The users enrolled in this course
* @var array
*/
protected $users = null;
/**
* The fields for this table
* @var array
*/
protected $fields = array();
protected static $sortablefields = array('firstname', 'lastname', 'email', 'lastaccess');
/**
* Constructs the table
*
* @param course_enrolment_manager $manager
*/
public function __construct(course_enrolment_manager $manager, moodle_url $pageurl) {
$this->manager = $manager;
$this->pageurl = $pageurl;
$this->page = optional_param(self::PAGEVAR, 0, PARAM_INT);
$this->perpage = optional_param(self::PERPAGEVAR, self::DEFAULTPERPAGE, PARAM_INT);
$this->sort = optional_param(self::SORTVAR, self::DEFAULTSORT, PARAM_ALPHA);
$this->sortdirection = optional_param(self::SORTDIRECTIONVAR, self::DEFAULTSORTDIRECTION, PARAM_ALPHA);
$this->attributes = array('class'=>'userenrolment');
if (!in_array($this->sort, self::$sortablefields)) {
$this->sort = self::DEFAULTSORT;
}
if ($this->page < 0) {
$this->page = 0;
}
if ($this->sortdirection !== 'ASC' && $this->sortdirection !== 'DESC') {
$this->sortdirection = self::DEFAULTSORTDIRECTION;
}
$this->id = html_writer::random_id();
$this->set_total_users($manager->get_total_users());
}
/**
* Gets the sort direction for a given field
*
* @param string $field
* @return string ASC or DESC
*/
public function get_field_sort_direction($field) {
if ($field == $this->sort) {
return ($this->sortdirection == 'ASC')?'DESC':'ASC';
}
return self::DEFAULTSORTDIRECTION;
}
/**
* Sets the fields for this table. These get added to the tables head as well.
*
* You can also use a multi dimensional array for this to have multiple fields
* in a single column
*
* @param array $fields An array of fields to set
* @param string $output
*/
public function set_fields($fields, $output=null) {
global $OUTPUT;
if ($output === null) {
$output = $OUTPUT;
}
$this->fields = $fields;
$this->head = array();
$this->colclasses = array();
$this->align = array();
$url = new moodle_url($this->pageurl, $this->get_url_params()+$this->manager->get_url_params());
foreach ($fields as $name => $label) {
$newlabel = '';
if (is_array($label)) {
$bits = array();
foreach ($label as $n => $l) {
if ($l === false) {
continue;
}
if (!in_array($n, self::$sortablefields)) {
$bits[] = $l;
} else {
$link = html_writer::link(new moodle_url($url, array(self::SORTVAR=>$n)), $fields[$name][$n]);
if ($this->sort == $n) {
$link .= ' '.html_writer::link(new moodle_url($url, array(self::SORTVAR=>$n, self::SORTDIRECTIONVAR=>$this->get_field_sort_direction($n))), $this->get_direction_icon($output, $n));
}
$bits[] = html_writer::tag('span', $link, array('class'=>'subheading_'.$n));
}
}
$newlabel = join(' / ', $bits);
} else {
if (!in_array($name, self::$sortablefields)) {
$newlabel = $label;
} else {
$newlabel = html_writer::link(new moodle_url($url, array(self::SORTVAR=>$name)), $fields[$name]);
if ($this->sort == $name) {
$newlabel .= ' '.html_writer::link(new moodle_url($url, array(self::SORTVAR=>$name, self::SORTDIRECTIONVAR=>$this->get_field_sort_direction($name))), $this->get_direction_icon($output, $name));
}
}
}
$this->head[] = $newlabel;
$this->colclasses[] = 'field col_'.$name;
}
}
/**
* Sets the total number of users
*
* @param int $totalusers
*/
public function set_total_users($totalusers) {
$this->totalusers = $totalusers;
$this->pages = ceil($this->totalusers / $this->perpage);
if ($this->page > $this->pages) {
$this->page = $this->pages;
}
}
/**
*/
/**
* Sets the users for this table
*
* @param array $users
* @param moodle_page $page
*/
public function set_users(array $users, moodle_page $page=null) {
global $PAGE;
if ($page === null) {
$page = $PAGE;
}
foreach ($users as $userid=>$user) {
$user = (array)$user;
$row = new html_table_row();
$row->attributes = array('class' => 'userinforow');
$row->id = 'user_'.$userid;
$row->cells = array();
foreach ($this->fields as $field => $label) {
if (is_array($label)) {
$bits = array();
foreach (array_keys($label) as $subfield) {
if (array_key_exists($subfield, $user)) {
$bits[] = html_writer::tag('div', $user[$subfield], array('class'=>'subfield subfield_'.$subfield));
}
}
if (empty($bits)) {
$bits[] = '&nbsp;';
}
$row->cells[] = new html_table_cell(join(' ', $bits));
} else {
if (!array_key_exists($field, $user)) {
$user[$field] = '&nbsp;';
}
$row->cells[] = new html_table_cell($user[$field]);
}
}
$this->data[] = $row;
}
if (has_capability('moodle/role:assign', $this->manager->get_context())) {
$arguments = array(array('containerId'=>$this->id, 'userIds'=>array_keys($users), 'courseId'=>$this->manager->get_course()->id));
$page->requires->yui_module(array('moodle-enrol-rolemanager', 'moodle-enrol-rolemanager-skin'), 'M.enrol.rolemanager.init', $arguments);
}
}
/**
* Gets the paging bar instance for this table
*
* @return paging_bar
*/
public function get_paging_bar() {
if ($this->pagingbar == null) {
$this->pagingbar = new paging_bar($this->totalusers, $this->page, $this->perpage, $this->pageurl, self::PAGEVAR);
}
return $this->pagingbar;
}
/**
* Gets the direction icon for the sortable field within this table
*
* @param core_renderer $output
* @param string $field
* @return string
*/
protected function get_direction_icon($output, $field) {
$direction = self::DEFAULTSORTDIRECTION;
if ($this->sort == $field) {
$direction = $this->sortdirection;
}
if ($direction === 'ASC') {
return html_writer::empty_tag('img', array('alt'=>'', 'src'=>$output->pix_url('t/down')));
} else {
return html_writer::empty_tag('img', array('alt'=>'', 'src'=>$output->pix_url('t/up')));
}
}
/**
* Gets the params that will need to be added to the url in order to return to this page.
*
* @return array
*/
public function get_url_params() {
return array(
self::PAGEVAR => $this->page,
self::PERPAGEVAR => $this->perpage,
self::SORTVAR => $this->sort,
self::SORTDIRECTIONVAR => $this->sortdirection
);
}
/**
* Gets the enrolment type filter control for this table
*
* @return single_select
*/
public function get_enrolment_type_filter() {
$url = new moodle_url($this->pageurl, $this->manager->get_url_params()+$this->get_url_params());
$selector = new single_select($url, 'ifilter', array(0=>get_string('all')) + $this->manager->get_enrolment_instance_names(), $this->manager->get_enrolment_filter(), array());
$selector->set_label( get_string('enrolmentinstances', 'enrol'));
return $selector;
}
/**
* Gets the enrolment selector control for this table and initialises its
* JavaScript
*
* @return single_button|url_select
*/
public function get_enrolment_selector(moodle_page $page) {
static $count = 0;
$instances = $this->manager->get_enrolment_instances();
$plugins = $this->manager->get_enrolment_plugins();
// print enrol link or selection
$links = array();
foreach($instances as $instance) {
$plugin = $plugins[$instance->enrol];
if ($link = $plugin->get_manual_enrol_link($instance)) {
$links[$instance->id] = $link;
}
}
if (!empty($links)) {
$arguments = array();
$count ++;
if (count($links) == 1) {
$control = new single_button(reset($links), get_string('enrolusers', 'enrol_manual'), 'get');
$control->class = 'singlebutton enrolusersbutton instance'.$count;
$control->formid = 'manuallyenrol_single_'+$count;
$arguments[] = array('id'=>key($links), 'name'=>$plugins[$instances[key($links)]->enrol]->get_instance_name($instances[key($links)]));
} else if (count($links) > 1) {
$inames = $this->manager->get_enrolment_instance_names();
$options = array();
foreach ($links as $i=>$link) {
$options[$link->out(false)] = $inames[$i];
$arguments[] = array('id'=>$i, 'name'=>$plugins[$instances[$i]->enrol]->get_instance_name($instances[$i]));
}
$control = new url_select($options, '', array(''=>get_string('enrolusers', 'enrol_manual').'...'));
$control->class = 'singlebutton enrolusersbutton instance'.$count;
$control->formid = 'manuallyenrol_select_'+$count;
}
$course = $this->manager->get_course();
$url = new moodle_url($this->pageurl, $this->manager->get_url_params()+$this->get_url_params());
$timeformat = get_string('strftimedatefullshort');
$today = time();
$today = make_timestamp(date('Y', $today), date('m', $today), date('d', $today), 0, 0, 0);
$startdateoptions = array();
if ($course->startdate > 0) {
$startdateoptions[2] = get_string('coursestart') . ' (' . userdate($course->startdate, $timeformat) . ')';
}
$startdateoptions[3] = get_string('today') . ' (' . userdate($today, $timeformat) . ')' ;
if ($count == 1) {
$page->requires->strings_for_js(array(
'ajaxoneuserfound',
'ajaxxusersfound',
'ajaxnext25',
'enrol',
'enrolmentoptions',
'enrolusers',
'errajaxfailedenrol',
'errajaxsearch',
'none',
'usersearch',
'unlimitedduration',
'startdatetoday',
'durationdays',
'enrolperiod'), 'enrol');
$page->requires->string_for_js('assignroles', 'role');
$page->requires->string_for_js('startingfrom', 'moodle');
$arguments = array(array(
'instances'=>$arguments,
'courseid'=>$course->id,
'ajaxurl'=>'/enrol/ajax.php',
'url'=>$url->out(false),
'optionsStartDate'=>$startdateoptions));
$page->requires->yui_module(array('moodle-enrol-enrolmentmanager', 'moodle-enrol-enrolmentmanager-skin'), 'M.enrol.enrolmentmanager.init', $arguments);
}
return $control;
}
return null;
}
}
+126 -428
View File
@@ -17,138 +17,80 @@
/**
* Main course enrolment management UI, this is not compatible with frontpage course.
*
* @package core
* @subpackage enrol
* @package moodlecore
* @copyright 2010 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require('../config.php');
require_once("$CFG->dirroot/enrol/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
$action = optional_param('action', '', PARAM_ACTION);
$confirm = optional_param('confirm', 0, PARAM_BOOL);
$ifilter = optional_param('ifilter', 0, PARAM_INT); // only one instance
$page = optional_param('page', 0, PARAM_INT);
$perpage = optional_param('perpage', 20, PARAM_INT);
$sort = optional_param('sort', 'lastname', PARAM_ALPHA);
$dir = optional_param('dir', 'ASC', PARAM_ALPHA);
$filter = optional_param('ifilter', 0, PARAM_INT);
$PAGE->set_url(new moodle_url('/enrol/users.php', array('id'=>$id)));
$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);
if ($course->id == SITEID) {
redirect("$CFG->wwwroot/");
}
$managegroups = has_capability('moodle/course:managegroups', $context);
$instances = enrol_get_instances($course->id, true);
$plugins = enrol_get_plugins(true);
$inames = array();
foreach ($instances as $k=>$i) {
if (!isset($plugins[$i->enrol])) {
// weird, some broken stuff in plugin
unset($instances[$k]);
continue;
}
$inames[$k] = $plugins[$i->enrol]->get_instance_name($i);
}
// validate paging params
if ($ifilter != 0 and !isset($instances[$ifilter])) {
$ifilter = 0;
}
if ($perpage < 3) {
$perpage = 3;
}
if ($page < 0) {
$page = 0;
}
if (!in_array($dir, array('ASC', 'DESC'))) {
$dir = 'ASC';
}
if (!in_array($sort, array('firstname', 'lastname', 'email', 'lastseen'))) {
$dir = 'lastname';
}
$PAGE->set_url('/enrol/users.php', array('id'=>$course->id, 'page'=>$page, 'sort'=>$sort, 'dir'=>$dir, 'perpage'=>$perpage, 'ifilter'=>$ifilter));
$PAGE->set_pagelayout('admin');
//lalala- nav hack
navigation_node::override_active_url(new moodle_url('/enrol/users.php', array('id'=>$course->id)));
$allroles = get_all_roles();
$allroles = role_fix_names($allroles, $context);
$assignable = get_assignable_roles($context, ROLENAME_ALIAS, false); // verifies unassign access control too
$allgroups = groups_get_all_groups($course->id);
foreach ($allgroups as $gid=>$group) {
$allgroups[$gid]->name = format_string($group->name);
}
$manager = new course_enrolment_manager($course, $filter);
$table = new course_enrolment_table($manager, $PAGE->url);
$pageurl = new moodle_url($PAGE->url, $manager->get_url_params()+$table->get_url_params());
// Check if there is an action to take
if ($action) {
// Check if the page is confirmed (and sesskey is correct)
$confirm = optional_param('confirm', false, PARAM_BOOL) && confirm_sesskey();
$actiontaken = false;
$pagetitle = '';
$pageheading = '';
$mform = null;
$pagecontent = null;
switch ($action) {
case 'unenrol':
$ue = required_param('ue', PARAM_INT);
if (!$ue = $DB->get_record('user_enrolments', array('id'=>$ue))) {
break;
}
$user = $DB->get_record('user', array('id'=>$ue->userid), '*', MUST_EXIST);
if (!isset($instances[$ue->enrolid])) {
break;
}
$instance = $instances[$ue->enrolid];
$plugin = $plugins[$instance->enrol];
if (!$plugin->allow_unenrol($instance) or !has_capability("enrol/$instance->enrol:unenrol", $context)) {
break;
}
if ($confirm and confirm_sesskey()) {
$plugin->unenrol_user($instance, $ue->userid);
redirect($PAGE->url);
$ue = $DB->get_record('user_enrolments', array('id'=>required_param('ue', PARAM_INT)), '*', MUST_EXIST);
if ($confirm && $manager->unenrol_user($ue)) {
redirect($pageurl);
} else {
$yesurl = new moodle_url($PAGE->url, array('action'=>'unenrol', 'ue'=>$ue->id, 'confirm'=>1, 'sesskey'=>sesskey()));
$user = $DB->get_record('user', array('id'=>$ue->userid), '*', MUST_EXIST);
$yesurl = new moodle_url($pageurl, array('action'=>'unenrol', 'ue'=>$ue->id, 'confirm'=>1, 'sesskey'=>sesskey()));
$message = get_string('unenrolconfirm', 'enrol', array('user'=>fullname($user, true), 'course'=>format_string($course->fullname)));
$PAGE->set_title(get_string('unenrol', 'enrol'));
echo $OUTPUT->header();
echo $OUTPUT->heading(get_string('unenrol', 'enrol'));
echo $OUTPUT->confirm($message, $yesurl, $PAGE->url);
echo $OUTPUT->footer();
die;
$pagetitle = get_string('unenrol', 'enrol');
$pagecontent = $OUTPUT->confirm($message, $yesurl, $pageurl);
}
$actiontaken = true;
break;
case 'unassign':
$role = required_param('role', PARAM_INT);
$user = required_param('user', PARAM_INT);
if (!isset($assignable[$role])) {
break;
}
$role = $allroles[$role];
$user = $DB->get_record('user', array('id'=>$user), '*', MUST_EXIST);
if ($confirm and confirm_sesskey()) {
role_unassign($role->id, $user->id, $context->id, '', NULL);
redirect($PAGE->url);
if ($confirm && $manager->unassign_role_from_user($user, $role)) {
redirect($pageurl);
} else {
$yesurl = new moodle_url($PAGE->url, array('action'=>'unassign', 'role'=>$role->id, 'user'=>$user->id, 'confirm'=>1, 'sesskey'=>sesskey()));
$user = $DB->get_record('user', array('id'=>$user), '*', MUST_EXIST);
$allroles = $manager->get_all_roles();
$role = $allroles[$role];
$yesurl = new moodle_url($pageurl, array('action'=>'unassign', 'role'=>$role->id, 'user'=>$user->id, 'confirm'=>1, 'sesskey'=>sesskey()));
$message = get_string('unassignconfirm', 'role', array('user'=>fullname($user, true), 'role'=>$role->localname));
$PAGE->set_title(get_string('unassignarole', 'role', $role->localname));
echo $OUTPUT->header();
echo $OUTPUT->heading(get_string('unassignarole', 'role', $role->localname));
echo $OUTPUT->confirm($message, $yesurl, $PAGE->url);
echo $OUTPUT->footer();
die;
$pagetitle = get_string('unassignarole', 'role', $role->localname);
$pagecontent = $OUTPUT->confirm($message, $yesurl, $pageurl);
}
$actiontaken = true;
break;
case 'assign':
@@ -159,363 +101,119 @@ if ($action) {
break; // no roles without enrolments here in this script
}
$mform = new enrol_users_assign_form(NULL, array('user'=>$user, 'course'=>$course, 'assignable'=>$assignable));
if ($mform->is_cancelled()) {
redirect($PAGE->url);
} else if ($data = $mform->get_data()) {
if ($data->roleid) {
role_assign($data->roleid, $user->id, $context->id, '', NULL);
}
redirect($PAGE->url);
$mform = new enrol_users_assign_form(NULL, array('user'=>$user, 'course'=>$course, 'assignable'=>$manager->get_assignable_roles()));
$mform->set_data($pageurl->params());
$data = $mform->get_data();
if ($mform->is_cancelled() || ($data && $manager->assign_role_to_user($data->roleid, $user->id))) {
redirect($pageurl);
} else {
$pagetitle = get_string('assignroles', 'role');
}
$PAGE->set_title(get_string('assignroles', 'role'));
echo $OUTPUT->header();
echo $OUTPUT->heading(get_string('assignroles', 'role'));
$mform->display();
echo $OUTPUT->footer();
die;
$actiontaken = true;
break;
case 'removemember':
$group = required_param('group', PARAM_INT);
$user = required_param('user', PARAM_INT);
if (!$managegroups) {
break;
}
if (!isset($allgroups[$group])) {
break;
}
$group = $allgroups[$group];
$user = $DB->get_record('user', array('id'=>$user), '*', MUST_EXIST);
if ($confirm and confirm_sesskey()) {
groups_remove_member($group, $user);
redirect($PAGE->url);
$groupid = required_param('group', PARAM_INT);
$userid = required_param('user', PARAM_INT);
$user = $DB->get_record('user', array('id'=>$userid), '*', MUST_EXIST);
if ($confirm && $manager->remove_user_from_group($user, $groupid)) {
redirect($pageurl);
} else {
$yesurl = new moodle_url($PAGE->url, array('action'=>'removemember', 'group'=>$group->id, 'user'=>$user->id, 'confirm'=>1, 'sesskey'=>sesskey()));
$group = $manager->get_group($groupid);
if (!$group) {
break;
}
$yesurl = new moodle_url($pageurl, array('action'=>'removemember', 'group'=>$groupid, 'user'=>$userid, 'confirm'=>1, 'sesskey'=>sesskey()));
$message = get_string('removefromgroupconfirm', 'group', array('user'=>fullname($user, true), 'group'=>$group->name));
$PAGE->set_title(get_string('removefromgroup', 'group', $group->name));
echo $OUTPUT->header();
echo $OUTPUT->heading(get_string('removefromgroup', 'group', $group->name));
echo $OUTPUT->confirm($message, $yesurl, $PAGE->url);
echo $OUTPUT->footer();
die;
$pagetitle = get_string('removefromgroup', 'group', $group->name);
$pagecontent = $OUTPUT->confirm($message, $yesurl, $pageurl);
}
$actiontaken = true;
break;
case 'addmember':
$user = required_param('user', PARAM_INT);
$user = $DB->get_record('user', array('id'=>$user), '*', MUST_EXIST);
$userid = required_param('user', PARAM_INT);
$user = $DB->get_record('user', array('id'=>$userid), '*', MUST_EXIST);
if (!$managegroups) {
break;
$mform = new enrol_users_addmember_form(NULL, array('user'=>$user, 'course'=>$course, 'allgroups'=>$manager->get_all_groups()));
$mform->set_data($pageurl->params());
$data = $mform->get_data();
if ($mform->is_cancelled() || ($data && $manager->add_user_to_group($user, $data->groupid))) {
redirect($pageurl);
} else {
$pagetitle = get_string('addgroup', 'group');
}
if (!is_enrolled($context, $user)) {
break; // no roles without enrolments here in this script
}
$mform = new enrol_users_addmember_form(NULL, array('user'=>$user, 'course'=>$course, 'allgroups'=>$allgroups));
if ($mform->is_cancelled()) {
redirect($PAGE->url);
} else if ($data = $mform->get_data()) {
if ($data->groupid) {
groups_add_member($data->groupid, $user->id);
}
redirect($PAGE->url);
}
$PAGE->set_title(get_string('addgroup', 'group'));
echo $OUTPUT->header();
echo $OUTPUT->heading(get_string('addgroup', 'group'));
$mform->display();
echo $OUTPUT->footer();
die;
$actiontaken = true;
break;
case 'edit':
$ue = required_param('ue', PARAM_INT);
if (!$ue = $DB->get_record('user_enrolments', array('id'=>$ue))) {
$actiontaken = false;
break;
}
$user = $DB->get_record('user', array('id'=>$ue->userid), '*', MUST_EXIST);
if (!isset($instances[$ue->enrolid])) {
break;
}
$instance = $instances[$ue->enrolid];
$plugin = $plugins[$instance->enrol];
if (!$plugin->allow_unenrol($instance) or !has_capability("enrol/$instance->enrol:unenrol", $context)) {
break;
}
$mform = new enrol_users_edit_form(NULL, array('user'=>$user, 'course'=>$course, 'ue'=>$ue));
if ($mform->is_cancelled()) {
redirect($PAGE->url);
} else if ($data = $mform->get_data()) {
if (!isset($data->status)) {
$status = $ue->status;
}
$plugin->update_user_enrol($instance, $ue->userid, $data->status, $data->timestart, $data->timeend);
redirect($PAGE->url);
$mform->set_data($pageurl->params());
$data = $mform->get_data();
if ($mform->is_cancelled() || ($data && $manager->edit_enrolment($ue, $data))) {
redirect($pageurl);
} else {
$pagetitle = fullname($user);
}
$actiontaken = true;
break;
}
$PAGE->set_title(fullname($user));
echo $OUTPUT->header();
echo $OUTPUT->heading(fullname($user));
if ($actiontaken) {
if (empty($pageheading)) {
$pageheading = $pagetitle;
}
$PAGE->set_title($pagetitle);
$PAGE->set_heading($pageheading);
echo $OUTPUT->header();
echo $OUTPUT->heading(fullname($user));
if (!is_null($mform)) {
$mform->display();
echo $OUTPUT->footer();
die;
} else {
echo $pagecontent;
}
echo $OUTPUT->footer();
exit;
}
}
$fields = array(
'userdetails' => array (
'picture' => false,
'firstname' => get_string('firstname'),
'lastname' => get_string('lastname'),
'email' => get_string('email')
),
'lastseen' => get_string('lastaccess'),
'role' => get_string('roles', 'role'),
'group' => get_string('groups', 'group'),
'enrol' => get_string('enrolmentinstances', 'enrol')
);
$table->set_fields($fields);
$renderer = $PAGE->get_renderer('core_enrol');
$canassign = has_capability('moodle/role:assign', $manager->get_context());
$users = $manager->get_users_for_display($renderer, $pageurl, $table->sort, $table->sortdirection, $table->page, $table->perpage);
foreach ($users as $userid=>&$user) {
$user['picture'] = $OUTPUT->render($user['picture']);
$user['role'] = $renderer->user_roles_and_actions($userid, $user['roles'], $manager->get_assignable_roles(), $canassign, $pageurl);
$user['group'] = $renderer->user_groups_and_actions($userid, $user['groups'], $manager->get_all_groups(), has_capability('moodle/course:managegroups', $manager->get_context()), $pageurl);
$user['enrol'] = $renderer->user_enrolments_and_actions($userid, $user['enrolments'], $pageurl);
}
$table->set_users($users);
$PAGE->set_title(get_string('enrolledusers', 'enrol'));
$PAGE->set_heading($PAGE->course->fullname);
echo $OUTPUT->header();
echo $OUTPUT->heading(get_string('enrolledusers', 'enrol'));
$PAGE->set_title(get_string('enrolledusers', 'enrol'));
notify('NOTICE TO TESTERS: This interface will shortly be replaced with a new one.'); // TODO FIXME REMOVE THIS
if ($ifilter) {
$instancessql = " = :ifilter";
$params = array('ifilter'=>$ifilter);
} else {
if ($instances) {
list($instancessql, $params) = $DB->get_in_or_equal(array_keys($instances), SQL_PARAMS_NAMED);
} else {
// no enabled instances, oops, we should probably say something
$instancessql = "= :never";
$params = array('never'=>-1);
}
}
$sqltotal = "SELECT COUNT(DISTINCT u.id)
FROM {user} u
JOIN {user_enrolments} ue ON (ue.userid = u.id AND ue.enrolid $instancessql)
JOIN {enrol} e ON (e.id = ue.enrolid)";
$totalusers = $DB->count_records_sql($sqltotal, $params);
$ufields = user_picture::fields('u');
$sql = "SELECT DISTINCT $ufields, ul.timeaccess AS lastseen
FROM {user} u
JOIN {user_enrolments} ue ON (ue.userid = u.id AND ue.enrolid $instancessql)
JOIN {enrol} e ON (e.id = ue.enrolid)
LEFT JOIN {user_lastaccess} ul ON (ul.courseid = e.courseid AND ul.userid = u.id)";
if ($sort === 'firstname') {
$sql .= " ORDER BY u.firstname $dir, u.lastname $dir";
} else if ($sort === 'lastname') {
$sql .= " ORDER BY u.lastname $dir, u.firstname $dir";
} else if ($sort === 'email') {
$sql .= " ORDER BY u.email $dir, u.lastname $dir, u.firstname $dir";
} else if ($sort === 'lastseen') {
$sql .= " ORDER BY ul.timeaccess $dir, u.lastname $dir, u.firstname $dir";
}
$pagingbar = new paging_bar($totalusers, $page, $perpage, $PAGE->url, 'page');
$users = $DB->get_records_sql($sql, $params, $page*$perpage, $perpage);
$strfirstname = get_string('firstname');
$strlastname = get_string('lastname');
$stremail = get_string('email');
$strlastseen = get_string('lastaccess');
if ($dir === 'ASC') {
$diricon = html_writer::empty_tag('img', array('alt'=>'', 'src'=>$OUTPUT->pix_url('t/down')));
$newdir = 'DESC';
} else {
$diricon = html_writer::empty_tag('img', array('alt'=>'', 'src'=>$OUTPUT->pix_url('t/up')));
$newdir = 'ASC';
}
$table = new html_table();
$table->head = array();
if ($sort === 'firstname') {
$h = html_writer::link(new moodle_url($PAGE->url, array('dir'=>$newdir)), $strfirstname);
$h .= " $diricon / ";
$h .= html_writer::link(new moodle_url($PAGE->url, array('sort'=>'lastname')), $strlastname);
} else if ($sort === 'lastname') {
$newdir = ($dir === 'ASC') ? 'DESC' : 'ASC';
$h = html_writer::link(new moodle_url($PAGE->url, array('sort'=>'firstname')), $strfirstname);
$h .= " / ";
$h .= html_writer::link(new moodle_url($PAGE->url, array('dir'=>$newdir)), $strlastname);
$h .= " $diricon";
} else {
$h = html_writer::link(new moodle_url($PAGE->url, array('sort'=>'firstname')), $strfirstname);
$h .= " / ";
$h .= html_writer::link(new moodle_url($PAGE->url, array('sort'=>'lastname')), $strlastname);
}
$table->head[] = $h;
if ($sort === 'email') {
$h = html_writer::link(new moodle_url($PAGE->url, array('dir'=>$newdir)), $stremail);
$h .= " $diricon";
} else {
$h = html_writer::link(new moodle_url($PAGE->url, array('sort'=>'email')), $stremail);
}
$table->head[] = $h;
if ($sort === 'lastseen') {
$h = html_writer::link(new moodle_url($PAGE->url, array('dir'=>$newdir)), $strlastseen);
$h .= " $diricon";
} else {
$h = html_writer::link(new moodle_url($PAGE->url, array('sort'=>'lastseen')), $strlastseen);
}
$table->head[] = $h;
$table->head[] = get_string('roles', 'role');
$table->head[] = get_string('groups', 'group');
$table->head[] = get_string('enrolmentinstances', 'enrol');
$table->align = array('left', 'left', 'left', 'left', 'left', 'left');
$table->width = "95%";
foreach ($users as $user) {
$picture = $OUTPUT->user_picture($user, array('courseid'=>$course->id));
if ($user->lastseen) {
$strlastaccess = userdate($user->lastseen);
} else {
$strlastaccess = get_string('never');
}
$fullname = fullname($user, true);
// get list of roles
$roles = array();
$ras = get_user_roles($context, $user->id, true, 'c.contextlevel DESC, r.sortorder ASC');
foreach ($ras as $ra) {
if ($ra->contextid != $context->id) {
if (!isset($roles[$ra->roleid])) {
$roles[$ra->roleid] = null;
}
// higher ras, course always takes precedence
continue;
}
if (isset($roles[$ra->roleid]) and $roles[$ra->roleid] === false) {
continue;
}
$roles[$ra->roleid] = ($ra->itemid == 0 and $ra->component === '');
}
foreach ($roles as $rid=>$unassignable) {
if ($unassignable and isset($assignable[$rid])) {
$icon = html_writer::empty_tag('img', array('alt'=>get_string('unassignarole', 'role', $allroles[$rid]->localname), 'src'=>$OUTPUT->pix_url('t/delete')));
$url = new moodle_url($PAGE->url, array('action'=>'unassign', 'role'=>$rid, 'user'=>$user->id));
$roles[$rid] = $allroles[$rid]->localname . html_writer::link($url, $icon);
} else {
$roles[$rid] = $allroles[$rid]->localname;
}
}
$addrole = '';
if ($assignable) {
foreach ($assignable as $rid=>$unused) {
if (!isset($roles[$rid])) {
//candidate for role assignment
$icon = html_writer::empty_tag('img', array('alt'=>get_string('assignroles', 'role'), 'src'=>$OUTPUT->pix_url('t/add')));
$url = new moodle_url($PAGE->url, array('action'=>'assign', 'user'=>$user->id));
$addrole .= html_writer::link($url, $icon);
break;
}
}
}
$roles = implode(', ', $roles);
if ($addrole) {
$roles = $roles . '<div>'.$addrole.'</div>';
}
$groups = array();
$usergroups = groups_get_all_groups($course->id, $user->id, 0, 'g.id');
foreach($usergroups as $gid=>$unused) {
$group = $allgroups[$gid];
if ($managegroups) {
$icon = html_writer::empty_tag('img', array('alt'=>get_string('removefromgroup', 'group', $group->name), 'src'=>$OUTPUT->pix_url('t/delete')));
$url = new moodle_url($PAGE->url, array('action'=>'removemember', 'group'=>$gid, 'user'=>$user->id));
$groups[] = $group->name . html_writer::link($url, $icon);
} else {
$groups[] = $group->name;
}
}
$groups = implode(', ', $groups);
if ($managegroups and (count($usergroups) < count($allgroups))) {
$icon = html_writer::empty_tag('img', array('alt'=>get_string('addgroup', 'group'), 'src'=>$OUTPUT->pix_url('t/add')));
$url = new moodle_url($PAGE->url, array('action'=>'addmember', 'user'=>$user->id));
$groups .= '<div>'.html_writer::link($url, $icon).'</div>';
}
// get list of enrol instances
$now = time();
$edits = array();
$params['userid'] = $user->id;
$ues = $DB->get_records_select('user_enrolments', "enrolid $instancessql AND userid = :userid", $params);
foreach ($ues as $ue) {
$instance = $instances[$ue->enrolid];
$plugin = $plugins[$instance->enrol];
$edit = $inames[$instance->id];
$dimmed = false;
if ($ue->timestart and $ue->timeend) {
$edit .= '&nbsp;('.get_string('periodstartend', 'enrol', array('start'=>userdate($ue->timestart), 'end'=>userdate($ue->timeend))).')';
$dimmed = ($now < $ue->timestart and $now > $ue->timeend);
} else if ($ue->timestart) {
$edit .= '&nbsp;('.get_string('periodstart', 'enrol', userdate($ue->timestart)).')';
$dimmed = ($now < $ue->timestart);
} else if ($ue->timeend) {
$edit .= '&nbsp;('.get_string('periodend', 'enrol', userdate($ue->timeend)).')';
$dimmed = ($now > $ue->timeend);
}
if ($dimmed or $ue->status != ENROL_USER_ACTIVE) {
$edit = html_writer::tag('span', $edit, array('class'=>'dimmed_text'));
}
if ($plugin->allow_unenrol($instance) and has_capability("enrol/$instance->enrol:unenrol", $context)) {
$icon = html_writer::empty_tag('img', array('alt'=>get_string('unenrol', 'enrol'), 'src'=>$OUTPUT->pix_url('t/delete')));
$url = new moodle_url($PAGE->url, array('action'=>'unenrol', 'ue'=>$ue->id));
$edit .= html_writer::link($url, $icon);
}
if ($plugin->allow_manage($instance) and has_capability("enrol/$instance->enrol:manage", $context)) {
$icon = html_writer::empty_tag('img', array('alt'=>get_string('edit'), 'src'=>$OUTPUT->pix_url('t/edit')));
$url = new moodle_url($PAGE->url, array('action'=>'edit', 'ue'=>$ue->id));
$edit .= html_writer::link($url, $icon);
}
$edits[] = $edit;
}
$edits = implode('<br />', $edits);
$table->data[] = array("$picture <a href=\"$CFG->wwwroot/user/view.php?id=$user->id&amp;course=$course->id\">$fullname</a>", $user->email, $strlastaccess, $roles, $groups, $edits);
}
$ifilters = new single_select($PAGE->url, 'ifilter', array(0=>get_string('all')) + $inames, $ifilter, array());
$ifilters->set_label(get_string('enrolmentinstances', 'enrol'));
echo $OUTPUT->render($ifilters);
echo $OUTPUT->render($pagingbar);
echo html_writer::table($table);
echo $OUTPUT->render($pagingbar);
// print enrol link or selection
$links = array();
foreach($instances as $instance) {
$plugin = $plugins[$instance->enrol];
if ($link = $plugin->get_manual_enrol_link($instance)) {
$links[$instance->id] = $link;
}
}
if (count($links) == 1) {
$link = reset($links);
echo $OUTPUT->single_button($link, get_string('enrolusers', 'enrol_manual'), 'get');
} else if (count($links) > 1) {
$options = array();
foreach ($links as $i=>$link) {
$options[$link->out(false)] = $inames[$i];
}
echo $OUTPUT->url_select($options, '', array(''=>get_string('enrolusers', 'enrol_manual').'...'));
}
echo $renderer->render($table);
echo $OUTPUT->footer();
+3 -6
View File
@@ -30,7 +30,7 @@ require_once("$CFG->libdir/formslib.php");
class enrol_users_assign_form extends moodleform {
function definition() {
global $CFG, $DB, $PAGE;
global $CFG, $DB;
$mform = $this->_form;
@@ -75,14 +75,13 @@ class enrol_users_assign_form extends moodleform {
$this->add_action_buttons();
$this->set_data($PAGE->url->params());
$this->set_data(array('action'=>'assign', 'user'=>$user->id));
}
}
class enrol_users_addmember_form extends moodleform {
function definition() {
global $CFG, $DB, $PAGE;
global $CFG, $DB;
$mform = $this->_form;
@@ -130,14 +129,13 @@ class enrol_users_addmember_form extends moodleform {
$this->add_action_buttons();
$this->set_data($PAGE->url->params());
$this->set_data(array('action'=>'addmember', 'user'=>$user->id));
}
}
class enrol_users_edit_form extends moodleform {
function definition() {
global $CFG, $DB, $PAGE;
global $CFG, $DB;
$mform = $this->_form;
@@ -184,7 +182,6 @@ class enrol_users_edit_form extends moodleform {
$this->add_action_buttons();
$this->set_data($PAGE->url->params());
$this->set_data(array('action'=>'edit', 'ue'=>$ue->id, 'status'=>$ue->status, 'timestart'=>$ue->timestart, 'timeend'=>$ue->timeend));
}
@@ -0,0 +1,71 @@
/**************************************
Structure of the user enroller panel
.user-enroller-panel(.visible)
.uep-wrap
.uep-header
.uep-content
.uep-ajax-content
.uep-search-results
.totalusers
.users
.user.clearfix(.odd|.even)(.enrolled)
.count
.picture
.details
.fullname
.email
.options
.enrol
.uep-more-results
.uep-loading-lightbox(.hidden)
.loading-icon
.uep-footer
.uep-search
input
.uep-searchoptions
.collapsibleheading
.collapsiblearea(.hidden)
.uep-enrolment-option
.role
.startdate
.duration
**************************************/
.user-enroller-panel {width:400px;background-color:#666;position:absolute;top:10%;left:10%;border:1px solid #666;border-width:0 5px 5px 0;}
.user-enroller-panel.hidden {display:none;}
.user-enroller-panel .uep-wrap {margin-top:-5px;margin-left:-5px;background-color:#FFF;border:1px solid #999;height:inherit;}
.user-enroller-panel .uep-header {background-color:#eee;padding:1px;}
.user-enroller-panel .uep-header h2 {margin:3px 1em 0.5em 1em;font-size:1em;}
.user-enroller-panel .uep-header .close {width:25px;height:15px;position:absolute;top:2px;right:1em;cursor:pointer;background:url("sprite.png") no-repeat scroll 0 0 transparent;}
.user-enroller-panel .uep-content {text-align:center;position:relative;width:100%;border-top:1px solid #999;border-bottom:1px solid #999;}
.user-enroller-panel .uep-ajax-content {height:375px;overflow:auto;}
.user-enroller-panel .uep-search-results .totalusers {background-color:#eee;padding:5px;border-bottom:1px solid #BBB;font-size:7pt;font-weight: bold;}
.user-enroller-panel .uep-search-results .user {width:100%;text-align:left;font-size:9pt;border-bottom:1px solid #ddd;border-top:1px solid #eee;}
.user-enroller-panel .uep-search-results .user.odd {border-bottom:1px solid #ddd;border-top:1px solid #eee;background-color:#f9f9f9;}
.user-enroller-panel .uep-search-results .user .count {width:20px;float:left;font-size:7pt;line-height:41px;border-right:1px solid #ddd;background-color:#EEE;text-align:right;padding:2px;}
.user-enroller-panel .uep-search-results .user .picture {width:45px;float:left;margin:3px;}
.user-enroller-panel .uep-search-results .user .details {width:250px;float:left;margin:3px;}
.user-enroller-panel .uep-search-results .user .options {padding-right:7px;font-size:8pt;margin:3px;}
.user-enroller-panel .uep-search-results .user .options .enrol {margin:3px;float:right;border:1px outset #ddd;background-color:#EEE;padding:3px;-moz-border-radius:3px;cursor:pointer;}
.user-enroller-panel .uep-search-results .user.enrolled .count {width:40px;color:#eee;}
.user-enroller-panel .uep-search-results .uep-more-results {background-color:#eee;padding:5px;border-top:1px solid #BBB;}
.user-enroller-panel .uep-loading-lightbox {position:absolute;width:100%;height:100%;top:0;left:0;background-color:#FFF;min-width:50px;min-height:50px;}
.user-enroller-panel .uep-loading-lightbox.hidden {display:none;}
.user-enroller-panel .uep-loading-lightbox .loading-icon {margin:auto;vertical-align:middle;margin-top:125px;}
.user-enroller-panel .uep-footer {padding:3px;background-color:#ddd;}
.user-enroller-panel .uep-search {margin:3px;}
.user-enroller-panel .uep-search label {padding-right:8px;}
.user-enroller-panel .uep-search input {width:70%;}
.user-enroller-panel .uep-searchoptions {margin:3px;cursor:pointer;}
.user-enroller-panel .uep-searchoptions select {margin-left:1em;}
.user-enroller-panel .collapsibleheading img {margin-right:8px;}
.user-enroller-panel .collapsiblearea {border:1px solid #bbb;background-color:#f6f6f6;}
.user-enroller-panel .collapsiblearea.hidden {display:none;}
.user-enroller-panel .collapsiblearea .uep-enrolment-option {margin:5px 1em;}
Binary file not shown.

After

Width:  |  Height:  |  Size: 1002 B

+493
View File
@@ -0,0 +1,493 @@
YUI.add('moodle-enrol-enrolmentmanager', function(Y) {
var UEP = {
NAME : 'Enrolment Manager',
/** Properties **/
BASE : 'base',
SEARCH : 'search',
PARAMS : 'params',
URL : 'url',
AJAXURL : 'ajaxurl',
MULTIPLE : 'multiple',
PAGE : 'page',
COURSEID : 'courseid',
USERS : 'users',
USERCOUNT : 'userCount',
REQUIREREFRESH : 'requiresRefresh',
LASTSEARCH : 'lastPreSearchValue',
INSTANCES : 'instances',
OPTIONSTARTDATE : 'optionsStartDate',
DEFAULTROLE : 'defaultRole',
DEFAULTSTARTDATE : 'defaultStartDate',
DEFAULTDURATION : 'defaultDuration',
ASSIGNABLEROLES : 'assignableRoles'
},
/** CSS classes for nodes in structure **/
CSS = {
PANEL : 'user-enroller-panel',
WRAP : 'uep-wrap',
HEADER : 'uep-header',
CONTENT : 'uep-content',
AJAXCONTENT : 'uep-ajax-content',
SEARCHRESULTS : 'uep-search-results',
TOTALUSERS : 'totalusers',
USERS : 'users',
USER : 'user',
MORERESULTS : 'uep-more-results',
LIGHTBOX : 'uep-loading-lightbox',
LOADINGICON : 'loading-icon',
FOOTER : 'uep-footer',
ENROL : 'enrol',
ENROLLED : 'enrolled',
COUNT : 'count',
PICTURE : 'picture',
DETAILS : 'details',
FULLNAME : 'fullname',
EMAIL : 'email',
OPTIONS : 'options',
ODD : 'odd',
EVEN : 'even',
HIDDEN : 'hidden',
SEARCHOPTIONS : 'uep-searchoptions',
COLLAPSIBLEHEADING : 'collapsibleheading',
COLLAPSIBLEAREA : 'collapsiblearea',
SEARCHOPTION : 'uep-enrolment-option',
ROLE : 'role',
STARTDATE : 'startdate',
DURATION : 'duration',
ACTIVE : 'active',
SEARCH : 'uep-search',
CLOSE : 'close'
};
var USERENROLLER = function(config) {
USERENROLLER.superclass.constructor.apply(this, arguments);
};
Y.extend(USERENROLLER, Y.Base, {
_searchTimeout : null,
_loadingNode : null,
_escCloseEvent : null,
initializer : function(config) {
this.set(UEP.BASE, Y.Node.create('<div class="'+CSS.PANEL+' '+CSS.HIDDEN+'"></div>')
.append(Y.Node.create('<div class="'+CSS.WRAP+'"></div>')
.append(Y.Node.create('<div class="'+CSS.HEADER+' header"></div>')
.append(Y.Node.create('<div class="'+CSS.CLOSE+'"></div>'))
.append(Y.Node.create('<h2>'+M.str.enrol.enrolusers+'</h2>')))
.append(Y.Node.create('<div class="'+CSS.CONTENT+'"></div>')
.append(Y.Node.create('<div class="'+CSS.AJAXCONTENT+'"></div>'))
.append(Y.Node.create('<div class="'+CSS.LIGHTBOX+' '+CSS.HIDDEN+'"></div>')
.append(Y.Node.create('<img alt="loading" class="'+CSS.LOADINGICON+'" />')
.setAttribute('src', M.util.image_url('i/loading', 'moodle')))
.setStyle('opacity', 0.5)))
.append(Y.Node.create('<div class="'+CSS.FOOTER+'"></div>')
.append(Y.Node.create('<div class="'+CSS.SEARCH+'"><label>'+M.str.enrol.usersearch+'</label></div>')
.append(Y.Node.create('<input type="text" id="enrolusersearch" value="" />'))
.append(Y.Node.create('<div class="'+CSS.SEARCHOPTION+' '+CSS.ROLE+'">'+M.str.role.assignroles+'</div>')
.append(Y.Node.create('<select><option value="">'+M.str.enrol.none+'</option></select>'))
)
)
.append(Y.Node.create('<div class="'+CSS.SEARCHOPTIONS+'"></div>')
.append(Y.Node.create('<div class="'+CSS.COLLAPSIBLEHEADING+'"><img alt="" />'+M.str.enrol.enrolmentoptions+'</div>'))
.append(Y.Node.create('<div class="'+CSS.COLLAPSIBLEAREA+' '+CSS.HIDDEN+'"></div>')
.append(Y.Node.create('<div class="'+CSS.SEARCHOPTION+' '+CSS.STARTDATE+'">'+M.str.moodle.startingfrom+'</div>')
.append(Y.Node.create('<select></select>')))
.append(Y.Node.create('<div class="'+CSS.SEARCHOPTION+' '+CSS.DURATION+'">'+M.str.enrol.enrolperiod+'</div>')
.append(Y.Node.create('<select><option value="0" selected="selected">'+M.str.enrol.unlimitedduration+'</option></select>')))
)
)
)
)
);
this.set(UEP.SEARCH, this.get(UEP.BASE).one('#enrolusersearch'));
Y.all('.enrolusersbutton input').each(function(node){
if (node.getAttribute('type', 'submit')) {
node.on('click', this.show, this);
}
}, this);
this.get(UEP.BASE).one('.'+CSS.HEADER+' .'+CSS.CLOSE).on('click', this.hide, this);
this._loadingNode = this.get(UEP.BASE).one('.'+CSS.CONTENT+' .'+CSS.LIGHTBOX);
var params = this.get(UEP.PARAMS);
params['id'] = this.get(UEP.COURSEID);
this.set(UEP.PARAMS, params);
Y.on('key', this.preSearch, this.get(UEP.SEARCH), 'down:13', this);
Y.one(document.body).append(this.get(UEP.BASE));
var base = this.get(UEP.BASE);
base.plug(Y.Plugin.Drag);
base.dd.addHandle('.'+CSS.HEADER+' h2');
base.one('.'+CSS.HEADER+' h2').setStyle('cursor', 'move');
this.get(UEP.BASE).one('.'+CSS.SEARCHOPTIONS+' .'+CSS.COLLAPSIBLEHEADING).one('img').setAttribute('src', M.util.image_url('t/collapsed', 'moodle'));
this.get(UEP.BASE).one('.'+CSS.SEARCHOPTIONS+' .'+CSS.COLLAPSIBLEHEADING).on('click', function(){
this.get(UEP.BASE).one('.'+CSS.SEARCHOPTIONS+' .'+CSS.COLLAPSIBLEHEADING).toggleClass(CSS.ACTIVE);
this.get(UEP.BASE).one('.'+CSS.SEARCHOPTIONS+' .'+CSS.COLLAPSIBLEAREA).toggleClass(CSS.HIDDEN);
if (this.get(UEP.BASE).one('.'+CSS.SEARCHOPTIONS+' .'+CSS.COLLAPSIBLEAREA).hasClass(CSS.HIDDEN)) {
this.get(UEP.BASE).one('.'+CSS.SEARCHOPTIONS+' .'+CSS.COLLAPSIBLEHEADING).one('img').setAttribute('src', M.util.image_url('t/collapsed', 'moodle'));
} else {
this.get(UEP.BASE).one('.'+CSS.SEARCHOPTIONS+' .'+CSS.COLLAPSIBLEHEADING).one('img').setAttribute('src', M.util.image_url('t/expanded', 'moodle'));
}
}, this);
this.populateAssignableRoles();
this.populateStartDates();
this.populateDuration();
},
populateAssignableRoles : function() {
this.on('assignablerolesloaded', function(){
var roles = this.get(UEP.ASSIGNABLEROLES);
var s = this.get(UEP.BASE).one('.'+CSS.SEARCHOPTION+'.'+CSS.ROLE+' select');
var v = this.get(UEP.DEFAULTROLE);
var index = 0, count = 0;
for (var i in roles) {
count++;
var option = Y.Node.create('<option value="'+i+'">'+roles[i]+'</option>');
if (i == v) {
index = count;
}
s.append(option);
}
s.set('selectedIndex', index);
}, this);
this.getAssignableRoles();
},
populateStartDates : function() {
var select = this.get(UEP.BASE).one('.'+CSS.SEARCHOPTION+'.'+CSS.STARTDATE+' select');
var defaultvalue = this.get(UEP.DEFAULTSTARTDATE);
var options = this.get(UEP.OPTIONSTARTDATE);
var index = 0, count = 0;
for (var i in options) {
count++;
var option = Y.Node.create('<option value="'+i+'">'+options[i]+'</option>');
if (i == defaultvalue) {
index = count;
}
select.append(option);
}
select.set('selectedIndex', index);
},
populateDuration : function() {
var select = this.get(UEP.BASE).one('.'+CSS.SEARCHOPTION+'.'+CSS.DURATION+' select');
var defaultvalue = this.get(UEP.DEFAULTDURATION);
var index = 0, count = 0;
for (var i = 1; i <= 365; i++) {
count++;
var option = Y.Node.create('<option value="'+i+'">'+M.str.enrol.durationdays.replace(/\%d/, i)+'</option>');
if (i == defaultvalue) {
index = count;
}
select.append(option);
}
select.set('selectedIndex', index);
},
getAssignableRoles : function(){
Y.io(M.cfg.wwwroot+'/enrol/ajax.php', {
method:'POST',
data:'id='+this.get(UEP.COURSEID)+'&action=getassignable&sesskey='+M.cfg.sesskey,
on: {
complete: function(tid, outcome, args) {
try {
var roles = Y.JSON.parse(outcome.responseText);
this.set(UEP.ASSIGNABLEROLES, roles.response);
} catch (e) {
Y.fail(UEP.NAME+': Failed to load assignable roles');
}
this.getAssignableRoles = function() {
this.fire('assignablerolesloaded');
}
this.getAssignableRoles();
}
},
context:this
});
},
preSearch : function(e) {
this.search(null, false);
/*
var value = this.get(UEP.SEARCH).get('value');
if (value.length < 3 || value == this.get(UEP.LASTSEARCH)) {
return;
}
this.set(UEP.LASTSEARCH, value);
if (this._searchTimeout) {
clearTimeout(this._searchTimeout);
this._searchTimeout = null;
}
var self = this;
this._searchTimeout = setTimeout(function(){
self._searchTimeout = null;
self.search(null, false);
}, 300);
*/
},
show : function(e) {
e.preventDefault();
e.halt();
var base = this.get(UEP.BASE);
base.removeClass(CSS.HIDDEN);
var x = (base.get('winWidth') - 400)/2;
var y = (parseInt(base.get('winHeight'))-base.get('offsetHeight'))/2 + parseInt(base.get('docScrollY'));
if (y < parseInt(base.get('winHeight'))*0.1) {
y = parseInt(base.get('winHeight'))*0.1;
}
base.setXY([x,y]);
if (this.get(UEP.USERS)===null) {
this.search(e, false);
}
this._escCloseEvent = Y.on('key', this.hide, document.body, 'down:27', this);
},
hide : function(e) {
if (this._escCloseEvent) {
this._escCloseEvent.detach();
this._escCloseEvent = null;
}
this.get(UEP.BASE).addClass(CSS.HIDDEN);
if (this.get(UEP.REQUIREREFRESH)) {
window.location = this.get(UEP.URL);
}
},
search : function(e, append) {
if (e) {
e.halt();
e.preventDefault();
}
var on, params;
if (append) {
this.set(UEP.PAGE, this.get(UEP.PAGE)+1);
} else {
this.set(UEP.USERCOUNT, 0);
}
params = this.get(UEP.PARAMS);
params['sesskey'] = M.cfg.sesskey;
params['action'] = 'searchusers';
params['search'] = this.get(UEP.SEARCH).get('value');
params['page'] = this.get(UEP.PAGE);
if (this.get(UEP.MULTIPLE)) {
alert('oh no there are multiple');
} else {
var instance = this.get(UEP.INSTANCES)[0];
params['enrolid'] = instance.id;
}
Y.io(M.cfg.wwwroot+this.get(UEP.AJAXURL), {
method:'POST',
data:build_querystring(params),
on : {
start : this.displayLoading,
complete: this.processSearchResults,
end : this.removeLoading
},
context:this,
arguments:{
append:append,
enrolid:params['enrolid']
}
});
},
displayLoading : function() {
this._loadingNode.removeClass(CSS.HIDDEN);
},
removeLoading : function() {
this._loadingNode.addClass(CSS.HIDDEN);
},
processSearchResults : function(tid, outcome, args) {
try {
var result = Y.JSON.parse(outcome.responseText);
} catch (e) {
Y.fail(UEP.NAME+': Failed to parse user search response ['+e.linenum+':'+e.message+']');
}
if (!result.success) {
this.setContent = M.str.enrol.errajaxsearch;
}
var users;
if (!args.append) {
users = Y.Node.create('<div class="'+CSS.USERS+'"></div>');
} else {
users = this.get(UEP.BASE).one('.'+CSS.SEARCHRESULTS+' .'+CSS.USERS);
}
var count = this.get(UEP.USERCOUNT);
for (var i in result.response.users) {
count++;
var user = result.response.users[i];
users.append(Y.Node.create('<div class="'+CSS.USER+' clearfix" rel="'+user.id+'"></div>')
.addClass((i%2)?CSS.ODD:CSS.EVEN)
.append(Y.Node.create('<div class="'+CSS.COUNT+'">'+count+'</div>'))
.append(Y.Node.create('<div class="'+CSS.PICTURE+'"></div>')
.append(Y.Node.create(user.picture)))
.append(Y.Node.create('<div class="'+CSS.DETAILS+'"></div>')
.append(Y.Node.create('<div class="'+CSS.FULLNAME+'">'+user.fullname+'</div>'))
.append(Y.Node.create('<div class="'+CSS.EMAIL+'">'+user.email+'</div>')))
.append(Y.Node.create('<div class="'+CSS.OPTIONS+'"></div>')
.append(Y.Node.create('<div class="'+CSS.ENROL+'">'+M.str.enrol.enrol+'</div>')))
);
}
this.set(UEP.USERCOUNT, count);
if (!args.append) {
var usersstr = (result.response.totalusers == '1')?M.str.enrol.ajaxoneuserfound:M.str.enrol.ajaxxusersfound.replace(/\[users\]/, result.response.totalusers);
var content = Y.Node.create('<div class="'+CSS.SEARCHRESULTS+'"></div>')
.append(Y.Node.create('<div class="'+CSS.TOTALUSERS+'">'+usersstr+'</div>'))
.append(users);
if (result.response.totalusers > (this.get(UEP.PAGE)+1)*25) {
var fetchmore = Y.Node.create('<div class="'+CSS.MORERESULTS+'"><a href="#">'+M.str.enrol.ajaxnext25+'</a></div>');
fetchmore.on('click', this.search, this, true);
content.append(fetchmore)
}
this.setContent(content);
Y.delegate("click", this.enrolUser, users, '.'+CSS.USER+' .'+CSS.ENROL, this, args);
} else {
if (result.response.totalusers <= (this.get(UEP.PAGE)+1)*25) {
this.get(UEP.BASE).one('.'+CSS.MORERESULTS).remove();
}
}
},
enrolUser : function(e, args) {
var user = e.currentTarget.ancestor('.'+CSS.USER);
var params = [];
params['id'] = this.get(UEP.COURSEID);
params['userid'] = user.getAttribute("rel");
params['enrolid'] = args.enrolid;
params['sesskey'] = M.cfg.sesskey;
params['action'] = 'enrol';
params['role'] = this.get(UEP.BASE).one('.'+CSS.SEARCHOPTION+'.'+CSS.ROLE+' select').get('value');
params['startdate'] = this.get(UEP.BASE).one('.'+CSS.SEARCHOPTION+'.'+CSS.STARTDATE+' select').get('value');
params['duration'] = this.get(UEP.BASE).one('.'+CSS.SEARCHOPTION+'.'+CSS.DURATION+' select').get('value');
Y.io(M.cfg.wwwroot+this.get(UEP.AJAXURL), {
method:'POST',
data:build_querystring(params),
on: {
start : this.displayLoading,
complete : function(tid, outcome, args) {
try {
var result = Y.JSON.parse(outcome.responseText);
} catch (e) {
Y.fail(UEP.NAME+': Failed to parse user search response ['+e.linenum+':'+e.message+']');
}
if (result.success) {
args.userNode.addClass(CSS.ENROLLED);
args.userNode.one('.'+CSS.ENROL).remove();
this.set(UEP.REQUIREREFRESH, true);
} else {
alert(M.str.enrol.errajaxfailedenrol);
}
},
end : this.removeLoading
},
context:this,
arguments:{
params : params,
userNode : user
}
});
},
setContent: function(content) {
this.get(UEP.BASE).one('.'+CSS.CONTENT+' .'+CSS.AJAXCONTENT).setContent(content);
}
}, {
NAME : UEP.NAME,
ATTRS : {
url : {
validator : Y.Lang.isString
},
ajaxurl : {
validator : Y.Lang.isString
},
base : {
setter : function(node) {
var n = Y.one(node);
if (!n) {
Y.fail(UEP.NAME+': invalid base node set');
}
return n;
}
},
users : {
validator : Y.Lang.isArray,
value : null
},
courseid : {
value : null
},
params : {
validator : Y.Lang.isArray,
value : []
},
instances : {
validator : Y.Lang.isArray,
setter : function(instances) {
var i,ia = [], count=0;
for (i in instances) {
ia.push(instances[i]);
count++;
}
this.set(UEP.MULTIPLE, (count>1));
}
},
multiple : {
validator : Y.Lang.isBool,
value : false
},
page : {
validator : Y.Lang.isNumber,
value : 0
},
userCount : {
value : 0,
validator : Y.Lang.isNumber
},
requiresRefresh : {
value : false,
validator : Y.Lang.isBool
},
search : {
setter : function(node) {
var n = Y.one(node);
if (!n) {
Y.fail(UEP.NAME+': invalid search node set');
}
return n;
}
},
lastPreSearchValue : {
value : '',
validator : Y.Lang.isString
},
strings : {
value : {},
validator : Y.Lang.isObject
},
defaultRole : {
value : 0,
validator : Y.Lang.isNumber
},
defaultStartDate : {
value : 2,
validator : Y.Lang.isNumber
},
defaultDuration : {
value : ''
},
assignableRoles : {
value : []
},
optionsStartDate : {
value : []
}
}
});
Y.augment(USERENROLLER, Y.EventTarget);
M.enrol = M.enrol || {};
M.enrol.enrolmentmanager = {
init : function(cfg) {
new USERENROLLER(cfg);
}
}
}, '@VERSION@', {requires:['base','node', 'overlay', 'io', 'test', 'json-parse', 'event-delegate', 'dd-plugin', 'event-key']});
@@ -0,0 +1,8 @@
.enrolpanel {display:none;position:absolute;background-color:#666;padding:0 5px;}
.enrolpanel.visible {display:block;}
.enrolpanel .container {position:relative;background-color:#fff;border:1px solid #999;top:-5px;}
.enrolpanel .container .header {border-bottom:1px solid #999;}
.enrolpanel .container .header h2 {font-size:90%;text-align:center;margin:5px;}
.enrolpanel .container .header .close {width:25px;height:15px;position:absolute;top:5px;right:1em;cursor:pointer;background:url("sprite.png") no-repeat scroll 0 0 transparent;}
.enrolpanel .container .content {}
.enrolpanel .container .content input {margin:5px;font-size:10px;}
Binary file not shown.

After

Width:  |  Height:  |  Size: 1002 B

+389
View File
@@ -0,0 +1,389 @@
YUI.add('moodle-enrol-rolemanager', function(Y) {
var MOD_NAME = 'Moodle role manager',
MOD_USER = 'Moodle role user',
MOD_PANEL = 'Moodle role assignment panel',
USERIDS = 'userIds',
COURSEID = 'courseId',
USERID = 'userId',
CONTAINER = 'container',
CONTAINERID = 'containerId',
ASSIGNABLEROLES = 'assignableRoles',
ASSIGNROLELINK = 'assignRoleLink',
ASSIGNROLELINKSELECTOR = 'assignRoleLinkSelector',
UNASSIGNROLELINKS = 'unassignRoleLinks',
UNASSIGNROLELINKSSELECTOR = 'unassignRoleLinksSelector',
MANIPULATOR = 'manipulator',
CURRENTROLES = 'currentroles';
var ROLE = function(config) {
ROLE.superclass.constructor.apply(this, arguments);
}
ROLE.NAME = MOD_NAME;
ROLE.ATTRS = {
containerId : {
validator: Y.Lang.isString
},
container : {
setter : function(node) {
var n = Y.one(node);
if (!n) {
Y.fail(MOD_NAME+': invalid container set');
}
return n;
}
},
courseId : {
value: 0,
setter : function(courseId) {
if (!(/^\d+$/.test(courseId))) {
Y.fail(MOD_NAME+': Invalid course id specified');
}
return courseId;
}
},
userIds : {
validator: Y.Lang.isArray
},
assignableRoles : {
value : []
}
}
Y.extend(ROLE, Y.Base, {
users : [],
roleAssignmentPanel : null,
panelsubmitevent : null,
rolesLoadedEvent : null,
escCloseEvent : null,
initializer : function(config) {
var i;
var container = Y.one('#'+this.get(CONTAINERID));
container.addClass('ajaxactive');
this.set(CONTAINER, container);
var userids = this.get(USERIDS);
for (i in userids) {
this.users[userids[i]] = new ROLEUSER({userId:userids[i],manipulator:this}).wire();
}
},
addRole : function(e, user) {
e.halt();
this.rolesLoadedEvent = this.on('assignablerolesloaded', function(){
this.rolesLoadedEvent.detach();
var panel = this._getRoleAssignmentPanel();
this.panelsubmitevent = panel.on('submit', this.addRoleCallback, this);
panel.hide().display(user);
}, this);
this._loadAssignableRoles();
},
addRoleCallback : function(e, roleid, userid) {
this.panelsubmitevent.detach();
var panel = this._getRoleAssignmentPanel();
Y.io(M.cfg.wwwroot+'/enrol/ajax.php', {
method:'POST',
data:'id='+this.get(COURSEID)+'&action=assign&sesskey='+M.cfg.sesskey+'&roleid='+roleid+'&user='+userid,
on: {
complete: function(tid, outcome, args) {
try {
var o = Y.JSON.parse(outcome.responseText);
if (o.success) {
panel.user.addRoleToDisplay(args.roleid, this.get(ASSIGNABLEROLES)[args.roleid]);
}
} catch (e) {
Y.fail(MOD_PANEL+': Failed to parse role assignment response ['+e.linenum+':'+e.message+']');
}
panel.hide();
}
},
context:this,
arguments:{
roleid : roleid
}
});
},
removeRole : function(e, user, roleid) {
e.halt();
if (confirm('Are you sure you wish to remove this role from this user?')) {
this.removeRoleCallback(e, user.get(USERID), roleid);
}
},
removeRoleCallback : function(e, userid, roleid) {
Y.io(M.cfg.wwwroot+'/enrol/ajax.php', {
method:'POST',
data:'id='+this.get(COURSEID)+'&action=unassign&sesskey='+M.cfg.sesskey+'&role='+roleid+'&user='+userid,
on: {
complete: function(tid, outcome, args) {
try {
var o = Y.JSON.parse(outcome.responseText);
if (o.success) {
this.users[userid].removeRoleFromDisplay(args.roleid);
}
} catch (e) {
Y.fail(MOD_PANEL+': Failed to parse role assignment response ['+e.linenum+':'+e.message+']');
}
}
},
context:this,
arguments:{
roleid : roleid
}
});
},
_loadAssignableRoles : function() {
var c = this.get(COURSEID);
Y.io(M.cfg.wwwroot+'/enrol/ajax.php', {
method:'POST',
data:'id='+this.get(COURSEID)+'&action=getassignable&sesskey='+M.cfg.sesskey,
on: {
complete: function(tid, outcome, args) {
try {
var roles = Y.JSON.parse(outcome.responseText);
this.set(ASSIGNABLEROLES, roles.response);
} catch (e) {
Y.fail(MOD_NAME+': Failed to load assignable roles');
}
this._loadAssignableRoles = function() {
this.fire('assignablerolesloaded');
}
this._loadAssignableRoles();
}
},
context:this
});
},
_getRoleAssignmentPanel : function() {
if (this.roleAssignmentPanel === null) {
this.roleAssignmentPanel = new ROLEPANEL({manipulator:this});
}
return this.roleAssignmentPanel;
}
});
Y.augment(ROLE, Y.EventTarget);
var ROLEUSER = function(config) {
ROLEUSER.superclass.constructor.apply(this, arguments);
}
ROLEUSER.NAME = MOD_USER;
ROLEUSER.ATTRS = {
userId : {
validator: Y.Lang.isNumber
},
manipulator : {
validator: Y.Lang.isObject
},
container : {
setter : function(node) {
var n = Y.one(node);
if (!n) {
Y.fail(MOD_USER+': invalid container set '+node);
}
return n;
}
},
assignableroles : {
value : []
},
currentroles : {
value : [],
validator: Y.Lang.isArray
},
assignRoleLink : {
setter : function(node) {
if (node===false) {
return node;
}
var n = Y.one(node);
if (!n) {
Y.fail(MOD_NAME+': invalid assign role link given '+node);
}
return n;
},
value : false
},
assignRoleLinkSelector : {
value : '.assignrolelink',
validator : Y.Lang.isString
},
unassignRoleLinks : {
},
unassignRoleLinksSelector : {
value : '.unassignrolelink',
validator : Y.Lang.isString
}
}
Y.extend(ROLEUSER, Y.Base, {
initializer : function() {
var container = this.get(MANIPULATOR).get(CONTAINER).one('#user_'+this.get(USERID));
this.set(CONTAINER, container);
var assignrole = container.one(this.get(ASSIGNROLELINKSELECTOR));
if (assignrole) {
this.set(ASSIGNROLELINK, assignrole.ancestor());
}
this.set(UNASSIGNROLELINKS , container.all(this.get(UNASSIGNROLELINKSSELECTOR)));
},
wire : function() {
var container = this.get(MANIPULATOR).get(CONTAINER).one('#user_'+this.get(USERID));
var arl = this.get(ASSIGNROLELINK);
var uarls = this.get(UNASSIGNROLELINKS);
var m = this.get(MANIPULATOR);
if (arl) {
arl.ancestor().on('click', m.addRole, m, this);
}
var currentroles = [];
if (uarls.size() > 0) {
uarls.each(function(link){
link.roleId = link.getAttribute('rel');
link.on('click', m.removeRole, m, this, link.roleId);
currentroles[link.roleId] = true;
}, this);
}
container.all('.role.unchangeable').each(function(node){
currentroles[node.getAttribute('rel')] = true;
}, this);
this.set(CURRENTROLES, currentroles);
return this;
},
_checkIfHasAllRoles : function() {
var roles = this.get(MANIPULATOR).get(ASSIGNABLEROLES);
var current = this.get(CURRENTROLES);
var allroles = true, i = 0;
for (i in roles) {
if (!current[i]) {
allroles = false;
break;
}
}
var link = this.get(ASSIGNROLELINK);
if (allroles) {
this.get(CONTAINER).addClass('hasAllRoles');
} else {
if (!link) {
var m = this.get(MANIPULATOR);
link = Y.Node.create('<div class="addrole">&nbsp;</div>');
link.on('click', m.addRole, m, this);
this.get(CONTAINER).one('.col_role').insert(link, 0);
this.set(ASSIGNROLELINK, link);
}
this.get(CONTAINER).removeClass('hasAllRoles');
}
},
addRoleToDisplay : function(roleId, roleTitle) {
var m = this.get(MANIPULATOR);
var container = this.get(CONTAINER);
var role = Y.Node.create('<div class="role role_'+roleId+'">'+roleTitle+'<a class="unassignrolelink"><img src="'+M.util.image_url('t/delete', 'moodle')+'" alt="" /></a></div>');
var link = role.one('.unassignrolelink');
link.roleId = roleId;
link.on('click', m.removeRole, m, this, link.roleId);
container.one('.col_role .roles').append(role);
this._toggleCurrentRole(link.roleId, true);
},
removeRoleFromDisplay : function(roleId) {
var container = this.get(CONTAINER);
container.all('.role_'+roleId).remove();
this._toggleCurrentRole(roleId, false);
},
_toggleCurrentRole : function(roleId, hasRole) {
var roles = this.get(CURRENTROLES);
if (hasRole) {
roles[roleId] = true;
} else {
roles[roleId] = false;
}
this.set(CURRENTROLES, roles);
this._checkIfHasAllRoles();
}
});
var ROLEPANEL = function(config) {
ROLEPANEL.superclass.constructor.apply(this, arguments);
}
ROLEPANEL.NAME = MOD_PANEL;
ROLEPANEL.ATTRS = {
elementNode : {
setter : function(node) {
var n = Y.one(node);
if (!n) {
Y.fail(MOD_PANEL+': Invalid element node');
}
return n;
}
},
contentNode : {
setter : function(node) {
var n = Y.one(node);
if (!n) {
Y.fail(MOD_PANEL+': Invalid content node');
}
return n;
}
},
manipulator : {
validator: Y.Lang.isObject
}
}
Y.extend(ROLEPANEL, Y.Base, {
user : null,
roles : [],
initializer : function() {
var i, m = this.get(MANIPULATOR);
var element = Y.Node.create('<div class="enrolpanel roleassign"><div class="container"><div class="header"><h2>'+M.str.role.assignroles+'</h2><div class="close"></div></div><div class="content"></div></div></div>');
var content = element.one('.content');
var roles = m.get(ASSIGNABLEROLES);
for (i in roles) {
var button = Y.Node.create('<input type="button" value="'+roles[i]+'" id="add_assignable_role_'+i+'" />');
button.on('click', this.submit, this, i);
content.append(button);
}
Y.one(document.body).append(element);
this.set('elementNode', element);
this.set('contentNode', content);
element.one('.header .close').on('click', this.hide, this);
},
display : function(user) {
var currentroles = user.get(CURRENTROLES);
for (var i in currentroles) {
if (currentroles[i] === true) {
this.get('contentNode').one('#add_assignable_role_'+i).setAttribute('disabled', 'disabled');
this.roles.push(i);
}
}
this.user = user;
var roles = this.user.get(CONTAINER).one('.col_role .roles');
var x = roles.getX() + 10;
var y = roles.getY() + this.user.get(CONTAINER).get('offsetHeight') - 10 + Y.one(window).get('scrollTop');
this.get('elementNode').setXY([x, y]);
this.get('elementNode').addClass('visible');
this.escCloseEvent = Y.on('key', this.hide, document.body, 'down:27', this);
this.displayed = true;
},
hide : function() {
if (this._escCloseEvent) {
this._escCloseEvent.detach();
this._escCloseEvent = null;
}
for (var i in this.roles) {
this.get('contentNode').one('#add_assignable_role_'+this.roles[i]).removeAttribute('disabled');
}
this.roles = [];
this.user = null;
this.get('elementNode').removeClass('visible');
this.displayed = false;
return this;
},
submit : function(e, roleid) {
this.fire('submit', roleid, this.user.get(USERID));
}
});
Y.augment(ROLEPANEL, Y.EventTarget);
M.enrol = M.enrol || {};
M.enrol.rolemanager = {
instance : null,
init : function(config) {
M.enrol.rolemanager.instance = new ROLE(config);
return M.enrol.rolemanager.instance;
}
}
}, '@VERSION@', {requires:['base','node','io','json-parse','test']});
+13
View File
@@ -26,10 +26,15 @@
$string['actenrolshhdr'] = 'Available course enrolment plugins';
$string['addinstance'] = 'Add method';
$string['ajaxoneuserfound'] = '1 user found';
$string['ajaxxusersfound'] = '[users] users found';
$string['ajaxnext25'] = 'Next 25...';
$string['configenrolplugins'] = 'Please select all required plugins and arrange then in appropriate order.';
$string['defaultenrol'] = 'Add instance to new courses';
$string['defaultenrol_desc'] = 'It is possible to add this plugin to all new courses by default.';
$string['deleteinstanceconfirm'] = 'Do you really want to delete enrol plugin instance "{$a->name}" with {$a->users} enrolled users?';
$string['durationdays'] = '%d days';
$string['enrol'] = 'Enrol';
$string['enrolcandidates'] = 'Not enrolled users';
$string['enrolcandidatesmatching'] = 'Matching not enrolled users';
$string['enrolledusers'] = 'Enrolled users';
@@ -39,14 +44,19 @@ $string['enrolmentinstances'] = 'Enrolment methods';
$string['enrolmentnew'] = 'New enrolment in {$a}';
$string['enrolmentnewuser'] = '{$a->user} has enrolled in course "{$a->course}"';
$string['enrolments'] = 'Enrolments';
$string['enrolmentoptions'] = 'Enrolment options';
$string['enrolperiod'] = 'Enrolment duration';
$string['enrolusage'] = 'Instances / enrolments';
$string['enrolusers'] = 'Enrol users';
$string['enroltimeend'] = 'Enrolment ends';
$string['enroltimestart'] = 'Enrolment starts';
$string['errajaxfailedenrol'] = 'Failed to enrol user';
$string['errajaxsearch'] = 'Error when searching users';
$string['manageenrols'] = 'Manage enrol plugins';
$string['manageinstance'] = 'Manage';
$string['noexistingparticipants'] = 'No existing participants';
$string['noguestaccess'] = 'Guests can not access this course, please try to log in.';
$string['none'] = 'None';
$string['notenrollable'] = 'This course is not enrollable at the moment.';
$string['notenrolledusers'] = 'Other users';
$string['participationactive'] = 'Active';
@@ -55,9 +65,12 @@ $string['participationsuspended'] = 'Suspended';
$string['periodend'] = 'until {$a}';
$string['periodstart'] = 'from {$a}';
$string['periodstartend'] = 'from {$a->start} until {$a->end}';
$string['startdatetoday'] = 'Today';
$string['unenrol'] = 'Unenrol';
$string['unenrolconfirm'] = 'Do you really want to unenrol user "{$a->user}" from course "{$a->course}"?';
$string['unenrolme'] = 'Unenrol me from {$a}';
$string['unenrolroleusers'] = 'Unenrol users';
$string['uninstallconfirm'] = 'You are about to completely delete the enrol plugin \'{$a}\'. This will completely delete everything in the database associated with this enrolment type. Are you SURE you want to continue?';
$string['uninstalldeletefiles'] = 'All data associated with the enrol plugin \'{$a->plugin}\' has been deleted from the database. To complete the deletion (and prevent the plugin re-installing itself), you should now delete this directory from your server: {$a->directory}';
$string['unlimitedduration'] = 'Unlmited';
$string['usersearch'] = 'Search ';
+2
View File
@@ -25,6 +25,8 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
define('AJAX_SCRIPT', true);
/** Include config */
require_once(dirname(__FILE__) . '/../../config.php');
/** Include course lib for its functions */
Binary file not shown.

After

Width:  |  Height:  |  Size: 288 B

+23
View File
@@ -598,3 +598,26 @@ body.tag .managelink {padding: 5px;}
* Registration
*/
#page-admin-registration-register .registration_textfield {width: 300px;}
/**
* Enrol
*/
.userenrolment {width:100%;border-collapse: collapse;}
.userenrolment td {padding:0;height:41px;}
.userenrolment .subfield {margin-right:5px;}
.userenrolment .col_userdetails .subfield_picture {float:left;}
.userenrolment .col_lastseen {width:150px;}
.userenrolment .col_role {width:262px;}
.userenrolment .col_role .roles {margin-right:30px;}
.userenrolment .col_role .role {float:left;padding:3px;margin:3px;}
.userenrolment .col_role .role a {margin-left:3px;cursor:pointer;}
.userenrolment .col_role .addrole {float:right;width:18px;margin:3px;height:18px;text-align:center;}
.userenrolment .col_role .addrole a img {vertical-align:bottom;}
.userenrolment .hasAllRoles .col_role .addrole {display:none;}
.userenrolment .col_group .groups {margin-right:30px;}
.userenrolment .col_group .group {float:left;padding:3px;margin:3px;white-space:nowrap;}
.userenrolment .col_group .group a {margin-left:3px;cursor:pointer;}
.userenrolment .col_group .addgroup {float:right;width:18px;margin:3px;height:18px;text-align:center;}
.userenrolment .col_group .addgroup a img {vertical-align:bottom;}
.userenrolment .col_enrol .enrolment {float:left;padding:3px;margin:3px;}
.userenrolment .col_enrol .enrolment a {float:right;margin-left:3px;}
+22
View File
@@ -417,3 +417,25 @@ table#tag-management-list {margin: 10px auto;width: 80%;}
.smartselect .smartselect_submenu {border-color:#999;}
.smartselect .smartselect_menu,
.smartselect .smartselect_submenu {-moz-border-radius:4px;-webkit-border-radius: 5px;}
/**
* Enrol
*/
.userenrolment {font-size:90%;border:1px solid #999;}
.userenrolment tr.r0 {background-color:#F9F9F9;}
.userenrolment tr.r1 {background-color:#F3F3F3;}
.userenrolment td {border:1px solid #E9E9E9;border-top-color:#F6F6F6;border-right-color:#EEE;border-left-color:#F3F3F3;}
.userenrolment td.c0 {border-left-color:#999;}
.userenrolment td.c4 {border-right-color:#999;}
.userenrolment .col_userdetails {padding:3px;min-width:35%;}
.userenrolment .col_role .roles {position:relative;}
.userenrolment .col_role .role {line-height:10px;font-size:10px;}
.userenrolment .col_role .role a img {height:8px;}
.userenrolment .col_role .addrole {background-color:#DDD;border:1px outset #EEE;-moz-border-radius:5px;}
.userenrolment .col_group {max-width:300px;}
.userenrolment .col_group .group {line-height:10px;font-size:10px;}
.userenrolment .col_group .group a img {height:8px;}
.userenrolment .col_group .addgroup {background-color:#DDD;border:1px outset #EEE;-moz-border-radius:5px;}
.userenrolment .col_enrol {max-width:300px;}
.userenrolment .col_enrol .enrolment {border:1px outset #E6E6E6;background-color:#EEE;line-height:10px;font-size:10px;-moz-border-radius:5px;}
.path-enrol .enrolusersbutton.instance1 {float:right;}