Skip to content

Commit 0111bf8

Browse files
authored
Parse geo URIs (#189)
* Add function to parse geo into mf * Remove duplicate code * Final parsing fixes * Bump version
1 parent d098e0b commit 0111bf8

File tree

5 files changed

+96
-40
lines changed

5 files changed

+96
-40
lines changed

includes/class-micropub-endpoint.php

Lines changed: 72 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,17 @@ protected static function load_input( $request ) {
167167
}
168168
static::log_error( static::$input, 'Micropub Input' );
169169
}
170+
171+
if ( isset( static::$input['properties'] ) ) {
172+
$properties = static::$input['properties'];
173+
if ( isset( $properties['location'] ) ) {
174+
static::$input['properties']['location'] = self::parse_geo_uri( $properties['location'][0] );
175+
}
176+
if ( isset( $properties['checkin'] ) ) {
177+
static::$input['properties']['checkin'] = self::parse_geo_uri( $properties['checkin'][0] );
178+
}
179+
}
180+
170181
static::$input = apply_filters( 'before_micropub', static::$input );
171182
}
172183

@@ -775,7 +786,7 @@ public static function default_file_handler( $post_id ) {
775786
public static function store_geodata( $args ) {
776787
$properties = static::get( static::$input, 'properties' );
777788
$location = static::get( $properties, 'location', static::get( $properties, 'checkin' ) );
778-
$location = static::get( $location, 0, null );
789+
$location = static::get( $location, 0, $location );
779790
// Location-visibility is an experimental property https://indieweb.org/Micropub-extensions#Location_Visibility
780791
// It attempts to mimic the geo_public property
781792
$visibility = static::get( $properties, 'location-visibility', null );
@@ -807,6 +818,7 @@ public static function store_geodata( $args ) {
807818
if ( ! isset( $args['meta_input'] ) ) {
808819
$args['meta_input'] = array();
809820
}
821+
// $location = self::parse_geo_uri( $location );
810822
if ( is_array( $location ) ) {
811823
$props = $location['properties'];
812824
if ( isset( $props['geo'] ) ) {
@@ -834,44 +846,72 @@ function( $v ) {
834846
$args['meta_input']['geo_latitude'] = $props['latitude'][0];
835847
$args['meta_input']['geo_longitude'] = $props['longitude'][0];
836848
$args['meta_input']['geo_altitude'] = $props['altitude'][0];
837-
} elseif ( 'geo:' === substr( $location, 0, 4 ) ) {
838-
// Geo URI format:
839-
// http://en.wikipedia.org/wiki/Geo_URI#Example
840-
// https://indieweb.org/Micropub#h-entry
841-
//
842-
// e.g. geo:37.786971,-122.399677;u=35
843-
$geo = explode( ':', substr( urldecode( $location ), 4 ) );
844-
$geo = explode( ';', $geo[0] );
845-
$coords = explode( ',', $geo[0] );
846-
$args['meta_input']['geo_latitude'] = trim( $coords[0] );
847-
$args['meta_input']['geo_longitude'] = trim( $coords[1] );
848-
// Geo URI optionally allows for altitude to be stored as a third csv
849-
if ( isset( $coords[2] ) ) {
850-
$args['meta_input']['geo_altitude'] = trim( $coords[2] );
851-
}
852-
// Store additional parameters
853-
array_shift( $geo ); // Remove coordinates to check for other parameters
854-
$params = array();
855-
foreach ( $geo as $g ) {
856-
$g = explode( '=', $g );
857-
$params[ $g[0] ] = $g[1];
858-
}
859-
$args['meta_input']['geo'] = $params;
860-
if ( array_key_exists( 'u', $params ) ) {
861-
$args['meta_input']['geo_accuracy'] = $params['u'];
862-
}
863-
if ( array_key_exists( 'name', $params ) ) {
864-
$args['meta_input']['geo_address'] = $params['name'];
865-
} elseif ( array_key_exists( 'label', $params ) ) {
866-
$args['meta_input']['geo_address'] = $params['label'];
867-
}
849+
$args['meta_input']['geo_accuracy'] = $props['accuracy'][0];
868850
} elseif ( 'http' !== substr( $location, 0, 4 ) ) {
869851
$args['meta_input']['geo_address'] = $location;
870852
}
871853
}
872854
return $args;
873855
}
874856

857+
/**
858+
* Parse a GEO URI into an mf2 object for storage
859+
*/
860+
public static function parse_geo_uri( $uri ) {
861+
if ( ! is_string( $uri ) ) {
862+
return $uri;
863+
}
864+
// Ensure this is a geo uri
865+
if ( 'geo:' !== substr( $uri, 0, 4 ) ) {
866+
return $uri;
867+
}
868+
$properties = array();
869+
// Geo URI format:
870+
// http://en.wikipedia.org/wiki/Geo_URI#Example
871+
// https://indieweb.org/Micropub#h-entry
872+
//
873+
// e.g. geo:37.786971,-122.399677;u=35
874+
$geo = str_replace( 'geo:', '', urldecode( $uri ) );
875+
$geo = explode( ';', $geo );
876+
$coords = explode( ',', $geo[0] );
877+
$properties['latitude'] = array( trim( $coords[0] ) );
878+
$properties['longitude'] = array( trim( $coords[1] ) );
879+
// Geo URI optionally allows for altitude to be stored as a third csv
880+
if ( isset( $coords[2] ) ) {
881+
$properties['altitude'] = array( trim( $coords[2] ) );
882+
}
883+
// Store additional parameters
884+
array_shift( $geo ); // Remove coordinates to check for other parameters
885+
foreach ( $geo as $g ) {
886+
$g = explode( '=', $g );
887+
if ( 'u' === $g[0] ) {
888+
$g[0] = 'accuracy';
889+
}
890+
$properties[ $g[0] ] = array( $g[1] );
891+
}
892+
// If geo URI is overloaded h-card... e.g. geo:37.786971,-122.399677;u=35;h=card;name=Home;url=https://example.com
893+
if ( array_key_exists( 'h', $return ) ) {
894+
$type = array( 'h-' . $properties['h'][0] );
895+
unset( $properties['h'] );
896+
} else {
897+
$diff = array_diff(
898+
array_keys( $properties ),
899+
array( 'longitude', 'latitude', 'altitude', 'accuracy' )
900+
);
901+
// If empty that means this is a geo
902+
if ( empty( $diff ) ) {
903+
$type = array( 'h-geo' );
904+
} else {
905+
$type = array( 'h-card' );
906+
}
907+
}
908+
909+
return array(
910+
'type' => $type,
911+
'properties' => array_filter( $properties ),
912+
);
913+
}
914+
875915
/**
876916
* Store the return of the authorization endpoint as post metadata. Details:
877917
* https://tokens.indieauth.com/

micropub.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Author: Ryan Barrett
88
* Author URI: https://snarfed.org/
99
* Text Domain: micropub
10-
* Version: 2.0.7
10+
* Version: 2.0.8
1111
*/
1212

1313
/* See README for supported filters and actions.

readme.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,11 @@ into markdown and saved to readme.md.
212212
## Changelog
213213
214214
215-
### 2.0.7 (2018-02-18)
215+
### 2.0.8 (2019-03-08)
216+
* Parse geo URI into h-geo or h-card object
217+
218+
219+
### 2.0.7 (2019-02-18)
216220
* Update geo storage to fix accuracy storage as well as allow for name parameter and future parameters to be passed. Indigenous for Android now supports passing this
217221
218222

readme.txt

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ Contributors: indieweb, snarfed, dshanske
33
Tags: micropub, publish, indieweb, microformats
44
Requires at least: 4.7
55
Requires PHP: 5.3
6-
Tested up to: 5.0.3
7-
Stable tag: 2.0.7
6+
Tested up to: 5.1
7+
Stable tag: 2.0.8
88
License: CC0
99
License URI: http://creativecommons.org/publicdomain/zero/1.0/
1010
Donate link: -
@@ -207,7 +207,10 @@ into markdown and saved to readme.md.
207207

208208
== Changelog ==
209209

210-
= 2.0.7 (2018-02-18) =
210+
= 2.0.8 (2019-03-08) =
211+
* Parse geo URI into h-geo or h-card object
212+
213+
= 2.0.7 (2019-02-18) =
211214
* Update geo storage to fix accuracy storage as well as allow for name parameter and future parameters to be passed. Indigenous for Android now supports passing this
212215

213216
= 2.0.6 (2018-12-30) =

tests/test_endpoint.php

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class Micropub_Endpoint_Test extends WP_UnitTestCase {
1616
'summary' => 'my summary',
1717
'category' => array( 'tag1', 'tag4' ),
1818
'published' => '2016-01-01T04:01:23-08:00',
19-
'location' => 'geo:42.361,-71.092;u=25000',
19+
'location' => 'geo:42.361,-71.092,25000;u=25000',
2020
);
2121

2222
// JSON mf2 input
@@ -29,7 +29,7 @@ class Micropub_Endpoint_Test extends WP_UnitTestCase {
2929
'summary' => array( 'my summary' ),
3030
'category' => array( 'tag1', 'tag4' ),
3131
'published' => array( '2016-01-01T04:01:23-08:00' ),
32-
'location' => array( 'geo:42.361,-71.092;u=25000' ),
32+
'location' => array( 'geo:42.361,-71.092,25000;u=25000' ),
3333
),
3434
);
3535

@@ -51,6 +51,7 @@ class Micropub_Endpoint_Test extends WP_UnitTestCase {
5151
'latitude' => array( '42.361' ),
5252
'longitude' => array( '-71.092' ),
5353
'altitude' => array( '25000' ),
54+
'accuracy' => array( '25000' )
5455
),
5556
);
5657

@@ -101,6 +102,11 @@ public function setUp() {
101102
static::$scopes = array( 'post' );
102103
}
103104

105+
public function test_parse_geo_uri() {
106+
$geo = Micropub_Endpoint::parse_geo_uri( 'geo:42.361,-71.092,25000;u=25000' );
107+
$this->assertEquals( $geo, static::$geo );
108+
}
109+
104110

105111
public function test_register_routes() {
106112
$routes = rest_get_server()->get_routes();
@@ -196,6 +202,7 @@ public function check_create_basic( $request, $input = null ) {
196202
if ( ! $input ) {
197203
$input = static::$mf2;
198204
}
205+
199206
$post = $this->check_create( $request );
200207
$this->assertEquals( 'publish', $post->post_status );
201208
$this->assertEquals( 'post', $post->post_type );
@@ -212,7 +219,9 @@ public function check_create_basic( $request, $input = null ) {
212219
$this->assertEquals( '42.361', get_post_meta( $post->ID, 'geo_latitude', true ) );
213220
$this->assertEquals( '-71.092', get_post_meta( $post->ID, 'geo_longitude', true ) );
214221
$this->assertEquals( '', get_post_meta( $post->ID, 'geo_address', true ) );
215-
$this->assertEquals( $input, $this->query_source( $post->ID ) );
222+
$source = $this->query_source( $post->ID );
223+
$input['properties']['location'] = static::$geo;
224+
$this->assertEquals( $input, $source, wp_json_encode( $source ) );
216225
return $post;
217226
}
218227

0 commit comments

Comments
 (0)