mirror of
https://github.com/moodle/moodle.git
synced 2025-08-04 08:26:37 +02:00
Merge branch 'MDL-31973-master-6' of git://git.luns.net.uk/moodle
Conflicts: lib/db/upgrade.php
This commit is contained in:
commit
238f7761af
14 changed files with 161 additions and 7 deletions
|
@ -1005,7 +1005,7 @@ class backup_groups_structure_step extends backup_structure_step {
|
|||
$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');
|
||||
|
||||
|
|
|
@ -780,6 +780,17 @@ class restore_groups_structure_step extends restore_structure_step {
|
|||
// 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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -545,6 +545,9 @@ class core_group_external extends external_api {
|
|||
}
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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)) {
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -67,6 +67,10 @@ if (optional_param('remove', false, PARAM_BOOL) && confirm_sesskey()) {
|
|||
$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);
|
||||
}
|
||||
|
|
|
@ -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';
|
||||
|
@ -62,6 +63,7 @@ $string['erroraddremoveuser'] = 'Error adding/removing user {$a} to group';
|
|||
$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.';
|
||||
|
|
|
@ -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"/>
|
||||
|
@ -2864,4 +2866,4 @@
|
|||
</KEYS>
|
||||
</TABLE>
|
||||
</TABLES>
|
||||
</XMLDB>
|
||||
</XMLDB>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;}
|
||||
|
|
|
@ -578,6 +578,12 @@ abstract class user_selector_base {
|
|||
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">' .
|
||||
' ' . s($user->infobelow) . '</option>';
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$output = ' <optgroup label="' . htmlspecialchars($groupname) . '">' . "\n";
|
||||
|
@ -712,6 +718,10 @@ abstract class groups_user_selector_base extends user_selector_base {
|
|||
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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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++;
|
||||
}
|
||||
|
||||
|
|
|
@ -87,6 +87,9 @@ foreach ($users as &$group) {
|
|||
if (!empty($user->disabled)) {
|
||||
$output->disabled = true;
|
||||
}
|
||||
if (!empty($user->infobelow)) {
|
||||
$output->infobelow = $user->infobelow;
|
||||
}
|
||||
$group[$user->id] = $output;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue