Skip to content

Commit

Permalink
Merge branch 'MDL-31973-master-6' of git://git.luns.net.uk/moodle
Browse files Browse the repository at this point in the history
Conflicts:
	lib/db/upgrade.php
  • Loading branch information
stronk7 committed Aug 28, 2012
2 parents 71ff7c2 + 1d1917a commit 238f776
Show file tree
Hide file tree
Showing 14 changed files with 161 additions and 7 deletions.
2 changes: 1 addition & 1 deletion backup/moodle2/backup_stepslib.php
Original file line number Diff line number Diff line change
Expand Up @@ -1005,7 +1005,7 @@ protected function define_structure() {
$members = new backup_nested_element('group_members');

$member = new backup_nested_element('group_member', array('id'), array(
'userid', 'timeadded'));
'userid', 'timeadded', 'component', 'itemid'));

$groupings = new backup_nested_element('groupings');

Expand Down
11 changes: 11 additions & 0 deletions backup/moodle2/restore_stepslib.php
Original file line number Diff line number Diff line change
Expand Up @@ -780,6 +780,17 @@ public function process_member($data) {
// map user newitemid and insert if not member already
if ($data->userid = $this->get_mappingid('user', $data->userid)) {
if (!$DB->record_exists('groups_members', array('groupid' => $data->groupid, 'userid' => $data->userid))) {
// Check the componment, if any, exists
if (!empty($data->component)) {
$dir = get_component_directory($data->component);
if (!$dir || !is_dir($dir)) {
// Component does not exist on restored system; clear
// component and itemid
unset($data->component);
unset($data->itemid);
}
}

$DB->insert_record('groups_members', $data);
}
}
Expand Down
16 changes: 15 additions & 1 deletion enrol/imsenterprise/lib.php
Original file line number Diff line number Diff line change
Expand Up @@ -702,7 +702,8 @@ function process_membership_tag($tagcontents){
}
// Add the user-to-group association if it doesn't already exist
if($member->groupid) {
groups_add_member($member->groupid, $memberstoreobj->userid);
groups_add_member($member->groupid, $memberstoreobj->userid,
'enrol_imsenterprise', $einstance->id);
}
} // End of group-enrolment (from member.role.extension.cohort tag)

Expand Down Expand Up @@ -793,6 +794,19 @@ function load_role_mappings() {
}
}

/**
* Called whenever anybody tries (from the normal interface) to remove a group
* member which is registered as being created by this component. (Not called
* when deleting an entire group or course at once.)
* @param int $itemid Item ID that was stored in the group_members entry
* @param int $groupid Group ID
* @param int $userid User ID being removed from group
* @return bool True if the remove is permitted, false to give an error
*/
function enrol_imsenterprise_allow_group_member_remove($itemid, $groupid, $userid) {
return false;
}

} // end of class


3 changes: 3 additions & 0 deletions group/externallib.php
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,9 @@ public static function delete_group_members($members) {
}
require_capability('moodle/course:managegroups', $context);

if (!groups_remove_member_allowed($group, $user)) {
throw new moodle_exception('errorremovenotpermitted', 'group', '', fullname($user));
}
groups_remove_member($group, $user);
}

Expand Down
74 changes: 73 additions & 1 deletion group/lib.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,12 @@
*
* @param mixed $grouporid The group id or group object
* @param mixed $userorid The user id or user object
* @param string $component Optional component name e.g. 'enrol_imsenterprise'
* @param int $itemid Optional itemid associated with component
* @return bool True if user added successfully or the user is already a
* member of the group, false otherwise.
*/
function groups_add_member($grouporid, $userorid) {
function groups_add_member($grouporid, $userorid, $component=null, $itemid=0) {
global $DB;

if (is_object($userorid)) {
Expand Down Expand Up @@ -68,6 +70,25 @@ function groups_add_member($grouporid, $userorid) {
$member->groupid = $groupid;
$member->userid = $userid;
$member->timeadded = time();
$member->component = '';
$member->itemid = 0;

// Check the component exists if specified
if (!empty($component)) {
$dir = get_component_directory($component);
if ($dir && is_dir($dir)) {
// Component exists and can be used
$member->component = $component;
$member->itemid = $itemid;
} else {
throw new coding_exception('Invalid call to groups_add_member(). An invalid component was specified');
}
}

if ($itemid !== 0 && empty($member->component)) {
// An itemid can only be specified if a valid component was found
throw new coding_exception('Invalid call to groups_add_member(). A component must be specified if an itemid is given');
}

$DB->insert_record('groups_members', $member);

Expand All @@ -78,11 +99,62 @@ function groups_add_member($grouporid, $userorid) {
$eventdata = new stdClass();
$eventdata->groupid = $groupid;
$eventdata->userid = $userid;
$eventdata->component = $member->component;
$eventdata->itemid = $member->itemid;
events_trigger('groups_member_added', $eventdata);

return true;
}

/**
* Checks whether the current user is permitted (using the normal UI) to
* remove a specific group member, assuming that they have access to remove
* group members in general.
*
* For automatically-created group member entries, this checks with the
* relevant plugin to see whether it is permitted. The default, if the plugin
* doesn't provide a function, is true.
*
* For other entries (and any which have already been deleted/don't exist) it
* just returns true.
*
* @param mixed $grouporid The group id or group object
* @param mixed $userorid The user id or user object
* @return bool True if permitted, false otherwise
*/
function groups_remove_member_allowed($grouporid, $userorid) {
global $DB;

if (is_object($userorid)) {
$userid = $userorid->id;
} else {
$userid = $userorid;
}
if (is_object($grouporid)) {
$groupid = $grouporid->id;
} else {
$groupid = $grouporid;
}

// Get entry
if (!($entry = $DB->get_record('groups_members',
array('groupid' => $groupid, 'userid' => $userid), '*', IGNORE_MISSING))) {
// If the entry does not exist, they are allowed to remove it (this
// is consistent with groups_remove_member below).
return true;
}

// If the entry does not have a component value, they can remove it
if (empty($entry->component)) {
return true;
}

// It has a component value, so we need to call a plugin function (if it
// exists); the default is to allow removal
return component_callback($entry->component, 'allow_group_member_remove',
array($entry->itemid, $entry->groupid, $entry->userid), true);
}

/**
* Deletes the link between the specified user and group.
*
Expand Down
4 changes: 4 additions & 0 deletions group/members.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@
$userstoremove = $groupmembersselector->get_selected_users();
if (!empty($userstoremove)) {
foreach ($userstoremove as $user) {
if (!groups_remove_member_allowed($groupid, $user->id)) {
print_error('errorremovenotpermitted', 'group', $returnurl,
$user->fullname);
}
if (!groups_remove_member($groupid, $user->id)) {
print_error('erroraddremoveuser', 'group', $returnurl);
}
Expand Down
2 changes: 2 additions & 0 deletions lang/en/group.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/

$string['addedby'] = 'Added by {$a}';
$string['addgroup'] = 'Add user into group';
$string['addgroupstogrouping'] = 'Add group to grouping';
$string['addgroupstogroupings'] = 'Add/remove groups';
Expand Down Expand Up @@ -62,6 +63,7 @@
$string['erroreditgroup'] = 'Error creating/updating group {$a}';
$string['erroreditgrouping'] = 'Error creating/updating grouping {$a}';
$string['errorinvalidgroup'] = 'Error, invalid group {$a}';
$string['errorremovenotpermitted'] = 'You do not have permission to remove automatically-added group member {$a}';
$string['errorselectone'] = 'Please select a single group before choosing this option';
$string['errorselectsome'] = 'Please select one or more groups before choosing this option';
$string['evenallocation'] = 'Note: To keep group allocation even, the actual number of members per group differs from the number you specified.';
Expand Down
6 changes: 4 additions & 2 deletions lib/db/install.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2097,7 +2097,9 @@
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true" NEXT="groupid"/>
<FIELD NAME="groupid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="id" NEXT="userid"/>
<FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="groupid" NEXT="timeadded"/>
<FIELD NAME="timeadded" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="userid"/>
<FIELD NAME="timeadded" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" PREVIOUS="userid" NEXT="component"/>
<FIELD NAME="component" TYPE="char" LENGTH="100" NOTNULL="true" SEQUENCE="false" COMMENT="Defines the Moodle component which added this group membership (e.g. 'auth_myplugin'), or blank if it was added manually. (Entries which are created by a Moodle component cannot be removed in the normal user interface.)" PREVIOUS="timeadded" NEXT="itemid"/>
<FIELD NAME="itemid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="If the 'component' field is set, this can be used to define the instance of the component that created the entry. Otherwise should be left as default (0)." PREVIOUS="component"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id" NEXT="groupid"/>
Expand Down Expand Up @@ -2864,4 +2866,4 @@
</KEYS>
</TABLE>
</TABLES>
</XMLDB>
</XMLDB>
21 changes: 21 additions & 0 deletions lib/db/upgrade.php
Original file line number Diff line number Diff line change
Expand Up @@ -1162,6 +1162,27 @@ function xmldb_main_upgrade($oldversion) {
upgrade_main_savepoint(true, 2012082300.01);
}

if ($oldversion < 2012082300.02) {
// Define field component to be added to groups_members
$table = new xmldb_table('groups_members');
$field = new xmldb_field('component', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null, 'timeadded');

// Conditionally launch add field component
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);
}

// Define field itemid to be added to groups_members
$field = new xmldb_field('itemid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'component');

// Conditionally launch add field itemid
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);
}

// Main savepoint reached
upgrade_main_savepoint(true, 2012082300.02);
}

return true;
}
4 changes: 4 additions & 0 deletions mod/page/lib.php
Original file line number Diff line number Diff line change
Expand Up @@ -515,3 +515,7 @@ function page_dndupload_handle($uploadinfo) {

return page_add_instance($data, null);
}

function mod_page_allow_group_member_remove($itemid, $groupid, $userid) {
return true;
}
3 changes: 3 additions & 0 deletions theme/base/style/user.css
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@
.userselector select {width: 100%;}
.userselector div {margin-top: 0.2em;}
.userselector div label {margin-right: 0.3em;}
/* Next style does not work in all browsers but looks nicer when it does */
.userselector .userselector-infobelow {font-size: 0.8em;}

#userselector_options {padding:0.3em 0;}
#userselector_options .collapsibleregioncaption {font-weight: bold;}
#userselector_options p {margin:0.2em 0;text-align:left;}
Expand Down
14 changes: 12 additions & 2 deletions user/selector/lib.php
Original file line number Diff line number Diff line change
Expand Up @@ -578,6 +578,12 @@ protected function output_optgroup($groupname, $users, $select) {
unset($this->selected[$user->id]);
$output .= ' <option' . $attributes . ' value="' . $user->id . '">' .
$this->output_user($user) . "</option>\n";
if (!empty($user->infobelow)) {
// 'Poor man's indent' here is because CSS styles do not work
// in select options, except in Firefox.
$output .= ' <option disabled="disabled" class="userselector-infobelow">' .
'&nbsp;&nbsp;&nbsp;&nbsp;' . s($user->infobelow) . '</option>';
}
}
} else {
$output = ' <optgroup label="' . htmlspecialchars($groupname) . '">' . "\n";
Expand Down Expand Up @@ -712,6 +718,10 @@ protected function convert_array_format($roles, $search) {
foreach ($groupedusers[$groupname] as &$user) {
unset($user->roles);
$user->fullname = fullname($user);
if (!empty($user->component)) {
$user->infobelow = get_string('addedby', 'group',
get_string('pluginname', $user->component));
}
}
}
return $groupedusers;
Expand All @@ -726,8 +736,8 @@ class group_members_selector extends groups_user_selector_base {
public function find_users($search) {
list($wherecondition, $params) = $this->search_sql($search, 'u');
$roles = groups_get_members_by_role($this->groupid, $this->courseid,
$this->required_fields_sql('u'), 'u.lastname, u.firstname',
$wherecondition, $params);
$this->required_fields_sql('u') . ', gm.component',
'u.lastname, u.firstname', $wherecondition, $params);
return $this->convert_array_format($roles, $search);
}
}
Expand Down
5 changes: 5 additions & 0 deletions user/selector/module.js
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,11 @@ M.core_user.init_user_selector = function (Y, name, hash, extrafields, lastsearc
option.set('selected', false);
}
optgroup.append(option);
if (user.infobelow) {
extraoption = Y.Node.create('<option disabled="disabled" class="userselector-infobelow"/>');
extraoption.appendChild(document.createTextNode(user.infobelow));
optgroup.append(extraoption);
}
count++;
}

Expand Down
3 changes: 3 additions & 0 deletions user/selector/search.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@
if (!empty($user->disabled)) {
$output->disabled = true;
}
if (!empty($user->infobelow)) {
$output->infobelow = $user->infobelow;
}
$group[$user->id] = $output;
}
}
Expand Down

0 comments on commit 238f776

Please sign in to comment.