From bb1c6f85f580214f61de5a44dedcaddc323cd15a Mon Sep 17 00:00:00 2001 From: Jun Pataleta Date: Mon, 24 Jul 2017 12:52:28 +0800 Subject: [PATCH 1/4] MDL-59366 core: New enrolid param for get_enrolled_* functions * New optional parameter $enrolid for the following functions: - get_enrolled_join() - get_enrolled_sql() - get_enrolled_with_capabilities_join() Setting this parameter to a non-zero value will add a condition to the query such that only users that were enrolled with this enrolment method will be returned. Part of MDL-59290. --- lib/enrollib.php | 39 +++++++++++++++++++++++++++++++-------- lib/upgrade.txt | 6 ++++++ 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/lib/enrollib.php b/lib/enrollib.php index 93f67dc2890..7f81f174f1c 100644 --- a/lib/enrollib.php +++ b/lib/enrollib.php @@ -1209,15 +1209,16 @@ function is_enrolled(context $context, $user = null, $withcapability = '', $only * @param int $group optional, 0 indicates no current group, otherwise the group id * @param bool $onlyactive consider only active enrolments in enabled plugins and time restrictions * @param bool $onlysuspended inverse of onlyactive, consider only suspended enrolments + * @param int $enrolid The enrolment ID. If not 0, only users enrolled using this enrolment method will be returned. * @return \core\dml\sql_join Contains joins, wheres, params */ function get_enrolled_with_capabilities_join(context $context, $prefix = '', $capability = '', $group = 0, - $onlyactive = false, $onlysuspended = false) { + $onlyactive = false, $onlysuspended = false, $enrolid = 0) { $uid = $prefix . 'u.id'; $joins = array(); $wheres = array(); - $enrolledjoin = get_enrolled_join($context, $uid, $onlyactive, $onlysuspended); + $enrolledjoin = get_enrolled_join($context, $uid, $onlyactive, $onlysuspended, $enrolid); $joins[] = $enrolledjoin->joins; $wheres[] = $enrolledjoin->wheres; $params = $enrolledjoin->params; @@ -1253,9 +1254,11 @@ function get_enrolled_with_capabilities_join(context $context, $prefix = '', $ca * @param int $groupid 0 means ignore groups, any other value limits the result by group id * @param bool $onlyactive consider only active enrolments in enabled plugins and time restrictions * @param bool $onlysuspended inverse of onlyactive, consider only suspended enrolments + * @param int $enrolid The enrolment ID. If not 0, only users enrolled using this enrolment method will be returned. * @return array list($sql, $params) */ -function get_enrolled_sql(context $context, $withcapability = '', $groupid = 0, $onlyactive = false, $onlysuspended = false) { +function get_enrolled_sql(context $context, $withcapability = '', $groupid = 0, $onlyactive = false, $onlysuspended = false, + $enrolid = 0) { // Use unique prefix just in case somebody makes some SQL magic with the result. static $i = 0; @@ -1263,7 +1266,7 @@ function get_enrolled_sql(context $context, $withcapability = '', $groupid = 0, $prefix = 'eu' . $i . '_'; $capjoin = get_enrolled_with_capabilities_join( - $context, $prefix, $withcapability, $groupid, $onlyactive, $onlysuspended); + $context, $prefix, $withcapability, $groupid, $onlyactive, $onlysuspended, $enrolid); $sql = "SELECT DISTINCT {$prefix}u.id FROM {user} {$prefix}u @@ -1285,9 +1288,10 @@ function get_enrolled_sql(context $context, $withcapability = '', $groupid = 0, * @param string $useridcolumn User id column used the calling query, e.g. u.id * @param bool $onlyactive consider only active enrolments in enabled plugins and time restrictions * @param bool $onlysuspended inverse of onlyactive, consider only suspended enrolments + * @param int $enrolid The enrolment ID. If not 0, only users enrolled using this enrolment method will be returned. * @return \core\dml\sql_join Contains joins, wheres, params */ -function get_enrolled_join(context $context, $useridcolumn, $onlyactive = false, $onlysuspended = false) { +function get_enrolled_join(context $context, $useridcolumn, $onlyactive = false, $onlysuspended = false, $enrolid = 0) { // Use unique prefix just in case somebody makes some SQL magic with the result. static $i = 0; $i++; @@ -1315,7 +1319,18 @@ function get_enrolled_join(context $context, $useridcolumn, $onlyactive = false, if (!$isfrontpage) { $where1 = "{$prefix}ue.status = :{$prefix}active AND {$prefix}e.status = :{$prefix}enabled"; $where2 = "{$prefix}ue.timestart < :{$prefix}now1 AND ({$prefix}ue.timeend = 0 OR {$prefix}ue.timeend > :{$prefix}now2)"; - $ejoin = "JOIN {enrol} {$prefix}e ON ({$prefix}e.id = {$prefix}ue.enrolid AND {$prefix}e.courseid = :{$prefix}courseid)"; + + $enrolconditions = array( + "{$prefix}e.id = {$prefix}ue.enrolid", + "{$prefix}e.courseid = :{$prefix}courseid", + ); + if ($enrolid) { + $enrolconditions[] = "{$prefix}e.id = :{$prefix}enrolid"; + $params[$prefix . 'enrolid'] = $enrolid; + } + $enrolconditionssql = implode(" AND ", $enrolconditions); + $ejoin = "JOIN {enrol} {$prefix}e ON ($enrolconditionssql)"; + $params[$prefix.'courseid'] = $coursecontext->instanceid; if (!$onlysuspended) { @@ -1329,8 +1344,16 @@ function get_enrolled_join(context $context, $useridcolumn, $onlyactive = false, // Consider multiple enrols where one is not suspended or plain role_assign. $enrolselect = "SELECT DISTINCT {$prefix}ue.userid FROM {user_enrolments} {$prefix}ue $ejoin WHERE $where1 AND $where2"; $joins[] = "JOIN {user_enrolments} {$prefix}ue1 ON {$prefix}ue1.userid = $useridcolumn"; - $joins[] = "JOIN {enrol} {$prefix}e1 ON ({$prefix}e1.id = {$prefix}ue1.enrolid - AND {$prefix}e1.courseid = :{$prefix}_e1_courseid)"; + $enrolconditions = array( + "{$prefix}e1.id = {$prefix}ue1.enrolid", + "{$prefix}e1.courseid = :{$prefix}_e1_courseid", + ); + if ($enrolid) { + $enrolconditions[] = "{$prefix}e1.id = :{$prefix}e1.enrolid"; + $params[$prefix . 'e1.enrolid'] = $enrolid; + } + $enrolconditionssql = implode(" AND ", $enrolconditions); + $joins[] = "JOIN {enrol} {$prefix}e1 ON ($enrolconditionssql)"; $params["{$prefix}_e1_courseid"] = $coursecontext->instanceid; $wheres[] = "$useridcolumn NOT IN ($enrolselect)"; } diff --git a/lib/upgrade.txt b/lib/upgrade.txt index ea0eace1434..ff6000822b4 100644 --- a/lib/upgrade.txt +++ b/lib/upgrade.txt @@ -32,6 +32,12 @@ information provided here is intended especially for developers. These attributes enable enrol actions to be rendered via modals. If not added, clicking on the enrolment action buttons will still redirect the user to the appropriate enrolment action page. Though optional, it is recommended to add these attributes for a better user experience when performing enrol actions. +* New optional parameter $enrolid for the following functions: + - get_enrolled_join() + - get_enrolled_sql() + - get_enrolled_with_capabilities_join() + Setting this parameter to a non-zero value will add a condition to the query such that only users that were enrolled + with this enrolment method will be returned. === 3.3.1 === From 198d72913f58e20c4eabbd3f8f6797847d409d23 Mon Sep 17 00:00:00 2001 From: Jun Pataleta Date: Thu, 20 Jul 2017 13:32:50 +0800 Subject: [PATCH 2/4] MDL-59366 core_amd: Modifications for form-autocomplete * New optional parameter 'closeSuggestionsOnSelect' for the enhance() function for form-autocomplete. Setting this to true will close the suggestions popup immediately after an option has been selected. If not specified, it defaults to true for single-select elements and false for multiple-select elements. Part of MDL-59290. --- lib/amd/build/form-autocomplete.min.js | 2 +- lib/amd/src/form-autocomplete.js | 13 +++++++++++-- lib/upgrade.txt | 3 +++ 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/lib/amd/build/form-autocomplete.min.js b/lib/amd/build/form-autocomplete.min.js index 5e301a0b296..233e46e18dc 100644 --- a/lib/amd/build/form-autocomplete.min.js +++ b/lib/amd/build/form-autocomplete.min.js @@ -1 +1 @@ -define(["jquery","core/log","core/str","core/templates","core/notification"],function(a,b,c,d,e){var f={DOWN:40,ENTER:13,SPACE:32,ESCAPE:27,COMMA:44,UP:38},g=function(b,c){var d=a(document.getElementById(c.selectionId)),e=d.children("[aria-selected=true]").length;for(b%=e;b<0;)b+=e;var f=a(d.children("[aria-selected=true]").get(b)),g=c.selectionId+"-"+b;d.children().attr("data-active-selection",!1).attr("id",""),f.attr("data-active-selection",!0).attr("id",g),d.attr("aria-activedescendant",g)},h=function(b,c,f){var h=[],i=a(document.getElementById(c.selectionId)),j=i.attr("aria-activedescendant"),k=!1;j&&(k=a(document.getElementById(j)).attr("data-value")),f.children("option").each(function(b,c){a(c).prop("selected")&&h.push({label:a(c).html(),value:a(c).attr("value")})});var l=a.extend({items:h},b,c);d.render("core/form_autocomplete_selection",l).done(function(b){i.empty().append(a(b).html()),k!==!1&&i.children("[aria-selected=true]").each(function(b,d){a(d).attr("data-value")===k&&g(b,c)})}).fail(e.exception)},i=function(a){"undefined"!=typeof M.core_formchangechecker&&M.core_formchangechecker.set_form_changed(),a.change()},j=function(b,c,d,e){var f=a(d).attr("data-value");b.multiple&&e.children("option").each(function(b,c){a(c).attr("value")==f&&(a(c).prop("selected",!1),a(c).attr("data-iscustom")&&a(c).remove())}),h(b,c,e),i(e)},k=function(b,c){var d=a(document.getElementById(c.inputId)),e=a(document.getElementById(c.suggestionsId)),f=e.children("[aria-hidden=false]").length;for(b%=f;b<0;)b+=f;var g=a(e.children("[aria-hidden=false]").get(b)),h=a(e.children("[role=option]")).index(g),i=c.suggestionsId+"-"+h;e.children().attr("aria-selected",!1).attr("id",""),g.attr("aria-selected",!0).attr("id",i),d.attr("aria-activedescendant",i);var j=g.offset().top-e.offset().top+e.scrollTop()-e.height()/2;e.animate({scrollTop:j},100)},l=function(b){var c=a(document.getElementById(b.suggestionsId)),d=c.children("[aria-selected=true]"),e=c.children("[aria-hidden=false]").index(d);k(e+1,b)},m=function(b){var c=a(document.getElementById(b.selectionId)),d=c.children("[data-active-selection=true]");if(!d)return void g(0,b);var e=c.children("[aria-selected=true]").index(d);g(e-1,b)},n=function(b){var c=a(document.getElementById(b.selectionId)),d=c.children("[data-active-selection=true]");if(!d)return void g(0,b);var e=c.children("[aria-selected=true]").index(d);g(e+1,b)},o=function(b){var c=a(document.getElementById(b.suggestionsId)),d=c.children("[aria-selected=true]"),e=c.children("[aria-hidden=false]").index(d);k(e-1,b)},p=function(b){var c=a(document.getElementById(b.inputId)),d=a(document.getElementById(b.suggestionsId));c.attr("aria-expanded",!1).attr("aria-activedescendant",b.selectionId),d.hide().attr("aria-hidden",!0)},q=function(b,f,g,h){var i=a(document.getElementById(f.inputId)),j=a(document.getElementById(f.suggestionsId)),l=!1,m=[];h.children("option").each(function(b,c){a(c).prop("selected")!==!0&&(m[m.length]={label:c.innerHTML,value:a(c).attr("value")})});var n=f.caseSensitive?g:g.toLocaleLowerCase(),o=a.extend({options:m},b,f);d.render("core/form_autocomplete_suggestions",o).done(function(d){j.replaceWith(d),j=a(document.getElementById(f.suggestionsId)),j.show().attr("aria-hidden",!1),j.children().each(function(c,d){d=a(d),b.caseSensitive&&d.text().indexOf(n)>-1||!b.caseSensitive&&d.text().toLocaleLowerCase().indexOf(n)>-1?(d.show().attr("aria-hidden",!1),l=!0):d.hide().attr("aria-hidden",!0)}),i.attr("aria-expanded",!0),l?b.tags||k(0,f):c.get_string("nosuggestions","form").done(function(a){j.html(a)})}).fail(e.exception)},r=function(b,c,d){var e=a(document.getElementById(c.inputId)),f=e.val(),g=f.split(","),j=!1;a.each(g,function(c,e){if(e=e.trim(),""!==e&&(b.multiple||d.children("option").prop("selected",!1),d.children("option").each(function(b,c){a(c).attr("value")==e&&(j=!0,a(c).prop("selected",!0))}),!j)){var f=a("