LGV_TZ_Lookup 1.4.2
Time zone lookup for PHP applications and HTTP clients
Loading...
Searching...
No Matches
index.php
Go to the documentation of this file.
1<?php
2/***************************************************************************************************************************/
3/**
4 © Copyright 2023-2026, [Little Green Viper Software Development LLC](https://littlegreenviper.com)
5
6 LICENSE:
7
8 MIT License
9
10 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
11 files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
12 modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
13 Software is furnished to do so, subject to the following conditions:
14
15 The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
16
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18 OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
20 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22 [Little Green Viper Software Development LLC](https://littlegreenviper.com)
23*/
24/***************************************************************************************************************************/
25/**
26 \brief This is the main entrypoint for the TZ Lookup Utility.
27
28 It needs to import a configuration file, with database information.
29
30 The configuration file needs to declare the following:
31
32 $g_dbName = "<DATABASE NAME>";
33 $g_dbUserName = "<DATABASE USERNAME>";
34 $g_dbPassword = "<DATABASE USER PASSWORD>";
35 $g_dbType = "<DATABASE TYPE>";
36 $g_dbHost = "<DATABASE HOST>";
37 $g_dbPort = "<DATABASE PORT>";
38
39 If this is left blank, or omitted, then anyone can access the server (may not be good). Otherwise, they need to include "&secret=<SERVER SECRET>", when calling.
40
41 $g_server_secret = "<SERVER SECRET>";
42
43 The server can be told to re-initialize the database, but that should only be done via command line.
44
45 Otherwise, a simple long/lat HTTP query will result in a string, containing the time zone that has that location.
46*/
47
48declare(strict_types = 1);
49
50// This is the location of the config file. It should generally be located outside the HTTP directory. Change the path below, to wherever you put the file.
51if (!defined('__CONFIG_FILE_')) {
52 define("__CONFIG_FILE_", __DIR__.'/../../../../TZInfo/config.php');
53}
54
55// The class that we use to make queries.
56require_once __DIR__.'/Sources/LGV_TZ_Lookup_Query.class.php';
57
58// The class that we use to run tests.
59require_once __DIR__.'/LGV_TZ_Lookup_Test.php';
60
61$queryString = isset($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : (isset($_SERVER['argv'][1]) ? implode('&', array_slice($_SERVER['argv'], 1)) : '');
62
63echo call_server($queryString, "cli" == php_sapi_name());
64
65/***************************************************************************************************************************/
66/**
67 This is the "home function" of the server.
68
69 \returns: The text of the run. Successful calls will result in a simple string. A successful load will result in 1, and other calls may return HTML.
70*/
71function call_server( $inQuery, ///< This is an ampersand-concatenated list of parameters, either from the query, or from the arguments.
72 $inIsCLI ///< This is true, if we are calling this from the command-line.
73 ) {
74 include __CONFIG_FILE_;
75 $ret = "";
76
77 if (!empty($inQuery)) {
78 $queries = [];
79 $path = $inIsCLI ? dirname($_SERVER['argv'][0]) : "";
80 if (!empty($inQuery)) {
81 $queryArray = explode('&', $inQuery);
82
83 foreach ($queryArray as $param) {
84 // Now, see if we have a bunch of parameters.
85 $key = trim($param);
86 $value = NULL;
87
88 $parts = explode('=', $param, 2);
89
90 if (1 < count($parts)) {
91 $key = trim($parts[0]);
92 $value = trim($parts[1]);
93 }
94
95 if (!empty($key)) {
96 if (empty($value)) {
97 $value = true;
98 }
99
100 $queries[$key] = $value;
101 }
102 }
103 }
104 if (!empty($queries)) {
105 $authorized = !isset($g_server_secret) || $g_server_secret === '' ||
106 (isset($queries['secret']) && is_string($queries['secret']) && hash_equals((string)$g_server_secret, $queries['secret']));
107 if ($authorized) {
108 $db_object = new LGV_TZ_Lookup_Database($g_dbName, $g_dbUserName, $g_dbPassword, $g_dbType, $g_dbHost, $g_dbPort);
109 if (isset($queries['test'])) { // Test trumps all
110 $ret = '<html><head><style>.pass{color:green}.fail{color:red}</style></head><body>'.test_server().'</body></html>';
111 } elseif (isset($queries['load'])) {
112 if ($inIsCLI) {
113 set_time_limit(180); // It can take a couple of minutes to load.
114 $stream = fopen("$path/combined-with-oceans.json", 'r');
115
116 try {
117 // The JSON parser is needed only for a boundary-file load.
118 require_once __DIR__.'/Sources/LGV_TZ_Lookup_Loader.class.php';
119 $listener = new LGV_TZ_Lookup_Loader($db_object);
120 $parser = new \JsonStreamingParser\Parser($stream, $listener);
121 $parser->parse();
122 fclose($stream);
123 $ret = '1';
124 } catch (Exception $e) {
125 fclose($stream);
126 $ret = '0';
127 }
128 } else {
129 $ret = 'Only Available Through CLI';
130 header('HTTP/1.1 403 Not Authorized');
131 }
132 } elseif (!empty($queries['ll'])) {
133 $long_lat = explode(',', $queries['ll']);
134 if (2 == count($long_lat) && isset($long_lat[0]) && isset($long_lat[1])) {
135 $lng = floatval($long_lat[0]);
136 $lat = floatval($long_lat[1]);
137
138 // Adjust for overflow.
139 while (-180 > $lng) { $lng += 360; }
140 while (180 < $lng) { $lng -= 360; }
141 while (-90 > $lat) { $lat += 180; }
142 while (90 < $lat) { $lat -= 180; }
143
144 $lookup = new LGV_TZ_Lookup_Query($db_object);
145 $ret = $lookup->get_tz($lng, $lat);
146 if (empty($ret)) {
147 return $ret;
148 }
149 } else {
150 $ret = 'Malformed Query';
151 header('HTTP/1.1 400 Malformed Query');
152 }
153 }
154 } elseif (isset($g_server_secret)) {
155 $ret = 'Ah - Ah - Aaaah! You didn\'t say the magic word!';
156 if ("cli" != php_sapi_name()) {
157 header('HTTP/1.1 403 Not Authorized');
158 }
159 } else {
160 $ret = 'Illegal Query';
161 if ("cli" != php_sapi_name()) {
162 header('HTTP/1.1 400 Illegal Query');
163 }
164 }
165 } else {
166 if (!$inIsCLI) {
167 $ret = 'Illegal Query';
168 header('HTTP/1.1 400 Illegal Query');
169 }
170 }
171 }
172
173 if (empty($ret)) {
174 if ($inIsCLI) {
175 $secret_note = isset($g_server_secret) && !empty($g_server_secret) ? "\n\n\tNOTE: This server has a \"secret\" set\n\n\tThis means that you will need to provide an additional string in each call. Please contact the administrator of this server to obtain the secret." : "";
176 $ret = "Usage: \$> php ".__FILE__." load\n\n\tInitializes the database from the GeoJSON file.\n\tIt will return 1, if successful, 0, if not. It may take some time.$secret_note\n";
177 } else {
178 $s = (isset($_SERVER['HTTPS']) && !empty($_SERVER['HTTPS'])) ? "s" : "";
179 $secret_note = isset($g_server_secret) && !empty($g_server_secret) ? "<em><h4>NOTE: This server has a \"secret\" set</h4><p>This means that you will need to provide an additional string in each call. Please contact the administrator of this server to obtain the secret.</p></em>" : "";
180 $ret = "<html><head><title>Using LGV_TZ_Lookup</title></head><body><pre>Usage: http$s://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']."?ll=<em style='color:gray'>&lt;LONG&gt;,&lt;LAT&gt;</em>\n\n\tThis is the standard query. Provide the requested long/lat, as comma-delimited floating-point numbers, between -180 and 180.\n\tThe response will be <a href='https://en.wikipedia.org/wiki/List_of_tz_database_time_zones'>the TZ name</a> of the timezone that contains that point. It will be a simple string.</pre>$secret_note</body></html>";
181 }
182 }
183
184 return $ret;
185}
$lookup
Definition composer.php:54
const __CONFIG_FILE_
Definition server.php:45
call_server( $inQuery, $inIsCLI)
Definition index.php:71
$queryString
Definition index.php:61