Skip to content
Open
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .vscode/settings.json

This file was deleted.

144 changes: 108 additions & 36 deletions class.geocoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
/**
* Geocoder
*
* calls the specific geocoder function (chosen in admin or default: google_geocode)
* calls the specific geocoder function (chosen in admin or default: osm)
*
*/

Expand All @@ -11,7 +11,7 @@ class Leaflet_Geocoder {
* Geocoder should return this on error/not found
* @var array $not_found
*/
private $not_found = array('lat' => 0, 'lng' => 0);
private static $not_found = array('lat' => 0, 'lng' => 0);
/**
* Latitude
* @var float $lat
Expand All @@ -23,6 +23,9 @@ class Leaflet_Geocoder {
*/
public $lng = 0;

/** key for all locations */
public static $locations_key = 'leaflet_geocoded_locations';

/**
* new Geocoder from address
*
Expand All @@ -42,7 +45,7 @@ public function __construct ($address) {
$cached_address = 'leaflet_' . $geocoder . '_' . $address;

/* retrieve cached geocoded location */
$found_cache = get_option( $cached_address );
$found_cache = $this->get_cache( $cached_address, $address );

if ( $found_cache ) {
$location = $found_cache;
Expand All @@ -53,16 +56,17 @@ public function __construct ($address) {
try {
$location = (Object) $this->$geocoding_method( $address );

/* add location */
add_option($cached_address, $location);
/* update location data in db/cache */
$this->set_cache( $cached_address, $location );

/* add option key to locations for clean up purposes */
$locations = get_option('leaflet_geocoded_locations', array());
array_push($locations, $cached_address);
update_option('leaflet_geocoded_locations', $locations);
/* add cache to cached list for cleanup */
$this->update_caches( $cached_address );
} catch (Exception $e) {
// failed
$location = $this->not_found;
/**
* @since 3.4.0
* use 'leaflet_geocoder_not_found' filter to return your own not_found response
*/
$location = apply_filters( 'leaflet_geocoder_not_found', self::$not_found );
}
}

Expand All @@ -72,17 +76,6 @@ public function __construct ($address) {
}
}

/**
* Removes location caches
*/
public static function remove_caches () {
$addresses = get_option('leaflet_geocoded_locations', array());
foreach ($addresses as $address) {
delete_option($address);
}
delete_option('leaflet_geocoded_locations');
}

/**
* Used by geocoders to make requests via curl or file_get_contents
*
Expand All @@ -95,13 +88,12 @@ private function get_url( $url ) {
$referer = get_site_url();

if (in_array('curl', get_loaded_extensions())) {
/* try curl */
$ch = curl_init();

curl_setopt($ch, CURLOPT_AUTOREFERER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_REFERER, $referer);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_REFERER, $referer);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);

Expand All @@ -110,14 +102,12 @@ private function get_url( $url ) {

return $data;
} else if (ini_get('allow_url_fopen')) {
/* try file get contents */

$opts = array(
'http' => array(
'header' => array("Referer: $referer\r\n")
)
);
$context = stream_context_create($opts);
$opts = array(
'http' => array(
'header' => array("Referer: $referer\r\n")
)
);
$context = stream_context_create($opts);

return file_get_contents($url, false, $context);
}
Expand All @@ -132,7 +122,6 @@ private function get_url( $url ) {
* @param string $address the urlencoded address to look up
* @return varies object from API or null (failed)
*/

private function google_geocode ( $address ) {
// Leaflet_Map_Plugin_Settings
$settings = Leaflet_Map_Plugin_Settings::init();
Expand All @@ -146,7 +135,6 @@ private function google_geocode ( $address ) {

/* found location */
if ($json->status == 'OK') {

$location = $json->results[0]->geometry->location;

return (Object) $location;
Expand All @@ -161,7 +149,6 @@ private function google_geocode ( $address ) {
* @param string $address the urlencoded address to look up
* @return varies object from API or null (failed)
*/

private function osm_geocode ( $address ) {
$geocode_url = 'https://nominatim.openstreetmap.org/?format=json&limit=1&q=';
$geocode_url .= $address;
Expand Down Expand Up @@ -198,4 +185,89 @@ private function dawa_geocode ( $address ) {
'lng' => $json[0]->adgangsadresse->adgangspunkt->koordinater[0]
);
}

/**
* gets a single location's coordinates from the cached locations
*/
public function get_cache($address_key, $plain_address) {
/**
* @since 3.4.0
* using 'leaflet_geocoder_get_cache',
* you can return any value that is not identical to the address_key to avoid using get_transient
*/
$filtered = apply_filters( 'leaflet_geocoder_get_cache', $address_key, $plain_address );

if ($filtered === $address_key) {
return get_transient( $address_key );
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

alright, I've gone back to transients

}

return $filtered;
}

/**
* gets the array of saved locations and updates an individual location
*/
public function set_cache($key, $value) {
/**
* @since 3.4.0
* using 'leaflet_geocoder_set_cache',
* you can return any falsy value to omit the set_transient
*/
if (apply_filters('leaflet_geocoder_set_cache', $key, $value)) {
// get user-defined expiry (maybe this should be an admin option?)
$expiry = apply_filters('leaflet_geocoder_expiry', null);
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

power users can define their own transient expiries


if ($expiry === null) {
// stagger caches between 200-400 days to prevent all caches expiring on the same day
$stagger = random_int(200, 400);
$expiry = DAY_IN_SECONDS * $stagger;
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

by default, we set expiry randomly between 200 and 400 days

}

set_transient( $key, $value, $expiry );
}
}

/**
* Appends an address to a list of addresses in the db, for cleanup
*/
public function update_caches( $address ) {
/**
* @since 3.4.0
* using 'leaflet_geocoder_update_caches',
* you can return any falsy value to omit the set_transient
*/
if (apply_filters('leaflet_geocoder_update_caches', $address)) {
$locations = get_transient( self::$locations_key );

if (!$locations) {
$locations = array();
}

array_push( $locations, $address );

// set to 25 year expiry since we never really want it to expire
// but omitting expiry causes it to autoload
set_transient( self::$locations_key, $locations, YEAR_IN_SECONDS * 25 );
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the transient which holds all address keys is 25 years to avoid expiry and avoid autoload

}
}

/**
* Removes all location caches
*/
public static function remove_caches() {
/** @since 3.4.0 */
do_action('leaflet_geocoder_remove_caches');

$addresses = get_transient( self::$locations_key );

if ( !$addresses ) {
return;
}

foreach ($addresses as $address) {
delete_transient( $address );
}

delete_transient( self::$locations_key );
}
}
28 changes: 25 additions & 3 deletions class.leaflet-map.php
Original file line number Diff line number Diff line change
Expand Up @@ -104,13 +104,34 @@ public static function init() {
* Leaflet_Map Constructor
*/
private function __construct() {
$this->run_migrations();
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

run migrations before any other initialization of the plugin

$this->init_hooks();
$this->add_shortcodes();

// loaded
do_action('leaflet_map_loaded');
}

/**
* Check for version discrepancy and run migrations if necessary
* @since 3.4.0
*/
private function run_migrations() {
// assume 3.3.0 if it doesn't exist
$db_version = get_option(LEAFLET_MAP__DB_VERSION_KEY, '3.3.0');

if ($db_version === LEAFLET_MAP__PLUGIN_VERSION) {
return;
}

include_once LEAFLET_MAP__PLUGIN_DIR . 'class.migrations.php';
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only include migrations if there's a version mismatch in the db


Leaflet_Map_Migrations::run_once($db_version);

// set db version to current plugin version
update_option(LEAFLET_MAP__DB_VERSION_KEY, LEAFLET_MAP__PLUGIN_VERSION);
}

/**
* Add actions and filters
*/
Expand Down Expand Up @@ -187,8 +208,8 @@ public static function enqueue_and_register()
$js_url = $settings->get('js_url');
$css_url = $settings->get('css_url');

wp_register_style('leaflet_stylesheet', $css_url, Array(), null, false);
wp_register_script('leaflet_js', $js_url, Array(), null, true);
wp_register_style('leaflet_stylesheet', $css_url, Array(), LEAFLET_MAP__PLUGIN_VERSION, false);
wp_register_script('leaflet_js', $js_url, Array(), LEAFLET_MAP__PLUGIN_VERSION, true);
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

adds plugin version like all the other registered scripts; #222

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I don't think this is right. Adding the plugin version rather than the Leaflet JS version means that if the Leaflet JS version is changed then the cache potentially wouldn't know (if the URL was the same). This is why I would opt for apply_filters('leaflet_js_version', Leaflet_Map::$leaflet_version) instead because it would also allow this to be filtered when the version is changed programatically (as we do).

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Furthermore, $in_footer is set to true here but line 218 is set to false. I think that both need to be true or both need to be false which is why the JavaScript is breaking when using "Merge + Minify + Refresh" plugin.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I don't think this is right. Adding the plugin version rather than the Leaflet JS version means that if the Leaflet JS version is changed then the cache potentially wouldn't know (if the URL was the same). This is why I would opt for apply_filters('leaflet_js_version', Leaflet_Map::$leaflet_version) instead because it would also allow this to be filtered when the version is changed programatically (as we do).

This makes me think "null" is better here.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Furthermore, $in_footer is set to true here but line 218 is set to false. I think that both need to be true or both need to be false which is why the JavaScript is breaking when using "Merge + Minify + Refresh" plugin.

Hesitant to change this because we've had issues in the past with people running async and deferred scripts.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It makes no odds to me. I've developed around it by directly filtering the global $wp_styles and $wp_scripts. Here is what Wordpress says though (script version not plugin version) https://developer.wordpress.org/reference/functions/wp_register_script/#parameters

$ver string|bool|null Optional
String specifying script version number, if it has one, which is added to the URL as a query string for cache busting purposes. If version is set to false, a version number is automatically added equal to current installed WordPress version.

But "null" will definitely not help the cache at all.

Again, it doesn't bother me if you change the scripts to both be in the header or footer because I've developed around it by directly filtering the global $wp_scripts. We chose to put them both in the footer FYI.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UPDATE: We have changed our position on this and moved both scripts to be loaded in the header instead of the footer. This is because loading them in the footer breaks compatibility with Leaflet.GestureHandling https://elmarquis.github.io/Leaflet.GestureHandling/


// new required MapQuest javascript file
$tiling_service = $settings->get('default_tiling_service');
Expand All @@ -204,7 +225,8 @@ public static function enqueue_and_register()
// optional ajax geojson plugin
wp_register_script('tmcw_togeojson', $settings->get('togeojson_url'), Array('jquery'), LEAFLET_MAP__PLUGIN_VERSION, false);

if (defined('WP_DEBUG') && WP_DEBUG) {
// @since 3.4.0
if (defined('LEAFLET_MAP__DEBUG') && LEAFLET_MAP__DEBUG) {
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as per #222

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great!

$minified = '';
} else {
$minified = '.min';
Expand Down
40 changes: 40 additions & 0 deletions class.migrations.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php
/**
* Leaflet Map Migrations
* @since 3.4.0
*/

// Exit if accessed directly
if (!defined('ABSPATH')) {
exit;
}

define('LEAFLET_MAP__MIGRATION_DIR', LEAFLET_MAP__PLUGIN_DIR . 'migrations/');

class Leaflet_Map_Migrations {
/**
* only call once
**/
private static $called = false;

/**
* We assume if this is called, our db version diverges from plugin version
* migrations here are run in ascending order, always compared via '<' against db version
*/
public static function run_once($db_version) {
if ( self::$called ) {
return;
}

self::$called = true;

if (version_compare($db_version, '3.4.0', '<')) {
include_once LEAFLET_MAP__MIGRATION_DIR . '001-v3.4.0-geocoder-transients.php';

migration001();
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

included above; needs to be a unique migration function name; assuming this is ok; maybe I could use "leaflet_map__" prefix?


// update version, if for some reason something fails afterwards, and we want to prevent this migration
update_option(LEAFLET_MAP__DB_VERSION_KEY, '3.4.0');
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

assuming there may be more migrations in the future, we update db asap so this particular migration never refires

}
}
}
8 changes: 8 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,14 @@ services:
WORDPRESS_DB_PASSWORD: wordpress
WORDPRESS_DEBUG: 1

# phpmyadmin:
# image: phpmyadmin
# restart: always
# ports:
# - 8080:80
# environment:
# - PMA_ARBITRARY=1

volumes:
wp_db:
wordpress:
10 changes: 5 additions & 5 deletions leaflet-map.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
/**
* Plugin Name: Leaflet Map
* Plugin URI: https://wordpress.org/plugins/leaflet-map/
* Description: A plugin for creating a Leaflet JS map with a shortcode. Boasts two free map tile services and three free geocoders.
* Description: A plugin for creating a Leaflet JS map with shortcodes. Boasts integrations with free map tile services and geocoders.
* Author: bozdoz
* Author URI: https://bozdoz.com/
* Text Domain: leaflet-map
* Domain Path: /languages/
* Version: 3.3.0
* Version: 3.4.0
* License: GPL2
* Leaflet Map is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand All @@ -29,14 +29,14 @@
exit;
}

define('LEAFLET_MAP__PLUGIN_VERSION', '3.3.0');
define('LEAFLET_MAP__PLUGIN_VERSION', '3.4.0');
define('LEAFLET_MAP__DB_VERSION_KEY', 'leaflet_map_version');
define('LEAFLET_MAP__PLUGIN_FILE', __FILE__);
define('LEAFLET_MAP__PLUGIN_DIR', plugin_dir_path(__FILE__));

// import main class
require_once LEAFLET_MAP__PLUGIN_DIR . 'class.leaflet-map.php';

// uninstall hook
register_uninstall_hook(__FILE__, array('Leaflet_Map', 'uninstall'));

add_action('init', array('Leaflet_Map', 'init'));
add_action('init', array('Leaflet_Map', 'init'));
Loading