From 82aa988db43c92f0e70ef625b2ba000cecdac89e Mon Sep 17 00:00:00 2001 From: Dmitrii Metelkin Date: Wed, 15 Aug 2018 12:48:38 +1000 Subject: [PATCH] Recursively check recurring date ranges (#185) --- element/daterange/classes/element.php | 41 +++++++++++++++++++-------- 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/element/daterange/classes/element.php b/element/daterange/classes/element.php index 3fcf03f..06ebf5d 100644 --- a/element/daterange/classes/element.php +++ b/element/daterange/classes/element.php @@ -133,7 +133,6 @@ class element extends \mod_customcert\element { $mform->setType('numranges', PARAM_INT); for ($i = 0; $i < $maxranges; $i++) { - $datarange = array(); $mform->addElement('static', $this->build_element_name('group', $i), @@ -433,15 +432,18 @@ class element extends \mod_customcert\element { $outputstring = ''; foreach ($this->get_decoded_data()->dateranges as $key => $range) { - if (!empty($range->recurring)) { - $range = $this->build_recurring_daterange($range); - } - - if ($date >= $range->startdate && $date <= $range->enddate) { + if ($this->is_date_in_range($date, $range)) { $rangematched = $range; $outputstring = $range->datestring; break; } + + if (!empty($range->recurring)) { + if ($rangematched = $this->get_matched_recurring_range($date, $range)) { + $outputstring = $rangematched->datestring; + break; + } + } } if (empty($outputstring) && !empty($this->get_decoded_data()->fallbackstring)) { @@ -452,24 +454,39 @@ class element extends \mod_customcert\element { } /** - * Build a recurring daterange by updating start and end dates if required. + * Check if the provided date is in the date range. * + * @param int $date Unix timestamp date to check. * @param \stdClass $range Range object. * - * @return \stdClass + * @return bool */ - protected function build_recurring_daterange(\stdClass $range) { - if ($range->enddate < time()) { + protected function is_date_in_range($date, \stdClass $range) { + return ($date >= $range->startdate && $date <= $range->enddate); + } + + /** + * Get recurring date range matched provided date. + * + * @param int $date Unix timestamp date to check. + * @param \stdClass $range Range object. + * + * @return \stdClass || null + */ + protected function get_matched_recurring_range($date, \stdClass $range) { + while ($range->enddate < time()) { $startyear = date('Y', $range->startdate) + 1; // Max recurring period is 12 months. $endyear = date('Y', $range->enddate) + 1; // Max recurring period is 12 months. $range->startdate = strtotime(date('d.m.', $range->startdate) . $startyear); $range->enddate = strtotime(date('d.m.', $range->enddate) . $endyear); - $range = $this->build_recurring_daterange($range); + if ($this->is_date_in_range($date, $range)) { + return $range; + } } - return $range; + return null; } /**