MDL-70565 user: filter course participants by country.

This commit is contained in:
Paul Holden 2021-02-24 10:37:18 +00:00
parent fc335f5ea0
commit be2862fe6f
7 changed files with 284 additions and 2 deletions

View file

@ -24,6 +24,7 @@
namespace core_user\output;
use context_course;
use core\user_fields;
use renderable;
use renderer_base;
use stdClass;
@ -89,6 +90,10 @@ class participants_filter implements renderable, templatable {
$filtertypes[] = $filtertype;
}
if ($filtertype = $this->get_country_filter()) {
$filtertypes[] = $filtertype;
}
return $filtertypes;
}
@ -322,6 +327,34 @@ class participants_filter implements renderable, templatable {
);
}
/**
* Get data for the country filter
*
* @return stdClass|null
*/
protected function get_country_filter(): ?stdClass {
$extrauserfields = user_fields::get_identity_fields($this->context, false);
if (array_search('country', $extrauserfields) === false) {
return null;
}
$countries = get_string_manager()->get_list_of_countries(true);
return $this->get_filter_object(
'country',
get_string('country'),
false,
true,
'core_user/local/participantsfilter/filtertypes/country',
array_map(function(string $code, string $name): stdClass {
return (object) [
'value' => $code,
'title' => $name,
];
}, array_keys($countries), array_values($countries))
);
}
/**
* Get data for the keywords filter.
*

View file

@ -27,7 +27,6 @@ declare(strict_types=1);
namespace core_user\table;
use core_table\local\filter\boolean_filter;
use core_table\local\filter\filterset;
use core_table\local\filter\integer_filter;
use core_table\local\filter\string_filter;
@ -61,6 +60,7 @@ class participants_filterset extends filterset {
* - enrolments;
* - groups;
* - keywords;
* - country;
* - roles; and
* - status.
*
@ -72,6 +72,7 @@ class participants_filterset extends filterset {
'enrolments' => integer_filter::class,
'groups' => integer_filter::class,
'keywords' => string_filter::class,
'country' => string_filter::class,
'roles' => integer_filter::class,
'status' => integer_filter::class,
];

View file

@ -257,6 +257,22 @@ class participants_search {
}
}
// Apply any country filtering.
if ($this->filterset->has_filter('country')) {
[
'where' => $countrywhere,
'params' => $countryparams,
] = $this->get_country_sql();
if (!empty($countrywhere)) {
$wheres[] = "($countrywhere)";
}
if (!empty($countryparams)) {
$params = array_merge($params, $countryparams);
}
}
// Apply any keyword text searches.
if ($this->filterset->has_filter('keywords')) {
[
@ -877,6 +893,32 @@ class participants_search {
];
}
/**
* Prepare SQL where clause and associated parameters for country filtering
*
* @return array SQL query data in the format ['where' => '', 'params' => []].
*/
protected function get_country_sql(): array {
global $DB;
$where = '';
$params = [];
$countryfilter = $this->filterset->get_filter('country');
if ($countrycodes = $countryfilter->get_filter_values()) {
// If filter type is "None", then we negate the comparison.
[$countrywhere, $params] = $DB->get_in_or_equal($countrycodes, SQL_PARAMS_NAMED, 'country',
$countryfilter->get_join_type() !== $countryfilter::JOINTYPE_NONE);
$where = "(u.country {$countrywhere})";
}
return [
'where' => $where,
'params' => $params,
];
}
/**
* Prepare SQL where clause and associated parameters for any keyword searches being performed.
*
@ -975,7 +1017,7 @@ class participants_search {
$extrasearchfields = user_fields::get_identity_fields(null);
foreach ($extrasearchfields as $fieldindex => $extrasearchfield) {
if (in_array($extrasearchfield, ['email', 'idnumber', 'country'])) {
// Already covered above. Search by country not supported.
// Already covered above.
continue;
}
// The param must be short (max 32 characters) so don't include field name.