mirror of
https://github.com/moodle/moodle.git
synced 2025-04-21 16:32:18 +02:00
MDL-59368 groups: Peer review fixes
* Fix coalesce on postgres. * The edit icon's alt shows the HTML entities causing * enrol/tests/behat/add_to_group.feature Contains a '@doit' tag which I assume is there from testing. * group/classes/output/user_groups_editable.php ** Missing MOODLE_INTERNAL check. ** Unused variables context_system and moodle_exception. ** The PHPDocs for the constructors are wrong. ** export_for_template() returns an array, not stdClass (according to parent docs). ** Change moodle_exception to coding_exception at the beginning. * group/lib.php ** Missing docs for core_group_inplace_editable(). * user/classes/participants_table.php ** The docs for the class variables $groups, $course and $context need a '\' beforehand as they are in a namespace. ** I would prefer $this->context = $context; and $this->groups = ... to be done at the end of the constructor with the other class variable assignments. ** You could get rid of the class variable courseid if we are setting course and use $this->course->id instead. ** The function col_groups has @param \stdclass $row but it should be $data * lib/amd/src/form-autocomplete.js and lib/amd/src/inplace_editable.js ** Some issues here CiBot has pointed out. * lib/classes/output/inplace_editable.php ** @see should be on a new line.
This commit is contained in:
parent
f746a078cb
commit
f3ecea3af4
@ -1,4 +1,4 @@
|
||||
@core_enrol @core_group @doit
|
||||
@core_enrol @core_group
|
||||
Feature: Users can be added to multiple groups at once
|
||||
In order to manage group membership effectively
|
||||
As a user
|
||||
|
@ -24,11 +24,12 @@
|
||||
|
||||
namespace core_group\output;
|
||||
|
||||
use context_system;
|
||||
use context_course;
|
||||
use core_user;
|
||||
use core_external;
|
||||
use moodle_exception;
|
||||
use coding_exception;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
require_once($CFG->dirroot . '/group/lib.php');
|
||||
|
||||
@ -49,7 +50,11 @@ class user_groups_editable extends \core\output\inplace_editable {
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param \stdClass|core_tag_tag $tag
|
||||
* @param \stdClass $course The current course
|
||||
* @param \context $context The course context
|
||||
* @param \stdClass $user The current user
|
||||
* @param \stdClass[] $coursegroups The list of course groups from groups_get_all_groups with membership.
|
||||
* @param string $value JSON Encoded list of group ids.
|
||||
*/
|
||||
public function __construct($course, $context, $user, $coursegroups, $value) {
|
||||
// Check capabilities to get editable value.
|
||||
@ -83,7 +88,7 @@ class user_groups_editable extends \core\output\inplace_editable {
|
||||
* Export this data so it can be used as the context for a mustache template.
|
||||
*
|
||||
* @param \renderer_base $output
|
||||
* @return \stdClass
|
||||
* @return array
|
||||
*/
|
||||
public function export_for_template(\renderer_base $output) {
|
||||
$listofgroups = [];
|
||||
|
@ -1097,6 +1097,14 @@ function groups_sync_with_enrolment($enrolname, $courseid = 0, $gidfield = 'cust
|
||||
return $affectedusers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for inplace editable API.
|
||||
*
|
||||
* @param string $itemtype - Only user_groups is supported.
|
||||
* @param string $itemid - Userid and groupid separated by a :
|
||||
* @param string $newvalue - json encoded list of groupids.
|
||||
* @return \core\output\inplace_editable
|
||||
*/
|
||||
function core_group_inplace_editable($itemtype, $itemid, $newvalue) {
|
||||
if ($itemtype === 'user_groups') {
|
||||
return \core_group\output\user_groups_editable::update($itemid, $newvalue);
|
||||
|
2
lib/amd/build/form-autocomplete.min.js
vendored
2
lib/amd/build/form-autocomplete.min.js
vendored
File diff suppressed because one or more lines are too long
2
lib/amd/build/inplace_editable.min.js
vendored
2
lib/amd/build/inplace_editable.min.js
vendored
@ -1 +1 @@
|
||||
define(["jquery","core/ajax","core/templates","core/notification","core/str","core/config","core/url","core/form-autocomplete"],function(a,b,c,d,e,f,g,h){return a("body").on("click keypress","[data-inplaceeditable] [data-inplaceeditablelink]",function(i){if("keypress"!==i.type||13===i.keyCode){i.stopImmediatePropagation(),i.preventDefault();var j=a(this),k=j.closest("[data-inplaceeditable]"),l=function(b){b.addClass("updating");var c=b.find("img.spinner");c.length?c.show():(c=a("<img/>").attr("src",g.imageUrl("i/loading_small")).addClass("spinner").addClass("smallicon"),b.append(c))},m=function(a){a.removeClass("updating"),a.find("img.spinner").hide()},n=function(e,f){l(e),b.call([{methodname:"core_update_inplace_editable",args:{itemid:e.attr("data-itemid"),component:e.attr("data-component"),itemtype:e.attr("data-itemtype"),value:f},done:function(b){var d=e.attr("data-value");c.render("core/inplace_editable",b).done(function(f,g){var h=a(f);c.replaceNode(e,h,g),h.find("[data-inplaceeditablelink]").focus(),h.trigger({type:"updated",ajaxreturn:b,oldvalue:d})})},fail:function(b){var c=a.Event("updatefailed",{exception:b,newvalue:f});m(e),e.trigger(c),c.isDefaultPrevented()||d.exception(b)}}],!0)},o=function(a){a.find("input").off(),a.find("select").off(),a.html(a.attr("data-oldcontent")),a.removeAttr("data-oldcontent"),a.removeClass("inplaceeditingon"),a.find("[data-inplaceeditablelink]").focus()},p=function(){a("span.inplaceeditable.inplaceeditingon").each(function(){o(a(this))})},q=function(b,c){var d,e=b;for(d=0;d<c;d++)e+=String(Math.floor(10*Math.random()));return 0===a("#"+e).length?e:q(b,c)},r=function(b){e.get_string("edittitleinstructions").done(function(c){var d=a('<span class="editinstructions">'+c+"</span>").attr("id",q("id_editinstructions_",20)),e=a('<input type="text"/>').attr("id",q("id_inplacevalue_",20)).attr("value",b.attr("data-value")).attr("aria-describedby",d.attr("id")).addClass("ignoredirty").addClass("form-control"),g=a('<label class="accesshide">'+k.attr("data-editlabel")+"</label>").attr("for",e.attr("id"));b.html("").append(d).append(g).append(e),e.focus(),e.select(),e.on("keyup keypress focusout",function(a){if(!f.behatsiterunning||"focusout"!==a.type){if("keypress"===a.type&&13===a.keyCode){var c=e.val();o(b),n(b,c)}("keyup"===a.type&&27===a.keyCode||"focusout"===a.type)&&o(b)}})})},s=function(a,b){o(a),n(a,b)},t=function(b,c){var d,e=a("<select></select>").attr("id",q("id_inplacevalue_",20)).addClass("custom-select"),g=a('<label class="accesshide">'+k.attr("data-editlabel")+"</label>").attr("for",e.attr("id"));for(d in c)e.append(a("<option>").attr("value",c[d].key).html(c[d].value));e.val(b.attr("data-value")),b.html("").append(g).append(e),e.focus(),e.select(),e.on("keyup change focusout",function(a){if(!f.behatsiterunning||"focusout"!==a.type){if("change"===a.type){var c=e.val();o(b),n(b,c)}("keyup"===a.type&&27===a.keyCode||"focusout"===a.type)&&o(b)}})},u=function(b,f){var g,i=a("<select></select>").attr("id",q("id_inplacevalue_",20)).addClass("custom-select"),j=a('<label class="accesshide">'+k.attr("data-editlabel")+"</label>").attr("for",i.attr("id")),l=f.options,m=f.attributes,p=a('<a href="#"></a>'),r=a('<a href="#"></a>');for(g in l)i.append(a("<option>").attr("value",l[g].key).html(l[g].value));m.multiple&&i.attr("multiple","true"),i.val(JSON.parse(b.attr("data-value"))),e.get_string("savechanges","core").then(function(a){return c.renderPix("e/save","core",a)}).then(function(a){p.append(a)}).fail(d.exception),e.get_string("cancel","core").then(function(a){return c.renderPix("e/cancel","core",a)}).then(function(a){r.append(a)}).fail(d.exception),b.html("").append(j).append(i).append(p).append(r),i.focus(),i.select(),h.enhance(i,m.tags,m.ajax,m.placeholder,m.caseSensitive,m.showSuggestions,m.noSelectionString).then(function(){b.find("[role=combobox]").focus()}),i.on("keyup",function(a){("keyup"===a.type&&27===a.keyCode||"focusout"===a.type)&&o(b)}),p.on("click",function(a){var c=JSON.stringify(i.val());o(b),n(b,c),a.preventDefault()}),r.on("click",function(a){o(b),a.preventDefault()})},v=function(b){b.addClass("inplaceeditingon"),b.attr("data-oldcontent",b.html());var c=b.attr("data-type"),d=b.attr("data-options");"toggle"===c?s(b,d):"select"===c?t(b,a.parseJSON(d)):"autocomplete"===c?u(b,a.parseJSON(d)):r(b)};p(),v(k)}}),{}});
|
||||
define(["jquery","core/ajax","core/templates","core/notification","core/str","core/config","core/url","core/form-autocomplete"],function(a,b,c,d,e,f,g,h){return a("body").on("click keypress","[data-inplaceeditable] [data-inplaceeditablelink]",function(i){if("keypress"!==i.type||13===i.keyCode){i.stopImmediatePropagation(),i.preventDefault();var j=a(this),k=j.closest("[data-inplaceeditable]"),l=function(b){b.addClass("updating");var c=b.find("img.spinner");c.length?c.show():(c=a("<img/>").attr("src",g.imageUrl("i/loading_small")).addClass("spinner").addClass("smallicon"),b.append(c))},m=function(a){a.removeClass("updating"),a.find("img.spinner").hide()},n=function(e,f){l(e),b.call([{methodname:"core_update_inplace_editable",args:{itemid:e.attr("data-itemid"),component:e.attr("data-component"),itemtype:e.attr("data-itemtype"),value:f},done:function(b){var d=e.attr("data-value");c.render("core/inplace_editable",b).done(function(f,g){var h=a(f);c.replaceNode(e,h,g),h.find("[data-inplaceeditablelink]").focus(),h.trigger({type:"updated",ajaxreturn:b,oldvalue:d})})},fail:function(b){var c=a.Event("updatefailed",{exception:b,newvalue:f});m(e),e.trigger(c),c.isDefaultPrevented()||d.exception(b)}}],!0)},o=function(a){a.find("input").off(),a.find("select").off(),a.html(a.attr("data-oldcontent")),a.removeAttr("data-oldcontent"),a.removeClass("inplaceeditingon"),a.find("[data-inplaceeditablelink]").focus()},p=function(){a("span.inplaceeditable.inplaceeditingon").each(function(){o(a(this))})},q=function(b,c){var d,e=b;for(d=0;d<c;d++)e+=String(Math.floor(10*Math.random()));return 0===a("#"+e).length?e:q(b,c)},r=function(b){e.get_string("edittitleinstructions").done(function(c){var d=a('<span class="editinstructions">'+c+"</span>").attr("id",q("id_editinstructions_",20)),e=a('<input type="text"/>').attr("id",q("id_inplacevalue_",20)).attr("value",b.attr("data-value")).attr("aria-describedby",d.attr("id")).addClass("ignoredirty").addClass("form-control"),g=a('<label class="accesshide">'+k.attr("data-editlabel")+"</label>").attr("for",e.attr("id"));b.html("").append(d).append(g).append(e),e.focus(),e.select(),e.on("keyup keypress focusout",function(a){if(!f.behatsiterunning||"focusout"!==a.type){if("keypress"===a.type&&13===a.keyCode){var c=e.val();o(b),n(b,c)}("keyup"===a.type&&27===a.keyCode||"focusout"===a.type)&&o(b)}})})},s=function(a,b){o(a),n(a,b)},t=function(b,c){var d,e=a("<select></select>").attr("id",q("id_inplacevalue_",20)).addClass("custom-select"),g=a('<label class="accesshide">'+k.attr("data-editlabel")+"</label>").attr("for",e.attr("id"));for(d in c)e.append(a("<option>").attr("value",c[d].key).html(c[d].value));e.val(b.attr("data-value")),b.html("").append(g).append(e),e.focus(),e.select(),e.on("keyup change focusout",function(a){if(!f.behatsiterunning||"focusout"!==a.type){if("change"===a.type){var c=e.val();o(b),n(b,c)}("keyup"===a.type&&27===a.keyCode||"focusout"===a.type)&&o(b)}})},u=function(b,f){var g,i=a("<select></select>").attr("id",q("id_inplacevalue_",20)).addClass("custom-select"),j=a('<label class="accesshide">'+k.attr("data-editlabel")+"</label>").attr("for",i.attr("id")),l=f.options,m=f.attributes,p=a('<a href="#"></a>'),r=a('<a href="#"></a>');for(g in l)i.append(a("<option>").attr("value",l[g].key).html(l[g].value));m.multiple&&i.attr("multiple","true"),i.val(JSON.parse(b.attr("data-value"))),e.get_string("savechanges","core").then(function(a){return c.renderPix("e/save","core",a)}).then(function(a){p.append(a)}).fail(d.exception),e.get_string("cancel","core").then(function(a){return c.renderPix("e/cancel","core",a)}).then(function(a){r.append(a)}).fail(d.exception),b.html("").append(j).append(i).append(p).append(r),i.focus(),i.select(),h.enhance(i,m.tags,m.ajax,m.placeholder,m.caseSensitive,m.showSuggestions,m.noSelectionString).then(function(){b.find("[role=combobox]").focus()}).fail(d.exception),i.on("keyup",function(a){("keyup"===a.type&&27===a.keyCode||"focusout"===a.type)&&o(b)}),p.on("click",function(a){var c=JSON.stringify(i.val());o(b),n(b,c),a.preventDefault()}),r.on("click",function(a){o(b),a.preventDefault()})},v=function(b){b.addClass("inplaceeditingon"),b.attr("data-oldcontent",b.html());var c=b.attr("data-type"),d=b.attr("data-options");"toggle"===c?s(b,d):"select"===c?t(b,a.parseJSON(d)):"autocomplete"===c?u(b,a.parseJSON(d)):r(b)};p(),v(k)}}),{}});
|
@ -738,7 +738,7 @@ define(['jquery', 'core/log', 'core/str', 'core/templates', 'core/notification']
|
||||
var originalSelect = $(selector);
|
||||
if (!originalSelect) {
|
||||
log.debug('Selector not found: ' + selector);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Hide the original select.
|
||||
@ -770,7 +770,7 @@ define(['jquery', 'core/log', 'core/str', 'core/templates', 'core/notification']
|
||||
var renderDatalist = templates.render('core/form_autocomplete_suggestions', context);
|
||||
var renderSelection = templates.render('core/form_autocomplete_selection', context);
|
||||
|
||||
return $.when(renderInput, renderDatalist, renderSelection).done(function(input, suggestions, selection) {
|
||||
return $.when(renderInput, renderDatalist, renderSelection).then(function(input, suggestions, selection) {
|
||||
// Add our new UI elements to the page.
|
||||
originalSelect.after(suggestions);
|
||||
originalSelect.after(input);
|
||||
|
@ -262,7 +262,9 @@ define(['jquery',
|
||||
.then(function() {
|
||||
// Focus on the enhanced combobox.
|
||||
el.find('[role=combobox]').focus();
|
||||
});
|
||||
// Stop eslint nagging.
|
||||
return;
|
||||
}).fail(notification.exception);
|
||||
|
||||
inputelement.on('keyup', function(e) {
|
||||
if ((e.type === 'keyup' && e.keyCode === 27) || e.type === 'focusout') {
|
||||
|
@ -197,7 +197,7 @@ class inplace_editable implements templatable, renderable {
|
||||
* Sets the element type to be an autocomplete field
|
||||
*
|
||||
* @param array $options associative array with dropdown options
|
||||
* @param array $attributes associative array with attributes for autoselect field. @see AMD module core/form-autocomplete
|
||||
* @param array $attributes associative array with attributes for autoselect field. See AMD module core/form-autocomplete.
|
||||
* @return self
|
||||
*/
|
||||
public function set_type_autocomplete($options, $attributes) {
|
||||
|
@ -56,7 +56,7 @@
|
||||
{{^ linkeverything }}{{{displayvalue}}}{{/ linkeverything }}
|
||||
<a href="#" class="quickeditlink" data-inplaceeditablelink="1" title="{{edithint}}">
|
||||
{{# linkeverything }}{{{displayvalue}}}{{/ linkeverything }}
|
||||
<span class="quickediticon visibleifjs">{{#pix}}t/editstring,core,{{edithint}}{{/pix}}</span>
|
||||
<span class="quickediticon visibleifjs">{{#pix}}t/editstring,core,{{{edithint}}}{{/pix}}</span>
|
||||
</a>
|
||||
</span>
|
||||
{{#js}}
|
||||
|
@ -76,7 +76,7 @@ class participants_table extends \table_sql {
|
||||
protected $countries;
|
||||
|
||||
/**
|
||||
* @var stdClass[] The list of groups with membership info for the course.
|
||||
* @var \stdClass[] The list of groups with membership info for the course.
|
||||
*/
|
||||
protected $groups;
|
||||
|
||||
@ -86,12 +86,12 @@ class participants_table extends \table_sql {
|
||||
protected $extrafields;
|
||||
|
||||
/**
|
||||
* @var stdClass The course details.
|
||||
* @var \stdClass The course details.
|
||||
*/
|
||||
protected $course;
|
||||
|
||||
/**
|
||||
* @var context The course context.
|
||||
* @var \context The course context.
|
||||
*/
|
||||
protected $context;
|
||||
|
||||
@ -115,7 +115,6 @@ class participants_table extends \table_sql {
|
||||
// Get the context.
|
||||
$this->course = get_course($courseid);
|
||||
$context = \context_course::instance($courseid, MUST_EXIST);
|
||||
$this->context = $context;
|
||||
|
||||
// Define the headers and columns.
|
||||
$headers = [];
|
||||
@ -136,7 +135,6 @@ class participants_table extends \table_sql {
|
||||
}
|
||||
|
||||
// Load and cache the course groupinfo.
|
||||
$this->groups = groups_get_all_groups($courseid, 0, 0, 'g.*', true);
|
||||
// Add column for groups.
|
||||
$headers[] = get_string('groups');
|
||||
$columns[] = 'groups';
|
||||
@ -173,7 +171,6 @@ class participants_table extends \table_sql {
|
||||
$this->set_attribute('id', 'participants');
|
||||
|
||||
// Set the variables we need to use later.
|
||||
$this->courseid = $courseid;
|
||||
$this->currentgroup = $currentgroup;
|
||||
$this->accesssince = $accesssince;
|
||||
$this->roleid = $roleid;
|
||||
@ -181,6 +178,8 @@ class participants_table extends \table_sql {
|
||||
$this->selectall = $selectall;
|
||||
$this->countries = get_string_manager()->get_list_of_countries();
|
||||
$this->extrafields = $extrafields;
|
||||
$this->context = $context;
|
||||
$this->groups = groups_get_all_groups($courseid, 0, 0, 'g.*', true);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -207,25 +206,25 @@ class participants_table extends \table_sql {
|
||||
public function col_fullname($data) {
|
||||
global $OUTPUT;
|
||||
|
||||
return $OUTPUT->user_picture($data, array('size' => 35, 'courseid' => $this->courseid)) . ' ' . fullname($data);
|
||||
return $OUTPUT->user_picture($data, array('size' => 35, 'courseid' => $this->course->id)) . ' ' . fullname($user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the groups column.
|
||||
*
|
||||
* @param \stdClass $row
|
||||
* @param \stdClass $data
|
||||
* @return string
|
||||
*/
|
||||
public function col_groups($user) {
|
||||
public function col_groups($data) {
|
||||
global $OUTPUT;
|
||||
|
||||
$usergroups = [];
|
||||
foreach ($this->groups as $coursegroup) {
|
||||
if (isset($coursegroup->members[$user->id])) {
|
||||
if (isset($coursegroup->members[$data->id])) {
|
||||
$usergroups[] = $coursegroup->id;
|
||||
}
|
||||
}
|
||||
$editable = new \core_group\output\user_groups_editable($this->course, $this->context, $user, $this->groups, $usergroups);
|
||||
$editable = new \core_group\output\user_groups_editable($this->course, $this->context, $data, $this->groups, $usergroups);
|
||||
return $OUTPUT->render_from_template('core/inplace_editable', $editable->export_for_template($OUTPUT));
|
||||
}
|
||||
|
||||
@ -295,7 +294,7 @@ class participants_table extends \table_sql {
|
||||
public function query_db($pagesize, $useinitialsbar = true) {
|
||||
list($twhere, $tparams) = $this->get_sql_where();
|
||||
|
||||
$total = user_get_total_participants($this->courseid, $this->currentgroup, $this->accesssince,
|
||||
$total = user_get_total_participants($this->course->id, $this->currentgroup, $this->accesssince,
|
||||
$this->roleid, $this->search, $twhere, $tparams);
|
||||
|
||||
$this->pagesize($pagesize, $total);
|
||||
@ -305,7 +304,7 @@ class participants_table extends \table_sql {
|
||||
$sort = 'ORDER BY ' . $sort;
|
||||
}
|
||||
|
||||
$this->rawdata = user_get_participants($this->courseid, $this->currentgroup, $this->accesssince,
|
||||
$this->rawdata = user_get_participants($this->course->id, $this->currentgroup, $this->accesssince,
|
||||
$this->roleid, $this->search, $twhere, $tparams, $sort, $this->get_page_start(),
|
||||
$this->get_page_size());
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user