Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

issue #40: add support for date field #72

Merged
merged 1 commit into from
Apr 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions classes/condition_base.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,16 @@ abstract class condition_base {
*/
public const FIELD_DATA_TYPE_CHECKBOX = 'checkbox';

/**
* Value for date field types.
*/
public const FIELD_DATA_TYPE_DATE = 'date';

/**
* Value for date field types.
*/
public const FIELD_DATA_TYPE_DATETIME = 'datetime';

/**
* Value for operator text contains.
*/
Expand Down Expand Up @@ -85,6 +95,16 @@ abstract class condition_base {
*/
public const TEXT_IS_NOT_EQUAL_TO = 8;

/**
* Value for operator date is after.
*/
public const DATE_IS_AFTER = 1;

/**
* Value for operator date is before.
*/
public const DATE_IS_BEFORE = 2;

/**
* Condition persistent object.
*
Expand Down
39 changes: 11 additions & 28 deletions classes/local/tool_dynamic_cohorts/condition/cohort_field.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@ protected function get_cohort_operators(): array {
* @return array
*/
protected function get_supported_custom_fields(): array {
return [self::FIELD_DATA_TYPE_TEXT, self::FIELD_DATA_TYPE_SELECT, self::FIELD_DATA_TYPE_CHECKBOX];
return [self::FIELD_DATA_TYPE_TEXT, self::FIELD_DATA_TYPE_SELECT,
self::FIELD_DATA_TYPE_CHECKBOX, self::FIELD_DATA_TYPE_DATE];
}

/**
Expand Down Expand Up @@ -154,6 +155,9 @@ protected function get_fields_info(): array {
case self::FIELD_DATA_TYPE_CHECKBOX:
$fields[$shortname]->param1 = array_combine([0, 1], [get_string('no'), get_string('yes')]);
break;
case self::FIELD_DATA_TYPE_DATE:
$fields[$shortname]->paramtype = PARAM_INT;
break;
default:
throw new coding_exception('Invalid field type ' . $fields[$shortname]->datatype);
}
Expand Down Expand Up @@ -217,6 +221,9 @@ public function config_form_add(\MoodleQuickForm $mform): void {
case self::FIELD_DATA_TYPE_CHECKBOX:
$this->add_checkbox_field($mform, $group, $field, $shortname);
break;
case self::FIELD_DATA_TYPE_DATE:
$this->add_date_field($mform, $group, $field, $shortname);
break;
default:
throw new coding_exception('Invalid field type ' . $field->datatype);
}
Expand Down Expand Up @@ -244,33 +251,6 @@ public function config_form_add(\MoodleQuickForm $mform): void {
}
}

/**
* Validate config form elements.
*
* @param array $data Data to validate.
* @return array
*/
public function config_form_validate(array $data): array {
$errors = [];

$fields = $this->get_fields_info();
if (empty($data[static::get_form_field()]) || !isset($fields[$data[static::get_form_field()]])) {
$errors['fieldgroup'] = get_string('pleaseselectfield', 'tool_dynamic_cohorts');
}

$fieldvalue = $data[static::get_form_field()] . '_value';
$operator = $data[static::get_form_field()] . '_operator';
$datatype = $fields[$data[static::get_form_field()]]->datatype ?? '';

if (empty($data[$fieldvalue])) {
if ($datatype == 'text' && !in_array($data[$operator], [self::TEXT_IS_EMPTY, self::TEXT_IS_NOT_EMPTY])) {
$errors['fieldgroup'] = get_string('invalidfieldvalue', 'tool_dynamic_cohorts');
}
}

return $errors;
}

/**
* Gets required config data from submitted condition form data.
*
Expand Down Expand Up @@ -405,6 +385,9 @@ public function get_sql(): condition_sql {
case self::FIELD_DATA_TYPE_SELECT:
$fieldsqldata = $this->get_menu_sql($fieldstable, $dbcolumn);
break;
case self::FIELD_DATA_TYPE_DATE:
$fieldsqldata = $this->get_date_sql($fieldstable, $dbcolumn);
break;
default:
throw new coding_exception('Invalid field type ' . $datatype);
}
Expand Down
126 changes: 117 additions & 9 deletions classes/local/tool_dynamic_cohorts/condition/fields_trait.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,20 @@ protected function get_menu_operators(): array {
];
}

/**
* Gets a list of comparison operators for date fields.
*
* @return array A list of operators.
*/
protected function get_date_operators(): array {
return [
self::DATE_IS_AFTER => get_string('isafter', 'tool_dynamic_cohorts'),
self::DATE_IS_BEFORE => get_string('isbefore', 'tool_dynamic_cohorts'),
self::TEXT_IS_EMPTY => get_string('isempty', 'filters'),
self::TEXT_IS_NOT_EMPTY => get_string('isnotempty', 'tool_dynamic_cohorts'),
];
}

/**
* Returns a field name for the configured field.
*
Expand Down Expand Up @@ -109,7 +123,9 @@ protected function get_field_value_text(): ?string {
case self::FIELD_DATA_TYPE_CHECKBOX:
$fieldvalue = $fieldinfo[$fieldname]->param1[$fieldvalue];
break;

case self::FIELD_DATA_TYPE_DATE:
case self::FIELD_DATA_TYPE_DATETIME:
$fieldvalue = userdate($fieldvalue);
}
}

Expand All @@ -136,15 +152,16 @@ protected function get_operator_value(): int {
* @return string
*/
protected function get_operator_text(string $fielddatatype): string {
if ($fielddatatype == self::FIELD_DATA_TYPE_TEXT) {
return $this->get_text_operators()[$this->get_operator_value()];
}

if ($fielddatatype == self::FIELD_DATA_TYPE_MENU) {
return $this->get_menu_operators()[$this->get_operator_value()];
switch ($fielddatatype) {
case self::FIELD_DATA_TYPE_MENU:
case self::FIELD_DATA_TYPE_SELECT:
return $this->get_menu_operators()[$this->get_operator_value()];
case self::FIELD_DATA_TYPE_DATETIME:
case self::FIELD_DATA_TYPE_DATE:
return $this->get_date_operators()[$this->get_operator_value()];
default:
return $this->get_text_operators()[$this->get_operator_value()];
}

return $this->get_text_operators()[$this->get_operator_value()];
}

/**
Expand Down Expand Up @@ -205,6 +222,57 @@ protected function add_checkbox_field(\MoodleQuickForm $mform, array &$group, \s
$mform->hideIf($shortname, self::get_form_field(), 'neq', $shortname);
}

/**
* Adds a date field to the form.
*
* @param \MoodleQuickForm $mform Form to add the field to.
* @param array $group A group to add the field to.
* @param \stdClass $field Field info.
* @param string $shortname A field shortname.
*/
protected function add_date_field(\MoodleQuickForm $mform, array &$group, \stdClass $field, string $shortname): void {
$elements = [];
$elements[] = $mform->createElement('select', $shortname . '_operator', null, $this->get_date_operators());

$elements[] = $mform->createElement('date_time_selector', $shortname . '_value');
$mform->setDefault($shortname . '_value', usergetmidnight(time()));
$mform->hideIf($shortname . '_value', $shortname . '_operator', 'in', self::TEXT_IS_EMPTY . '|' . self::TEXT_IS_NOT_EMPTY);

$group[] = $mform->createElement('group', $shortname, '', $elements, '', false);

$mform->hideIf($shortname . '_operator', static::get_form_field(), 'neq', $shortname);
$mform->hideIf($shortname . '_value', static::get_form_field(), 'neq', $shortname);
$mform->hideIf($shortname . '_value1', static::get_form_field(), 'neq', $shortname);
$mform->hideIf($shortname, static::get_form_field(), 'neq', $shortname);
}

/**
* Validate config form elements.
*
* @param array $data Data to validate.
* @return array
*/
public function config_form_validate(array $data): array {
$errors = [];

$fields = $this->get_fields_info();
if (empty($data[static::get_form_field()]) || !isset($fields[$data[static::get_form_field()]])) {
$errors['fieldgroup'] = get_string('pleaseselectfield', 'tool_dynamic_cohorts');
}

$fieldvalue = $data[static::get_form_field()] . '_value';
$operator = $data[static::get_form_field()] . '_operator';
$datatype = $fields[$data[static::get_form_field()]]->datatype ?? '';

if (empty($data[$fieldvalue])) {
if ($datatype == 'text' && !in_array($data[$operator], [self::TEXT_IS_EMPTY, self::TEXT_IS_NOT_EMPTY])) {
$errors['fieldgroup'] = get_string('invalidfieldvalue', 'tool_dynamic_cohorts');
}
}

return $errors;
}

/**
* Get SQl data for text type fields.
*
Expand Down Expand Up @@ -303,4 +371,44 @@ protected function get_menu_sql(string $tablealias, string $fieldname): conditio

return new condition_sql('', $where, $params);
}

/**
* Get SQL data for date type fields.
*
* @param string $tablealias Alias for a table.
* @param string $fieldname Field name.
* @return condition_sql
*/
protected function get_date_sql(string $tablealias, string $fieldname): condition_sql {
$fieldvalue = $this->get_field_value();
$operatorvalue = $this->get_operator_value();

if ($this->is_broken()) {
return new condition_sql('', '', []);
}

$param = condition_sql::generate_param_alias();
switch ($operatorvalue) {
case self::TEXT_IS_EMPTY:
$where = "$tablealias.$fieldname = :$param OR $tablealias.$fieldname IS NULL";
$params[$param] = 0;
break;
case self::TEXT_IS_NOT_EMPTY:
$where = "$tablealias.$fieldname <> :$param";
$params[$param] = (int) $fieldvalue;
break;
case self::DATE_IS_BEFORE:
$where = "$tablealias.$fieldname <= :$param";
$params[$param] = (int) $fieldvalue;
break;
case self::DATE_IS_AFTER:
$where = "$tablealias.$fieldname >= :$param";
$params[$param] = (int) $fieldvalue;
break;
default:
return new condition_sql('', '', []);
}

return new condition_sql('', $where, $params);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ public function get_name(): string {
* @return array
*/
protected function get_supported_custom_fields(): array {
return [self::FIELD_DATA_TYPE_TEXT, self::FIELD_DATA_TYPE_MENU, self::FIELD_DATA_TYPE_CHECKBOX];
return [self::FIELD_DATA_TYPE_TEXT, self::FIELD_DATA_TYPE_MENU,
self::FIELD_DATA_TYPE_CHECKBOX, self::FIELD_DATA_TYPE_DATETIME];
}

/**
Expand Down Expand Up @@ -87,6 +88,9 @@ protected function get_fields_info(): array {
case self::FIELD_DATA_TYPE_CHECKBOX:
$field->param1 = array_combine([0, 1], [get_string('no'), get_string('yes')]);
break;
case self::FIELD_DATA_TYPE_DATETIME:
$field->paramtype = PARAM_INT;
break;
default:
throw new coding_exception('Invalid field type ' . $field->datatype);
}
Expand Down Expand Up @@ -119,16 +123,19 @@ public function config_form_add(\MoodleQuickForm $mform): void {
case self::FIELD_DATA_TYPE_TEXT:
$this->add_text_field($mform, $group, $field, $shortname);
break;
case self::FIELD_DATA_TYPE_MENU:
case self::FIELD_DATA_TYPE_MENU:
$this->add_menu_field($mform, $group, $field, $shortname);
break;
case self::FIELD_DATA_TYPE_CHECKBOX:
case self::FIELD_DATA_TYPE_CHECKBOX:
$this->add_checkbox_field($mform, $group, $field, $shortname);
break;
case self::FIELD_DATA_TYPE_DATETIME:
$this->add_date_field($mform, $group, $field, $shortname);
break;
}
}

$mform->addGroup($group, 'profilefieldgroup', get_string('profilefield', 'tool_dynamic_cohorts'), '', false);
$mform->addGroup($group, 'fieldgroup', get_string('profilefield', 'tool_dynamic_cohorts'), '', false);

$mform->addElement(
'checkbox',
Expand Down Expand Up @@ -182,6 +189,9 @@ public function get_sql(): condition_sql {
case self::FIELD_DATA_TYPE_MENU:
$result = $this->get_menu_sql($ud, 'data');
break;
case self::FIELD_DATA_TYPE_DATETIME:
$result = $this->get_date_sql($ud, 'data');
break;
}

if (!empty($result->get_params())) {
Expand Down
31 changes: 3 additions & 28 deletions classes/local/tool_dynamic_cohorts/condition/user_profile.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,39 +84,14 @@ public function config_form_add(\MoodleQuickForm $mform): void {
case self::FIELD_DATA_TYPE_CHECKBOX:
$this->add_checkbox_field($mform, $group, $field, $shortname);
break;
case self::FIELD_DATA_TYPE_DATE:
$this->add_date_field($mform, $group, $field, $shortname);
default:
throw new coding_exception('Invalid field type ' . $field->datatype);
}
}

$mform->addGroup($group, 'profilefieldgroup', get_string('profilefield', 'tool_dynamic_cohorts'), '', false);
}

/**
* Validate config form elements.
*
* @param array $data Data to validate.
* @return array
*/
public function config_form_validate(array $data): array {
$errors = [];

$fields = $this->get_fields_info();
if (empty($data[static::get_form_field()]) || !isset($fields[$data[static::get_form_field()]])) {
$errors['profilefieldgroup'] = get_string('pleaseselectfield', 'tool_dynamic_cohorts');
}

$fieldvalue = $data[static::get_form_field()] . '_value';
$operator = $data[static::get_form_field()] . '_operator';
$datatype = $fields[$data[static::get_form_field()]]->datatype ?? '';

if (empty($data[$fieldvalue])) {
if ($datatype == 'text' && !in_array($data[$operator], [self::TEXT_IS_EMPTY, self::TEXT_IS_NOT_EMPTY])) {
$errors['profilefieldgroup'] = get_string('invalidfieldvalue', 'tool_dynamic_cohorts');
}
}

return $errors;
$mform->addGroup($group, 'fieldgroup', get_string('profilefield', 'tool_dynamic_cohorts'), '', false);
}

/**
Expand Down
2 changes: 2 additions & 0 deletions lang/en/tool_dynamic_cohorts.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@
$string['ismemberof'] = 'is member of';
$string['isnotmemberof'] = 'is not member of';
$string['isnotempty'] = 'is not empty';
$string['isafter'] = 'is after';
$string['isbefore'] = 'is before';
$string['logical_operator'] = 'Logical operator';
$string['logical_operator_help'] = 'A logical operator to be applied to conditions for this rule. Operator "AND" means a user has to match all conditions to be added to a cohort. "OR" means a user has to match any of conditions to be added to a cohort.';
$string['managerules'] = 'Manage rules';
Expand Down
Loading
Loading