diff --git a/lang/en/reportbuilder.php b/lang/en/reportbuilder.php index 69e828f669a..7e323887b5b 100644 --- a/lang/en/reportbuilder.php +++ b/lang/en/reportbuilder.php @@ -123,11 +123,13 @@ $string['filtercontains'] = 'Contains'; $string['filterdatecurrent'] = 'Current'; $string['filterdatedays'] = 'day(s)'; $string['filterdatefrom'] = 'Date from'; +$string['filterdatefuture'] = 'In the future'; $string['filterdatehours'] = 'hour(s)'; $string['filterdatelast'] = 'Last'; $string['filterdateminutes'] = 'minute(s)'; $string['filterdatemonths'] = 'month(s)'; $string['filterdatenext'] = 'Next'; +$string['filterdatepast'] = 'In the past'; $string['filterdateseconds'] = 'second(s)'; $string['filterdateto'] = 'Date to'; $string['filterdateweeks'] = 'week(s)'; diff --git a/reportbuilder/classes/local/filters/date.php b/reportbuilder/classes/local/filters/date.php index 13f87683962..cf316783b01 100644 --- a/reportbuilder/classes/local/filters/date.php +++ b/reportbuilder/classes/local/filters/date.php @@ -58,6 +58,12 @@ class date extends base { /** @var int Date in the next [X relative date unit(s)] */ public const DATE_NEXT = 6; + /** @var int Date in the past */ + public const DATE_PAST = 7; + + /** @var int Date in the future */ + public const DATE_FUTURE = 8; + /** @var int Relative date unit for a day */ public const DATE_UNIT_DAY = 1; @@ -84,6 +90,8 @@ class date extends base { self::DATE_LAST => new lang_string('filterdatelast', 'core_reportbuilder'), self::DATE_CURRENT => new lang_string('filterdatecurrent', 'core_reportbuilder'), self::DATE_NEXT => new lang_string('filterdatenext', 'core_reportbuilder'), + self::DATE_PAST => new lang_string('filterdatepast', 'core_reportbuilder'), + self::DATE_FUTURE => new lang_string('filterdatefuture', 'core_reportbuilder'), ]; return $this->filter->restrict_limited_operators($operators); @@ -97,6 +105,8 @@ class date extends base { public function setup_form(MoodleQuickForm $mform): void { // Operator selector. $operatorlabel = get_string('filterfieldoperator', 'core_reportbuilder', $this->get_header()); + $typesnounit = [self::DATE_ANY, self::DATE_NOT_EMPTY, self::DATE_EMPTY, self::DATE_RANGE, + self::DATE_PAST, self::DATE_FUTURE]; $elements[] = $mform->createElement('select', "{$this->name}_operator", $operatorlabel, $this->get_operators()); $mform->setType("{$this->name}_operator", PARAM_INT); @@ -108,11 +118,7 @@ class date extends base { $elements[] = $mform->createElement('text', "{$this->name}_value", $valuelabel, ['size' => 3]); $mform->setType("{$this->name}_value", PARAM_INT); $mform->setDefault("{$this->name}_value", 1); - $mform->hideIf("{$this->name}_value", "{$this->name}_operator", 'eq', self::DATE_ANY); - $mform->hideIf("{$this->name}_value", "{$this->name}_operator", 'eq', self::DATE_NOT_EMPTY); - $mform->hideIf("{$this->name}_value", "{$this->name}_operator", 'eq', self::DATE_EMPTY); - $mform->hideIf("{$this->name}_value", "{$this->name}_operator", 'eq', self::DATE_RANGE); - $mform->hideIf("{$this->name}_value", "{$this->name}_operator", 'eq', self::DATE_CURRENT); + $mform->hideIf("{$this->name}_value", "{$this->name}_operator", 'in', $typesnounit + [self::DATE_CURRENT]); // Unit selector for last and next operators. $unitlabel = get_string('filterdurationunit', 'core_reportbuilder', $this->get_header()); @@ -126,10 +132,7 @@ class date extends base { $elements[] = $mform->createElement('select', "{$this->name}_unit", $unitlabel, $units); $mform->setType("{$this->name}_unit", PARAM_INT); $mform->setDefault("{$this->name}_unit", self::DATE_UNIT_DAY); - $mform->hideIf("{$this->name}_unit", "{$this->name}_operator", 'eq', self::DATE_ANY); - $mform->hideIf("{$this->name}_unit", "{$this->name}_operator", 'eq', self::DATE_NOT_EMPTY); - $mform->hideIf("{$this->name}_unit", "{$this->name}_operator", 'eq', self::DATE_EMPTY); - $mform->hideIf("{$this->name}_unit", "{$this->name}_operator", 'eq', self::DATE_RANGE); + $mform->hideIf("{$this->name}_unit", "{$this->name}_operator", 'in', $typesnounit); // Add operator/value/unit group. $mform->addGroup($elements, "{$this->name}_group", '', '', false); @@ -208,6 +211,16 @@ class date extends base { $params[$paramdateto], ] = self::get_relative_timeframe($operator, $dateunitvalue, $dateunit); + break; + case self::DATE_PAST: + $param = database::generate_param_name(); + $sql = "{$fieldsql} < :{$param}"; + $params[$param] = time(); + break; + case self::DATE_FUTURE: + $param = database::generate_param_name(); + $sql = "{$fieldsql} > :{$param}"; + $params[$param] = time(); break; default: // Invalid or inactive filter. diff --git a/reportbuilder/tests/local/filters/date_test.php b/reportbuilder/tests/local/filters/date_test.php index d35a3baa828..3b28183856c 100644 --- a/reportbuilder/tests/local/filters/date_test.php +++ b/reportbuilder/tests/local/filters/date_test.php @@ -144,6 +144,9 @@ class date_test extends advanced_testcase { 'Next two weeks' => [date::DATE_NEXT, 2, date::DATE_UNIT_WEEK, '+10 day'], 'Next two months' => [date::DATE_NEXT, 2, date::DATE_UNIT_MONTH, '+7 week'], 'Next two years' => [date::DATE_NEXT, 2, date::DATE_UNIT_YEAR, '+15 month'], + + 'In the past' => [date::DATE_PAST, null, null, '-3 hour'], + 'In the future' => [date::DATE_FUTURE, null, null, '+3 hour'], ]; } @@ -152,12 +155,12 @@ class date_test extends advanced_testcase { * * @param int $operator * @param int|null $unitvalue - * @param int $unit + * @param int|null $unit * @param string|null $timecreated Relative time suitable for passing to {@see strtotime} (or null for current time) * * @dataProvider get_sql_filter_relative_provider */ - public function test_get_sql_filter_relative(int $operator, ?int $unitvalue, int $unit, ?string $timecreated = null): void { + public function test_get_sql_filter_relative(int $operator, ?int $unitvalue, ?int $unit, ?string $timecreated = null): void { global $DB; $this->resetAfterTest();