Skip to content

Commit 6f89e72

Browse files
dshanskesnarfed
authored andcommitted
Add support for location-visibility altitude and accuracy
1 parent a9aaeda commit 6f89e72

File tree

2 files changed

+88
-5
lines changed

2 files changed

+88
-5
lines changed

micropub.php

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -893,13 +893,43 @@ public static function default_file_handler( $post_id ) {
893893
* https://ownyourswarm.p3k.io/docs#checkins
894894
*
895895
* WordPress geo data is stored in post meta: geo_address (free text),
896-
* geo_latitude, and geo_longitude:
896+
* geo_latitude, geo_longitude, and geo_public:
897897
* https://codex.wordpress.org/Geodata
898+
* It is noted that should the HTML5 style geolocation properties of altitude, accuracy, speed, and heading are
899+
* used they would use the same geo prefix. Simple Location stores these when available using accuracy to estimate
900+
* map zoom when displayed.
898901
*/
899902
public static function store_geodata( $args ) {
900903
$properties = static::get( static::$input, 'properties' );
901904
$location = static::get( $properties, 'location', static::get( $properties, 'checkin' ) );
902905
$location = static::get( $location, 0, null );
906+
// Location-visibility is an experimental property https://indieweb.org/Micropub-extensions#Location_Visibility
907+
// It attempts to mimic the geo_public property
908+
$visibility = static::get( $properties, 'location-visibility', null );
909+
if ( $visibility ) {
910+
$visibility = array_pop( $visibility );
911+
if ( ! isset( $args['meta_input'] ) ) {
912+
$args['meta_input'] = array();
913+
}
914+
switch ( $visibility ) {
915+
// Currently supported by https://github.com/dshanske/simple-location as part of the Geodata store noted in codex link above
916+
// Public indicates coordinates, map, and textual description displayed
917+
case 'public':
918+
$args['meta_input']['geo_public'] = 1;
919+
break;
920+
// Private indicates no display
921+
case 'private':
922+
$args['meta_input']['geo_public'] = 0;
923+
break;
924+
// Protected which is not in the original geodata spec is used by Simple Location to indicate textual description only
925+
case 'protected':
926+
$args['meta_input']['geo_public'] = 2;
927+
break;
928+
default:
929+
static::error( 400, 'unsupported location visibility ' . $visibility );
930+
931+
}
932+
}
903933
if ( $location ) {
904934
if ( ! isset( $args['meta_input'] ) ) {
905935
$args['meta_input'] = array();
@@ -928,17 +958,24 @@ public static function store_geodata( $args ) {
928958
}
929959
$args['meta_input']['geo_latitude'] = $props['latitude'][0];
930960
$args['meta_input']['geo_longitude'] = $props['longitude'][0];
961+
$args['meta_input']['geo_altitude'] = $props['altitude'][0];
931962
} elseif ( 'geo:' === substr( $location, 0, 4 ) ) {
932963
// Geo URI format:
933964
// http://en.wikipedia.org/wiki/Geo_URI#Example
934-
// https://indiewebcamp.com/micropub##location
965+
// https://indieweb.org/Micropub#h-entry
935966
//
936967
// e.g. geo:37.786971,-122.399677;u=35
937-
$geo = explode( ':', substr( urldecode( $location ), 4 ) );
938-
$geo = explode( ';', $geo[0] );
968+
$geo = explode( ':', substr( urldecode( $location ), 4 ) );
969+
$geo = explode( ';', $geo[0] );
970+
// Store the accuracy/uncertainty
971+
$args['meta_input']['geo_accuracy'] = substr( $geo[1], 2 );
939972
$coords = explode( ',', $geo[0] );
940973
$args['meta_input']['geo_latitude'] = trim( $coords[0] );
941974
$args['meta_input']['geo_longitude'] = trim( $coords[1] );
975+
// Geo URI optionally allows for altitude to be stored as a third csv
976+
if ( isset( $coords[2] ) ) {
977+
$args['meta_input']['geo_altitude'] = trim( $coords[2] );
978+
}
942979
} elseif ( 'http' !== substr( $location, 0, 4 ) ) {
943980
$args['meta_input']['geo_address'] = $location;
944981
}

tests/test_micropub.php

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,7 @@ function test_create_location_h_geo() {
504504

505505
$this->assertEquals( '42.361', get_post_meta( $post->ID, 'geo_latitude', true ) );
506506
$this->assertEquals( '-71.092', get_post_meta( $post->ID, 'geo_longitude', true ) );
507+
$this->assertEquals( '25000', get_post_meta( $post->ID, 'geo_altitude', true ) );
507508
$this->assertEquals( '', get_post_meta( $post->ID, 'geo_address', true ) );
508509
}
509510

@@ -525,17 +526,62 @@ function test_create_location_h_adr() {
525526
$this->assertEquals( '', get_post_meta( $post->ID, 'geo_address', true ) );
526527
}
527528

529+
function test_create_location_geo_with_altitude() {
530+
Recorder::$request_headers = array( 'content-type' => 'application/json; charset=utf-8' );
531+
Recorder::$input = static::$mf2;
532+
Recorder::$input['properties']['location'] = array( 'geo:42.361,-71.092,1500;u=25000' );
533+
$post = self::check_create();
534+
535+
$this->assertEquals( '42.361', get_post_meta( $post->ID, 'geo_latitude', true ) );
536+
$this->assertEquals( '-71.092', get_post_meta( $post->ID, 'geo_longitude', true ) );
537+
$this->assertEquals( '1500', get_post_meta( $post->ID, 'geo_altitude', true ) );
538+
}
539+
528540
function test_create_location_plain_text() {
529541
Recorder::$request_headers = array( 'content-type' => 'application/json; charset=utf-8' );
530542
Recorder::$input = static::$mf2;
531543
Recorder::$input['properties']['location'] = array( 'foo bar baz' );
532544
$post = self::check_create();
533-
534545
$this->assertEquals( 'foo bar baz', get_post_meta( $post->ID, 'geo_address', true ) );
535546
$this->assertEquals( '', get_post_meta( $post->ID, 'geo_latitude', true ) );
536547
$this->assertEquals( '', get_post_meta( $post->ID, 'geo_longitude', true ) );
537548
}
538549

550+
function test_create_location_visibility_private() {
551+
Recorder::$request_headers = array( 'content-type' => 'application/json; charset=utf-8' );
552+
Recorder::$input = static::$mf2;
553+
Recorder::$input['properties']['location-visibility'] = array( 'private' );
554+
$post = self::check_create();
555+
$this->assertEquals( 0, get_post_meta( $post->ID, 'geo_public', true ) );
556+
557+
}
558+
559+
function test_create_location_visibility_public() {
560+
Recorder::$request_headers = array( 'content-type' => 'application/json; charset=utf-8' );
561+
Recorder::$input = static::$mf2;
562+
Recorder::$input['properties']['location-visibility'] = array( 'public' );
563+
$post = self::check_create();
564+
$this->assertEquals( 1, get_post_meta( $post->ID, 'geo_public', true ) );
565+
566+
}
567+
568+
function test_create_location_visibility_unsupported() {
569+
Recorder::$request_headers = array( 'content-type' => 'application/json; charset=utf-8' );
570+
Recorder::$input = static::$mf2;
571+
Recorder::$input['properties']['location-visibility'] = array( 'bleh' );
572+
$this->check( 400, 'unsupported location visibility bleh' ) ;
573+
}
574+
575+
576+
function test_create_location_visibility_none() {
577+
Recorder::$request_headers = array( 'content-type' => 'application/json; charset=utf-8' );
578+
Recorder::$input = static::$mf2;
579+
$post = self::check_create();
580+
$this->assertEquals( '', get_post_meta( $post->ID, 'geo_public', true ) );
581+
582+
}
583+
584+
539585
// checkin isn't a standard mf2 property yet, but OwnYourSwarm uses it.
540586
// https://ownyourswarm.p3k.io/docs#checkins
541587
function test_create_checkin() {

0 commit comments

Comments
 (0)