From 5464dec0570c2451d8607bc739c6f2b6f298bb75 Mon Sep 17 00:00:00 2001 From: Sarah Hoffmann Date: Sun, 31 Jul 2016 21:04:33 +0200 Subject: [PATCH] factor out parameter parsing into its own class Allows to use the parsing functions in website/search.php and utils/query.php as well. --- lib/Geocode.php | 194 ++++++++++++++++++++-------------------- lib/ParameterParser.php | 133 +++++++++++++++++++++++++++ lib/init-website.php | 91 ++++++++++++++++++- lib/lib.php | 56 ------------ lib/website.php | 140 ----------------------------- utils/query.php | 79 ++++++++-------- website/deletable.php | 2 +- website/details.php | 17 ++-- website/hierarchy.php | 16 ++-- website/lookup.php | 18 ++-- website/polygons.php | 10 ++- website/reverse.php | 43 +++++---- website/search.php | 36 ++++---- 13 files changed, 434 insertions(+), 401 deletions(-) create mode 100644 lib/ParameterParser.php delete mode 100644 lib/website.php diff --git a/lib/Geocode.php b/lib/Geocode.php index 9249b314..b102c4b2 100644 --- a/lib/Geocode.php +++ b/lib/Geocode.php @@ -33,9 +33,9 @@ protected $bBoundedSearch = false; protected $aViewBox = false; + protected $sViewboxCentreSQL = false; protected $sViewboxSmallSQL = false; protected $sViewboxLargeSQL = false; - protected $aRoutePoints = false; protected $iMaxRank = 20; protected $iMinAddressRank = 0; @@ -114,7 +114,7 @@ if ($iLimit < 1) $iLimit = 1; $this->iFinalLimit = $iLimit; - $this->iLimit = $this->iFinalLimit + min($this->iFinalLimit, 10); + $this->iLimit = $iLimit + min($iLimit, 10); } function getExcludedPlaceIDs() @@ -122,11 +122,6 @@ return $this->aExcludePlaceIDs; } - function setViewBox($fLeft, $fBottom, $fRight, $fTop) - { - $this->aViewBox = array($fLeft, $fBottom, $fRight, $fTop); - } - function getViewBoxString() { if (!$this->aViewBox) return null; @@ -158,6 +153,43 @@ $this->iMaxAddressRank = $iMax; } + function setRoute($aRoutePoints, $fRouteWidth) + { + $this->aViewBox = false; + + $this->sViewboxCentreSQL = "ST_SetSRID('LINESTRING("; + $sSep = ''; + foreach($this->aRoutePoints as $aPoint) + { + $fPoint = (float)$aPoint; + $this->sViewboxCentreSQL .= $sSep.$fPoint; + $sSep = ($sSep == ' ') ? ',' : ' '; + } + $this->sViewboxCentreSQL .= ")'::geometry,4326)"; + + $this->sViewboxSmallSQL = 'st_buffer('.$this->sViewboxCentreSQL; + $this->sViewboxSmallSQL .= ','.($fRouteWidth/69).')'; + + $this->sViewboxLargeSQL = 'st_buffer('.$this->sViewboxCentreSQL; + $this->sViewboxLargeSQL .= ','.($fRouteWidth/30).')'; + } + + function setViewbox($aViewbox) + { + $this->aViewBox = array_map('floatval', $aViewbox); + + $fHeight = $this->aViewBox[0] - $this->aViewBox[2]; + $fWidth = $this->aViewBox[1] - $this->aViewBox[3]; + $aBigViewBox[0] = $this->aViewBox[0] + $fHeight; + $aBigViewBox[2] = $this->aViewBox[2] - $fHeight; + $aBigViewBox[1] = $this->aViewBox[1] + $fWidth; + $aBigViewBox[3] = $this->aViewBox[3] - $fWidth; + + $this->sViewboxCentreSQL = false; + $this->sViewboxSmallSQL = "ST_SetSRID(ST_MakeBox2D(ST_Point(".$this->aViewBox[0].",".$this->aViewBox[1]."),ST_Point(".$this->aViewBox[2].",".$this->aViewBox[3].")),4326)"; + $this->sViewboxLargeSQL = "ST_SetSRID(ST_MakeBox2D(ST_Point(".$aBigViewBox[0].",".$aBigViewBox[1]."),ST_Point(".$aBigViewBox[2].",".$aBigViewBox[3].")),4326)"; + } + function setNearPoint($aNearPoint, $fRadiusDeg = 0.1) { $this->aNearPoint = array((float)$aNearPoint[0], (float)$aNearPoint[1], (float)$fRadiusDeg); @@ -175,24 +207,28 @@ } - function loadParamArray($aParams) + function loadParamArray($oParams) { - if (isset($aParams['addressdetails'])) $this->bIncludeAddressDetails = (bool)$aParams['addressdetails']; - if (isset($aParams['extratags'])) $this->bIncludeExtraTags = (bool)$aParams['extratags']; - if (isset($aParams['namedetails'])) $this->bIncludeNameDetails = (bool)$aParams['namedetails']; + $this->bIncludeAddressDetails = $oParams->getBool('addressdetails', + $this->bIncludeAddressDetails); + $this->bIncludeExtraTags = $oParams->getBool('extratags', + $this->bIncludeExtraTags); + $this->bIncludeNameDetails = $oParams->getBool('namedetails', + $this->bIncludeNameDetails); - if (isset($aParams['bounded'])) $this->bBoundedSearch = (bool)$aParams['bounded']; - if (isset($aParams['dedupe'])) $this->bDeDupe = (bool)$aParams['dedupe']; + $this->bBoundedSearch = $oParams->getBool('bounded', $this->bBoundedSearch); + $this->bDeDupe = $oParams->getBool('dedupe', $this->bDeDupe); - if (isset($aParams['limit'])) $this->setLimit((int)$aParams['limit']); - if (isset($aParams['offset'])) $this->iOffset = (int)$aParams['offset']; + $this->setLimit($oParams->getInt('limit', $this->iFinalLimit)); + $this->iOffset = $oParams->getInt('offset', $this->iOffset); - if (isset($aParams['fallback'])) $this->bFallback = (bool)$aParams['fallback']; + $this->bFallback = $oParams->getBool('fallback', $this->bFallback); // List of excluded Place IDs - used for more acurate pageing - if (isset($aParams['exclude_place_ids']) && $aParams['exclude_place_ids']) + $sExcluded = $oParams->getStringList('exclude_place_ids'); + if ($sExcluded) { - foreach(explode(',',$aParams['exclude_place_ids']) as $iExcludedPlaceID) + foreach($sExcluded as $iExcludedPlaceID) { $iExcludedPlaceID = (int)$iExcludedPlaceID; if ($iExcludedPlaceID) @@ -204,66 +240,63 @@ } // Only certain ranks of feature - if (isset($aParams['featureType'])) $this->setFeatureType($aParams['featureType']); - if (isset($aParams['featuretype'])) $this->setFeatureType($aParams['featuretype']); + $sFeatureType = $oParams->getString('featureType'); + if (!$sFeatureType) $sFeatureType = $oParams->getString('featuretype'); + if ($sFeatureType) $this->setFeatureType($sFeatureType); // Country code list - if (isset($aParams['countrycodes'])) + $sCountries = $oParams->getStringList('countrycodes'); + if ($sCountries) { - $aCountryCodes = array(); - foreach(explode(',',$aParams['countrycodes']) as $sCountryCode) + foreach($sCountries as $sCountryCode) { if (preg_match('/^[a-zA-Z][a-zA-Z]$/', $sCountryCode)) { - $aCountryCodes[] = strtolower($sCountryCode); + $aCountries[] = strtolower($sCountryCode); } } - $this->aCountryCodes = $aCountryCodes; + if (isset($aCountryCodes)) + $this->aCountryCodes = $aCountries; } - if (isset($aParams['viewboxlbrt']) && $aParams['viewboxlbrt']) + $aViewbox = $oParams->getStringList('viewboxlbrt'); + if ($aViewbox) { - $aCoOrdinatesLBRT = explode(',',$aParams['viewboxlbrt']); - $this->setViewBox($aCoOrdinatesLBRT[0], $aCoOrdinatesLBRT[1], $aCoOrdinatesLBRT[2], $aCoOrdinatesLBRT[3]); + $this->setViewbox($aViewbox); } - else if (isset($aParams['viewbox']) && $aParams['viewbox']) - { - $aCoOrdinatesLTRB = explode(',',$aParams['viewbox']); - $this->setViewBox($aCoOrdinatesLTRB[0], $aCoOrdinatesLTRB[3], $aCoOrdinatesLTRB[2], $aCoOrdinatesLTRB[1]); - } - - if (isset($aParams['route']) && $aParams['route'] && isset($aParams['routewidth']) && $aParams['routewidth']) + else { - $aPoints = explode(',',$aParams['route']); - if (sizeof($aPoints) % 2 != 0) + $aViewbox = $oParams->getStringList('viewbox'); + if ($aViewbox) { - userError("Uneven number of points"); - exit; + $this->setViewBox(array($aViewbox[0], $aViewbox[3], + $aViewbox[2], $aViewbox[1])); } - $fPrevCoord = false; - $aRoute = array(); - foreach($aPoints as $i => $fPoint) + else { - if ($i%2) - { - $aRoute[] = array((float)$fPoint, $fPrevCoord); - } - else + $aRoute = $oParams->getStringList('route'); + $fRouteWidth = $oParams->getFloat('routewidth'); + if ($aRoute && $fRouteWidth) { - $fPrevCoord = (float)$fPoint; + $this->setRoute($aRoute, $fRouteWidth); } } - $this->aRoutePoints = $aRoute; } } - function setQueryFromParams($aParams) + function setQueryFromParams($oParams) { // Search query - $sQuery = (isset($aParams['q'])?trim($aParams['q']):''); + $sQuery = $oParams->getString('q'); if (!$sQuery) { - $this->setStructuredQuery(@$aParams['amenity'], @$aParams['street'], @$aParams['city'], @$aParams['county'], @$aParams['state'], @$aParams['country'], @$aParams['postalcode']); + $this->setStructuredQuery($oParams->getString('amenity'), + $oParams->getString('street'), + $oParams->getString('city'), + $oParams->getString('county'), + $oParams->getString('state'), + $oParams->getString('country'), + $oParams->getString('postalcode')); $this->setReverseInPlan(false); } else @@ -783,7 +816,7 @@ $sLanguagePrefArraySQL = "ARRAY[".join(',',array_map("getDBQuoted",$this->aLangPrefOrder))."]"; $sCountryCodesSQL = false; - if ($this->aCountryCodes && sizeof($this->aCountryCodes)) + if ($this->aCountryCodes) { $sCountryCodesSQL = join(',', array_map('addQuotes', $this->aCountryCodes)); } @@ -798,46 +831,17 @@ $sQuery = preg_replace('/(^|,)\s*la\s*(,|$)/','\1louisiana\2', $sQuery); } - // View Box SQL - $sViewboxCentreSQL = false; - $bBoundingBoxSearch = false; - if ($this->aViewBox) - { - $fHeight = $this->aViewBox[0]-$this->aViewBox[2]; - $fWidth = $this->aViewBox[1]-$this->aViewBox[3]; - $aBigViewBox[0] = $this->aViewBox[0] + $fHeight; - $aBigViewBox[2] = $this->aViewBox[2] - $fHeight; - $aBigViewBox[1] = $this->aViewBox[1] + $fWidth; - $aBigViewBox[3] = $this->aViewBox[3] - $fWidth; - - $this->sViewboxSmallSQL = "ST_SetSRID(ST_MakeBox2D(ST_Point(".(float)$this->aViewBox[0].",".(float)$this->aViewBox[1]."),ST_Point(".(float)$this->aViewBox[2].",".(float)$this->aViewBox[3].")),4326)"; - $this->sViewboxLargeSQL = "ST_SetSRID(ST_MakeBox2D(ST_Point(".(float)$aBigViewBox[0].",".(float)$aBigViewBox[1]."),ST_Point(".(float)$aBigViewBox[2].",".(float)$aBigViewBox[3].")),4326)"; - $bBoundingBoxSearch = $this->bBoundedSearch; - } - - // Route SQL - if ($this->aRoutePoints) + $bBoundingBoxSearch = $this->bBoundedSearch && $this->sViewboxSmallSQL; + if ($this->sViewboxCentreSQL) { - $sViewboxCentreSQL = "ST_SetSRID('LINESTRING("; - $bFirst = true; - foreach($this->aRoutePoints as $aPoint) - { - if (!$bFirst) $sViewboxCentreSQL .= ","; - $sViewboxCentreSQL .= $aPoint[0].' '.$aPoint[1]; - $bFirst = false; - } - $sViewboxCentreSQL .= ")'::geometry,4326)"; - - $sSQL = "select st_buffer(".$sViewboxCentreSQL.",".(float)($_GET['routewidth']/69).")"; - $this->sViewboxSmallSQL = chksql($this->oDB->getOne($sSQL), - "Could not get small viewbox."); - $this->sViewboxSmallSQL = "'".$this->sViewboxSmallSQL."'::geometry"; - - $sSQL = "select st_buffer(".$sViewboxCentreSQL.",".(float)($_GET['routewidth']/30).")"; - $this->sViewboxLargeSQL = chksql($this->oDB->getOne($sSQL), - "Could not get large viewbox."); - $this->sViewboxLargeSQL = "'".$this->sViewboxLargeSQL."'::geometry"; - $bBoundingBoxSearch = $this->bBoundedSearch; + // For complex viewboxes (routes) precompute the bounding geometry + $sGeom = chksql($this->oDB->getOne("select ".$this->sViewboxSmallSQL), + "Could not get small viewbox"); + $this->sViewboxSmallSQL = "'".$sGeom."'::geometry"; + + $sGeom = chksql($this->oDB->getOne("select ".$this->sViewboxLargeSQL), + "Could not get large viewbox"); + $this->sViewboxLargeSQL = "'".$sGeom."'::geometry"; } // Do we have anything that looks like a lat/lon pair? @@ -1224,7 +1228,7 @@ { $sSQL .= " and place_id not in (".join(',',$this->aExcludePlaceIDs).")"; } - if ($sViewboxCentreSQL) $sSQL .= " order by st_distance($sViewboxCentreSQL, ct.centroid) asc"; + if ($this->sViewboxCentreSQL) $sSQL .= " order by st_distance($this->sViewboxCentreSQL, ct.centroid) asc"; $sSQL .= " limit $this->iLimit"; if (CONST_Debug) var_dump($sSQL); $aPlaceIDs = chksql($this->oDB->getCol($sSQL)); @@ -1239,7 +1243,7 @@ if ($sCountryCodesSQL) $sSQL .= " join placex using (place_id)"; $sSQL .= " where st_contains($this->sViewboxLargeSQL, ct.centroid)"; if ($sCountryCodesSQL) $sSQL .= " and calculated_country_code in ($sCountryCodesSQL)"; - if ($sViewboxCentreSQL) $sSQL .= " order by st_distance($sViewboxCentreSQL, ct.centroid) asc"; + if ($this->sViewboxCentreSQL) $sSQL .= " order by st_distance($this->sViewboxCentreSQL, ct.centroid) asc"; $sSQL .= " limit $this->iLimit"; if (CONST_Debug) var_dump($sSQL); $aPlaceIDs = chksql($this->oDB->getCol($sSQL)); @@ -1250,7 +1254,7 @@ $sSQL = "select place_id from placex where class='".$aSearch['sClass']."' and type='".$aSearch['sType']."'"; $sSQL .= " and st_contains($this->sViewboxSmallSQL, geometry) and linked_place_id is null"; if ($sCountryCodesSQL) $sSQL .= " and calculated_country_code in ($sCountryCodesSQL)"; - if ($sViewboxCentreSQL) $sSQL .= " order by st_distance($sViewboxCentreSQL, centroid) asc"; + if ($this->sViewboxCentreSQL) $sSQL .= " order by st_distance($this->sViewboxCentreSQL, centroid) asc"; $sSQL .= " limit $this->iLimit"; if (CONST_Debug) var_dump($sSQL); $aPlaceIDs = chksql($this->oDB->getCol($sSQL)); diff --git a/lib/ParameterParser.php b/lib/ParameterParser.php new file mode 100644 index 00000000..95a3281b --- /dev/null +++ b/lib/ParameterParser.php @@ -0,0 +1,133 @@ +aParams = ($aParams === NULL) ? $_GET : $aParams; + } + + function getBool($sName, $bDefault=false) + { + if (!isset($this->aParams[$sName]) || strlen($this->aParams[$sName]) == 0) + { + return $bDefault; + } + + return (bool) $this->aParams[$sName]; + } + + function getInt($sName, $bDefault=false) + { + if (!isset($this->aParams[$sName]) || strlen($this->aParams[$sName]) == 0) + { + return $bDefault; + } + + if (!preg_match('/^[+-]?[0-9]+$/', $this->aParams[$sName])) + { + userError("Integer number expected for parameter '$sName'"); + } + + return (int) $this->aParams[$sName]; + } + + function getFloat($sName, $bDefault=false) + { + if (!isset($this->aParams[$sName]) || strlen($this->aParams[$sName]) == 0) + { + return $bDefault; + } + + if (!preg_match('/^[+-]?[0-9]*\.?[0-9]+$/', $this->aParams[$sName])) + { + userError("Floating-point number expected for parameter '$sName'"); + } + + return (float) $this->aParams[$sName]; + } + + function getString($sName, $bDefault=false) + { + if (!isset($this->aParams[$sName]) || strlen($this->aParams[$sName]) == 0) + { + return $bDefault; + } + + return $this->aParams[$sName]; + } + + function getSet($sName, $aValues, $sDefault=false) + { + if (!isset($this->aParams[$sName]) || strlen($this->aParams[$sName]) == 0) + { + return $sDefault; + } + + if (!in_array($this->aParams[$sName], $aValues)) + { + userError("Parameter '$sName' must be one of: ".join(', ', $aValues)); + } + + return $this->aParams[$sName]; + } + + function getStringList($sName, $aDefault=false) + { + $sValue = $this->getString($sName); + + if ($sValue) + { + return explode(',', $sValue); + } + + return $aDefault; + } + + function getPreferredLanguages($sFallback=NULL) + { + if ($sFallback === NULL && isset($_SERVER["HTTP_ACCEPT_LANGUAGE"])) + { + $sFallback = $_SERVER["HTTP_ACCEPT_LANGUAGE"]; + } + + $aLanguages = array(); + $sLangString = $this->getString('accept-language', $sFallback); + + if ($sLangString) + { + if (preg_match_all('/(([a-z]{1,8})(-[a-z]{1,8})?)\s*(;\s*q\s*=\s*(1|0\.[0-9]+))?/i', $sLangString, $aLanguagesParse, PREG_SET_ORDER)) + { + foreach($aLanguagesParse as $iLang => $aLanguage) + { + $aLanguages[$aLanguage[1]] = isset($aLanguage[5])?(float)$aLanguage[5]:1 - ($iLang/100); + if (!isset($aLanguages[$aLanguage[2]])) $aLanguages[$aLanguage[2]] = $aLanguages[$aLanguage[1]]/10; + } + arsort($aLanguages); + } + } + if (!sizeof($aLanguages) && CONST_Default_Language) + { + $aLanguages[CONST_Default_Language] = 1; + } + + foreach($aLanguages as $sLanguage => $fLanguagePref) + { + $aLangPrefOrder['short_name:'.$sLanguage] = 'short_name:'.$sLanguage; + $aLangPrefOrder['name:'.$sLanguage] = 'name:'.$sLanguage; + } + $aLangPrefOrder['short_name'] = 'short_name'; + $aLangPrefOrder['name'] = 'name'; + $aLangPrefOrder['brand'] = 'brand'; + foreach($aLanguages as $sLanguage => $fLanguagePref) + { + $aLangPrefOrder['official_name:'.$sLanguage] = 'official_name:'.$sLanguage; + } + $aLangPrefOrder['official_name'] = 'official_name'; + $aLangPrefOrder['ref'] = 'ref'; + $aLangPrefOrder['type'] = 'type'; + return $aLangPrefOrder; + } +} diff --git a/lib/init-website.php b/lib/init-website.php index 61a41731..9d66a9ac 100644 --- a/lib/init-website.php +++ b/lib/init-website.php @@ -1,6 +1,93 @@ getMessage(); + + echo << + Internal Server Error + +

Internal Server Error

+

Nominatim has encountered an internal error while accessing the database. + This may happen because the database is broken or because of a bug in + the software. If you think it is a bug, feel free to report + it over on + Github. Please include the URL that caused the problem and the + complete error details below.

+

Message: $sMsg

+

SQL Error: $sSqlError

+

Details:

+INTERNALFAIL;
+
+		if (CONST_Debug)
+		{
+			var_dump($oSql);
+		}
+		else
+		{
+			echo "
\n".$oSql->getUserInfo()."
"; + } + + echo "

"; + exit; + } + + function failInternalError($sError, $sSQL = false, $vDumpVar = false) + { + header('HTTP/1.0 500 Internal Server Error'); + header('Content-type: text/html; charset=utf-8'); + echo "

Internal Server Error

"; + echo '

Nominatim has encountered an internal error while processing your request. This is most likely because of a bug in the software.

'; + echo "

Details: ".$sError,"

"; + echo '

Feel free to file an issue on Github. Please include the error message above and the URL you used.

'; + if (CONST_Debug) + { + echo "

Debugging Information


"; + if ($sSQL) + { + echo "

SQL query

".$sSQL.""; + } + if ($vDumpVar) + { + echo "

Result

"; + var_dump($vDumpVar); + echo ""; + } + } + echo "\n\n"; + exit; + } + + + function userError($sError) + { + header('HTTP/1.0 400 Bad Request'); + header('Content-type: text/html; charset=utf-8'); + echo "

Bad Request

"; + echo '

Nominatim has encountered an error with your request.

'; + echo "

Details: ".$sError."

"; + echo '

If you feel this error is incorrect feel file an issue on Github. Please include the error message above and the URL you used.

'; + echo "\n\n"; + exit; + } + + +/*************************************************************************** + * HTTP Reply header setup + */ if (CONST_NoAccessControl) { @@ -13,5 +100,5 @@ } if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') exit; - header('Content-type: text/html; charset=utf-8'); + if (CONST_Debug) header('Content-type: text/html; charset=utf-8'); diff --git a/lib/lib.php b/lib/lib.php index 94bed6d8..3aa80e80 100644 --- a/lib/lib.php +++ b/lib/lib.php @@ -50,62 +50,6 @@ } - function getPreferredLanguages($sLangString=false) - { - if (!$sLangString) - { - // If we have been provided the value in $_GET it overrides browser value - if (isset($_GET['accept-language']) && $_GET['accept-language']) - { - $_SERVER["HTTP_ACCEPT_LANGUAGE"] = $_GET['accept-language']; - $sLangString = $_GET['accept-language']; - } - else if (isset($_SERVER["HTTP_ACCEPT_LANGUAGE"])) - { - $sLangString = $_SERVER["HTTP_ACCEPT_LANGUAGE"]; - } - } - - $aLanguages = array(); - if ($sLangString) - { - if (preg_match_all('/(([a-z]{1,8})(-[a-z]{1,8})?)\s*(;\s*q\s*=\s*(1|0\.[0-9]+))?/i', $sLangString, $aLanguagesParse, PREG_SET_ORDER)) - { - foreach($aLanguagesParse as $iLang => $aLanguage) - { - $aLanguages[$aLanguage[1]] = isset($aLanguage[5])?(float)$aLanguage[5]:1 - ($iLang/100); - if (!isset($aLanguages[$aLanguage[2]])) $aLanguages[$aLanguage[2]] = $aLanguages[$aLanguage[1]]/10; - } - arsort($aLanguages); - } - } - if (!sizeof($aLanguages) && CONST_Default_Language) $aLanguages = array(CONST_Default_Language=>1); - foreach($aLanguages as $sLangauge => $fLangauagePref) - { - $aLangPrefOrder['short_name:'.$sLangauge] = 'short_name:'.$sLangauge; - } - foreach($aLanguages as $sLangauge => $fLangauagePref) - { - $aLangPrefOrder['name:'.$sLangauge] = 'name:'.$sLangauge; - } - foreach($aLanguages as $sLangauge => $fLangauagePref) - { - $aLangPrefOrder['place_name:'.$sLangauge] = 'place_name:'.$sLangauge; - } - foreach($aLanguages as $sLangauge => $fLangauagePref) - { - $aLangPrefOrder['official_name:'.$sLangauge] = 'official_name:'.$sLangauge; - } - $aLangPrefOrder['short_name'] = 'short_name'; - $aLangPrefOrder['name'] = 'name'; - $aLangPrefOrder['place_name'] = 'place_name'; - $aLangPrefOrder['official_name'] = 'official_name'; - $aLangPrefOrder['ref'] = 'ref'; - $aLangPrefOrder['type'] = 'type'; - return $aLangPrefOrder; - } - - function getWordSets($aWords, $iDepth) { $aResult = array(array(join(' ',$aWords))); diff --git a/lib/website.php b/lib/website.php deleted file mode 100644 index a6afb698..00000000 --- a/lib/website.php +++ /dev/null @@ -1,140 +0,0 @@ -getMessage(); - - echo << - Internal Server Error - -

Internal Server Error

-

Nominatim has encountered an internal error while accessing the database. - This may happen because the database is broken or because of a bug in - the software. If you think it is a bug, feel free to report - it over on - Github. Please include the URL that caused the problem and the - complete error details below.

-

Message: $sMsg

-

SQL Error: $sSqlError

-

Details:

-INTERNALFAIL;
-
-		if (CONST_Debug)
-		{
-			var_dump($oSql);
-		}
-		else
-		{
-			echo "
\n".$oSql->getUserInfo()."
"; - } - - echo "

"; - exit; - } - - function failInternalError($sError, $sSQL = false, $vDumpVar = false) - { - header('HTTP/1.0 500 Internal Server Error'); - header('Content-type: text/html; charset=utf-8'); - echo "

Internal Server Error

"; - echo '

Nominatim has encountered an internal error while processing your request. This is most likely because of a bug in the software.

'; - echo "

Details: ".$sError,"

"; - echo '

Feel free to file an issue on Github. Please include the error message above and the URL you used.

'; - if (CONST_Debug) - { - echo "

Debugging Information


"; - if ($sSQL) - { - echo "

SQL query

".$sSQL.""; - } - if ($vDumpVar) - { - echo "

Result

"; - var_dump($vDumpVar); - echo ""; - } - } - echo "\n\n"; - exit; - } - - - function userError($sError) - { - header('HTTP/1.0 400 Bad Request'); - header('Content-type: text/html; charset=utf-8'); - echo "

Bad Request

"; - echo '

Nominatim has encountered an error with your request.

'; - echo "

Details: ".$sError."

"; - echo '

If you feel this error is incorrect feel file an issue on Github. Please include the error message above and the URL you used.

'; - echo "\n\n"; - exit; - } - - -/*************************************************************************** - * - * Functions for parsing URL parameters - * - */ - - function getParamBool($sName, $bDefault=false) - { - if (!isset($_GET[$sName]) || strlen($_GET[$sName]) == 0) return $bDefault; - - return (bool) $_GET[$sName]; - } - - function getParamInt($sName, $bDefault=false) - { - if (!isset($_GET[$sName]) || strlen($_GET[$sName]) == 0) return $bDefault; - - if (!preg_match('/^[+-]?[0-9]+$/', $_GET[$sName])) - { - userError("Integer number expected for parameter '$sName'"); - } - - return (int) $_GET[$sName]; - } - - function getParamFloat($sName, $bDefault=false) - { - if (!isset($_GET[$sName]) || strlen($_GET[$sName]) == 0) return $bDefault; - - if (!preg_match('/^[+-]?[0-9]*\.?[0-9]+$/', $_GET[$sName])) - { - userError("Floating-point number expected for parameter '$sName'"); - } - - return (float) $_GET[$sName]; - } - - function getParamString($sName, $bDefault=false) - { - if (!isset($_GET[$sName]) || strlen($_GET[$sName]) == 0) return $bDefault; - - return $_GET[$sName]; - } - - function getParamSet($sName, $aValues, $sDefault=false) - { - if (!isset($_GET[$sName]) || strlen($_GET[$sName]) == 0) return $sDefault; - - if (!in_array($_GET[$sName], $aValues)) - { - userError("Parameter '$sName' must be one of: ".join(', ', $aValues)); - } - - return $_GET[$sName]; - } diff --git a/utils/query.php b/utils/query.php index 919486ad..a3f51f74 100755 --- a/utils/query.php +++ b/utils/query.php @@ -4,6 +4,7 @@ require_once(dirname(dirname(__FILE__)).'/settings/settings.php'); require_once(CONST_BasePath.'/lib/init-cmd.php'); require_once(CONST_BasePath.'/lib/Geocode.php'); + require_once(CONST_BasePath.'/lib/ParameterParser.php'); ini_set('memory_limit', '800M'); $aCMDOptions = array( @@ -12,45 +13,43 @@ array('quiet', 'q', 0, 1, 0, 0, 'bool', 'Quiet output'), array('verbose', 'v', 0, 1, 0, 0, 'bool', 'Verbose output'), - array('search', '', 0, 1, 1, 1, 'string', 'Search for given term or coordinate'), - - array('accept-language', '', 0, 1, 1, 1, 'string', 'Preferred language order for showing search results'), - array('bounded', '', 0, 1, 0, 0, 'bool', 'Restrict results to given viewbox'), - array('nodedupe', '', 0, 1, 0, 0, 'bool', 'Do not remove duplicate results'), - array('limit', '', 0, 1, 1, 1, 'int', 'Maximum number of results returned (default: 10)'), - array('exclude_place_ids', '', 0, 1, 1, 1, 'string', 'Comma-separated list of place ids to exclude from results'), - array('featureType', '', 0, 1, 1, 1, 'string', 'Restrict results to certain features (country, state,city,settlement)'), - array('countrycodes', '', 0, 1, 1, 1, 'string', 'Comma-separated list of countries to restrict search to'), - array('viewbox', '', 0, 1, 1, 1, 'string', 'Prefer results in given view box') - ); - getCmdOpt($_SERVER['argv'], $aCMDOptions, $aCMDResult, true, true); - - $oDB =& getDB(); - - if (isset($aCMDResult['search']) && $aCMDResult['search']) - { - if (isset($aCMDResult['bounded'])) $aCMDResult['bounded'] = 'true'; - if (isset($aCMDResult['nodedupe'])) $aCMDResult['dedupe'] = 'false'; - - $oGeocode = new Geocode($oDB); - if (isset($aCMDResult['accept-language']) && $aCMDResult['accept-language']) - $oGeocode->setLanguagePreference(getPreferredLanguages($aCMDResult['accept-language'])); - else - $oGeocode->setLanguagePreference(getPreferredLanguages()); - $oGeocode->loadParamArray($aCMDResult); - $oGeocode->setQuery($aCMDResult['search']); - - $aSearchResults = $oGeocode->lookup(); - - if (version_compare(phpversion(), "5.4.0", '<')) - echo json_encode($aSearchResults); - else - echo json_encode($aSearchResults, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)."\n"; - } - else - { - showUsage($aCMDOptions, true); - } - + array('search', '', 0, 1, 1, 1, 'string', 'Search for given term or coordinate'), + + array('accept-language', '', 0, 1, 1, 1, 'string', 'Preferred language order for showing search results'), + array('bounded', '', 0, 1, 0, 0, 'bool', 'Restrict results to given viewbox'), + array('nodedupe', '', 0, 1, 0, 0, 'bool', 'Do not remove duplicate results'), + array('limit', '', 0, 1, 1, 1, 'int', 'Maximum number of results returned (default: 10)'), + array('exclude_place_ids', '', 0, 1, 1, 1, 'string', 'Comma-separated list of place ids to exclude from results'), + array('featureType', '', 0, 1, 1, 1, 'string', 'Restrict results to certain features (country, state,city,settlement)'), + array('countrycodes', '', 0, 1, 1, 1, 'string', 'Comma-separated list of countries to restrict search to'), + array('viewbox', '', 0, 1, 1, 1, 'string', 'Prefer results in given view box') + ); + getCmdOpt($_SERVER['argv'], $aCMDOptions, $aCMDResult, true, true); + + $oDB =& getDB(); + $oParams = new ParameterParser($aCMDResult); + + if ($oParams->getBool('search')) + { + if (isset($aCMDResult['nodedupe'])) $aCMDResult['dedupe'] = 'false'; + + $oGeocode = new Geocode($oDB); + + $oGeocode->setLanguagePreference($oParams->getPreferredLanguages(false)); + $oGeocode->loadParamArray($oParams); + $oGeocode->setQuery($aCMDResult['search']); + + $aSearchResults = $oGeocode->lookup(); + + if (version_compare(phpversion(), "5.4.0", '<')) + echo json_encode($aSearchResults); + else + echo json_encode($aSearchResults, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)."\n"; + } + else + { + showUsage($aCMDOptions, true); + } + diff --git a/website/deletable.php b/website/deletable.php index 95a2ec00..c55cb20f 100755 --- a/website/deletable.php +++ b/website/deletable.php @@ -3,9 +3,9 @@ require_once(CONST_BasePath.'/lib/init-website.php'); require_once(CONST_BasePath.'/lib/log.php'); require_once(CONST_BasePath.'/lib/output.php'); + ini_set('memory_limit', '200M'); $sOutputFormat = 'html'; - ini_set('memory_limit', '200M'); $oDB =& getDB(); diff --git a/website/details.php b/website/details.php index 10cd07e1..10490097 100755 --- a/website/details.php +++ b/website/details.php @@ -5,19 +5,20 @@ require_once(CONST_BasePath.'/lib/init-website.php'); require_once(CONST_BasePath.'/lib/log.php'); require_once(CONST_BasePath.'/lib/output.php'); + ini_set('memory_limit', '200M'); + + $oParams = new ParameterParser(); $sOutputFormat = 'html'; + $aLangPrefOrder = $oParams->getPreferredLanguages(); + $sLanguagePrefArraySQL = "ARRAY[".join(',',array_map("getDBQuoted",$aLangPrefOrder))."]"; - ini_set('memory_limit', '200M'); + $sPlaceId = $oParams->getString('place_id'); + $sOsmType = $oParams->getSet('osmtype', array('N', 'W', 'R')); + $iOsmId = $oParams->getInt('osmid', -1); $oDB =& getDB(); - $aLangPrefOrder = getPreferredLanguages(); - $sLanguagePrefArraySQL = "ARRAY[".join(',',array_map("getDBQuoted",$aLangPrefOrder))."]"; - - $sPlaceId = getParamString('place_id'); - $sOsmType = getParamSet('osmtype', array('N', 'W', 'R')); - $iOsmId = getParamInt('osmid', -1); if ($sOsmType && $iOsmId > 0) { $sPlaceId = chksql($oDB->getOne("select place_id from placex where osm_type = '".$sOsmType."' and osm_id = ".$iOsmId." order by type = 'postcode' asc")); @@ -125,7 +126,7 @@ $aPlaceSearchNameKeywords = false; $aPlaceSearchAddressKeywords = false; - if (getParamBool('keywords')) + if ($oParams->getBool('keywords')) { $sSQL = "select * from search_name where place_id = $iPlaceID"; $aPlaceSearchName = $oDB->getRow($sSQL); diff --git a/website/hierarchy.php b/website/hierarchy.php index 28a56f00..60d77d6a 100755 --- a/website/hierarchy.php +++ b/website/hierarchy.php @@ -8,16 +8,18 @@ require_once(CONST_BasePath.'/lib/output.php'); ini_set('memory_limit', '200M'); - $oDB =& getDB(); - - $sOutputFormat = getParamSet('format', array('html', 'json'), 'html'); + $oParams = new ParameterParser(); - $aLangPrefOrder = getPreferredLanguages(); + $sOutputFormat = $oParams->getSet('format', array('html', 'json'), 'html'); + $aLangPrefOrder = $oParams->getPreferredLanguages(); $sLanguagePrefArraySQL = "ARRAY[".join(',',array_map("getDBQuoted",$aLangPrefOrder))."]"; - $sPlaceId = getParamString('place_id'); - $sOsmType = getParamSet('osmtype', array('N', 'W', 'R')); - $iOsmId = getParamInt('osmid', -1); + $sPlaceId = $oParams->getString('place_id'); + $sOsmType = $oParams->getSet('osmtype', array('N', 'W', 'R')); + $iOsmId = $oParams->getInt('osmid', -1); + + $oDB =& getDB(); + if ($sOsmType && $iOsmId > 0) { $sPlaceId = chksql($oDB->getOne("select place_id from placex where osm_type = '".$sOsmType."' and osm_id = ".$iOsmId." order by type = 'postcode' asc")); diff --git a/website/lookup.php b/website/lookup.php index 5fc6c309..0129f217 100755 --- a/website/lookup.php +++ b/website/lookup.php @@ -6,15 +6,17 @@ require_once(CONST_BasePath.'/lib/log.php'); require_once(CONST_BasePath.'/lib/PlaceLookup.php'); require_once(CONST_BasePath.'/lib/output.php'); - - $oDB =& getDB(); ini_set('memory_limit', '200M'); + $oParams = new ParameterParser(); + // Format for output - $sOutputFormat = getParamSet('format', array('xml', 'json'), 'xml'); + $sOutputFormat = $oParams->getSet('format', array('xml', 'json'), 'xml'); // Preferred language - $aLangPrefOrder = getPreferredLanguages(); + $aLangPrefOrder = $oParams->getPreferredLanguages(); + + $oDB =& getDB(); $hLog = logStart($oDB, 'place', $_SERVER['QUERY_STRING'], $aLangPrefOrder); @@ -23,11 +25,11 @@ $oPlaceLookup = new PlaceLookup($oDB); $oPlaceLookup->setLanguagePreference($aLangPrefOrder); - $oPlaceLookup->setIncludeAddressDetails(getParamBool('addressdetails', true)); - $oPlaceLookup->setIncludeExtraTags(getParamBool('extratags', false)); - $oPlaceLookup->setIncludeNameDetails(getParamBool('namedetails', false)); + $oPlaceLookup->setIncludeAddressDetails($oParams->getBool('addressdetails', true)); + $oPlaceLookup->setIncludeExtraTags($oParams->getBool('extratags', false)); + $oPlaceLookup->setIncludeNameDetails($oParams->getBool('namedetails', false)); - $aOsmIds = explode(',', getParamString('osm_ids', '')); + $aOsmIds = explode(',', $oParams->getString('osm_ids', '')); if (count($aOsmIds) > CONST_Places_Max_ID_count) { diff --git a/website/polygons.php b/website/polygons.php index b855214a..1e0f5f7e 100755 --- a/website/polygons.php +++ b/website/polygons.php @@ -5,12 +5,14 @@ require_once(CONST_BasePath.'/lib/output.php'); ini_set('memory_limit', '200M'); - $oDB =& getDB(); + $oParams = new ParameterParser(); $sOutputFormat = 'html'; - $iDays = getParamInt('days', 1); - $bReduced = getParamBool('reduced', false); - $sClass = getParamString('class', false); + $iDays = $oParams->getInt('days', 1); + $bReduced = $oParams->getBool('reduced', false); + $sClass = $oParams->getString('class', false); + + $oDB =& getDB(); $iTotalBroken = (int) chksql($oDB->getOne('select count(*) from import_polygon_error')); diff --git a/website/reverse.php b/website/reverse.php index f7c01860..50ce4787 100755 --- a/website/reverse.php +++ b/website/reverse.php @@ -7,11 +7,14 @@ require_once(CONST_BasePath.'/lib/PlaceLookup.php'); require_once(CONST_BasePath.'/lib/ReverseGeocode.php'); require_once(CONST_BasePath.'/lib/output.php'); + ini_set('memory_limit', '200M'); + + $oParams = new ParameterParser(); - $bAsGeoJSON = getParamBool('polygon_geojson'); - $bAsKML = getParamBool('polygon_kml'); - $bAsSVG = getParamBool('polygon_svg'); - $bAsText = getParamBool('polygon_text'); + $bAsGeoJSON = $oParams->getBool('polygon_geojson'); + $bAsKML = $oParams->getBool('polygon_kml'); + $bAsSVG = $oParams->getBool('polygon_svg'); + $bAsText = $oParams->getBool('polygon_text'); if ((($bAsGeoJSON?1:0) + ($bAsKML?1:0) + ($bAsSVG?1:0) + ($bAsText?1:0)) > CONST_PolygonOutput_MaximumTypes) { @@ -23,36 +26,32 @@ { userError("Polygon output is disabled"); } - exit; } - // Polygon simplification threshold (optional) - $fThreshold = getParamFloat('polygon_threshold', 0.0); - - - $oDB =& getDB(); - ini_set('memory_limit', '200M'); + $fThreshold = $oParams->getFloat('polygon_threshold', 0.0); // Format for output - $sOutputFormat = getParamSet('format', array('html', 'xml', 'json', 'jsonv2'), 'xml'); + $sOutputFormat = $oParams->getSet('format', array('html', 'xml', 'json', 'jsonv2'), 'xml'); // Preferred language - $aLangPrefOrder = getPreferredLanguages(); + $aLangPrefOrder = $oParams->getPreferredLanguages(); + + $oDB =& getDB(); $hLog = logStart($oDB, 'reverse', $_SERVER['QUERY_STRING'], $aLangPrefOrder); $oPlaceLookup = new PlaceLookup($oDB); $oPlaceLookup->setLanguagePreference($aLangPrefOrder); - $oPlaceLookup->setIncludeAddressDetails(getParamBool('addressdetails', true)); - $oPlaceLookup->setIncludeExtraTags(getParamBool('extratags', false)); - $oPlaceLookup->setIncludeNameDetails(getParamBool('namedetails', false)); - - $sOsmType = getParamSet('osm_type', array('N', 'W', 'R')); - $iOsmId = getParamInt('osm_id', -1); - $fLat = getParamFloat('lat'); - $fLon = getParamFloat('lon'); + $oPlaceLookup->setIncludeAddressDetails($oParams->getBool('addressdetails', true)); + $oPlaceLookup->setIncludeExtraTags($oParams->getBool('extratags', false)); + $oPlaceLookup->setIncludeNameDetails($oParams->getBool('namedetails', false)); + + $sOsmType = $oParams->getSet('osm_type', array('N', 'W', 'R')); + $iOsmId = $oParams->getInt('osm_id', -1); + $fLat = $oParams->getFloat('lat'); + $fLon = $oParams->getFloat('lon'); if ($sOsmType && $iOsmId > 0) { $aPlace = $oPlaceLookup->lookupOSMID($sOsmType, $iOsmId); @@ -60,7 +59,7 @@ else if ($fLat !== false && $fLon !== false) { $oReverseGeocode = new ReverseGeocode($oDB); - $oReverseGeocode->setZoom(getParamInt('zoom', 18)); + $oReverseGeocode->setZoom($oParams->getInt('zoom', 18)); $aLookup = $oReverseGeocode->lookup($fLat, $fLon); if (CONST_Debug) var_dump($aLookup); diff --git a/website/search.php b/website/search.php index 4c283d1a..cff9bb37 100755 --- a/website/search.php +++ b/website/search.php @@ -6,14 +6,14 @@ require_once(CONST_BasePath.'/lib/log.php'); require_once(CONST_BasePath.'/lib/Geocode.php'); require_once(CONST_BasePath.'/lib/output.php'); - ini_set('memory_limit', '200M'); $oDB =& getDB(); + $oParams = new ParameterParser(); $oGeocode = new Geocode($oDB); - $aLangPrefOrder = getPreferredLanguages(); + $aLangPrefOrder = $oParams->getPreferredLanguages(); $oGeocode->setLanguagePreference($aLangPrefOrder); if (CONST_Search_ReversePlanForAll @@ -26,21 +26,21 @@ } // Format for output - $sOutputFormat = getParamSet('format', array('html', 'xml', 'json', 'jsonv2'), 'html'); + $sOutputFormat = $oParams->getSet('format', array('html', 'xml', 'json', 'jsonv2'), 'html'); // Show / use polygons if ($sOutputFormat == 'html') { - $oGeocode->setIncludePolygonAsText(getParamBool('polygon')); + $oGeocode->setIncludePolygonAsText($oParams->getBool('polygon')); $bAsText = false; } else { - $bAsPoints = getParamBool('polygon'); - $bAsGeoJSON = getParamBool('polygon_geojson'); - $bAsKML = getParamBool('polygon_kml'); - $bAsSVG = getParamBool('polygon_svg'); - $bAsText = getParamBool('polygon_text'); + $bAsPoints = $oParams->getBool('polygon'); + $bAsGeoJSON = $oParams->getBool('polygon_geojson'); + $bAsKML = $oParams->getBool('polygon_kml'); + $bAsSVG = $oParams->getBool('polygon_svg'); + $bAsText = $oParams->getBool('polygon_text'); if ( ( ($bAsGeoJSON?1:0) + ($bAsKML?1:0) + ($bAsSVG?1:0) @@ -66,9 +66,9 @@ } // Polygon simplification threshold (optional) - $oGeocode->setPolygonSimplificationThreshold(getParamFloat('polygon_threshold', 0.0)); + $oGeocode->setPolygonSimplificationThreshold($oParams->getFloat('polygon_threshold', 0.0)); - $oGeocode->loadParamArray($_GET); + $oGeocode->loadParamArray($oParams); if (CONST_Search_BatchMode && isset($_GET['batch'])) { @@ -77,8 +77,9 @@ foreach($aBatch as $aBatchParams) { $oBatchGeocode = clone $oGeocode; - $oBatchGeocode->loadParamArray($aBatchParams); - $oBatchGeocode->setQueryFromParams($aBatchParams); + $oBatchParams = new ParameterParser($aBatchParams); + $oBatchGeocode->loadParamArray($oBatchParams); + $oBatchGeocode->setQueryFromParams($oBatchParams); $aSearchResults = $oBatchGeocode->lookup(); $aBatchResults[] = $aSearchResults; } @@ -86,7 +87,10 @@ exit; } - if (!getParamString('q') && isset($_SERVER['PATH_INFO']) && $_SERVER['PATH_INFO'][0] == '/') + $oGeocode->setQueryFromParams($oParams); + + if (!$oGeocode->getQueryString() + && isset($_SERVER['PATH_INFO']) && $_SERVER['PATH_INFO'][0] == '/') { $sQuery = substr(rawurldecode($_SERVER['PATH_INFO']), 1); @@ -96,10 +100,6 @@ $sQuery = join(', ',$aPhrases); $oGeocode->setQuery($sQuery); } - else - { - $oGeocode->setQueryFromParams($_GET); - } $hLog = logStart($oDB, 'search', $oGeocode->getQueryString(), $aLangPrefOrder); -- 2.45.1