Skip to content

Commit ef9fd90

Browse files
committed
issue #81: add operator for user role condition
1 parent 2618182 commit ef9fd90

File tree

4 files changed

+347
-18
lines changed

4 files changed

+347
-18
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ Conditions are simple predicates which assert something about a user in the syst
6363
* User created time (time since a user was created).
6464
* User standard profile fields (e.g. first name, last name, username, auth method and etc).
6565
* User custom profile fields (text and menu types are supported).
66-
* User role (if a user is assigned to a role in a context)
66+
* User role (if a user has a role in a given context)
6767

6868
## Rules
6969

classes/local/tool_dynamic_cohorts/condition/user_role.php

+61-7
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,16 @@
3232
*/
3333
class user_role extends condition_base {
3434

35+
/**
36+
* Operator for user who have role.
37+
*/
38+
public const OPERATOR_HAVE_ROLE = 0;
39+
40+
/**
41+
* Operator for user who do not have role.
42+
*/
43+
public const OPERATOR_DO_NOT_HAVE_ROLE = 1;
44+
3545
/**
3646
* Condition name.
3747
*
@@ -58,12 +68,32 @@ protected function get_all_roles(): array {
5868
return $roles;
5969
}
6070

71+
/**
72+
* Gets a list of operators.
73+
*
74+
* @return array A list of operators.
75+
*/
76+
protected function get_operators(): array {
77+
return [
78+
self::OPERATOR_HAVE_ROLE => get_string('haverole', 'tool_dynamic_cohorts'),
79+
self::OPERATOR_DO_NOT_HAVE_ROLE => get_string('donothaverole', 'tool_dynamic_cohorts'),
80+
];
81+
}
82+
6183
/**
6284
* Add config form elements.
6385
*
6486
* @param \MoodleQuickForm $mform
6587
*/
6688
public function config_form_add(\MoodleQuickForm $mform): void {
89+
// Operator.
90+
$mform->addElement(
91+
'select',
92+
'operator',
93+
get_string('operator', 'tool_dynamic_cohorts'),
94+
$this->get_operators()
95+
);
96+
6797
// Role field.
6898
$mform->addElement('select', 'roleid', get_string('role'), $this->get_all_roles());
6999

@@ -114,6 +144,15 @@ public function config_form_validate(array $data): array {
114144
return $errors;
115145
}
116146

147+
/**
148+
* Gets operator.
149+
*
150+
* @return int
151+
*/
152+
protected function get_operator_value(): int {
153+
return $this->get_config_data()['operator'] ?? self::OPERATOR_HAVE_ROLE;
154+
}
155+
117156
/**
118157
* Gets configured role ID.
119158
*
@@ -171,16 +210,21 @@ public function get_config_description(): string {
171210

172211
switch ($this->get_contextlevel_value()) {
173212
case CONTEXT_SYSTEM:
174-
return get_string('condition:user_role_description_system', 'tool_dynamic_cohorts', $rolename);
213+
return get_string('condition:user_role_description_system', 'tool_dynamic_cohorts', (object)[
214+
'role' => $rolename,
215+
'operator' => $this->get_operators()[$this->get_operator_value()],
216+
]);
175217

176218
case CONTEXT_COURSECAT:
177219
$children = !empty($this->get_includechildren_value()) ? get_string('includechildren', 'tool_dynamic_cohorts') : '';
178220
$categoryname = core_course_category::get($this->get_categoryid_value())->get_formatted_name();
179221

180222
return get_string('condition:user_role_description_category', 'tool_dynamic_cohorts', (object) [
181223
'role' => $rolename,
224+
'operator' => $this->get_operators()[$this->get_operator_value()],
182225
'categoryname' => $categoryname,
183226
'categoryid' => $this->get_categoryid_value(),
227+
184228
]) . ' ' . $children;
185229

186230
case CONTEXT_COURSE:
@@ -189,6 +233,7 @@ public function get_config_description(): string {
189233

190234
return get_string('condition:user_role_description_course', 'tool_dynamic_cohorts', (object) [
191235
'role' => $rolename,
236+
'operator' => $this->get_operators()[$this->get_operator_value()],
192237
'coursename' => $coursename,
193238
'courseid' => $this->get_courseid_value(),
194239
]);
@@ -242,16 +287,15 @@ public function get_sql(): condition_sql {
242287
$params[$roleidparam] = $roleid;
243288

244289
$ratable = condition_sql::generate_table_alias();
245-
$join = "JOIN {role_assignments} $ratable ON ($ratable.userid = u.id)";
246-
$where = "$ratable.roleid = :$roleidparam";
290+
$innerwhere = "$ratable.roleid = :$roleidparam";
247291

248292
switch ($this->get_contextlevel_value()) {
249293
case CONTEXT_SYSTEM:
250294
$context = context_system::instance();
251295
$contextid = $context->id;
252296
$contextidparam = condition_sql::generate_param_alias();
253297
$params[$contextidparam] = $contextid;
254-
$where .= " AND $ratable.contextid = :$contextidparam";
298+
$innerwhere .= " AND $ratable.contextid = :$contextidparam";
255299

256300
break;
257301
case CONTEXT_COURSECAT:
@@ -273,9 +317,9 @@ public function get_sql(): condition_sql {
273317
condition_sql::generate_param_alias()
274318
);
275319
$params = array_merge($params, $childcparams);
276-
$where .= " AND ( $ratable.contextid $parentcontexsql OR $ratable.contextid $childcontextsql ) ";
320+
$innerwhere .= " AND ( $ratable.contextid $parentcontexsql OR $ratable.contextid $childcontextsql ) ";
277321
} else {
278-
$where .= " AND $ratable.contextid $parentcontexsql ";
322+
$innerwhere .= " AND $ratable.contextid $parentcontexsql ";
279323
}
280324

281325
break;
@@ -290,11 +334,21 @@ public function get_sql(): condition_sql {
290334
);
291335

292336
$params = array_merge($params, $cparams);
293-
$where .= " AND $ratable.contextid $contextsql";
337+
$innerwhere .= " AND $ratable.contextid $contextsql";
294338

295339
break;
296340
}
297341

342+
$outertable = condition_sql::generate_table_alias();
343+
344+
$join = "LEFT JOIN (SELECT {$ratable}.userid
345+
FROM {role_assignments} $ratable
346+
WHERE $innerwhere) {$outertable}
347+
ON u.id = {$outertable}.userid";
348+
349+
$haverole = $this->get_operator_value() == self::OPERATOR_HAVE_ROLE;
350+
$where = $haverole ? " $outertable.userid is NOT NULL" : " $outertable.userid is NULL";
351+
298352
$sql = new condition_sql($join, $where, $params);
299353
}
300354

lang/en/tool_dynamic_cohorts.php

+5-3
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,9 @@
6565
$string['condition:user_profile'] = 'User standard profile field';
6666
$string['condition:user_custom_profile'] = 'User custom profile field';
6767
$string['condition:user_role'] = 'User role';
68-
$string['condition:user_role_description_system'] = 'A user has {$a} role in system context';
69-
$string['condition:user_role_description_category'] = 'A user has {$a->role} role in category {$a->categoryname} (id {$a->categoryid})';
70-
$string['condition:user_role_description_course'] = 'A user has {$a->role} role in course {$a->coursename} (id {$a->courseid})';
68+
$string['condition:user_role_description_system'] = 'Users who {$a->operator} "{$a->role}" in system context';
69+
$string['condition:user_role_description_category'] = 'Users who {$a->operator} "{$a->role}" in category {$a->categoryname} (id {$a->categoryid})';
70+
$string['condition:user_role_description_course'] = 'Users who {$a->operator} "{$a->role}" in course {$a->coursename} (id {$a->courseid})';
7171
$string['cf_include_missing_data'] = 'Include cohorts with missing data.';
7272
$string['cf_include_missing_data_help'] = 'Cohorts may not have a custom field data set yet. This option includes those cohorts in the final result.';
7373
$string['cf_includingmissingdatadesc'] = '(including cohorts with missing data)';
@@ -146,3 +146,5 @@
146146
$string['usercreatedtime'] = 'A user was created {$a->operator} {$a->time}';
147147
$string['usersforrule'] = 'Users matching rule "{$a->rule}" for cohort "{$a->cohort}"';
148148
$string['userlastlogin'] = 'User\'s last login';
149+
$string['haverole'] = 'have role';
150+
$string['donothaverole'] = 'do not have role';

0 commit comments

Comments
 (0)