diff --git a/public/reportbuilder/classes/local/filters/category.php b/public/reportbuilder/classes/local/filters/category.php index 8f1012c8a14..cb2b7acbac4 100644 --- a/public/reportbuilder/classes/local/filters/category.php +++ b/public/reportbuilder/classes/local/filters/category.php @@ -19,9 +19,9 @@ declare(strict_types=1); namespace core_reportbuilder\local\filters; use core_course_category; -use lang_string; -use MoodleQuickForm; +use core\lang_string; use core_reportbuilder\local\helpers\database; +use MoodleQuickForm; /** * Course category report filter @@ -37,6 +37,9 @@ use core_reportbuilder\local\helpers\database; */ class category extends base { + /** @var int Category is any value */ + public const ANY_VALUE = -1; + /** @var int Category is equal to */ public const EQUAL_TO = 0; @@ -50,6 +53,7 @@ class category extends base { */ private function get_operators(): array { $operators = [ + self::ANY_VALUE => new lang_string('filterisanyvalue', 'core_reportbuilder'), self::EQUAL_TO => new lang_string('filterisequalto', 'core_reportbuilder'), self::NOT_EQUAL_TO => new lang_string('filterisnotequalto', 'core_reportbuilder'), ]; @@ -73,7 +77,10 @@ class category extends base { $valuelabel = get_string('filterfieldvalue', 'core_reportbuilder', $this->get_header()); $mform->addElement('autocomplete', "{$this->name}_value", $valuelabel, $categories)->setHiddenLabel(true); + $mform->hideIf("{$this->name}_value", "{$this->name}_operator", 'eq', self::ANY_VALUE); + $mform->addElement('advcheckbox', "{$this->name}_subcategories", get_string('includesubcategories')); + $mform->hideIf("{$this->name}_subcategories", "{$this->name}_operator", 'eq', self::ANY_VALUE); } /** @@ -87,12 +94,12 @@ class category extends base { [$fieldsql, $params] = $this->filter->get_field_sql_and_params(); - $operator = (int) ($values["{$this->name}_operator"] ?? self::EQUAL_TO); + $operator = (int) ($values["{$this->name}_operator"] ?? self::ANY_VALUE); $category = (int) ($values["{$this->name}_value"] ?? 0); $subcategories = !empty($values["{$this->name}_subcategories"]); // Invalid or inactive filter. - if (empty($category)) { + if ($operator === self::ANY_VALUE || $category === 0) { return ['', []]; } @@ -132,6 +139,7 @@ class category extends base { */ public function get_sample_values(): array { return [ + "{$this->name}_operator" => self::EQUAL_TO, "{$this->name}_value" => 1, ]; } diff --git a/public/reportbuilder/tests/local/filters/category_test.php b/public/reportbuilder/tests/local/filters/category_test.php index 572a34f6944..aacb93932ef 100644 --- a/public/reportbuilder/tests/local/filters/category_test.php +++ b/public/reportbuilder/tests/local/filters/category_test.php @@ -40,6 +40,9 @@ final class category_test extends advanced_testcase { */ public static function get_sql_filter_provider(): array { return [ + // Any value. + [null, category::ANY_VALUE, false, ['Category 1', 'One', 'Two', 'Three', 'Four', 'Five', 'Six']], + // Equal to. ['One', category::EQUAL_TO, false, ['One']], ['One', category::EQUAL_TO, true, ['One', 'Two', 'Three']], @@ -138,6 +141,7 @@ final class category_test extends advanced_testcase { // When including sub-categories, the filter SQL is included twice (for the category itself, plus to find descendents). [$select, $params] = category::create($filter)->get_sql_filter([ + $filter->get_unique_identifier() . '_operator' => category::EQUAL_TO, $filter->get_unique_identifier() . '_value' => $category1->id, $filter->get_unique_identifier() . '_subcategories' => true, ]);