MDL-70909 core: add cannotmatchanyrows to capabilities join

This commit is contained in:
Ferran Recio
2021-04-22 13:10:37 +02:00
parent 7c1feb97b2
commit 78aabd1e28
2 changed files with 83 additions and 2 deletions
+73
View File
@@ -1362,4 +1362,77 @@ class core_enrollib_testcase extends advanced_testcase {
$durationinday = $duration / DAYSECS;
$this->assertEquals(9, $durationinday);
}
/**
* Test get_enrolled_with_capabilities_join cannotmatchanyrows attribute.
*
* @dataProvider get_enrolled_with_capabilities_join_cannotmatchanyrows_data()
* @param string $capability the tested capability
* @param bool $useprohibit if the capability must be assigned to prohibit
* @param int $expectedmatch expected cannotmatchanyrows value
* @param int $expectedcount expceted count value
*/
public function test_get_enrolled_with_capabilities_join_cannotmatchanyrows(
string $capability,
bool $useprohibit,
int $expectedmatch,
int $expectedcount
) {
global $DB, $CFG;
$this->resetAfterTest();
$course = $this->getDataGenerator()->create_course();
$context = context_course::instance($course->id);
$roleid = $CFG->defaultuserroleid;
// Override capability if necessary.
if ($useprohibit && $capability) {
assign_capability($capability, CAP_PROHIBIT, $roleid, $context);
}
// Check if we must enrol or not.
$this->getDataGenerator()->create_and_enrol($course, 'editingteacher');
$join = get_enrolled_with_capabilities_join($context, '', $capability);
// Execute query.
$sql = "SELECT COUNT(DISTINCT u.id)
FROM {user} u {$join->joins}
WHERE {$join->wheres}";
$countrecords = $DB->count_records_sql($sql, $join->params);
// Validate cannotmatchanyrows.
$this->assertEquals($expectedmatch, $join->cannotmatchanyrows);
$this->assertEquals($expectedcount, $countrecords);
}
/**
* Data provider for test_get_enrolled_with_capabilities_join_cannotmatchanyrows
*
* @return @array of testing scenarios
*/
public function get_enrolled_with_capabilities_join_cannotmatchanyrows_data() {
return [
'no prohibits, no capability' => [
'capability' => '',
'useprohibit' => false,
'expectedmatch' => 0,
'expectedcount' => 1,
],
'no prohibits with capability' => [
'capability' => 'moodle/course:manageactivities',
'useprohibit' => false,
'expectedmatch' => 0,
'expectedcount' => 1,
],
'prohibits with capability' => [
'capability' => 'moodle/course:manageactivities',
'useprohibit' => true,
'expectedmatch' => 1,
'expectedcount' => 0,
],
];
}
}
+10 -2
View File
@@ -1384,6 +1384,10 @@ function is_enrolled(context $context, $user = null, $withcapability = '', $only
* several times (e.g. as manual enrolment, and as self enrolment). You may
* need to use a SELECT DISTINCT in your query (see get_enrolled_sql for example).
*
* In case is guaranteed some of the joins never match any rows, the resulting
* join_sql->cannotmatchanyrows will be true. This happens when the capability
* is prohibited.
*
* @param context $context
* @param string $prefix optional, a prefix to the user id column
* @param string|array $capability optional, may include a capability name, or array of names.
@@ -1393,24 +1397,27 @@ function is_enrolled(context $context, $user = null, $withcapability = '', $only
* @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
* @return \core\dml\sql_join Contains joins, wheres, params and cannotmatchanyrows
*/
function get_enrolled_with_capabilities_join(context $context, $prefix = '', $capability = '', $group = 0,
$onlyactive = false, $onlysuspended = false, $enrolid = 0) {
$uid = $prefix . 'u.id';
$joins = array();
$wheres = array();
$cannotmatchanyrows = false;
$enrolledjoin = get_enrolled_join($context, $uid, $onlyactive, $onlysuspended, $enrolid);
$joins[] = $enrolledjoin->joins;
$wheres[] = $enrolledjoin->wheres;
$params = $enrolledjoin->params;
$cannotmatchanyrows = $cannotmatchanyrows || $enrolledjoin->cannotmatchanyrows;
if (!empty($capability)) {
$capjoin = get_with_capability_join($context, $capability, $uid);
$joins[] = $capjoin->joins;
$wheres[] = $capjoin->wheres;
$params = array_merge($params, $capjoin->params);
$cannotmatchanyrows = $cannotmatchanyrows || $capjoin->cannotmatchanyrows;
}
if ($group) {
@@ -1420,13 +1427,14 @@ function get_enrolled_with_capabilities_join(context $context, $prefix = '', $ca
if (!empty($groupjoin->wheres)) {
$wheres[] = $groupjoin->wheres;
}
$cannotmatchanyrows = $cannotmatchanyrows || $groupjoin->cannotmatchanyrows;
}
$joins = implode("\n", $joins);
$wheres[] = "{$prefix}u.deleted = 0";
$wheres = implode(" AND ", $wheres);
return new \core\dml\sql_join($joins, $wheres, $params);
return new \core\dml\sql_join($joins, $wheres, $params, $cannotmatchanyrows);
}
/**