mirror of
https://github.com/moodle/moodle.git
synced 2025-01-17 21:49:15 +01:00
MDL-12249 groups UI cleanup and improvements - see tracker for details; merged from MOODLE_19_STABLE
This commit is contained in:
parent
b9ce88c74c
commit
f16fa0a34b
@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php // $Id$
|
||||
/**
|
||||
* Add/remove group from grouping.
|
||||
* @package groups
|
||||
@ -31,22 +31,12 @@ if ($frm = data_submitted() and confirm_sesskey()) {
|
||||
|
||||
} else if (isset($frm->add) and !empty($frm->addselect)) {
|
||||
foreach ($frm->addselect as $groupid) {
|
||||
$groupid = (int)$groupid;
|
||||
if (record_exists('groupings_groups', 'groupingid', $grouping->id, 'groupid', $groupid)) {
|
||||
continue;
|
||||
}
|
||||
$assign = new object();
|
||||
$assign->groupingid = $grouping->id;
|
||||
$assign->groupid = $groupid;
|
||||
$assign->timeadded = time();
|
||||
insert_record('groupings_groups', $assign);
|
||||
groups_assign_grouping($grouping->id, (int)$groupid);
|
||||
}
|
||||
|
||||
} else if (isset($frm->remove) and !empty($frm->removeselect)) {
|
||||
|
||||
foreach ($frm->removeselect as $groupid) {
|
||||
$groupid = (int)$groupid;
|
||||
delete_records('groupings_groups', 'groupingid', $grouping->id, 'groupid', $groupid);
|
||||
groups_unassign_grouping($grouping->id, (int)$groupid);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -82,20 +72,6 @@ if ($currentmembers) {
|
||||
$managers = get_role_users($roleid, $context, true, 'u.id', 'u.id ASC', $canseehidden);
|
||||
}
|
||||
}
|
||||
|
||||
if ($potentialmembers != false) {
|
||||
// Put the groupings into a hash and sorts them
|
||||
foreach ($potentialmembers as $user) {
|
||||
if(!empty($managers[$user->id])) {
|
||||
$nonmembers[$user->id] = '#'.$user->firstname.' '.$user->lastname;
|
||||
}
|
||||
else {
|
||||
$nonmembers[$user->id] = $user->firstname.' '.$user->lastname;
|
||||
}
|
||||
$potentialmemberscount++;
|
||||
}
|
||||
natcasesort($nonmembers);
|
||||
}
|
||||
} else {
|
||||
$currentmembersoptions .= '<option> </option>';
|
||||
}
|
||||
@ -133,7 +109,6 @@ print_header("$course->shortname: $strgroups", $course->fullname, $navigation, '
|
||||
<form id="assignform" method="post" action="">
|
||||
<div>
|
||||
<input type="hidden" name="sesskey" value="<?php p(sesskey()); ?>" />
|
||||
<input type="hidden" name="group" value="<?php echo $groupid; ?>" />
|
||||
|
||||
<table summary="" cellpadding="5" cellspacing="0">
|
||||
<tr>
|
||||
@ -147,7 +122,6 @@ print_header("$course->shortname: $strgroups", $course->fullname, $navigation, '
|
||||
<?php echo $currentmembersoptions ?>
|
||||
</select></td>
|
||||
<td valign="top">
|
||||
<?php // Hidden assignment? ?>
|
||||
|
||||
<?php check_theme_arrows(); ?>
|
||||
<p class="arrow_button">
|
||||
|
@ -9,57 +9,50 @@
|
||||
*/
|
||||
|
||||
require_once('../config.php');
|
||||
require_once('lib.php');
|
||||
require_once('autogroup_form.php');
|
||||
|
||||
define('AUTOGROUP_MIN_RATIO', 0.7);
|
||||
|
||||
$courseid = required_param('courseid', PARAM_INT);
|
||||
|
||||
if (!$course = get_record('course', 'id',$courseid)) {
|
||||
if (!$course = get_record('course', 'id', $courseid)) {
|
||||
error('invalidcourse');
|
||||
}
|
||||
|
||||
// Make sure that the user has permissions to manage groups.
|
||||
require_login($course);
|
||||
|
||||
$context = get_context_instance(CONTEXT_COURSE, $courseid);
|
||||
$sitecontext = get_context_instance(CONTEXT_SYSTEM);
|
||||
$context = get_context_instance(CONTEXT_COURSE, $courseid);
|
||||
$systemcontext = get_context_instance(CONTEXT_SYSTEM);
|
||||
require_capability('moodle/course:managegroups', $context);
|
||||
|
||||
$returnurl = $CFG->wwwroot.'/group/index.php?id='.$course->id;
|
||||
|
||||
$strgroups = get_string('groups');
|
||||
$strparticipants = get_string('participants');
|
||||
$stroverview = get_string('overview', 'group');
|
||||
$strgrouping = get_string('grouping', 'group');
|
||||
$strgroup = get_string('group', 'group');
|
||||
$strnotingrouping = get_string('notingrouping', 'group');
|
||||
$strfiltergroups = get_string('filtergroups', 'group');
|
||||
|
||||
$strgroups = get_string('groups');
|
||||
$strparticipants = get_string('participants');
|
||||
$strautocreategroups = get_string('autocreategroups', 'group');
|
||||
|
||||
// Print the page and form
|
||||
$navlinks = array(array('name'=>$strparticipants, 'link'=>$CFG->wwwroot.'/user/index.php?id='.$courseid, 'type'=>'misc'),
|
||||
array('name'=>$strgroups, 'link'=>'', 'type'=>'misc'));
|
||||
array('name' => $strgroups, 'link' => "$CFG->wwwroot/group/index.php?id=$courseid", 'type' => 'misc'),
|
||||
array('name' => $strautocreategroups, 'link' => null, 'type' => 'misc'));
|
||||
$navigation = build_navigation($navlinks);
|
||||
|
||||
$preview = '';
|
||||
$error = '';
|
||||
|
||||
/// Get applicable roles
|
||||
$rolenames = array();
|
||||
$avoidroles = array();
|
||||
|
||||
if ($roles = get_roles_used_in_context($context, true)) {
|
||||
$canviewroles = get_roles_with_capability('moodle/course:view', CAP_ALLOW, $context);
|
||||
$doanythingroles = get_roles_with_capability('moodle/site:doanything', CAP_ALLOW, $sitecontext);
|
||||
$doanythingroles = get_roles_with_capability('moodle/site:doanything', CAP_ALLOW, $systemcontext);
|
||||
|
||||
foreach ($roles as $role) {
|
||||
if (!isset($canviewroles[$role->id])) { // Avoid this role (eg course creator)
|
||||
$avoidroles[] = $role->id;
|
||||
unset($roles[$role->id]);
|
||||
continue;
|
||||
}
|
||||
if (isset($doanythingroles[$role->id])) { // Avoid this role (ie admin)
|
||||
$avoidroles[] = $role->id;
|
||||
unset($roles[$role->id]);
|
||||
continue;
|
||||
}
|
||||
$rolenames[$role->id] = strip_tags(role_get_name($role, $context)); // Used in menus etc later on
|
||||
@ -67,113 +60,195 @@ if ($roles = get_roles_used_in_context($context, true)) {
|
||||
}
|
||||
|
||||
/// Create the form
|
||||
$editform = new autogroup_form('autogroup.php', array('roles' => $rolenames));
|
||||
$editform->set_data(array('courseid' => $courseid,
|
||||
'seed' => time()));
|
||||
|
||||
|
||||
$editform = new autogroup_form(null, array('roles' => $rolenames));
|
||||
$editform->set_data(array('courseid' => $courseid, 'seed' => time()));
|
||||
|
||||
/// Handle form submission
|
||||
if ($editform->is_cancelled()) {
|
||||
redirect($returnurl);
|
||||
} elseif ($data = $editform->get_data()) {
|
||||
|
||||
/// Allocate members from the selected role to groups
|
||||
if ($data->allocateby == 'random') {
|
||||
$orderby = 'firstname';
|
||||
} else {
|
||||
$orderby = $data->allocateby;
|
||||
|
||||
} elseif ($data = $editform->get_data(false)) {
|
||||
|
||||
/// Allocate members from the selected role to groups
|
||||
switch ($data->allocateby) {
|
||||
case 'no':
|
||||
case 'random':
|
||||
case 'lastname':
|
||||
$orderby = 'lastname, firstname'; break;
|
||||
case 'firstname':
|
||||
$orderby = 'firstname, lastname'; break;
|
||||
case 'idnumber':
|
||||
$orderby = 'idnumber'; break;
|
||||
default:
|
||||
error('Unknown ordering');
|
||||
}
|
||||
$users = groups_get_potental_members($data->courseid, $data->roleid, $orderby);
|
||||
$users = groups_get_potential_members($data->courseid, $data->roleid, $orderby);
|
||||
$usercnt = count($users);
|
||||
|
||||
|
||||
if ($data->allocateby == 'random') {
|
||||
srand ($data->seed);
|
||||
srand($data->seed);
|
||||
shuffle($users);
|
||||
}
|
||||
|
||||
|
||||
$groups = array();
|
||||
$i = 0;
|
||||
$cnt = 0;
|
||||
|
||||
|
||||
// Plan the allocation
|
||||
if ($data->groupby == 'groups') {
|
||||
$numgrps = $data->number;
|
||||
$userpergrp = ceil($usercnt/$numgrps);
|
||||
} else {
|
||||
$numgrps = ceil($usercnt/$data->number);
|
||||
$userpergrp = $data->number > $usercnt ? $usercnt : $data->number;
|
||||
$numgrps = $data->number;
|
||||
$userpergrp = floor($usercnt/$numgrps);
|
||||
|
||||
// If there would be one group with a small number of member reduce the number of groups
|
||||
$remainder = $userpergrp - ($userpergrp * $numgrps - $usercnt);
|
||||
if ($remainder && $remainder < $userpergrp * AUTOGROUP_MIN_RATIO) {
|
||||
$numgrps--;
|
||||
} else { // members
|
||||
$numgrps = ceil($usercnt/$data->number);
|
||||
$userpergrp = $data->number;
|
||||
|
||||
if (!empty($data->nosmallgroups) and $usercnt % $data->number != 0) {
|
||||
// If there would be one group with a small number of member reduce the number of groups
|
||||
$missing = $userpergrp * $numgrps - $usercnt;
|
||||
if ($missing > $userpergrp * AUTOGROUP_MIN_RATIO) {
|
||||
$numgrps--;
|
||||
$userpergrp = ceil($usercnt/$numgrps);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Do the allocation
|
||||
$remainggroups = $numgrps;
|
||||
$remaingusers = $usercnt;
|
||||
|
||||
foreach($users as $id => $user) {
|
||||
if (!isset($groups[$i])) { // Create a new group
|
||||
$groups[$i]['name'] = groups_parse_name($data->namingschemegrp['namingscheme'], $i);
|
||||
}
|
||||
@$groups[$i]['members'][] = &$users[$id];
|
||||
$cnt++;
|
||||
|
||||
if ($cnt >= round($usercnt / $remainggroups)) {
|
||||
$usercnt -= $cnt;
|
||||
$cnt = 0;
|
||||
$i++;
|
||||
$remainggroups--;
|
||||
|
||||
// allocate the users - all groups equal count first
|
||||
for ($i=0; $i<$numgrps; $i++) {
|
||||
$groups[$i] = array();
|
||||
$groups[$i]['name'] = groups_parse_name(trim($data->namingscheme), $i);
|
||||
$groups[$i]['members'] = array();
|
||||
if ($data->allocateby == 'no') {
|
||||
continue; // do not allocate users
|
||||
}
|
||||
for ($j=0; $j<$userpergrp; $j++) {
|
||||
if (empty($users)) {
|
||||
break 2;
|
||||
}
|
||||
$user = array_shift($users);
|
||||
$groups[$i]['members'][$user->id] = $user;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// now distribute the rest
|
||||
if ($data->allocateby != 'no') {
|
||||
for ($i=0; $i<$numgrps; $i++) {
|
||||
if (empty($users)) {
|
||||
break 1;
|
||||
}
|
||||
$user = array_shift($users);
|
||||
$groups[$i]['members'][$user->id] = $user;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($data->preview)) {
|
||||
/// Print the groups preview
|
||||
$preview = '';
|
||||
if (isset($remainder) && $remainder != $userpergrp && $data->groupby == 'members') {
|
||||
$preview .= '<p>'.get_string('evenallocation', 'group').'</p>';
|
||||
$table = new object();
|
||||
if ($data->allocateby == 'no') {
|
||||
$table->head = array(get_string('groupscount', 'group', $numgrps));
|
||||
$table->size = array('100%');
|
||||
$table->align = array('left');
|
||||
$table->width = '40%';
|
||||
} else {
|
||||
$table->head = array(get_string('groupscount', 'group', $numgrps), get_string('groupmembers', 'group'), get_string('usercounttotal', 'group', $usercnt));
|
||||
$table->size = array('20%', '70%', '10%');
|
||||
$table->align = array('left', 'left', 'center');
|
||||
$table->width = '90%';
|
||||
}
|
||||
$preview .= '<ul>';
|
||||
foreach ($groups as $group) {
|
||||
$preview .= "<li>$group[name] (".count($group['members'])." ".get_string('membersingroup', 'group').")\n<ul>";
|
||||
foreach ($group['members'] as $member) {
|
||||
$preview .= '<li>'.fullname($member).'</li>';
|
||||
}
|
||||
$preview .= "</ul><br />\n</li>\n";
|
||||
}
|
||||
$preview .= '</ul>';
|
||||
} else {
|
||||
/// Save the groups data
|
||||
foreach ($groups as $group) {
|
||||
$newgroup->timecreated = time();
|
||||
$newgroup->timemodified = $newgroup->timecreated;
|
||||
$newgroup->courseid = $data->courseid;
|
||||
$newgroup->name = $group['name'];
|
||||
$groupid = insert_record('groups', $newgroup);
|
||||
foreach($group['members'] as $user) {
|
||||
$member->groupid = $groupid;
|
||||
$member->userid = $user->id;
|
||||
$member->timeadded = time();
|
||||
insert_record('groups_members', $member);
|
||||
}
|
||||
}
|
||||
redirect($returnurl);
|
||||
}
|
||||
$table->data = array();
|
||||
|
||||
foreach ($groups as $group) {
|
||||
$line = array();
|
||||
if (groups_get_group_by_name($courseid, $group['name'])) {
|
||||
$line[] = '<span class="notifyproblem">'.get_string('groupnameexists', 'group', $group['name']).'</span>';
|
||||
$error = get_string('groupnameexists', 'group', $group['name']);
|
||||
} else {
|
||||
$line[] = $group['name'];
|
||||
}
|
||||
if ($data->allocateby != 'no') {
|
||||
$unames = array();
|
||||
foreach ($group['members'] as $user) {
|
||||
$unames[] = fullname($user, true);
|
||||
}
|
||||
$line[] = implode(', ', $unames);
|
||||
$line[] = count($group['members']);
|
||||
}
|
||||
$table->data[] = $line;
|
||||
}
|
||||
|
||||
$preview .= print_table($table, true);
|
||||
|
||||
} else {
|
||||
$grouping = null;
|
||||
$createdgrouping = null;
|
||||
$createdgroups = array();
|
||||
$failed = false;
|
||||
|
||||
// prepare grouping
|
||||
if (!empty($data->grouping)) {
|
||||
$groupingname = trim($data->groupingname);
|
||||
if ($data->grouping < 0) {
|
||||
$grouping = new object();
|
||||
$grouping->courseid = $COURSE->id;
|
||||
$grouping->name = $groupingname;
|
||||
if (!$grouping->id = groups_create_grouping(addslashes_recursive($grouping))) {
|
||||
$error = 'Can not create grouping'; //should not happen
|
||||
$failed = true;
|
||||
}
|
||||
$createdgrouping = $grouping->id;
|
||||
} else {
|
||||
$grouping = groups_get_grouping($data->grouping);
|
||||
}
|
||||
}
|
||||
|
||||
// Save the groups data
|
||||
foreach ($groups as $key=>$group) {
|
||||
if (groups_get_group_by_name($courseid, $group['name'])) {
|
||||
$error = get_string('groupnameexists', 'group', $group['name']);
|
||||
$failed = true;
|
||||
break;
|
||||
}
|
||||
$newgroup = new object();
|
||||
$newgroup->courseid = $data->courseid;
|
||||
$newgroup->name = $group['name'];
|
||||
if (!$groupid = groups_create_group(addslashes_recursive($newgroup))) {
|
||||
$error = 'Can not create group!'; // should not happen
|
||||
$failed = true;
|
||||
break;
|
||||
}
|
||||
$createdgroups[] = $groupid;
|
||||
foreach($group['members'] as $user) {
|
||||
groups_add_member($groupid, $user->id);
|
||||
}
|
||||
if ($grouping) {
|
||||
groups_assign_grouping($grouping->id, $groupid);
|
||||
}
|
||||
}
|
||||
|
||||
if ($failed) {
|
||||
foreach ($createdgroups as $groupid) {
|
||||
groups_delete_group($groupid);
|
||||
}
|
||||
if ($createdgrouping) {
|
||||
groups_delete_grouping($createdgrouping);
|
||||
}
|
||||
} else {
|
||||
redirect($returnurl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Print header
|
||||
print_header_simple($strgroups, ': '.$strgroups, $navigation, '', '', true, '', navmenu($course));
|
||||
print_heading($strautocreategroups);
|
||||
|
||||
if ($error != '') {
|
||||
notify($error);
|
||||
}
|
||||
|
||||
/// Display the form
|
||||
$editform->display();
|
||||
if(isset($preview)) {
|
||||
print_heading_block(get_string('groupspreview', 'group'));
|
||||
print_box($preview);
|
||||
|
||||
if($preview !== '') {
|
||||
print_heading(get_string('groupspreview', 'group'));
|
||||
|
||||
echo $preview;
|
||||
}
|
||||
|
||||
print_footer($course);
|
||||
|
@ -13,46 +13,74 @@ class autogroup_form extends moodleform {
|
||||
|
||||
$mform->addElement('header', 'autogroup', get_string('autocreategroups', 'group'));
|
||||
|
||||
$options = array(get_string('all'));
|
||||
$options = array(0=>get_string('all'));
|
||||
$options += $this->_customdata['roles'];
|
||||
$mform->addElement('select', 'roleid', get_string('selectfromrole', 'group'), $options);
|
||||
$mform->addRule('roleid', get_string('required'), 'required', null, 'client');
|
||||
if (!empty($COURSE->defaultrole) and array_key_exists($COURSE->defaultrole, $options)) {
|
||||
$mform->setDefault('roleid', $COURSE->defaultrole);
|
||||
} else if (!empty($CFG->defaultcourseroleid) and array_key_exists($CFG->defaultcourseroleid, $options)) {
|
||||
$mform->setDefault('roleid', $CFG->defaultcourseroleid);
|
||||
}
|
||||
|
||||
|
||||
$options = array('groups' => get_string('groups', 'group'),
|
||||
'members' => get_string('members', 'group'));
|
||||
$options = array('groups' => get_string('numgroups', 'group'),
|
||||
'members' => get_string('nummembers', 'group'));
|
||||
$mform->addElement('select', 'groupby', get_string('groupby', 'group'), $options);
|
||||
$mform->addRule('groupby', get_string('required'), 'required', null, 'client');
|
||||
|
||||
|
||||
$mform->addElement('text', 'number', get_string('number', 'group'),'maxlength="4" size="4"');
|
||||
$mform->setType('number', PARAM_INT);
|
||||
$mform->addRule('number', null, 'numeric', null, 'client');
|
||||
$mform->addRule('number', get_string('required'), 'required', null, 'client');
|
||||
|
||||
$options = array('random' => get_string('random', 'group'),
|
||||
'firstname' => get_string('firstname', 'group'),
|
||||
'lastname' => get_string('lastname', 'group'));
|
||||
|
||||
|
||||
$mform->addElement('checkbox', 'nosmallgroups', get_string('nosmallgroups', 'group'));
|
||||
$mform->disabledIf('nosmallgroups', 'groupby', 'noteq', 'members');
|
||||
$mform->setAdvanced('nosmallgroups');
|
||||
|
||||
$options = array('no' => get_string('noallocation', 'group'),
|
||||
'random' => get_string('random', 'group'),
|
||||
'firstname' => get_string('byfirstname', 'group'),
|
||||
'lastname' => get_string('bylastname', 'group'),
|
||||
'idnumber' => get_string('byidnumber', 'group'));
|
||||
$mform->addElement('select', 'allocateby', get_string('allocateby', 'group'), $options);
|
||||
$mform->addRule('allocateby', get_string('required'), 'required', null, 'client');
|
||||
|
||||
$grp[] = $mform->createElement('text', 'namingscheme');
|
||||
$grp[] = $mform->createElement('static', 'namingschemehelp', null, get_string('namingschemehelp', 'group'));
|
||||
$mform->addGroup($grp, 'namingschemegrp', get_string('namingscheme', 'group'), '<br />');
|
||||
|
||||
$mform->setType('namingschemegrp[namingscheme]', PARAM_RAW);
|
||||
$mform->setDefault('namingschemegrp[namingscheme]', get_string('group', 'group').' @');
|
||||
$mform->addRule('namingschemegrp', get_string('required'), 'required', null, 'client');
|
||||
$mform->setAdvanced('namingschemegrp');
|
||||
|
||||
$mform->setDefault('allocateby', 'random');
|
||||
$mform->setAdvanced('allocateby');
|
||||
|
||||
$mform->addElement('text', 'namingscheme', get_string('namingscheme', 'group'));
|
||||
$mform->setHelpButton('namingscheme', array(false, get_string('namingschemehelp', 'group'),
|
||||
false, true, false, get_string('namingschemehelp', 'group')));
|
||||
$mform->addRule('namingscheme', get_string('required'), 'required', null, 'client');
|
||||
$mform->setType('namingscheme', PARAM_MULTILANG);
|
||||
// there must not be duplicate group names in course
|
||||
$template = get_string('grouptemplate', 'group');
|
||||
$gname = groups_parse_name($template, 0);
|
||||
if (!groups_get_group_by_name($COURSE->id, $gname)) {
|
||||
$mform->setDefault('namingscheme', $template);
|
||||
}
|
||||
|
||||
if (!empty($CFG->enablegroupings)) {
|
||||
$options = array('0' => get_string('no'),
|
||||
'-1'=> get_string('newgrouping', 'group'));
|
||||
if ($groupings = groups_get_all_groupings($COURSE->id)) {
|
||||
foreach ($groupings as $grouping) {
|
||||
$options[$grouping->id] = strip_tags(format_string($grouping->name));
|
||||
}
|
||||
}
|
||||
$mform->addElement('select', 'grouping', get_string('createingrouping', 'group'), $options);
|
||||
if ($groupings) {
|
||||
$mform->setDefault('grouping', '-1');
|
||||
}
|
||||
|
||||
$mform->addElement('text', 'groupingname', get_string('groupingname', 'group'), $options);
|
||||
$mform->setType('groupingname', PARAM_MULTILANG);
|
||||
$mform->disabledIf('groupingname', 'grouping', 'noteq', '-1');
|
||||
}
|
||||
|
||||
$mform->addElement('hidden','courseid');
|
||||
$mform->setType('courseid', PARAM_INT);
|
||||
|
||||
|
||||
$mform->addElement('hidden','seed');
|
||||
$mform->setType('seed', PARAM_INT);
|
||||
|
||||
$buttonarray=array();
|
||||
|
||||
$buttonarray = array();
|
||||
$buttonarray[] = &$mform->createElement('submit', 'preview', get_string('preview'), 'xx');
|
||||
$buttonarray[] = &$mform->createElement('submit', 'submitbutton', get_string('submit'));
|
||||
$buttonarray[] = &$mform->createElement('cancel');
|
||||
@ -61,39 +89,50 @@ class autogroup_form extends moodleform {
|
||||
}
|
||||
|
||||
|
||||
function validation($data) {
|
||||
function validation($data, $files) {
|
||||
global $CFG, $COURSE;
|
||||
$errors = array();
|
||||
|
||||
if (!$users = groups_get_potental_members($data['courseid'], $data['roleid'])) {
|
||||
$errors['roleid'] = get_string('nousersinrole', 'group');
|
||||
}
|
||||
$usercnt = count($users);
|
||||
|
||||
/// Check the number entered is sane
|
||||
if ($data['groupby'] == 'groups') {
|
||||
if ($data['allocateby'] != 'no') {
|
||||
if (!$users = groups_get_potential_members($data['courseid'], $data['roleid'])) {
|
||||
$errors['roleid'] = get_string('nousersinrole', 'group');
|
||||
}
|
||||
|
||||
if ($data['number'] > $usercnt || $data['number'] < 1) {
|
||||
$errors['number'] = get_string('toomanygroups', 'group', $usercnt);
|
||||
/// Check the number entered is sane
|
||||
if ($data['groupby'] == 'groups') {
|
||||
$usercnt = count($users);
|
||||
|
||||
if ($data['number'] > $usercnt || $data['number'] < 1) {
|
||||
$errors['number'] = get_string('toomanygroups', 'group', $usercnt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Check the naming scheme
|
||||
$matchcnt = preg_match_all('/[#@]{1,1}/', $data['namingschemegrp']['namingscheme'], $matches);
|
||||
|
||||
if ($matchcnt != 1) {
|
||||
$errors['namingschemegrp'] = get_string('badnamingscheme', 'group');
|
||||
}
|
||||
|
||||
|
||||
if (count($errors) > 0) {
|
||||
return $errors;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//try to detect group name duplicates
|
||||
$name = groups_parse_name(stripslashes(trim($data['namingscheme'])), 0);
|
||||
if (groups_get_group_by_name($COURSE->id, $name)) {
|
||||
$errors['namingscheme'] = get_string('groupnameexists', 'group', $name);
|
||||
}
|
||||
|
||||
// check grouping name duplicates
|
||||
if ($data['grouping'] == '-1') {
|
||||
$name = trim(stripslashes($data['groupingname']));
|
||||
if (empty($name)) {
|
||||
$errors['groupingname'] = get_string('required');
|
||||
} else if (groups_get_grouping_by_name($COURSE->id, $name)) {
|
||||
$errors['groupingname'] = get_string('groupingnameexists', 'group', $name);
|
||||
}
|
||||
}
|
||||
|
||||
/// Check the naming scheme
|
||||
$matchcnt = preg_match_all('/[#@]{1,1}/', $data['namingscheme'], $matches);
|
||||
|
||||
if ($matchcnt != 1) {
|
||||
$errors['namingscheme'] = get_string('badnamingscheme', 'group');
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
@ -86,7 +86,7 @@ if ($editform->is_cancelled()) {
|
||||
}
|
||||
} else {
|
||||
if (!$id = groups_create_group($data, $editform->_upload_manager)) {
|
||||
error('Error updating group');
|
||||
error('Error creating group');
|
||||
}
|
||||
$returnurl = $CFG->wwwroot.'/group/index.php?id='.$course->id.'&group='.$id;
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ class group_form extends moodleform {
|
||||
|
||||
$errors = array();
|
||||
|
||||
$name = stripslashes($data['name']);
|
||||
$name = trim(stripslashes($data['name']));
|
||||
if ($data['id'] and $group = get_record('groups', 'id', $data['id'])) {
|
||||
if ($group->name != $name) {
|
||||
if (groups_get_group_by_name($COURSE->id, $name)) {
|
||||
|
@ -82,16 +82,13 @@ if ($editform->is_cancelled()) {
|
||||
$success = true;
|
||||
|
||||
if ($data->id) {
|
||||
$data->timemodified = time();
|
||||
if (!update_record('groupings', $data)) {
|
||||
error('Error updating group');
|
||||
if (!groups_update_grouping($data)) {
|
||||
error('Error updating grouping');
|
||||
}
|
||||
|
||||
} else {
|
||||
$data->timecreated = time();
|
||||
$data->timemodified = $data->timecreated;
|
||||
if (!$data->id = insert_record('groupings', $data)) {
|
||||
error('Error updating grouping');
|
||||
if (!groups_create_grouping($data)) {
|
||||
error('Error creating grouping');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,7 @@ class grouping_form extends moodleform {
|
||||
|
||||
$errors = array();
|
||||
|
||||
$name = stripslashes($data['name']);
|
||||
$name = trim(stripslashes($data['name']));
|
||||
if ($data['id'] and $grouping = get_record('groupings', 'id', $data['id'])) {
|
||||
if ($grouping->name != $name) {
|
||||
if (groups_get_grouping_by_name($COURSE->id, $name)) {
|
||||
|
@ -67,6 +67,7 @@ if ($groupings = get_records('groupings', 'courseid', $course->id)) {
|
||||
$data[] = $line;
|
||||
}
|
||||
}
|
||||
$tabke = new object();
|
||||
$table->head = array($strgrouping, $strgroups, $struses, $stredit);
|
||||
$table->size = array('30%', '50%', '10%', '10%');
|
||||
$table->align = array('left', 'left', 'center', 'center');
|
||||
|
@ -70,7 +70,7 @@ switch ($action) {
|
||||
|
||||
case 'showautocreategroupsform':
|
||||
redirect('autogroup.php?courseid='.$courseid);
|
||||
break;
|
||||
break;
|
||||
|
||||
case 'showgroupsettingsform':
|
||||
redirect('group.php?courseid='.$courseid.'&id='.$groupid);
|
||||
@ -106,12 +106,9 @@ $navigation = build_navigation($navlinks);
|
||||
|
||||
/// Print header
|
||||
print_header_simple($strgroups, ': '.$strgroups, $navigation, '', '', true, '', navmenu($course));
|
||||
|
||||
if (!empty($CFG->enablegroupings)) {
|
||||
// Add tabs
|
||||
$currenttab = 'groups';
|
||||
require('tabs.php');
|
||||
}
|
||||
// Add tabs
|
||||
$currenttab = 'groups';
|
||||
require('tabs.php');
|
||||
|
||||
$disabled = 'disabled="disabled"';
|
||||
|
||||
@ -145,7 +142,7 @@ echo '<p><label for="groups"><span id="groupslabel">'.get_string('groups').':</s
|
||||
if (ajaxenabled()) {
|
||||
$onchange = 'membersCombo.refreshMembers(this.options[this.selectedIndex].value);';
|
||||
} else {
|
||||
$onchange = '';
|
||||
$onchange = '';
|
||||
}
|
||||
|
||||
|
||||
@ -184,7 +181,7 @@ echo '<p><input type="submit" '. $deletegroup_disabled . ' name="act_deletegroup
|
||||
|
||||
echo '<p><input type="submit" name="act_showcreateorphangroupform" id="showcreateorphangroupform" value="'
|
||||
. get_string('creategroup', 'group') . '" /></p>'."\n";
|
||||
|
||||
|
||||
echo '<p><input type="submit" name="act_showautocreategroupsform" id="showautocreategroupsform" value="'
|
||||
. get_string('autocreategroups', 'group') . '" /></p>'."\n";
|
||||
|
||||
|
145
group/lib.php
145
group/lib.php
@ -17,8 +17,8 @@
|
||||
* Adds a specified user to a group
|
||||
* @param int $userid The user id
|
||||
* @param int $groupid The group id
|
||||
* @return boolean True if user added successfully or the user is already a
|
||||
* member of the group, false otherwise.
|
||||
* @return boolean True if user added successfully or the user is already a
|
||||
* member of the group, false otherwise.
|
||||
*/
|
||||
function groups_add_member($groupid, $userid) {
|
||||
if (!groups_group_exists($groupid)) {
|
||||
@ -45,7 +45,7 @@ function groups_add_member($groupid, $userid) {
|
||||
$eventdata = new object();
|
||||
$eventdata->groupid = $groupid;
|
||||
$eventdata->userid = $userid;
|
||||
events_trigger('group_user_added', $eventdata);
|
||||
events_trigger('group_user_added', $eventdata);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -67,7 +67,7 @@ function groups_remove_member($groupid, $userid) {
|
||||
|
||||
if (!delete_records('groups_members', 'groupid', $groupid, 'userid', $userid)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
//update group info
|
||||
set_field('groups', 'timemodified', time(), 'id', $groupid);
|
||||
|
||||
@ -76,7 +76,7 @@ function groups_remove_member($groupid, $userid) {
|
||||
|
||||
/**
|
||||
* Add a new group
|
||||
* @param object $data group properties (with magic quotes);
|
||||
* @param object $data group properties (with magic quotes)
|
||||
* @param object $um upload manager with group picture
|
||||
* @return id of group or false if error
|
||||
*/
|
||||
@ -86,6 +86,7 @@ function groups_create_group($data, $um=false) {
|
||||
|
||||
$data->timecreated = time();
|
||||
$data->timemodified = $data->timecreated;
|
||||
$data->name = trim($data->name);
|
||||
$id = insert_record('groups', $data);
|
||||
|
||||
if ($id and $um) {
|
||||
@ -99,8 +100,22 @@ function groups_create_group($data, $um=false) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new group
|
||||
* @param object $data group properties (with magic quotes);
|
||||
* Add a new grouping
|
||||
* @param object $data grouping properties (with magic quotes)
|
||||
* @return id of grouping or false if error
|
||||
*/
|
||||
function groups_create_grouping($data) {
|
||||
global $CFG;
|
||||
|
||||
$data->timecreated = time();
|
||||
$data->timemodified = $data->timecreated;
|
||||
$data->name = trim($data->name);
|
||||
return insert_record('groupings', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update group
|
||||
* @param object $data group properties (with magic quotes)
|
||||
* @param object $um upload manager with group picture
|
||||
* @return boolean success
|
||||
*/
|
||||
@ -109,6 +124,7 @@ function groups_update_group($data, $um=false) {
|
||||
require_once("$CFG->libdir/gdlib.php");
|
||||
|
||||
$data->timemodified = time();
|
||||
$data->name = trim($data->name);
|
||||
$result = update_record('groups', $data);
|
||||
|
||||
if ($result and $um) {
|
||||
@ -121,6 +137,18 @@ function groups_update_group($data, $um=false) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update grouping
|
||||
* @param object $data grouping properties (with magic quotes)
|
||||
* @return boolean success
|
||||
*/
|
||||
function groups_update_grouping($data) {
|
||||
global $CFG;
|
||||
$data->timemodified = time();
|
||||
$data->name = trim($data->name);
|
||||
return update_record('groupings', $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a group best effort, first removing members and links with courses and groupings.
|
||||
* Removes group avatar too.
|
||||
@ -145,6 +173,11 @@ function groups_delete_group($groupid) {
|
||||
return delete_records('groups', 'id', $groupid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete grouping
|
||||
* @param int $groupingid
|
||||
* @return bool success
|
||||
*/
|
||||
function groups_delete_grouping($groupingid) {
|
||||
if (empty($groupingid)) {
|
||||
return false;
|
||||
@ -161,6 +194,12 @@ function groups_delete_grouping($groupingid) {
|
||||
return delete_records('groupings', 'id', $groupingid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all users from group
|
||||
* @param int $courseid
|
||||
* @param bool $showfeedback
|
||||
* @return bool success
|
||||
*/
|
||||
function groups_delete_group_members($courseid, $showfeedback=false) {
|
||||
global $CFG;
|
||||
|
||||
@ -175,6 +214,12 @@ function groups_delete_group_members($courseid, $showfeedback=false) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all groups from course
|
||||
* @param int $courseid
|
||||
* @param bool $showfeedback
|
||||
* @return bool success
|
||||
*/
|
||||
function groups_delete_groups($courseid, $showfeedback=false) {
|
||||
global $CFG;
|
||||
require_once($CFG->libdir.'/gdlib.php');
|
||||
@ -201,6 +246,12 @@ function groups_delete_groups($courseid, $showfeedback=false) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all groupings from course
|
||||
* @param int $courseid
|
||||
* @param bool $showfeedback
|
||||
* @return bool success
|
||||
*/
|
||||
function groups_delete_groupings($courseid, $showfeedback=false) {
|
||||
global $CFG;
|
||||
|
||||
@ -287,7 +338,7 @@ function groups_get_users_not_in_group($courseid, $groupid, $searchtext='') {
|
||||
$from = " FROM {$CFG->prefix}user u
|
||||
INNER JOIN {$CFG->prefix}role_assignments ra ON ra.userid = u.id
|
||||
INNER JOIN {$CFG->prefix}role r ON r.id = ra.roleid";
|
||||
|
||||
|
||||
$where = " WHERE ra.contextid ".get_related_contexts_string($context)."
|
||||
AND u.deleted = 0
|
||||
AND ra.roleid in $roleids
|
||||
@ -296,7 +347,7 @@ function groups_get_users_not_in_group($courseid, $groupid, $searchtext='') {
|
||||
WHERE groupid = $groupid)
|
||||
$wheresearch";
|
||||
$groupby = " GROUP BY u.id, u.firstname, u.lastname ";
|
||||
|
||||
|
||||
return get_records_sql($select.$from.$where.$groupby);
|
||||
}
|
||||
|
||||
@ -308,9 +359,9 @@ function groups_get_users_not_in_group($courseid, $groupid, $searchtext='') {
|
||||
* @param string $orderby The colum to sort users by
|
||||
* @return array An array of the users
|
||||
*/
|
||||
function groups_get_potental_members($courseid, $roleid = null, $orderby = 'lastname') {
|
||||
function groups_get_potential_members($courseid, $roleid = null, $orderby = 'lastname,firstname') {
|
||||
global $CFG;
|
||||
|
||||
|
||||
$context = get_context_instance(CONTEXT_COURSE, $courseid);
|
||||
$sitecontext = get_context_instance(CONTEXT_SYSTEM);
|
||||
$rolenames = array();
|
||||
@ -335,7 +386,7 @@ function groups_get_potental_members($courseid, $roleid = null, $orderby = 'last
|
||||
$rolenames[$role->id] = strip_tags(role_get_name($role, $context)); // Used in menus etc later on
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$select = 'SELECT u.id, u.username, u.firstname, u.lastname, u.idnumber ';
|
||||
$from = "FROM {$CFG->prefix}user u INNER JOIN
|
||||
{$CFG->prefix}role_assignments r on u.id=r.userid ";
|
||||
@ -354,22 +405,21 @@ function groups_get_potental_members($courseid, $roleid = null, $orderby = 'last
|
||||
} else {
|
||||
$listofcontexts = '('.$sitecontext->id.')'; // must be site
|
||||
}
|
||||
|
||||
|
||||
if ($roleid) {
|
||||
$selectrole = " AND r.roleid = $roleid ";
|
||||
} else {
|
||||
$selectrole = " ";
|
||||
}
|
||||
|
||||
|
||||
$where = "WHERE (r.contextid = $context->id OR r.contextid in $listofcontexts)
|
||||
AND u.deleted = 0 $selectrole
|
||||
AND u.username != 'guest'
|
||||
$adminroles
|
||||
";
|
||||
AND u.deleted = 0 $selectrole
|
||||
AND u.username != 'guest'
|
||||
$adminroles ";
|
||||
$order = "ORDER BY $orderby ";
|
||||
|
||||
|
||||
return(get_records_sql($select.$from.$where.$order));
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -379,34 +429,43 @@ function groups_get_potental_members($courseid, $roleid = null, $orderby = 'last
|
||||
* @return string the parsed format string
|
||||
*/
|
||||
function groups_parse_name($format, $groupnumber) {
|
||||
|
||||
if (strstr($format, '@') !== false) { // Convert $groupnumber to a character series
|
||||
$tmp = $groupnumber;
|
||||
$places = 1;
|
||||
$serial = '';
|
||||
|
||||
if ($groupnumber > 25) {
|
||||
while (floor($groupnumber / pow(25, $places)) > 0) {
|
||||
$places++;
|
||||
}
|
||||
|
||||
} else {
|
||||
$places = 1;
|
||||
$letter = 'A';
|
||||
for($i=0; $i<$groupnumber; $i++) {
|
||||
$letter++;
|
||||
}
|
||||
|
||||
for($i=$places;$i>0;$i--) {
|
||||
if ($i>1) {
|
||||
$serial .= chr(65+floor($tmp/ pow(26, $i)));
|
||||
$tmp -= floor($tmp/ pow(26, $i))*pow(26, $i);
|
||||
} else {
|
||||
$serial .= chr(65+$tmp%26);
|
||||
}
|
||||
}
|
||||
$str = preg_replace('/[@]/', $serial, $format);
|
||||
$str = str_replace('@', $letter, $format);
|
||||
} else {
|
||||
$str = preg_replace('/[#]/', $groupnumber+1, $format);
|
||||
$str = str_replace('#', $groupnumber+1, $format);
|
||||
}
|
||||
return($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns group into grouping
|
||||
* @param int groupingid
|
||||
* @param int groupid
|
||||
* @return bool success
|
||||
*/
|
||||
function groups_assign_grouping($groupingid, $groupid) {
|
||||
if (record_exists('groupings_groups', 'groupingid', $groupingid, 'groupid', $groupid)) {
|
||||
return true;
|
||||
}
|
||||
$assign = new object();
|
||||
$assign->groupingid = $groupingid;
|
||||
$assign->groupid = $groupid;
|
||||
$assign->timeadded = time();
|
||||
return (bool)insert_record('groupings_groups', $assign);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unassigns group grom grouping
|
||||
* @param int groupingid
|
||||
* @param int groupid
|
||||
* @return bool success
|
||||
*/
|
||||
function groups_unassign_grouping($groupingid, $groupid) {
|
||||
return delete_records('groupings_groups', 'groupingid', $groupingid, 'groupid', $groupid);
|
||||
}
|
||||
|
||||
?>
|
@ -111,7 +111,7 @@ if ($potentialmemberscount <= MAX_USERS_PER_PAGE) {
|
||||
while ($usergroup = rs_fetch_next_record($rs)) {
|
||||
$usergroups[$usergroup->userid][$usergroup->id] = $usergroup;
|
||||
}
|
||||
|
||||
|
||||
// Put the groupings into a hash and sorts them
|
||||
foreach ($potentialmembers as $userid => $user) {
|
||||
$nonmembers[$userid] = fullname($user)." (".@count($usergroups[$userid]).")";
|
||||
@ -147,7 +147,7 @@ print_header("$course->shortname: $strgroups", $course->fullname, $navigation, '
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
var userSummaries = Array(
|
||||
var userSummaries = Array(
|
||||
<?php
|
||||
$membercnt = count($nonmembers);
|
||||
$i=1;
|
||||
@ -155,7 +155,7 @@ foreach ($nonmembers as $userid => $potentalmember) {
|
||||
|
||||
if (isset($usergroups[$userid])) {
|
||||
$usergrouplist = '<ul>';
|
||||
|
||||
|
||||
foreach ($usergroups[$userid] as $groupitem) {
|
||||
$usergrouplist .= '<li>'.addslashes(format_string($groupitem->name)).'</li>';
|
||||
}
|
||||
@ -180,7 +180,7 @@ function updateUserSummary() {
|
||||
var length = selectEl.length;
|
||||
var selectCnt = 0;
|
||||
var selectIdx = -1;
|
||||
|
||||
|
||||
for(i=0;i<length;i++) {
|
||||
if (selectEl.options[i].selected) {
|
||||
selectCnt++;
|
||||
@ -193,7 +193,7 @@ function updateUserSummary() {
|
||||
} else {
|
||||
summaryDiv.innerHTML = '';
|
||||
}
|
||||
|
||||
|
||||
return(true);
|
||||
}
|
||||
//]]>
|
||||
|
@ -7,14 +7,15 @@
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
||||
* @package groups
|
||||
*/
|
||||
|
||||
|
||||
require_once('../config.php');
|
||||
|
||||
$courseid = required_param('id', PARAM_INT);
|
||||
$groupid = optional_param('groupid', 0, PARAM_INT);
|
||||
$groupingid = optional_param('groupingid', 0, PARAM_INT);
|
||||
$courseid = required_param('id', PARAM_INT);
|
||||
$groupid = optional_param('group', 0, PARAM_INT);
|
||||
$groupingid = optional_param('grouping', 0, PARAM_INT);
|
||||
|
||||
$returnurl = $CFG->wwwroot.'/group/index.php?id='.$courseid;
|
||||
$rooturl = $CFG->wwwroot.'/group/overview.php?id='.$courseid;
|
||||
|
||||
if (!$course = get_record('course', 'id',$courseid)) {
|
||||
error('invalidcourse');
|
||||
@ -26,17 +27,76 @@ require_login($course);
|
||||
$context = get_context_instance(CONTEXT_COURSE, $courseid);
|
||||
require_capability('moodle/course:managegroups', $context);
|
||||
|
||||
$strgroups = get_string('groups');
|
||||
$strparticipants = get_string('participants');
|
||||
$stroverview = get_string('overview', 'group');
|
||||
$strgrouping = get_string('grouping', 'group');
|
||||
$strgroup = get_string('group', 'group');
|
||||
$strnotingrouping = get_string('notingrouping', 'group');
|
||||
$strfiltergroups = get_string('filtergroups', 'group');
|
||||
$strnogroups = get_string('nogroups', 'group');
|
||||
$strdescription = get_string('description');
|
||||
|
||||
// Get all groupings
|
||||
if (empty($CFG->enablegroupings)) {
|
||||
$groupings = array();
|
||||
$members = array(-1 => array()); //groups not in a grouping
|
||||
$groupingid = 0;
|
||||
} else {
|
||||
if (!$groupings = get_records('groupings', 'courseid', $courseid, 'name')) {
|
||||
$groupings = array();
|
||||
}
|
||||
$members = array();
|
||||
foreach ($groupings as $grouping) {
|
||||
$members[$grouping->id] = array();
|
||||
}
|
||||
$members[-1] = array(); //groups not in a grouping
|
||||
}
|
||||
|
||||
// Get all groups
|
||||
if (!$groups = get_records('groups', 'courseid', $courseid, 'name')) {
|
||||
$groups = array();
|
||||
}
|
||||
|
||||
if (empty($CFG->enablegroupings)) {
|
||||
$groupwhere = $groupid ? "AND g.id = $groupid" : "";
|
||||
$sql = "SELECT g.id AS groupid, NULL AS groupingid, u.id AS userid, u.firstname, u.lastname, u.idnumber, u.username
|
||||
FROM {$CFG->prefix}groups g
|
||||
LEFT JOIN {$CFG->prefix}groups_members gm ON g.id = gm.groupid
|
||||
LEFT JOIN {$CFG->prefix}user u ON gm.userid = u.id
|
||||
WHERE g.courseid = {$course->id} $groupwhere
|
||||
ORDER BY g.name, u.lastname, u.firstname";
|
||||
} else {
|
||||
$groupingwhere = $groupingid ? "AND gg.groupingid = $groupingid" : "";
|
||||
$groupwhere = $groupid ? "AND g.id = $groupid" : "";
|
||||
$sql = "SELECT g.id AS groupid, gg.groupingid, u.id AS userid, u.firstname, u.lastname, u.idnumber, u.username
|
||||
FROM {$CFG->prefix}groups g
|
||||
LEFT JOIN {$CFG->prefix}groupings_groups gg ON g.id = gg.groupid
|
||||
LEFT JOIN {$CFG->prefix}groups_members gm ON g.id = gm.groupid
|
||||
LEFT JOIN {$CFG->prefix}user u ON gm.userid = u.id
|
||||
WHERE g.courseid = {$course->id} $groupingwhere $groupwhere
|
||||
ORDER BY g.name, u.lastname, u.firstname";
|
||||
}
|
||||
|
||||
if ($rs = get_recordset_sql($sql)) {
|
||||
while ($row = rs_fetch_next_record($rs)) {
|
||||
$user = new object();
|
||||
$user->id = $row->userid;
|
||||
$user->firstname = $row->firstname;
|
||||
$user->lastname = $row->lastname;
|
||||
$user->username = $row->username;
|
||||
$user->idnumber = $row->idnumber;
|
||||
if (!$row->groupingid) {
|
||||
$row->groupingid = -1;
|
||||
}
|
||||
if (!array_key_exists($row->groupid, $members[$row->groupingid])) {
|
||||
$members[$row->groupingid][$row->groupid] = array();
|
||||
}
|
||||
$members[$row->groupingid][$row->groupid][] = $user;
|
||||
}
|
||||
rs_close($rs);
|
||||
}
|
||||
|
||||
$strgroups = get_string('groups');
|
||||
$strparticipants = get_string('participants');
|
||||
$stroverview = get_string('overview', 'group');
|
||||
$strgrouping = get_string('grouping', 'group');
|
||||
$strgroup = get_string('group', 'group');
|
||||
$strnotingrouping = get_string('notingrouping', 'group');
|
||||
$strfiltergroups = get_string('filtergroups', 'group');
|
||||
$strnogroups = get_string('nogroups', 'group');
|
||||
$strnogroupsassigned = get_string('nogroupsassigned', 'group');
|
||||
|
||||
// Print the page and form
|
||||
$navlinks = array(array('name'=>$strparticipants, 'link'=>$CFG->wwwroot.'/user/index.php?id='.$courseid, 'type'=>'misc'),
|
||||
@ -45,162 +105,80 @@ $navigation = build_navigation($navlinks);
|
||||
|
||||
/// Print header
|
||||
print_header_simple($strgroups, ': '.$strgroups, $navigation, '', '', true, '', navmenu($course));
|
||||
// Add tabs
|
||||
$currenttab = 'overview';
|
||||
require('tabs.php');
|
||||
|
||||
/// Print overview
|
||||
print_heading(format_string($course->shortname) .' '.$stroverview, 'center', 3);
|
||||
|
||||
echo $strfiltergroups;
|
||||
|
||||
if (!empty($CFG->enablegroupings)) {
|
||||
// Add tabs
|
||||
$currenttab = 'overview';
|
||||
require('tabs.php');
|
||||
}
|
||||
|
||||
$groupings= array();
|
||||
|
||||
// Get groupings and child group id's
|
||||
if (!empty($CFG->enablegroupings)) {
|
||||
$sql = "SELECT gs.id, gs.name, gg.groupid " .
|
||||
"FROM {$CFG->prefix}groupings gs " .
|
||||
"LEFT JOIN {$CFG->prefix}groupings_groups gg ON gs.id = gg.groupingid " .
|
||||
"WHERE gs.courseid = {$course->id} " .
|
||||
"ORDER BY gs.name, gs.id ";
|
||||
|
||||
$rs = get_recordset_sql($sql);
|
||||
while ($row = rs_fetch_next_record($rs)) {
|
||||
$groupings[] = $row;
|
||||
}
|
||||
}
|
||||
|
||||
// Get groups & group members
|
||||
$sql = "SELECT g.id AS groupid, g.name, u.id AS userid, u.firstname, u.lastname, u.idnumber, u.username " .
|
||||
"FROM {$CFG->prefix}groups g " .
|
||||
"LEFT JOIN {$CFG->prefix}groups_members gm ON g.id = gm.groupid " .
|
||||
"LEFT JOIN {$CFG->prefix}user u ON gm.userid = u.id " .
|
||||
"WHERE g.courseid = {$course->id} " .
|
||||
"ORDER BY g.name, g.id ";
|
||||
|
||||
$rs = get_recordset_sql($sql);
|
||||
|
||||
$groupsmembers = array();
|
||||
|
||||
// Build a hash of keyed on groupid and userid;
|
||||
while ($row = rs_fetch_next_record($rs)) {
|
||||
$groupsmembers[$row->groupid]->name = $row->name;
|
||||
$groupsmembers[$row->groupid]->groupid = $row->groupid;
|
||||
$groupsmembers[$row->groupid]->users[$row->userid] = $row;
|
||||
$groupsmembers[$row->groupid]->printed = false;
|
||||
}
|
||||
|
||||
if (empty($groupsmembers)) {
|
||||
print_box($strnogroups);
|
||||
} else {
|
||||
|
||||
/// Print overview filter form
|
||||
|
||||
echo '<form method="get" action="overview.php">';
|
||||
echo "<input type=\"hidden\" name=\"id\" value=\"{$course->id}\" />";
|
||||
echo "<label for=\"groupingselect\">$strfiltergroups $strgrouping </label>";
|
||||
echo '<select id="groupingselect" name="groupingid" onchange="this.parentNode.submit();">';
|
||||
echo ' <option value=""></option>';
|
||||
$lastgroupingid = false;
|
||||
$options = array();
|
||||
$options[0] = get_string('all');
|
||||
foreach ($groupings as $grouping) {
|
||||
if ($lastgroupingid === false || $lastgroupingid != $grouping->id) {
|
||||
$selected = $grouping->id == $groupingid ? 'selected="selected"':'';
|
||||
echo "<option value=\"{$grouping->id}\" $selected>".format_string($grouping->name)."</option>\n";
|
||||
}
|
||||
$lastgroupingid = $grouping->id;
|
||||
$options[$grouping->id] = strip_tags(format_string($grouping->name));
|
||||
}
|
||||
echo '</select>';
|
||||
|
||||
echo "<label for=\"groupselect\"> $strgroup </label>";
|
||||
echo '<select id="groupselect" name="groupid" onchange="this.parentNode.submit();">';
|
||||
echo ' <option value=""></option>';
|
||||
$lastgroupid = false;
|
||||
|
||||
foreach ($groupsmembers as $group) {
|
||||
if ($lastgroupid === false || $lastgroupid != $group->groupid) {
|
||||
$selected = $group->groupid == $groupid ? 'selected="selected"':'';
|
||||
echo "<option value=\"{$group->groupid}\" $selected>".format_string($group->name)."</option>\n";
|
||||
}
|
||||
$lastgroupid = $group->groupid ;
|
||||
}
|
||||
echo '</select>';
|
||||
|
||||
echo '</form>';
|
||||
|
||||
|
||||
/// Print overview
|
||||
print_heading(format_string($course->shortname) .' '.$stroverview, 'center', 3);
|
||||
|
||||
popup_form($rooturl.'&group='.$groupid.'&grouping=', $options, 'selectgrouping', $groupingid, '', '', '', false, 'self', $strgrouping);
|
||||
}
|
||||
|
||||
|
||||
echo '<div id="grouping-groups-overview"><ul>';
|
||||
|
||||
if (!empty($CFG->enablegroupings) && isset($groupings)) {
|
||||
$lastgroupingid = false;
|
||||
foreach ($groupings as $grouping) {
|
||||
if (!empty($groupingid) && $groupingid != $grouping->id) {
|
||||
continue;
|
||||
}
|
||||
if (!empty($groupid) && $groupid != $grouping->groupid) {
|
||||
continue;
|
||||
}
|
||||
if ($lastgroupingid === false || $lastgroupingid != $grouping->id) {
|
||||
if($lastgroupingid !== false) {
|
||||
echo '</ul></li>';
|
||||
}
|
||||
|
||||
echo "<li>$strgrouping: {$grouping->name}<ul>\n";
|
||||
$lastgroupingid = $grouping->id;
|
||||
}
|
||||
if (isset($groupsmembers[$grouping->groupid])) {
|
||||
echo "<li>{$strgroup}: ".format_string($groupsmembers[$grouping->groupid]->name)."<ul>\n";
|
||||
foreach ($groupsmembers[$grouping->groupid]->users as $user) {
|
||||
echo "<li><a href=\"{$CFG->wwwroot}/user/view.php?id={$user->userid}\">".fullname($user)."</a></li>\n";
|
||||
}
|
||||
echo "</ul></li>";
|
||||
}
|
||||
else {
|
||||
echo "<li>$strnogroupsassigned</li>";
|
||||
}
|
||||
if (isset($groupsmembers[$grouping->groupid])) {
|
||||
$groupsmembers[$grouping->groupid]->printed = true;
|
||||
}
|
||||
}
|
||||
$options = array();
|
||||
$options[0] = get_string('all');
|
||||
foreach ($groups as $group) {
|
||||
$options[$group->id] = strip_tags(format_string($group->name));
|
||||
}
|
||||
popup_form($rooturl.'&grouping='.$groupingid.'&group=', $options, 'selectgroup', $groupid, '', '', '', false, 'self', $strgroup);
|
||||
|
||||
|
||||
/// Print table
|
||||
$printed = false;
|
||||
foreach ($members as $gpgid=>$groupdata) {
|
||||
if ($groupingid and $groupingid != $gpgid) {
|
||||
continue; // do not show
|
||||
}
|
||||
if ($lastgroupingid !== false) {
|
||||
echo '</ul></li>';
|
||||
}
|
||||
echo '</ul>';
|
||||
|
||||
// Print Groups not in a grouping
|
||||
|
||||
|
||||
if (empty($groupingid)) {
|
||||
|
||||
$labelprinted = false;
|
||||
foreach($groupsmembers as $groupmembers) {
|
||||
if ($groupmembers->printed) {
|
||||
continue;
|
||||
}
|
||||
if (!empty($groupid) && $groupid != $groupmembers->groupid) {
|
||||
continue;
|
||||
}
|
||||
if ($labelprinted === false) {
|
||||
echo "<ul><li>$strnotingrouping<ul>";
|
||||
$labelprinted = true;
|
||||
}
|
||||
|
||||
echo '<li>'.format_string($groupmembers->name).'<ul>';
|
||||
|
||||
foreach ($groupmembers->users as $user) {
|
||||
echo "<li><a href=\"{$CFG->wwwroot}/user/view.php?id={$user->userid}\">".fullname($user)."</a></li>\n";
|
||||
}
|
||||
echo "</ul></li>";
|
||||
$table = new object();
|
||||
$table->head = array(get_string('groupscount', 'group', count($groupdata)), get_string('groupmembers', 'group'), get_string('usercount', 'group'));
|
||||
$table->size = array('20%', '70%', '10%');
|
||||
$table->align = array('left', 'left', 'center');
|
||||
$table->width = '90%';
|
||||
$table->data = array();
|
||||
foreach ($groupdata as $gpid=>$users) {
|
||||
if ($groupid and $groupid != $gpid) {
|
||||
continue;
|
||||
}
|
||||
if ($labelprinted !== false) {
|
||||
echo '</ul></li></ul>';
|
||||
$line = array();
|
||||
$name = format_string($groups[$gpid]->name);
|
||||
$jsdescription = addslashes_js(trim($groups[$gpid]->description));
|
||||
if (empty($jsdescription)) {
|
||||
$line[] = $name;
|
||||
} else {
|
||||
$jsstrdescription = addslashes_js($strdescription);
|
||||
$overlib = "return overlib('$jsdescription', BORDER, 0, FGCLASS, 'description', "
|
||||
."CAPTIONFONTCLASS, 'caption', CAPTION, '$jsstrdescription');";
|
||||
$line[] = '<span onmouseover="'.s($overlib).'" onmouseout="return nd();">'.$name.'</span>';
|
||||
}
|
||||
$fullnames = array();
|
||||
foreach ($users as $user) {
|
||||
$fullnames[] = '<a href="'.$CFG->wwwroot.'/user/view.php?id='.$user->id.'&course='.$course->id.'">'.fullname($user, true).'</a>';
|
||||
}
|
||||
$line[] = implode(', ', $fullnames);
|
||||
$line[] = count($users);
|
||||
$table->data[] = $line;
|
||||
}
|
||||
if ($groupid and empty($table->data)) {
|
||||
continue;
|
||||
}
|
||||
if (!empty($CFG->enablegroupings)) {
|
||||
if ($gpgid < 0) {
|
||||
print_heading($strnotingrouping, '', 3);
|
||||
} else {
|
||||
print_heading(format_string($groupings[$gpgid]->name), '', 3);
|
||||
print_box($groupings[$gpgid]->description, 'generalbox boxwidthnarrow boxaligncenter');
|
||||
}
|
||||
}
|
||||
echo '</div>';
|
||||
print_table($table, false);
|
||||
$printed = true;
|
||||
}
|
||||
|
||||
print_footer($course);
|
||||
|
@ -4,9 +4,12 @@
|
||||
$CFG->wwwroot.'/group/index.php?id='.$courseid,
|
||||
get_string('groups'));
|
||||
|
||||
$row[] = new tabobject('groupings',
|
||||
$CFG->wwwroot.'/group/groupings.php?id='.$courseid,
|
||||
get_string('groupings', 'group'));
|
||||
if (!empty($CFG->enablegroupings)) {
|
||||
$row[] = new tabobject('groupings',
|
||||
$CFG->wwwroot.'/group/groupings.php?id='.$courseid,
|
||||
get_string('groupings', 'group'));
|
||||
}
|
||||
|
||||
$row[] = new tabobject('overview',
|
||||
$CFG->wwwroot.'/group/overview.php?id='.$courseid,
|
||||
get_string('overview', 'group'));
|
||||
|
@ -52,15 +52,6 @@ $string['addgroupstogroupings'] = 'Add/remove groups'; //'from group'
|
||||
$string['groupingname'] = 'Grouping name';
|
||||
$string['defaultgroupingname'] = 'Grouping';
|
||||
$string['groupingdescription'] = 'Grouping description';
|
||||
$string['prefixforgroupnames'] = 'Prefix for group names';
|
||||
$string['defaultgroupprefix'] = 'Group ';
|
||||
$string['distributealphabetically'] = 'Distribute into groups alphabetically by last name';
|
||||
$string['usestudentsonlyfromselectedgroup'] = 'Only use students from currently selected group';
|
||||
$string['selectnumberineachgroup'] = 'Select number in each group';
|
||||
$string['numberofstudents'] = 'Number of students';
|
||||
$string['distributeevenly'] = 'Distribute leftover students evenly';
|
||||
$string['selectnumberofgroups'] = 'Select number of groups';
|
||||
$string['numberofgroups'] = 'Number of groups';
|
||||
$string['creategrouping'] = 'Create grouping';
|
||||
$string['creategroup'] = 'Create group';
|
||||
$string['createorphangroup'] = 'Create orphan group';
|
||||
@ -73,10 +64,7 @@ $string['groupdescription'] = 'Group description';
|
||||
$string['enrolmentkey'] = 'Enrolment key';
|
||||
$string['hidepicture'] = 'Hide picture';
|
||||
$string['newpicture'] = 'New picture';
|
||||
|
||||
$string['defaultgroupdescription'] = 'Default group description';
|
||||
|
||||
$string['displaygrouping'] = 'Display grouping';
|
||||
$string['newgrouping'] = 'New grouping';
|
||||
|
||||
$string['backtogroups'] = 'Back to groups';
|
||||
$string['backtogroupings'] = 'Back to groupings';
|
||||
@ -101,6 +89,7 @@ $string['groupsseparate'] = 'Separate groups';
|
||||
$string['groupsvisible'] = 'Visible groups';
|
||||
$string['groupmembersonly'] = 'Available for group members only';
|
||||
$string['groupmembersonlyerror'] = 'Sorry, you must be member of at least one group that is used in this activity.';
|
||||
$string['grouptemplate'] = 'Group @';
|
||||
|
||||
$string['groupaddedsuccesfully'] = 'Group $a added succesfully';
|
||||
$string['nopermissionforcreation'] = 'Can\'t create group \"$a\" as you dont have the required permissions';
|
||||
@ -110,21 +99,33 @@ $string['filtergroups'] = 'Filter groups by: ';
|
||||
$string['nogroups'] = 'There are no groups setup in this course yet';
|
||||
|
||||
$string['autocreategroups'] = 'Auto-create groups';
|
||||
$string['selectfromrole'] = 'Role to select members from';
|
||||
$string['groupby'] = 'Create groups based on the number of ';
|
||||
$string['selectfromrole'] = 'Select members from role';
|
||||
$string['groupby'] = 'Specify';
|
||||
$string['numgroups'] = 'Number of groups';
|
||||
$string['nummembers'] = 'Members per group';
|
||||
$string['nosmallgroups'] = 'Prevent last small group';
|
||||
|
||||
$string['groupscount'] = 'Groups ($a)';
|
||||
$string['usercounttotal'] = 'User count ($a)';
|
||||
$string['usercount'] = 'User count';
|
||||
|
||||
$string['members'] = 'Members per group';
|
||||
$string['number'] = 'Number of groups or members per group';
|
||||
$string['number'] = 'Group/member count';
|
||||
$string['allocateby'] = 'Allocate members';
|
||||
$string['random'] = 'randomly';
|
||||
$string['firstname'] = 'alphabetically by first name';
|
||||
$string['lastname'] = 'alphabetically by last name';
|
||||
$string['noallocation'] = 'No allocation';
|
||||
$string['random'] = 'Randomly';
|
||||
$string['byfirstname'] = 'Alphabetically by first name, last name';
|
||||
$string['bylastname'] = 'Alphabetically by last name, first name';
|
||||
$string['byidnumber'] = 'Alphabetically by ID number';
|
||||
$string['createingrouping'] = 'Create in grouping';
|
||||
|
||||
$string['namingscheme'] = 'Naming scheme';
|
||||
$string['namingschemehelp'] = 'note: Use \'@\' to represent the group letter or \'#\' to represent the group number';
|
||||
$string['namingschemehelp'] = 'Use @ character to represent the group letter (A-Z) or # to represent the group number.';
|
||||
$string['toomanygroups'] = 'Insufficient users to populate this number of groups - there are only $a users in the selected role.';
|
||||
$string['badnamingscheme'] = 'Must contain exactly one \'@\' or one \'#\' character';
|
||||
$string['groupspreview'] = 'Groups preview';
|
||||
$string['nousersinrole'] = 'There are no suitable users in the selected role';
|
||||
$string['nogroupsassigned'] = 'No groups assigned';
|
||||
$string['evenallocation'] = 'Note: To keep group allocation even, the actual number of members per group differs from the number you specified.';
|
||||
$string['membersingroup'] = 'members';
|
||||
|
||||
?>
|
||||
|
@ -81,6 +81,15 @@ function groups_get_group($groupid) {
|
||||
return get_record('groups', 'id', $groupid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the grouping object
|
||||
* @param groupingid ID of the group.
|
||||
* @return group object
|
||||
*/
|
||||
function groups_get_grouping($groupingid) {
|
||||
return get_record('groupings', 'id', $groupingid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets array of all groups in a specified course.
|
||||
* @param int $courseid The id of the course.
|
||||
@ -166,9 +175,9 @@ function groups_is_member($groupid, $userid=null) {
|
||||
*/
|
||||
function groups_has_membership($cm, $userid=null) {
|
||||
global $CFG, $USER;
|
||||
|
||||
|
||||
static $cache = array();
|
||||
|
||||
|
||||
// groupings are ignored when not enabled
|
||||
if (empty($CFG->enablegroupings)) {
|
||||
$cm->groupingid = 0;
|
||||
@ -195,9 +204,9 @@ function groups_has_membership($cm, $userid=null) {
|
||||
FROM {$CFG->prefix}groups_members gm, {$CFG->prefix}groups g
|
||||
WHERE gm.userid = $userid AND gm.groupid = g.id AND g.courseid = {$cm->course}";
|
||||
}
|
||||
|
||||
|
||||
$cache[$cachekey] = record_exists_sql($sql);
|
||||
|
||||
|
||||
return $cache[$cachekey];
|
||||
}
|
||||
|
||||
@ -329,15 +338,15 @@ function groups_print_course_menu($course, $urlroot, $return=false) {
|
||||
/**
|
||||
* Print group menu selector for activity.
|
||||
* @param object $cm course module object
|
||||
* @param string $urlroot return address that users get to if they choose an option;
|
||||
* @param string $urlroot return address that users get to if they choose an option;
|
||||
* should include any parameters needed, e.g. 'view.php?id=34'
|
||||
* @param boolean $return return as string instead of printing
|
||||
* @param boolean $hideallparticipants If true, this prevents the 'All participants'
|
||||
* option from appearing in cases where it normally would. This is intended for
|
||||
* use only by activities that cannot display all groups together. (Note that
|
||||
* selecting this option does not prevent groups_get_activity_group from
|
||||
* returning 0; it will still do that if the user has chosen 'all participants'
|
||||
* in another activity, or not chosen anything.)
|
||||
* @param boolean $hideallparticipants If true, this prevents the 'All participants'
|
||||
* option from appearing in cases where it normally would. This is intended for
|
||||
* use only by activities that cannot display all groups together. (Note that
|
||||
* selecting this option does not prevent groups_get_activity_group from
|
||||
* returning 0; it will still do that if the user has chosen 'all participants'
|
||||
* in another activity, or not chosen anything.)
|
||||
* @return mixed void or string depending on $return param
|
||||
*/
|
||||
function groups_print_activity_menu($cm, $urlroot, $return=false, $hideallparticipants=false) {
|
||||
@ -366,7 +375,7 @@ function groups_print_activity_menu($cm, $urlroot, $return=false, $hideallpartic
|
||||
$activegroup = groups_get_activity_group($cm, true);
|
||||
|
||||
$groupsmenu = array();
|
||||
if ((!$allowedgroups or $groupmode == VISIBLEGROUPS or
|
||||
if ((!$allowedgroups or $groupmode == VISIBLEGROUPS or
|
||||
has_capability('moodle/site:accessallgroups', $context)) and !$hideallparticipants) {
|
||||
$groupsmenu[0] = get_string('allparticipants');
|
||||
}
|
||||
@ -547,7 +556,7 @@ function groups_get_activity_group($cm, $update=false) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a list of groups that the user is allowed to access within the
|
||||
* Gets a list of groups that the user is allowed to access within the
|
||||
* specified activity.
|
||||
* @param object $cm Course-module
|
||||
* @param int $userid User ID (defaults to current user)
|
||||
@ -559,19 +568,19 @@ function groups_get_activity_allowed_groups($cm,$userid=0) {
|
||||
if(!$userid) {
|
||||
$userid=$USER->id;
|
||||
}
|
||||
|
||||
|
||||
// Get groupmode for activity, taking into account course settings
|
||||
$groupmode=groups_get_activity_groupmode($cm);
|
||||
|
||||
// If visible groups mode, or user has the accessallgroups capability,
|
||||
// then they can access all groups for the activity...
|
||||
$context = get_context_instance(CONTEXT_MODULE, $cm->id);
|
||||
$context = get_context_instance(CONTEXT_MODULE, $cm->id);
|
||||
if ($groupmode == VISIBLEGROUPS or has_capability('moodle/site:accessallgroups', $context)) {
|
||||
return groups_get_all_groups($cm->course, 0, $cm->groupingid);
|
||||
return groups_get_all_groups($cm->course, 0, $cm->groupingid);
|
||||
} else {
|
||||
// ...otherwise they can only access groups they belong to
|
||||
return groups_get_all_groups($cm->course, $userid, $cm->groupingid);
|
||||
}
|
||||
return groups_get_all_groups($cm->course, $userid, $cm->groupingid);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -583,7 +592,7 @@ function groups_get_activity_allowed_groups($cm,$userid=0) {
|
||||
*/
|
||||
function groups_course_module_visible($cm, $userid=null) {
|
||||
global $CFG, $USER;
|
||||
|
||||
|
||||
if (empty($userid)) {
|
||||
$userid = $USER->id;
|
||||
}
|
||||
|
@ -426,42 +426,6 @@ form.popupform label {
|
||||
width: 14em;
|
||||
}
|
||||
|
||||
|
||||
#grouping-groups-overview {
|
||||
margin: auto;
|
||||
width: 90%;
|
||||
}
|
||||
|
||||
#grouping-groups-overview ul {
|
||||
list-style: none;
|
||||
padding-left: 0;
|
||||
margin-left: 0px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* First level list items i.e. groupings */
|
||||
#grouping-groups-overview ul li {
|
||||
padding-bottom: 1.8em;
|
||||
}
|
||||
|
||||
/* Second level list items i.e. groups */
|
||||
#grouping-groups-overview ul li ul li {
|
||||
font-style: italic;
|
||||
font-weight: normal;
|
||||
background-color: #ffffff;
|
||||
border: 1px solid #DDDDDD;
|
||||
padding: 1.1em;
|
||||
margin: 0.1em;
|
||||
}
|
||||
|
||||
/* Third level list items i.e. group members */
|
||||
#grouping-groups-overview ul li ul li ul li {
|
||||
font-style: normal;
|
||||
border: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
|
||||
img.icon {
|
||||
vertical-align:middle;
|
||||
/*margin-right:4px;*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user