From c535ce5e2f78f5223662c97543f718334abf2a35 Mon Sep 17 00:00:00 2001 From: Christian Hofmaier Date: Tue, 8 Sep 2020 20:56:19 +0200 Subject: [locations] Migrate openingtimes from infoscreen to locations module - move openingtimes from infoscreen db to locations db - read-only openingtimes in infoscreen --- modules-available/locations/pages/details.inc.php | 177 ++++++++++++++++++++++ 1 file changed, 177 insertions(+) (limited to 'modules-available/locations/pages') diff --git a/modules-available/locations/pages/details.inc.php b/modules-available/locations/pages/details.inc.php index 81b58456..a55460cf 100644 --- a/modules-available/locations/pages/details.inc.php +++ b/modules-available/locations/pages/details.inc.php @@ -8,6 +8,9 @@ class SubPage if ($action === 'updatelocation') { self::updateLocation(); return true; + } else if ($action === 'updateOpeningtimes') { + self::updateOpeningTimes(); + return true; } return false; } @@ -22,10 +25,75 @@ class SubPage if ($action === 'showlocation') { self::ajaxShowLocation(); return true; + } elseif ($action === 'getOpeningtimes') { + $id = Request::any('locid', 0, 'int'); + self::ajaxOpeningTimes($id); + return true; } return false; } + private static function updateOpeningTimes() { + $openingTimes = Request::post('openingtimes', '', 'string'); + $locationid = Request::post('locationid', false, 'int'); + + User::assertPermission('location.edit', $locationid); + + // Construct opening-times for database + if ($openingTimes !== '') { + $openingTimes = json_decode($openingTimes, true); + if (!is_array($openingTimes)) { + $openingTimes = ''; + } else { + $mangled = array(); + foreach (array_keys($openingTimes) as $key) { + $entry = $openingTimes[$key]; + if (!isset($entry['days']) || !is_array($entry['days']) || empty($entry['days'])) { + Message::addError('ignored-line-no-days'); + continue; + } + $start = self::getTime($entry['openingtime']); + $end = self::getTime($entry['closingtime']); + if ($start === false) { + Message::addError('ignored-invalid-start', $entry['openingtime']); + continue; + } + if ($end === false) { + Message::addError('ignored-invalid-end', $entry['closingtime']); + continue; + } + if ($end <= $start) { + Message::addError('ignored-invalid-range', $entry['openingtime'], $entry['closingtime']); + continue; + } + unset($entry['tag']); + $mangled[] = $entry; + } + if (empty($mangled)) { + $openingTimes = null; + } else { + $openingTimes = json_encode($mangled); + } + } + } + // Check if opening-times changed + // $res = Database::queryFirst('SELECT openingtime FROM location WHERE locationid = :locationid', compact('locationid')); + // $otChanged = $res === false || $res['openingtime'] !== $openingTimes; + + Database::exec('UPDATE location SET openingtime = :openingtime WHERE locationid = :locationid', + array('locationid' => $locationid, 'openingtime' => $openingTimes)); + + return true; + } + + private static function getTime($str) + { + $str = explode(':', $str); + if (count($str) !== 2) return false; + if ($str[0] < 0 || $str[0] > 23 || $str[1] < 0 || $str[1] > 59) return false; + return $str[0] * 60 + $str[1]; + } + private static function updateLocation() { $locationId = Request::post('locationid', false, 'integer'); @@ -313,4 +381,113 @@ class SubPage echo Render::parse('location-subnets', $data); } + private static function ajaxOpeningTimes($id) { + User::assertPermission('location.edit', $id); + $openTimes = Database::queryFirst("SELECT openingtime FROM `location` WHERE locationid = :id", array('id' => $id)); + if ($openTimes !== false) { + $openingTimes = json_decode($openTimes['openingtime'], true); + } + if (!isset($openingTimes) || !is_array($openingTimes)) { + $openingTimes = array(); + } + $data = array('id' => $id); + $data['expertMode'] = !self::isSimpleMode($openingTimes); + $data['schedule_data'] = json_encode($openingTimes); + + echo Render::parse('ajax-opening-location', $data); + } + + private static function isSimpleMode(&$array) { + if (empty($array)) + return true; + // Decompose by day + $new = array(); + foreach ($array as $row) { + $s = self::getTime($row['openingtime']); + $e = self::getTime($row['closingtime']); + if ($s === false || $e === false || $e <= $s) + continue; + foreach ($row['days'] as $day) { + self::addDay($new, $day, $s, $e); + } + } + // Merge by timespan, but always keep saturday and sunday separate + $merged = array(); + foreach ($new as $day => $ranges) { + foreach ($ranges as $range) { + if ($day === 'Saturday' || $day === 'Sunday') { + $add = $day; + } else { + $add = ''; + } + $key = '#' . $range[0] . '#' . $range[1] . '#' . $add; + if (!isset($merged[$key])) { + $merged[$key] = array(); + } + $merged[$key][$day] = true; + } + } + // Check if it passes as simple mode + if (count($merged) > 3) + return false; + foreach ($merged as $days) { + if (count($days) === 5) { + $res = array_keys($days); + $res = array_intersect($res, array("Monday", "Tuesday", "Wednesday", "Thursday", "Friday")); + if (count($res) !== 5) + return false; + } elseif (count($days) === 1) { + if (!isset($days['Saturday']) && !isset($days['Sunday'])) { + return false; + } + } else { + return false; + } + } + // Valid simple mode, finally transform back to what we know + $new = array(); + foreach ($merged as $span => $days) { + preg_match('/^#(\d+)#(\d+)#/', $span, $out); + $new[] = array( + 'days' => array_keys($days), + 'openingtime' => floor($out[1] / 60) . ':' . ($out[1] % 60), + 'closingtime' => floor($out[2] / 60) . ':' . ($out[2] % 60), + ); + } + $array = $new; + return true; + } + + private static function addDay(&$array, $day, $s, $e) + { + if (!isset($array[$day])) { + $array[$day] = array(array($s, $e)); + return; + } + foreach (array_keys($array[$day]) as $key) { + $current = $array[$day][$key]; + if ($s <= $current[0] && $e >= $current[1]) { + // Fully dominated + unset($array[$day][$key]); + continue; // Might partially overlap with additional ranges, keep going + } + if ($current[0] <= $s && $current[1] >= $s) { + // $start lies within existing range + if ($current[0] <= $e && $current[1] >= $e) + return; // Fully in existing range, do nothing + // $end seems to extend range we're checking against but $start lies within this range, update and keep going + $s = $current[0]; + unset($array[$day][$key]); + continue; + } + // Last possibility: $start is before range, $end within range + if ($current[0] <= $e && $current[1] >= $e) { + // $start must lie before range start, otherwise we'd have hit the case above + $e = $current[1]; + unset($array[$day][$key]); + continue; + } + } + $array[$day][] = array($s, $e); + } } \ No newline at end of file -- cgit v1.2.3-55-g7522