diff --git a/langs/en/weather.json b/langs/en/weather.json index dbaf255..782fa87 100644 --- a/langs/en/weather.json +++ b/langs/en/weather.json @@ -4,5 +4,6 @@ "Temperature: {temp}{units}": "Temperature: {temp}{units}", "{temp}{units}": "{temp}{units}", "{tempLow} to {tempHigh}{units}": "{tempLow} to {tempHigh}{units}", - "Low: {tempLow}{units} High: {tempHigh}{units}": "Low: {tempLow}{units} | High: {tempHigh}{units}" + "Low: {tempLow}{units} High: {tempHigh}{units}": "Low: {tempLow}{units} | High: {tempHigh}{units}", + "Geolocate": "Geolocate" } diff --git a/lib/Weather.lib.php b/lib/Weather.lib.php index 9540520..a821e1c 100644 --- a/lib/Weather.lib.php +++ b/lib/Weather.lib.php @@ -28,7 +28,7 @@ abstract class Weather { * @global type $SETTINGS * @return boolean true if successful, false if not */ - public function setLocationByUserIP() { + public function setLocationByUserIP(): bool { global $SETTINGS; // Make sure we'll have a valid IP when testing on localhost if ($SETTINGS['debug'] && $_SERVER['REMOTE_ADDR'] == "127.0.0.1") { @@ -59,6 +59,24 @@ abstract class Weather { } } + /** + * Attempt to set the user's location based on sent cookies named "Latitude" + * and "Longitude". + * @return bool true if successful. + */ + public function setLocationByCookie(): bool { + if (!empty($_COOKIE['Latitude']) && !empty($_COOKIE['Longitude'])) { + $latlngregex = "/-?[0-9]{1,3}(\.[0-9]+)?/"; + if (preg_match($latlngregex, $_COOKIE['Latitude']) && preg_match($latlngregex, $_COOKIE['Longitude'])) { + $this->lat = $_COOKIE['Latitude'] * 1.0; + $this->lng = $_COOKIE['Longitude'] * 1.0; + return true; + } + return false; + } + return false; + } + abstract protected function loadForecast(); // Getters diff --git a/pages.php b/pages.php index 34e1107..1b9010c 100644 --- a/pages.php +++ b/pages.php @@ -15,6 +15,7 @@ define("PAGES", [ ], "scripts" => [ "static/Shuffle/dist/shuffle.min.js", + "static/js/locationcookie.js", "static/js/newsgrid.js", "static/js/home.js" ] @@ -36,6 +37,9 @@ define("PAGES", [ "styles" => [ "static/weather-icons/css/weather-icons.min.css" ], + "scripts" => [ + "static/js/locationcookie.js" + ] ], "404" => [ "title" => "404 error" diff --git a/pages/home.php b/pages/home.php index c42c084..a08e935 100644 --- a/pages/home.php +++ b/pages/home.php @@ -8,8 +8,12 @@ header("Link: ; rel=preload; as=image", false); $weatherclass = "Weather_" . $SETTINGS['sources']['weather']; -$weather = new $weatherclass(46.595, -112.027); // TODO: get user location -$weather->setLocationByUserIP(); +$lat = 46.595; +$lng = -112.027; +$weather = new $weatherclass($lat, $lng); +if (!$weather->setLocationByCookie()) { + $weather->setLocationByUserIP(); +} $weather->loadForecast(); $tempunits = "C"; @@ -112,13 +116,18 @@ foreach ($newsitems as $item) { K -
- getLocationName())) { - echo htmlentities($weather->getLocationName()) . " | "; - } - echo round($weather->getLatitude(), 2) . ", " . round($weather->getLongitude(), 2); - ?> +
+ + getLocationName())) { + echo htmlentities($weather->getLocationName()) . " | "; + } + echo round($weather->getLatitude(), 2) . ", " . round($weather->getLongitude(), 2); + ?> + + + get("Geolocate"); ?> +
diff --git a/pages/weather.php b/pages/weather.php index 261bcc2..51e14f7 100644 --- a/pages/weather.php +++ b/pages/weather.php @@ -6,8 +6,12 @@ */ $weatherclass = "Weather_" . $SETTINGS['sources']['weather']; -$weather = new $weatherclass(46.595, -112.027); // TODO: get user location -$weather->setLocationByUserIP(); +$lat = 46.595; +$lng = -112.027; +$weather = new $weatherclass($lat, $lng); +if (!$weather->setLocationByCookie()) { + $weather->setLocationByUserIP(); +} $weather->loadForecast(); $tempunits = "C"; @@ -112,13 +116,18 @@ if (!empty($_COOKIE['TemperatureUnitsPref']) && preg_match("/[FCK]/", $_COOKIE[' K -
- getLocationName())) { - echo htmlentities($weather->getLocationName()) . " | "; - } - echo round($weather->getLatitude(), 2) . ", " . round($weather->getLongitude(), 2); - ?> +
+ + getLocationName())) { + echo htmlentities($weather->getLocationName()) . " | "; + } + echo round($weather->getLatitude(), 2) . ", " . round($weather->getLongitude(), 2); + ?> + + + get("Geolocate"); ?> +
diff --git a/static/js/locationcookie.js b/static/js/locationcookie.js new file mode 100644 index 0000000..2ce944c --- /dev/null +++ b/static/js/locationcookie.js @@ -0,0 +1,21 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + + +function geolocateToCookie() { + navigator.geolocation.getCurrentPosition(function (pos) { + document.cookie = "Latitude=" + pos.coords.latitude.toFixed(2) + ";samesite=strict;max-age=" + (60 * 60 * 24 * 90); + document.cookie = "Longitude=" + pos.coords.longitude.toFixed(2) + ";samesite=strict;max-age=" + (60 * 60 * 24 * 90); + document.location.reload(); + }, function () { + alert("Could not determine location. Please note that your coordinates are rounded to approx. 1km before being sent to the server."); + }, { + timeout: 1000 * 60, + enableHighAccuracy: true + }); +} + +$("#geolocate-btn").click(geolocateToCookie); \ No newline at end of file