Skip to content

Commit

Permalink
make parsing of numeric parameters more robust (#39)
Browse files Browse the repository at this point in the history
* make parsing of numeric parameters more robust

accepts now spaces between parameter name and =|:, between =|:  and number and integers instead of floats

* fix copy paste error

* require php 8.0 minimum

* fix formatting + style

* make parsing of numeric parameters more robust

accepts now spaces between parameter name and =|:, between =|:  and number and integers instead of floats

* fix copy paste error

* require php 8.0 minimum

* fix formatting + style

* Update plugin.info.txt

* Update geotag.php

* fix return type

---------

Co-authored-by: Mark Prins <1165786+mprins@users.noreply.github.com>
  • Loading branch information
e-dschungel and mprins authored Aug 24, 2024
1 parent 3c71dab commit 2029bb3
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 23 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
}
],
"require": {
"php": ">=7.4"
"php": ">=8.0"
},
"config": {
"platform": {
Expand Down
2 changes: 1 addition & 1 deletion plugin.info.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
base geotag
author Mark C. Prins
email mprins@users.sf.net
date 2023-07-14
date 2024-08-24
name geotag plugin
desc Allow a user to annotate pages with a geotag
url https://www.dokuwiki.org/plugin:geotag
70 changes: 49 additions & 21 deletions syntax/geotag.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

use dokuwiki\Extension\SyntaxPlugin;
use geoPHP\Geometry\Point;

Expand Down Expand Up @@ -72,9 +73,9 @@ final public function handle($match, $state, $pos, Doku_Handler $handler): array
{
$tags = trim(substr($match, 9, -2));
// parse geotag content
preg_match("(lat[:|=]-?\d*\.\d*)", $tags, $lat);
preg_match("(lon[:|=]-?\d*\.\d*)", $tags, $lon);
preg_match("(alt[:|=]-?\d*\.?\d*)", $tags, $alt);
$lat = $this->parseNumericParameter("lat", $tags);
$lon = $this->parseNumericParameter("lon", $tags);
$alt = $this->parseNumericParameter("alt", $tags);
preg_match("/(region[:|=][\p{L}\s\w'-]*)/u", $tags, $region);
preg_match("/(placename[:|=][\p{L}\s\w'-]*)/u", $tags, $placename);
preg_match("/(country[:|=][\p{L}\s\w'-]*)/u", $tags, $country);
Expand All @@ -98,20 +99,46 @@ final public function handle($match, $state, $pos, Doku_Handler $handler): array
} elseif (array_key_exists(0, $hide) && trim($hide [0]) === 'unhide') {
$style = '';
}
return [
hsc($lat),
hsc($lon),
hsc($alt),
$this->geohash($lat, $lon),
hsc(trim(substr(($region[0] ?? ''), 7))),
hsc(trim(substr(($placename[0] ?? ''), 10))),
hsc(trim(substr(($country [0] ?? ''), 8))),
hsc($showlocation), $style
];
}

$data = [hsc(trim(substr($lat [0], 4))), hsc(trim(substr($lon [0], 4))), hsc(trim(substr(($alt[0] ?? ''), 4))), $this->geohash(substr($lat [0], 4), substr($lon [0], 4)), hsc(trim(substr(($region[0] ?? ''), 7))), hsc(trim(substr(($placename[0] ?? ''), 10))), hsc(trim(substr(($country [0] ?? ''), 8))), hsc($showlocation), $style];
return $data;
/**
* parses numeric parameter with given name
*
* @param string $name name of the parameter
* @param string $input text to consume
* @return string parameter values as numeric string or empty string if nothing is found
*/
private function parseNumericParameter(string $name, string $input): string
{
$output = '';
$pattern = "/" . $name . "\s*[:=]\s*(-?\d*\.?\d*)/";
if (preg_match($pattern, $input, $matches)) {
$output = $matches[1];
}
return $output;
}

/**
* Calculate the geohash for this lat/lon pair.
*
* @param float $lat
* @param float $lon
* @return string
* @throws Exception
*/
private function geohash(float $lat, float $lon)
private function geohash(float $lat, float $lon): string
{
if (($geophp = plugin_load('helper', 'geophp')) === null) {
if ((plugin_load('helper', 'geophp')) === null) {
return "";
}

Expand Down Expand Up @@ -142,16 +169,16 @@ final public function render($format, Doku_Renderer $renderer, $data): bool
if ($this->getConf('geotag_prevent_microformat_render')) {
return true;
}
$searchPre = '';
$searchPre = '';
$searchPost = '';
if ($this->getConf('geotag_showsearch')) {
if (($spHelper = plugin_load('helper', 'spatialhelper_search')) !== null) {
$title = $this->getLang('findnearby') . '&nbsp;' . $placename;
$url = wl(
$title = $this->getLang('findnearby') . '&nbsp;' . $placename;
$url = wl(
getID(),
['do' => 'findnearby', 'lat' => $ddlat, 'lon' => $ddlon]
['do' => 'findnearby', 'lat' => $ddlat, 'lon' => $ddlon]
);
$searchPre = '<a href="' . $url . '" title="' . $title . '">';
$searchPre = '<a href="' . $url . '" title="' . $title . '">';
$searchPost = '<span class="a11y">' . $title . '</span></a>';
}
}
Expand All @@ -174,12 +201,12 @@ final public function render($format, Doku_Renderer $renderer, $data): bool
return true;
} elseif ($format === 'metadata') {
// render metadata (our action plugin will put it in the page head)
$renderer->meta ['geo'] ['lat'] = $ddlat;
$renderer->meta ['geo'] ['lon'] = $ddlon;
$renderer->meta ['geo'] ['lat'] = $ddlat;
$renderer->meta ['geo'] ['lon'] = $ddlon;
$renderer->meta ['geo'] ['placename'] = $placename;
$renderer->meta ['geo'] ['region'] = $region;
$renderer->meta ['geo'] ['country'] = $country;
$renderer->meta ['geo'] ['geohash'] = $geohash;
$renderer->meta ['geo'] ['region'] = $region;
$renderer->meta ['geo'] ['country'] = $country;
$renderer->meta ['geo'] ['geohash'] = $geohash;
if (!empty($alt)) {
$renderer->meta ['geo'] ['alt'] = $alt;
}
Expand All @@ -205,6 +232,7 @@ final public function render($format, Doku_Renderer $renderer, $data): bool
* convert latitude in decimal degrees to DMS+hemisphere.
*
* @param float $decimaldegrees
* @return string
* @todo move this into a shared library
*/
private function convertLat(float $decimaldegrees): string
Expand All @@ -227,11 +255,11 @@ private function convertLat(float $decimaldegrees): string
*/
private function convertDDtoDMS(float $decimaldegrees): string
{
$dms = floor($decimaldegrees);
$dms = floor($decimaldegrees);
$secs = ($decimaldegrees - $dms) * 3600;
$min = floor($secs / 60);
$sec = round($secs - ($min * 60), 3);
$dms .= 'º' . $min . '\'' . $sec . '"';
$min = floor($secs / 60);
$sec = round($secs - ($min * 60), 3);
$dms .= 'º' . $min . '\'' . $sec . '"';
return $dms;
}

Expand Down

0 comments on commit 2029bb3

Please sign in to comment.