Skip to content

Commit 152cc5a

Browse files
authored
Merge pull request #96 from catalyst/issue94-MOODLE_404_STABLE
issue #94: add support for autocomplete user profile field
2 parents 89bc942 + 9f914de commit 152cc5a

File tree

4 files changed

+87
-3
lines changed

4 files changed

+87
-3
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ Conditions are simple predicates which assert something about a user in the syst
6262
* Course completed (if a user has completed a course).
6363
* Course not completed (if a user has not completed a course).
6464
* User created time (time since a user was created).
65-
* User custom profile fields (text and menu types are supported).
65+
* User custom profile fields (text, menu, date and autocomplete types are supported).
6666
* User enrolment (if a user is enrolled into a course).
6767
* User last login (time since a user last logged in).
6868
* User role (if a user has a role in a given context)

classes/condition_base.php

+5
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,11 @@ abstract class condition_base {
5555
*/
5656
public const FIELD_DATA_TYPE_DATETIME = 'datetime';
5757

58+
/**
59+
* Value for autocomplete field types.
60+
*/
61+
public const FIELD_DATA_TYPE_AUTOCOMPLETE = 'autocomplete';
62+
5863
/**
5964
* Value for operator text contains.
6065
*/

classes/local/tool_dynamic_cohorts/condition/fields_trait.php

+69
Original file line numberDiff line numberDiff line change
@@ -411,4 +411,73 @@ protected function get_date_sql(string $tablealias, string $fieldname): conditio
411411

412412
return new condition_sql('', $where, $params);
413413
}
414+
415+
/**
416+
* Get SQL data for multi select type fields.
417+
*
418+
* @param string $tablealias Alias for a table.
419+
* @param string $fieldname Field name.
420+
* @param bool $addspace Does a field type add space?
421+
* @return condition_sql
422+
*/
423+
protected function get_multiselect_sql(string $tablealias, string $fieldname, bool $addspace = true): condition_sql {
424+
global $DB;
425+
426+
$fieldvalue = $this->get_field_value();
427+
$operatorvalue = $this->get_operator_value();
428+
429+
if ($this->is_broken()) {
430+
return new condition_sql('', '', []);
431+
}
432+
// For some reason user profile field autocomplete adds space when saving field values
433+
// like implode(', ', $data). However multiselect custom field doesn't do it, instead it does
434+
// like implode(',', $data). To make it flexible we add space when we consider (or not) an extra
435+
// space when we build following SQL.
436+
$space = $addspace ? ' ' : '';
437+
438+
// User data for multiselect fields is stored like Option 1, Option 2, Option 3.
439+
// So to be accurate in our SQL we have to cover three scenarios:
440+
// 1. Value is in the beginning of the string.
441+
// 2. Value is somewhere in the middle.
442+
// 3. Value is at the end of the string.
443+
// So our SQL should like:
444+
// WHERE data like 'value%' OR data like '% value, %' OR data like '%, value'
445+
// This is a bit hacky, but should give us accurate results.
446+
$startparam = condition_sql::generate_param_alias();
447+
$middleparam = condition_sql::generate_param_alias();
448+
$endparam = condition_sql::generate_param_alias();
449+
450+
switch ($operatorvalue) {
451+
case self::TEXT_IS_EQUAL_TO:
452+
$value = $DB->sql_like_escape($fieldvalue);
453+
454+
$where = $DB->sql_like("$tablealias.$fieldname", ":$startparam", false, false);
455+
$params[$startparam] = "$value%";
456+
457+
$where .= ' OR ' . $DB->sql_like("$tablealias.$fieldname", ":$middleparam", false, false);
458+
$params[$middleparam] = "%,$space$value,$space%";
459+
460+
$where .= ' OR ' . $DB->sql_like("$tablealias.$fieldname", ":$endparam", false, false);
461+
$params[$endparam] = "%,$space$value";
462+
463+
break;
464+
case self::TEXT_IS_NOT_EQUAL_TO:
465+
$value = $DB->sql_like_escape($fieldvalue);
466+
467+
$where = $DB->sql_like("$tablealias.$fieldname", ":$startparam", false, false, true);
468+
$params[$startparam] = "$value%";
469+
470+
$where .= ' AND ' . $DB->sql_like("$tablealias.$fieldname", ":$middleparam", false, false, true);
471+
$params[$middleparam] = "%,$space$value,$space%";
472+
473+
$where .= ' AND ' . $DB->sql_like("$tablealias.$fieldname", ":$endparam", false, false, true);
474+
$params[$endparam] = "%,$space$value";
475+
476+
break;
477+
default:
478+
return new condition_sql('', '', []);
479+
}
480+
481+
return new condition_sql('', $where, $params);
482+
}
414483
}

classes/local/tool_dynamic_cohorts/condition/user_custom_profile.php

+12-2
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,13 @@ public function get_name(): string {
5353
* @return array
5454
*/
5555
protected function get_supported_custom_fields(): array {
56-
return [self::FIELD_DATA_TYPE_TEXT, self::FIELD_DATA_TYPE_MENU,
57-
self::FIELD_DATA_TYPE_CHECKBOX, self::FIELD_DATA_TYPE_DATETIME];
56+
return [
57+
self::FIELD_DATA_TYPE_TEXT,
58+
self::FIELD_DATA_TYPE_MENU,
59+
self::FIELD_DATA_TYPE_CHECKBOX,
60+
self::FIELD_DATA_TYPE_DATETIME,
61+
self::FIELD_DATA_TYPE_AUTOCOMPLETE,
62+
];
5863
}
5964

6065
/**
@@ -79,6 +84,7 @@ protected function get_fields_info(): array {
7984

8085
switch ($field->datatype) {
8186
case self::FIELD_DATA_TYPE_MENU:
87+
case self::FIELD_DATA_TYPE_AUTOCOMPLETE:
8288
$options = explode("\n", $field->param1);
8389
$field->param1 = array_combine($options, $options);
8490
break;
@@ -124,6 +130,7 @@ public function config_form_add(\MoodleQuickForm $mform): void {
124130
$this->add_text_field($mform, $group, $field, $shortname);
125131
break;
126132
case self::FIELD_DATA_TYPE_MENU:
133+
case self::FIELD_DATA_TYPE_AUTOCOMPLETE:
127134
$this->add_menu_field($mform, $group, $field, $shortname);
128135
break;
129136
case self::FIELD_DATA_TYPE_CHECKBOX:
@@ -192,6 +199,9 @@ public function get_sql(): condition_sql {
192199
case self::FIELD_DATA_TYPE_DATETIME:
193200
$result = $this->get_date_sql($ud, 'data');
194201
break;
202+
case self::FIELD_DATA_TYPE_AUTOCOMPLETE:
203+
$result = $this->get_multiselect_sql($ud, 'data');
204+
break;
195205
}
196206

197207
if (!empty($result->get_params())) {

0 commit comments

Comments
 (0)