mirror of
https://github.com/moodle/moodle.git
synced 2025-01-18 14:03:52 +01:00
MDL-73180 reportbuilder: improve relative date filter definitions.
Changes since the original implementation in e55abd71 mean that relative date filtering (by last/next day/week, etc) is now based on the actual current time, rather than the start or end of the current time unit.
This commit is contained in:
parent
a01f1fa71c
commit
a844d885b2
@ -113,10 +113,10 @@ $string['filterdatecurrent'] = 'Current';
|
|||||||
$string['filterdatedays'] = 'day(s)';
|
$string['filterdatedays'] = 'day(s)';
|
||||||
$string['filterdatefrom'] = 'Date from';
|
$string['filterdatefrom'] = 'Date from';
|
||||||
$string['filterdatehours'] = 'hour(s)';
|
$string['filterdatehours'] = 'hour(s)';
|
||||||
|
$string['filterdatelast'] = 'Last';
|
||||||
$string['filterdateminutes'] = 'minute(s)';
|
$string['filterdateminutes'] = 'minute(s)';
|
||||||
$string['filterdatemonths'] = 'month(s)';
|
$string['filterdatemonths'] = 'month(s)';
|
||||||
$string['filterdatenext'] = 'Next';
|
$string['filterdatenext'] = 'Next';
|
||||||
$string['filterdateprevious'] = 'Previous';
|
|
||||||
$string['filterdateseconds'] = 'second(s)';
|
$string['filterdateseconds'] = 'second(s)';
|
||||||
$string['filterdateto'] = 'Date to';
|
$string['filterdateto'] = 'Date to';
|
||||||
$string['filterdateweeks'] = 'week(s)';
|
$string['filterdateweeks'] = 'week(s)';
|
||||||
|
@ -46,8 +46,11 @@ class date extends base {
|
|||||||
/** @var int Date within defined range */
|
/** @var int Date within defined range */
|
||||||
public const DATE_RANGE = 3;
|
public const DATE_RANGE = 3;
|
||||||
|
|
||||||
/** @var int Date in the previous [X relative date unit(s)] */
|
/** @var int Date in the last [X relative date unit(s)] */
|
||||||
public const DATE_PREVIOUS = 4;
|
public const DATE_LAST = 4;
|
||||||
|
|
||||||
|
/** @var int Date in the previous [X relative date unit(s)] Kept for backwards compatibility */
|
||||||
|
public const DATE_PREVIOUS = self::DATE_LAST;
|
||||||
|
|
||||||
/** @var int Date in current [relative date unit] */
|
/** @var int Date in current [relative date unit] */
|
||||||
public const DATE_CURRENT = 5;
|
public const DATE_CURRENT = 5;
|
||||||
@ -78,7 +81,7 @@ class date extends base {
|
|||||||
self::DATE_NOT_EMPTY => new lang_string('filterisnotempty', 'core_reportbuilder'),
|
self::DATE_NOT_EMPTY => new lang_string('filterisnotempty', 'core_reportbuilder'),
|
||||||
self::DATE_EMPTY => new lang_string('filterisempty', 'core_reportbuilder'),
|
self::DATE_EMPTY => new lang_string('filterisempty', 'core_reportbuilder'),
|
||||||
self::DATE_RANGE => new lang_string('filterrange', 'core_reportbuilder'),
|
self::DATE_RANGE => new lang_string('filterrange', 'core_reportbuilder'),
|
||||||
self::DATE_PREVIOUS => new lang_string('filterdateprevious', 'core_reportbuilder'),
|
self::DATE_LAST => new lang_string('filterdatelast', 'core_reportbuilder'),
|
||||||
self::DATE_CURRENT => new lang_string('filterdatecurrent', 'core_reportbuilder'),
|
self::DATE_CURRENT => new lang_string('filterdatecurrent', 'core_reportbuilder'),
|
||||||
self::DATE_NEXT => new lang_string('filterdatenext', 'core_reportbuilder'),
|
self::DATE_NEXT => new lang_string('filterdatenext', 'core_reportbuilder'),
|
||||||
];
|
];
|
||||||
@ -99,7 +102,7 @@ class date extends base {
|
|||||||
$mform->setType("{$this->name}_operator", PARAM_INT);
|
$mform->setType("{$this->name}_operator", PARAM_INT);
|
||||||
$mform->setDefault("{$this->name}_operator", self::DATE_ANY);
|
$mform->setDefault("{$this->name}_operator", self::DATE_ANY);
|
||||||
|
|
||||||
// Value selector for previous and next operators.
|
// Value selector for last and next operators.
|
||||||
$valuelabel = get_string('filterfieldvalue', 'core_reportbuilder', $this->get_header());
|
$valuelabel = get_string('filterfieldvalue', 'core_reportbuilder', $this->get_header());
|
||||||
|
|
||||||
$elements[] = $mform->createElement('text', "{$this->name}_value", $valuelabel, ['size' => 3]);
|
$elements[] = $mform->createElement('text', "{$this->name}_value", $valuelabel, ['size' => 3]);
|
||||||
@ -111,7 +114,7 @@ class date extends base {
|
|||||||
$mform->hideIf("{$this->name}_value", "{$this->name}_operator", 'eq', self::DATE_RANGE);
|
$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", 'eq', self::DATE_CURRENT);
|
||||||
|
|
||||||
// Unit selector for previous and next operators.
|
// Unit selector for last and next operators.
|
||||||
$unitlabel = get_string('filterdurationunit', 'core_reportbuilder', $this->get_header());
|
$unitlabel = get_string('filterdurationunit', 'core_reportbuilder', $this->get_header());
|
||||||
$units = [
|
$units = [
|
||||||
self::DATE_UNIT_DAY => get_string('filterdatedays', 'core_reportbuilder'),
|
self::DATE_UNIT_DAY => get_string('filterdatedays', 'core_reportbuilder'),
|
||||||
@ -187,11 +190,11 @@ class date extends base {
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
// Relative helper method can handle these three cases.
|
// Relative helper method can handle these three cases.
|
||||||
case self::DATE_PREVIOUS:
|
case self::DATE_LAST:
|
||||||
case self::DATE_CURRENT:
|
case self::DATE_CURRENT:
|
||||||
case self::DATE_NEXT:
|
case self::DATE_NEXT:
|
||||||
|
|
||||||
// Previous and next operators require a unit value greater than zero.
|
// Last and next operators require a unit value greater than zero.
|
||||||
if ($operator !== self::DATE_CURRENT && $dateunitvalue === 0) {
|
if ($operator !== self::DATE_CURRENT && $dateunitvalue === 0) {
|
||||||
return ['', []];
|
return ['', []];
|
||||||
}
|
}
|
||||||
@ -217,80 +220,65 @@ class date extends base {
|
|||||||
/**
|
/**
|
||||||
* Return start and end time of given relative date period
|
* Return start and end time of given relative date period
|
||||||
*
|
*
|
||||||
* @param int $operator
|
* @param int $operator One of the ::DATE_LAST/CURRENT/NEXT constants
|
||||||
* @param int $dateunitvalue
|
* @param int $dateunitvalue Unit multiplier of the date unit
|
||||||
* @param int $dateunit
|
* @param int $dateunit One of the ::DATE_UNIT_DAY/WEEK/MONTH/YEAR constants
|
||||||
* @return int[]
|
* @return int[] Timestamps representing the start/end of timeframe
|
||||||
*/
|
*/
|
||||||
private static function get_relative_timeframe(int $operator, int $dateunitvalue, int $dateunit): array {
|
private static function get_relative_timeframe(int $operator, int $dateunitvalue, int $dateunit): array {
|
||||||
$datenow = new DateTimeImmutable();
|
// Initialise start/end time to now.
|
||||||
|
$datestart = $dateend = new DateTimeImmutable();
|
||||||
|
|
||||||
switch ($dateunit) {
|
switch ($dateunit) {
|
||||||
case self::DATE_UNIT_DAY:
|
case self::DATE_UNIT_DAY:
|
||||||
// Current day.
|
if ($operator === self::DATE_CURRENT) {
|
||||||
$datestart = $dateend = $datenow;
|
$datestart = $datestart->setTime(0, 0);
|
||||||
|
$dateend = $dateend->setTime(23, 59, 59);
|
||||||
if ($operator === self::DATE_PREVIOUS) {
|
} else if ($operator === self::DATE_LAST) {
|
||||||
$datestart = $datestart->modify("-{$dateunitvalue} day");
|
$datestart = $datestart->modify("-{$dateunitvalue} day");
|
||||||
$dateend = $dateend->modify('-1 day');
|
|
||||||
} else if ($operator === self::DATE_NEXT) {
|
} else if ($operator === self::DATE_NEXT) {
|
||||||
$datestart = $datestart->modify('+1 day');
|
|
||||||
$dateend = $dateend->modify("+{$dateunitvalue} day");
|
$dateend = $dateend->modify("+{$dateunitvalue} day");
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case self::DATE_UNIT_WEEK:
|
case self::DATE_UNIT_WEEK:
|
||||||
// Current week.
|
if ($operator === self::DATE_CURRENT) {
|
||||||
$datestart = $datenow->modify('monday this week');
|
$datestart = $datestart->modify('monday this week')->setTime(0, 0);
|
||||||
$dateend = $datenow->modify('sunday this week');
|
$dateend = $dateend->modify('sunday this week')->setTime(23, 59, 59);
|
||||||
|
} else if ($operator === self::DATE_LAST) {
|
||||||
if ($operator === self::DATE_PREVIOUS) {
|
|
||||||
$datestart = $datestart->modify("-{$dateunitvalue} week");
|
$datestart = $datestart->modify("-{$dateunitvalue} week");
|
||||||
$dateend = $dateend->modify('-1 week');
|
|
||||||
} else if ($operator === self::DATE_NEXT) {
|
} else if ($operator === self::DATE_NEXT) {
|
||||||
$datestart = $datestart->modify('+1 week');
|
|
||||||
$dateend = $dateend->modify("+{$dateunitvalue} week");
|
$dateend = $dateend->modify("+{$dateunitvalue} week");
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case self::DATE_UNIT_MONTH:
|
case self::DATE_UNIT_MONTH:
|
||||||
// Current month.
|
if ($operator === self::DATE_CURRENT) {
|
||||||
$datestart = $datenow->modify('first day of this month');
|
$datestart = $datestart->modify('first day of this month')->setTime(0, 0);
|
||||||
$dateend = $datenow->modify('last day of this month');
|
$dateend = $dateend->modify('last day of this month')->setTime(23, 59, 59);
|
||||||
|
} else if ($operator === self::DATE_LAST) {
|
||||||
[$dateyear, $datemonth] = explode('/', $datenow->format('Y/m'));
|
$datestart = $datestart->modify("-{$dateunitvalue} month");
|
||||||
if ($operator === self::DATE_PREVIOUS) {
|
|
||||||
$datestart = $datestart->setDate((int) $dateyear, $datemonth - $dateunitvalue, 1);
|
|
||||||
$dateend = $dateend->modify('last day of last month');
|
|
||||||
} else if ($operator === self::DATE_NEXT) {
|
} else if ($operator === self::DATE_NEXT) {
|
||||||
$datestart = $datestart->modify('first day of next month');
|
$dateend = $dateend->modify("+{$dateunitvalue} month");
|
||||||
$dateend = $dateend->setDate((int) $dateyear, $datemonth + $dateunitvalue, 1)
|
|
||||||
->modify('last day of this month');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case self::DATE_UNIT_YEAR:
|
case self::DATE_UNIT_YEAR:
|
||||||
// Current year.
|
if ($operator === self::DATE_CURRENT) {
|
||||||
$datestart = $datenow->modify('first day of january this year');
|
$datestart = $datestart->modify('first day of january this year')->setTime(0, 0);
|
||||||
$dateend = $datenow->modify('last day of december this year');
|
$dateend = $dateend->modify('last day of december this year')->setTime(23, 59, 59);
|
||||||
|
} else if ($operator === self::DATE_LAST) {
|
||||||
$dateyear = (int) $datenow->format('Y');
|
$datestart = $datestart->modify("-{$dateunitvalue} year");
|
||||||
if ($operator === self::DATE_PREVIOUS) {
|
|
||||||
$datestart = $datestart->setDate($dateyear - $dateunitvalue, 1, 1);
|
|
||||||
$dateend = $dateend->modify('last day of december last year');
|
|
||||||
} else if ($operator === self::DATE_NEXT) {
|
} else if ($operator === self::DATE_NEXT) {
|
||||||
$datestart = $datestart->modify('first day of january next year');
|
$dateend = $dateend->modify("+{$dateunitvalue} year");
|
||||||
$dateend = $dateend->setDate($dateyear + $dateunitvalue, 12, 31);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
|
||||||
return [0, 0];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
$datestart->setTime(0, 0)->getTimestamp(),
|
$datestart->getTimestamp(),
|
||||||
$dateend->setTime(23, 59, 59)->getTimestamp(),
|
$dateend->getTimestamp(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -122,20 +122,28 @@ class date_test extends advanced_testcase {
|
|||||||
*/
|
*/
|
||||||
public function get_sql_filter_relative_provider(): array {
|
public function get_sql_filter_relative_provider(): array {
|
||||||
return [
|
return [
|
||||||
'Previous day' => [date::DATE_PREVIOUS, 1, date::DATE_UNIT_DAY, '-1 day'],
|
'Last day' => [date::DATE_LAST, 1, date::DATE_UNIT_DAY, '-6 hour'],
|
||||||
'Previous week' => [date::DATE_PREVIOUS, 1, date::DATE_UNIT_WEEK, '-1 week'],
|
'Last week' => [date::DATE_LAST, 1, date::DATE_UNIT_WEEK, '-3 day'],
|
||||||
'Previous month' => [date::DATE_PREVIOUS, 1, date::DATE_UNIT_MONTH, 'last day of last month'],
|
'Last month' => [date::DATE_LAST, 1, date::DATE_UNIT_MONTH, '-3 week'],
|
||||||
'Previous year' => [date::DATE_PREVIOUS, 1, date::DATE_UNIT_YEAR, 'last day of december last year'],
|
'Last year' => [date::DATE_LAST, 1, date::DATE_UNIT_YEAR, '-6 month'],
|
||||||
|
'Last two days' => [date::DATE_LAST, 2, date::DATE_UNIT_DAY, '-25 hour'],
|
||||||
|
'Last two weeks' => [date::DATE_LAST, 2, date::DATE_UNIT_WEEK, '-10 day'],
|
||||||
|
'Last two months' => [date::DATE_LAST, 2, date::DATE_UNIT_MONTH, '-7 week'],
|
||||||
|
'Last two years' => [date::DATE_LAST, 2, date::DATE_UNIT_YEAR, '-15 month'],
|
||||||
|
|
||||||
'Current day' => [date::DATE_CURRENT, null, date::DATE_UNIT_DAY],
|
'Current day' => [date::DATE_CURRENT, null, date::DATE_UNIT_DAY],
|
||||||
'Current week' => [date::DATE_CURRENT, null, date::DATE_UNIT_WEEK],
|
'Current week' => [date::DATE_CURRENT, null, date::DATE_UNIT_WEEK],
|
||||||
'Current month' => [date::DATE_CURRENT, null, date::DATE_UNIT_MONTH],
|
'Current month' => [date::DATE_CURRENT, null, date::DATE_UNIT_MONTH],
|
||||||
'Current year' => [date::DATE_CURRENT, null, date::DATE_UNIT_YEAR],
|
'Current year' => [date::DATE_CURRENT, null, date::DATE_UNIT_YEAR],
|
||||||
|
|
||||||
'Next day' => [date::DATE_NEXT, 1, date::DATE_UNIT_DAY, '+1 day'],
|
'Next day' => [date::DATE_NEXT, 1, date::DATE_UNIT_DAY, '+6 hour'],
|
||||||
'Next week' => [date::DATE_NEXT, 1, date::DATE_UNIT_WEEK, '+1 week'],
|
'Next week' => [date::DATE_NEXT, 1, date::DATE_UNIT_WEEK, '+3 day'],
|
||||||
'Next month' => [date::DATE_NEXT, 1, date::DATE_UNIT_MONTH, 'first day of next month'],
|
'Next month' => [date::DATE_NEXT, 1, date::DATE_UNIT_MONTH, '+3 week'],
|
||||||
'Next year' => [date::DATE_NEXT, 1, date::DATE_UNIT_YEAR, 'first day of january next year'],
|
'Next year' => [date::DATE_NEXT, 1, date::DATE_UNIT_YEAR, '+6 month'],
|
||||||
|
'Next two days' => [date::DATE_NEXT, 2, date::DATE_UNIT_DAY, '+25 hour'],
|
||||||
|
'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'],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user