mirror of
https://github.com/10h30/wp-strava.git
synced 2026-07-14 04:06:48 +09:00
Moved code to src directory
This commit is contained in:
Executable
+153
@@ -0,0 +1,153 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Polyline
|
||||
*
|
||||
* PHP Version 5.2 (forked)
|
||||
*
|
||||
* A simple class to handle polyline-encoding for Google Maps
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* @category Mapping
|
||||
* @package Polyline
|
||||
* @author E. McConville <emcconville@emcconville.com>
|
||||
* @copyright 2009-2015 E. McConville
|
||||
* @license http://www.gnu.org/licenses/lgpl.html LGPL v3
|
||||
* @version GIT: $Id: db01b3fea5d96533da928252135ac8f247c1b250 $
|
||||
* @link https://github.com/emcconville/google-map-polyline-encoding-tool
|
||||
*/
|
||||
|
||||
/**
|
||||
* Polyline encoding & decoding class
|
||||
*
|
||||
* Convert list of points to encoded string following Google's Polyline
|
||||
* Algorithm.
|
||||
*
|
||||
* @category Mapping
|
||||
* @package Polyline
|
||||
* @author E. McConville <emcconville@emcconville.com>
|
||||
* @license http://www.gnu.org/licenses/lgpl.html LGPL v3
|
||||
* @link https://github.com/emcconville/google-map-polyline-encoding-tool
|
||||
*/
|
||||
class Polyline {
|
||||
|
||||
/**
|
||||
* Default precision level of 1e-5.
|
||||
*
|
||||
* Overwrite this property in extended class to adjust precision of numbers.
|
||||
* !!!CAUTION!!!
|
||||
* 1) Adjusting this value will not guarantee that third party
|
||||
* libraries will understand the change.
|
||||
* 2) Float point arithmetic IS NOT real number arithmetic. PHP's internal
|
||||
* float precision may contribute to undesired rounding.
|
||||
*
|
||||
* @var int $precision
|
||||
*/
|
||||
protected static $precision = 5;
|
||||
|
||||
// To remove PHP 5.3 requirement.
|
||||
protected static $flatten = array();
|
||||
|
||||
/**
|
||||
* Apply Google Polyline algorithm to list of points.
|
||||
*
|
||||
* @param array $points List of points to encode. Can be a list of tuples,
|
||||
* or a flat on dimensional array.
|
||||
*
|
||||
* @return string encoded string
|
||||
*/
|
||||
final public static function encode( $points ) {
|
||||
$points = self::flatten( $points );
|
||||
$encoded_string = '';
|
||||
$index = 0;
|
||||
$previous = array( 0, 0 );
|
||||
foreach ( $points as $number ) {
|
||||
$number = (float) $number;
|
||||
$number = (int) round( $number * pow( 10, static::$precision ) );
|
||||
$diff = $number - $previous[ $index % 2 ];
|
||||
|
||||
$previous[ $index % 2 ] = $number;
|
||||
|
||||
$number = $diff;
|
||||
$index++;
|
||||
$number = ( $number < 0 ) ? ~( $number << 1 ) : ( $number << 1 );
|
||||
$chunk = '';
|
||||
while ( $number >= 0x20 ) {
|
||||
$chunk .= chr( ( 0x20 | ( $number & 0x1f ) ) + 63 );
|
||||
$number >>= 5;
|
||||
}
|
||||
$chunk .= chr( $number + 63 );
|
||||
$encoded_string .= $chunk;
|
||||
}
|
||||
return $encoded_string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse Google Polyline algorithm on encoded string.
|
||||
*
|
||||
* @param string $string Encoded string to extract points from.
|
||||
*
|
||||
* @return array points
|
||||
*/
|
||||
final public static function decode( $string ) {
|
||||
$points = array();
|
||||
$index = $i = 0; // phpcs:ignore Squiz.PHP.DisallowMultipleAssignments.Found
|
||||
$previous = array( 0, 0 );
|
||||
while ( $i < strlen( $string ) ) { // phpcs:ignore Squiz.PHP.DisallowSizeFunctionsInLoops.Found
|
||||
$shift = $result = 0x00; // phpcs:ignore Squiz.PHP.DisallowMultipleAssignments.Found
|
||||
do {
|
||||
$bit = ord( substr( $string, $i++ ) ) - 63;
|
||||
$result |= ( $bit & 0x1f ) << $shift;
|
||||
$shift += 5;
|
||||
} while ( $bit >= 0x20 );
|
||||
|
||||
$diff = ( $result & 1 ) ? ~( $result >> 1 ) : ( $result >> 1 );
|
||||
$number = $previous[ $index % 2 ] + $diff;
|
||||
|
||||
$previous[ $index % 2 ] = $number;
|
||||
$index++;
|
||||
$points[] = $number * 1 / pow( 10, static::$precision );
|
||||
}
|
||||
return $points;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reduce multi-dimensional to single list
|
||||
*
|
||||
* @param array $array Subject array to flatten.
|
||||
*
|
||||
* @return array flattened
|
||||
*/
|
||||
final public static function flatten( $array ) {
|
||||
self::$flatten = array();
|
||||
array_walk_recursive( $array, array( __CLASS__, 'flatten_callback' ) );
|
||||
return self::$flatten;
|
||||
}
|
||||
|
||||
final public static function flatten_callback( $value ) {
|
||||
self::$flatten[] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Concat list into pairs of points
|
||||
*
|
||||
* @param array $list One-dimensional array to segment into list of tuples.
|
||||
*
|
||||
* @return array pairs
|
||||
*/
|
||||
final public static function pair( $list ) {
|
||||
return is_array( $list ) ? array_chunk( $list, 2 ) : array();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
<?php
|
||||
/*
|
||||
* Main Strava plugin class.
|
||||
*/
|
||||
class WPStrava {
|
||||
|
||||
/**
|
||||
* Instance of this class (singleton).
|
||||
* @var WPStrava
|
||||
*/
|
||||
private static $instance = null;
|
||||
|
||||
/**
|
||||
* Settings object to access settings.
|
||||
* @var WPStrava_Settings
|
||||
*/
|
||||
private $settings = null;
|
||||
|
||||
/**
|
||||
* Authorization object.
|
||||
* @var WPStrava_Auth
|
||||
*/
|
||||
private $auth = null;
|
||||
|
||||
/**
|
||||
* Array of WPStrava_API objects (one for each athlete).
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $api = array();
|
||||
|
||||
/**
|
||||
* Activity object to get activities.
|
||||
* @var WPStrava_Activity
|
||||
*/
|
||||
private $activity = null;
|
||||
|
||||
/**
|
||||
* Route object to get routes.
|
||||
* @var WPStrava_Routes
|
||||
*/
|
||||
private $routes = null;
|
||||
|
||||
/**
|
||||
* Private constructor (singleton).
|
||||
*/
|
||||
private function __construct() {
|
||||
$this->settings = new WPStrava_Settings();
|
||||
$this->auth = WPStrava_Auth::get_auth( 'refresh' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a singleton instance.
|
||||
*
|
||||
* @return WPStrava
|
||||
*/
|
||||
public static function get_instance() {
|
||||
if ( ! self::$instance ) {
|
||||
$class = __CLASS__;
|
||||
self::$instance = new $class();
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to install hooks at WP runtime.
|
||||
*
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public function hook() {
|
||||
$this->auth->hook();
|
||||
|
||||
if ( is_admin() ) {
|
||||
$this->settings->hook();
|
||||
} else {
|
||||
add_action( 'init', array( $this, 'register_shortcodes' ) );
|
||||
add_action( 'wp_enqueue_scripts', array( $this, 'register_scripts' ) );
|
||||
}
|
||||
|
||||
// Register widgets.
|
||||
add_action( 'widgets_init', array( $this, 'register_widgets' ) );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic method to access activity, routes, settings, etc.
|
||||
*
|
||||
* @param string $name One of activity, routes, settings.
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function __get( $name ) {
|
||||
// On-demand classes.
|
||||
if ( 'activity' === $name ) {
|
||||
return $this->get_activity();
|
||||
}
|
||||
|
||||
if ( 'routes' === $name ) {
|
||||
return $this->get_routes();
|
||||
}
|
||||
|
||||
if ( isset( $this->{$name} ) ) {
|
||||
return $this->{$name};
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an API object for the given Client ID.
|
||||
*
|
||||
* @param string $id Client ID.
|
||||
* @return WPStrava_API
|
||||
*/
|
||||
public function get_api( $id = null ) {
|
||||
if ( ! $id ) {
|
||||
$id = $this->settings->get_default_id();
|
||||
}
|
||||
|
||||
if ( empty( $this->api[ $id ] ) ) {
|
||||
$this->api[ $id ] = new WPStrava_API( $id );
|
||||
}
|
||||
|
||||
return $this->api[ $id ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the activity object.
|
||||
*
|
||||
* @return WPStrava_Activity
|
||||
*/
|
||||
public function get_activity() {
|
||||
if ( ! $this->activity ) {
|
||||
$this->activity = new WPStrava_Activity();
|
||||
}
|
||||
|
||||
return $this->activity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the routes object.
|
||||
*
|
||||
* @return WPStrava_Routes
|
||||
*/
|
||||
public function get_routes() {
|
||||
if ( ! $this->routes ) {
|
||||
$this->routes = new WPStrava_Routes();
|
||||
}
|
||||
return $this->routes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the wp-strava stylesheet.
|
||||
*/
|
||||
public function register_scripts() {
|
||||
// Register a personalized stylesheet.
|
||||
wp_register_style( 'wp-strava-style', WPSTRAVA_PLUGIN_URL . 'css/wp-strava.css', array(), WPSTRAVA_PLUGIN_VERSION );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the widgets.
|
||||
*/
|
||||
public function register_widgets() {
|
||||
register_widget( 'WPStrava_LatestActivitiesWidget' );
|
||||
register_widget( 'WPStrava_LatestMapWidget' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the shortcodes.
|
||||
*/
|
||||
public function register_shortcodes() {
|
||||
// Initialize short code classes.
|
||||
new WPStrava_ActivityShortcode();
|
||||
new WPStrava_LatestActivitiesShortcode();
|
||||
new WPStrava_RouteShortcode();
|
||||
new WPStrava_LatestMapShortcode();
|
||||
}
|
||||
|
||||
}
|
||||
Executable
+196
@@ -0,0 +1,196 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* API class for all remote calls.
|
||||
*/
|
||||
class WPStrava_API {
|
||||
|
||||
const STRAVA_V3_API = 'https://www.strava.com/api/v3/';
|
||||
|
||||
private $client_id = null;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param int $client_id Strava API Client ID representing an athlete.
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
*/
|
||||
public function __construct( $client_id = null ) {
|
||||
$this->client_id = $client_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* POST something to the Strava API.
|
||||
*
|
||||
* @param string $uri Path within the Strava API.
|
||||
* @param array $data Data to POST.
|
||||
* @return stdClass Strava API response.
|
||||
* @throws WPStrava_Exception
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
*/
|
||||
public function post( $uri, $data = null ) {
|
||||
$url = self::STRAVA_V3_API;
|
||||
|
||||
$args = array(
|
||||
'body' => http_build_query( $data ),
|
||||
'sslverify' => false,
|
||||
'headers' => array(),
|
||||
'timeout' => 30,
|
||||
);
|
||||
|
||||
$access_token = $this->get_access_token();
|
||||
if ( $access_token ) {
|
||||
$args['headers']['Authorization'] = 'Bearer ' . $access_token;
|
||||
}
|
||||
|
||||
$response = wp_remote_post( $url . $uri, $args );
|
||||
|
||||
if ( is_wp_error( $response ) ) {
|
||||
throw WPStrava_Exception::from_wp_error( $response );
|
||||
}
|
||||
|
||||
if ( 200 != $response['response']['code'] ) { // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
|
||||
|
||||
// See if there's useful info in the body.
|
||||
$body = json_decode( $response['body'] );
|
||||
$error = '';
|
||||
if ( ! empty( $body->error ) ) {
|
||||
$error = $body->error;
|
||||
} else {
|
||||
$error = print_r( $response, true ); // phpcs:ignore -- Debug output.
|
||||
}
|
||||
|
||||
// Throw an informational exception with a detailed debug exception.
|
||||
throw new WPStrava_Exception(
|
||||
$response['response']['message'],
|
||||
$response['response']['code'],
|
||||
new WPStrava_Exception( $error )
|
||||
);
|
||||
}
|
||||
|
||||
return json_decode( $response['body'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* GET something from the Strava API - checking the cache first.
|
||||
*
|
||||
* @param string $uri Path within the Strava API.
|
||||
* @param array $args Request arguments.
|
||||
* @return stdClass Strava API response.
|
||||
* @throws WPStrava_Exception
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
*/
|
||||
public function get( $uri, $args = null ) {
|
||||
|
||||
// @see https://stackoverflow.com/a/3764390/2146022
|
||||
$arg_suffix = is_array( $args ) ? '_' . substr( md5( wp_json_encode( $args ) ), 0, 12 ) : '';
|
||||
|
||||
$transient_key = 'strava_api_data_' . $this->client_id . '_' . $uri . $arg_suffix;
|
||||
|
||||
$data = get_transient( $transient_key );
|
||||
|
||||
if ( $data ) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
$data = $this->remote_get( $uri, $args );
|
||||
|
||||
set_transient( $transient_key, $data, HOUR_IN_SECONDS );
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* GET something from the Strava API.
|
||||
*
|
||||
* @param string $uri Path within the Strava API.
|
||||
* @param array $args Request arguments.
|
||||
* @return stdClass Strava API response.
|
||||
* @throws WPStrava_Exception
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 2.0.1
|
||||
*/
|
||||
private function remote_get( $uri, $args = null ) {
|
||||
static $retry = true;
|
||||
|
||||
$url = self::STRAVA_V3_API;
|
||||
$url .= $uri;
|
||||
|
||||
if ( ! empty( $args ) ) {
|
||||
$url = add_query_arg( $args, $url );
|
||||
}
|
||||
|
||||
$get_args = array(
|
||||
'headers' => array(),
|
||||
'sslverify' => false,
|
||||
'timeout' => 30,
|
||||
);
|
||||
|
||||
$access_token = $this->get_access_token();
|
||||
if ( $access_token ) {
|
||||
$get_args['headers']['Authorization'] = 'Bearer ' . $access_token;
|
||||
}
|
||||
|
||||
$response = wp_remote_get( $url, $get_args );
|
||||
if ( is_wp_error( $response ) ) {
|
||||
throw WPStrava_Exception::from_wp_error( $response );
|
||||
}
|
||||
|
||||
// Try *one* real-time token refresh if 404.
|
||||
if ( $retry && 404 == $response['response']['code'] ) {
|
||||
$retry = false;
|
||||
$auth = WPStrava::get_instance()->auth;
|
||||
if ( $auth instanceof WPStrava_AuthRefresh ) {
|
||||
$auth->auth_refresh();
|
||||
return $this->remote_get( $uri, $args );
|
||||
}
|
||||
} else {
|
||||
$retry = true;
|
||||
}
|
||||
|
||||
if ( 200 != $response['response']['code'] ) { // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
|
||||
|
||||
// See if there's useful info in the body.
|
||||
$body = json_decode( $response['body'] );
|
||||
$error = '';
|
||||
if ( ! empty( $body->error ) ) {
|
||||
$error = $body->error;
|
||||
} elseif ( 503 == $response['response']['code'] ) { // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
|
||||
$error = __( 'Strava Temporarily Unavailable', 'wp-strava' );
|
||||
} else {
|
||||
$error = print_r( $response, true ); // phpcs:ignore -- Debug output.
|
||||
}
|
||||
|
||||
// Throw an informational exception with a detailed debug exception.
|
||||
throw new WPStrava_Exception(
|
||||
$response['response']['message'],
|
||||
$response['response']['code'],
|
||||
new WPStrava_Exception( $error )
|
||||
);
|
||||
}
|
||||
|
||||
return json_decode( $response['body'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the (ever changing) access token based on current Client ID.
|
||||
*
|
||||
* @return string|null String for access token, null if not found.
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 2.0.0
|
||||
*/
|
||||
private function get_access_token() {
|
||||
// If client_id not set (OAuth set-up), don't even look.
|
||||
if ( ! $this->client_id ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$settings = WPStrava::get_instance()->settings;
|
||||
$info = $settings->info;
|
||||
|
||||
if ( ! empty( $info[ $this->client_id ]->access_token ) ) {
|
||||
return $info[ $this->client_id ]->access_token;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Executable
+75
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
/*
|
||||
* Activity is a class wrapper for the Strava REST API functions.
|
||||
*/
|
||||
class WPStrava_Activity {
|
||||
|
||||
const ACTIVITIES_URL = 'https://strava.com/activities/';
|
||||
const ATHLETES_URL = 'https://strava.com/athletes/';
|
||||
|
||||
/**
|
||||
* Get single activity by ID.
|
||||
*
|
||||
* @param string $client_id Client ID of athlete to retrieve for
|
||||
* @param int $activity_id ID of activity to retrieve.
|
||||
* @return object stdClass Representing this activity.
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
*/
|
||||
public function get_activity( $client_id, $activity_id ) {
|
||||
return WPStrava::get_instance()->get_api( $client_id )->get( "activities/{$activity_id}" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get activity list from Strava API.
|
||||
*
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @param string $client_id Client ID of athlete to retrieve for
|
||||
* @param int $club_id Club ID of all club riders (optional).
|
||||
* @param int|null $quantity Number of records to retrieve (optional).
|
||||
* @return array Array of activities.
|
||||
*/
|
||||
public function get_activities( $client_id, $club_id = null, $quantity = null ) {
|
||||
$api = WPStrava::get_instance()->get_api( $client_id );
|
||||
|
||||
$data = null;
|
||||
|
||||
$args = $quantity ? array( 'per_page' => $quantity ) : null;
|
||||
|
||||
//Get the json results using the constructor specified values.
|
||||
if ( is_numeric( $club_id ) ) {
|
||||
$data = $api->get( "clubs/{$club_id}/activities", $args );
|
||||
} else {
|
||||
$data = $api->get( 'athlete/activities', $args );
|
||||
}
|
||||
|
||||
if ( is_array( $data ) ) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
return array();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get activities with a distance longer than specified length.
|
||||
*
|
||||
* @param array $activities
|
||||
* @param float $dist Distance in default system of measure (km/mi).
|
||||
* @return void
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
*/
|
||||
public function get_activities_longer_than( $activities, $dist ) {
|
||||
$som = WPStrava_SOM::get_som();
|
||||
$meters = $som->distance_inverse( $dist );
|
||||
|
||||
$long_activities = array();
|
||||
foreach ( $activities as $activity_info ) {
|
||||
if ( $activity_info->distance > $meters ) {
|
||||
$long_activities[] = $activity_info;
|
||||
}
|
||||
}
|
||||
|
||||
return $long_activities;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,197 @@
|
||||
<?php
|
||||
/**
|
||||
* Activity Shortcode [activity].
|
||||
* @package WPStrava
|
||||
*/
|
||||
|
||||
/**
|
||||
* Activity Shortcode class (converted from Ride).
|
||||
*
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 1.0
|
||||
*/
|
||||
class WPStrava_ActivityShortcode {
|
||||
|
||||
/**
|
||||
* Whether or not to enqueue styles (if shortcode is present).
|
||||
*
|
||||
* @var boolean
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 1.0
|
||||
*/
|
||||
private $add_script = false;
|
||||
|
||||
/**
|
||||
* Constructor (converted from static init()).
|
||||
*
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 1.0
|
||||
*/
|
||||
public function __construct() {
|
||||
add_shortcode( 'ride', array( $this, 'handler' ) ); // @deprecated 1.1
|
||||
add_shortcode( 'activity', array( $this, 'handler' ) );
|
||||
add_action( 'wp_footer', array( $this, 'print_scripts' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Shortcode handler for [activity].
|
||||
*
|
||||
* [activity id=id som=metric map_width="100%" map_height="400px" markers=false]
|
||||
*
|
||||
* @param array $atts Array of attributes (id, map_width, etc.).
|
||||
* @return string Shortcode output
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 1.0
|
||||
*/
|
||||
public function handler( $atts ) {
|
||||
if ( isset( $atts['athlete_token'] ) ) {
|
||||
// Translators: Message shown when using deprecated athlete_token parameter.
|
||||
return __( 'The <code>athlete_token</code> parameter is deprecated as of WP-Strava version 2 and should be replaced with <code>client_id</code>.', 'wp-strava' );
|
||||
}
|
||||
|
||||
$this->add_script = true;
|
||||
|
||||
$defaults = array(
|
||||
'id' => 0,
|
||||
'som' => WPStrava::get_instance()->settings->som,
|
||||
'map_width' => '480',
|
||||
'map_height' => '320',
|
||||
'client_id' => WPStrava::get_instance()->settings->get_default_id(),
|
||||
'markers' => false,
|
||||
'image_only' => false,
|
||||
);
|
||||
|
||||
$atts = shortcode_atts( $defaults, $atts, 'activity' );
|
||||
|
||||
/* Make sure boolean values are actually boolean
|
||||
* @see https://wordpress.stackexchange.com/a/119299
|
||||
*/
|
||||
$atts['markers'] = filter_var( $atts['markers'], FILTER_VALIDATE_BOOLEAN );
|
||||
$atts['image_only'] = filter_var( $atts['image_only'], FILTER_VALIDATE_BOOLEAN );
|
||||
|
||||
$activity = WPStrava::get_instance()->activity;
|
||||
$activity_details = null;
|
||||
|
||||
try {
|
||||
$activity_details = $activity->get_activity( $atts['client_id'], $atts['id'] );
|
||||
} catch ( WPStrava_Exception $e ) {
|
||||
return $e->to_html();
|
||||
}
|
||||
|
||||
$activity_output = '';
|
||||
if ( $activity_details ) {
|
||||
$activity_output .= '<div id="activity-header-' . $atts['id'] . '" class="wp-strava-activity-container">';
|
||||
if ( ! $atts['image_only'] ) {
|
||||
$activity_output .= $this->get_table( $activity_details, $atts['som'] );
|
||||
}
|
||||
|
||||
// Sanitize width & height.
|
||||
$map_width = str_replace( '%', '', $atts['map_width'] );
|
||||
$map_height = str_replace( '%', '', $atts['map_height'] );
|
||||
$map_width = str_replace( 'px', '', $map_width );
|
||||
$map_height = str_replace( 'px', '', $map_height );
|
||||
|
||||
$activity_output .= '<a title="' . $activity_details->name . '" href="' . WPStrava_Activity::ACTIVITIES_URL . $activity_details->id . '">' .
|
||||
WPStrava_StaticMap::get_image_tag( $activity_details, $map_height, $map_width, $atts['markers'] ) .
|
||||
'</a>
|
||||
</div>';
|
||||
} // End if( $activity_details ).
|
||||
return $activity_output;
|
||||
}
|
||||
|
||||
/**
|
||||
* The the activity details in in HTML table.
|
||||
*
|
||||
* @param string $activity_details Activity details from the activity class.
|
||||
* @param string $som System of measure (english/metric).
|
||||
* @return string HTML Table of activity details.
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @author Sebastian Erb <mail@sebastianerb.com>
|
||||
* @since 1.7.0
|
||||
*/
|
||||
private function get_table( $activity_details, $som ) {
|
||||
$strava_som = WPStrava_SOM::get_som( $som );
|
||||
$strava_activitytype = WPStrava_ActivityType::get_type_group( $activity_details->type );
|
||||
$avg_title = '<th>' . __( 'Average Speed', 'wp-strava' ) . '</th>';
|
||||
$max_title = '<th>' . __( 'Max Speed', 'wp-strava' ) . '</th>';
|
||||
$elevation_title = '<th>' . __( 'Elevation Gain', 'wp-strava' ) . '</th>';
|
||||
$avg_speed = '';
|
||||
$max_speed = '';
|
||||
$elevation = '<td>' . $strava_som->elevation( $activity_details->total_elevation_gain ) . '</td>';
|
||||
$speed_label = '';
|
||||
$elevation_label = '<td>' . $strava_som->get_elevation_label() . '</td>';
|
||||
|
||||
switch ( $strava_activitytype ) {
|
||||
case WPStrava_ActivityType::TYPE_GROUP_PACE:
|
||||
$avg_speed = '<td>' . $strava_som->pace( $activity_details->average_speed ) . '</td>';
|
||||
$max_speed = '<td>' . $strava_som->pace( $activity_details->max_speed ) . '</td>';
|
||||
$speed_label = '<td>' . $strava_som->get_pace_label() . '</td>';
|
||||
break;
|
||||
case WPStrava_ActivityType::TYPE_GROUP_SPEED:
|
||||
$avg_speed = '<td>' . $strava_som->speed( $activity_details->average_speed ) . '</td>';
|
||||
$max_speed = '<td>' . $strava_som->speed( $activity_details->max_speed ) . '</td>';
|
||||
$speed_label = '<td>' . $strava_som->get_speed_label() . '</td>';
|
||||
break;
|
||||
case WPStrava_ActivityType::TYPE_GROUP_PACE:
|
||||
$avg_speed = '<td>' . $strava_som->swimpace( $activity_details->average_speed ) . '</td>';
|
||||
$max_speed = '<td>' . $strava_som->swimpace( $activity_details->max_speed ) . '</td>';
|
||||
$speed_label = '<td>' . $strava_som->get_swimpace_label() . '</td>';
|
||||
break;
|
||||
default:
|
||||
$avg_title = '';
|
||||
$max_title = '';
|
||||
break;
|
||||
}
|
||||
|
||||
if ( WPStrava::get_instance()->settings->hide_elevation ) {
|
||||
$elevation = '';
|
||||
$elevation_title = '';
|
||||
$elevation_label = '';
|
||||
}
|
||||
|
||||
return '
|
||||
<table id="activity-details-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>' . __( 'Elapsed Time', 'wp-strava' ) . '</th>
|
||||
<th>' . __( 'Moving Time', 'wp-strava' ) . '</th>
|
||||
<th>' . __( 'Distance', 'wp-strava' ) . '</th>
|
||||
' . $avg_title . '
|
||||
' . $max_title . '
|
||||
' . $elevation_title . '
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="activity-details-table-info">
|
||||
<td>' . $strava_som->time( $activity_details->elapsed_time ) . '</td>
|
||||
<td>' . $strava_som->time( $activity_details->moving_time ) . '</td>
|
||||
<td>' . $strava_som->distance( $activity_details->distance ) . '</td>
|
||||
' . $avg_speed . '
|
||||
' . $max_speed . '
|
||||
' . $elevation . '
|
||||
</tr>
|
||||
<tr class="activity-details-table-units">
|
||||
<td>' . $strava_som->get_time_label() . '</td>
|
||||
<td>' . $strava_som->get_time_label() . '</td>
|
||||
<td>' . $strava_som->get_distance_label() . '</td>
|
||||
' . $speed_label . '
|
||||
' . $speed_label . '
|
||||
' . $elevation_label . '
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
';
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue style if shortcode is being used.
|
||||
*
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 1.0
|
||||
*/
|
||||
public function print_scripts() {
|
||||
if ( $this->add_script ) {
|
||||
wp_enqueue_style( 'wp-strava-style' );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
/**
|
||||
* ActivityType [activitytype].
|
||||
* @package WPStrava
|
||||
*/
|
||||
|
||||
/**
|
||||
* ActivityType class.
|
||||
*
|
||||
* @author Sebastian Erb <mail@sebastianerb.com>
|
||||
* @since 1.7.0
|
||||
*/
|
||||
class WPStrava_ActivityType {
|
||||
|
||||
const TYPE_ALPINESKI = 'AlpineSki';
|
||||
const TYPE_BACKCOUNTRYSKI = 'BackcountrySki';
|
||||
const TYPE_CANOEING = 'Canoeing';
|
||||
const TYPE_CROSSFIT = 'Crossfit';
|
||||
const TYPE_EBIKERIDE = 'EBikeRide';
|
||||
const TYPE_ELLIPTICAL = 'Elliptical';
|
||||
const TYPE_HANDCYCLE = 'Hike';
|
||||
const TYPE_HIKE = 'IceSkate';
|
||||
const TYPE_ICESKATE = 'InlineSkate';
|
||||
const TYPE_INLINESKATE = 'AlpineSki';
|
||||
const TYPE_KAYAKING = 'Kayaking';
|
||||
const TYPE_KITESURF = 'Kitesurf';
|
||||
const TYPE_NORDICSKI = 'NordicSki';
|
||||
const TYPE_RIDE = 'Ride';
|
||||
const TYPE_ROCKCLIMBING = 'RockClimbing';
|
||||
const TYPE_ROLLERSKI = 'RollerSki';
|
||||
const TYPE_ROWING = 'Rowing';
|
||||
const TYPE_RUN = 'Run';
|
||||
const TYPE_SNOWBOARD = 'Snowboard';
|
||||
const TYPE_SNOWSHOE = 'Snowshoe';
|
||||
const TYPE_STAIRSTEPPER = 'StairStepper';
|
||||
const TYPE_STANDUPPADDLING = 'StandUpPaddling';
|
||||
const TYPE_SURFING = 'Surfing';
|
||||
const TYPE_SWIM = 'Swim';
|
||||
const TYPE_VIRTUALRIDE = 'VirtualRide';
|
||||
const TYPE_VIRTUALRUN = 'VirtualRun';
|
||||
const TYPE_WALK = 'Walk';
|
||||
const TYPE_WEIGHTTRAINING = 'WeightTraining';
|
||||
const TYPE_WHEELCHAIR = 'Wheelchair';
|
||||
const TYPE_WINDSURF = 'Windsurf';
|
||||
const TYPE_WORKOUT = 'Workout';
|
||||
const TYPE_YOGA = 'Yoga';
|
||||
|
||||
const TYPE_DEFAULT = self::TYPE_RIDE;
|
||||
|
||||
private static $water_types = array( self::TYPE_SWIM );
|
||||
private static $pace_types = array( self::TYPE_CANOEING, self::TYPE_HIKE, self::TYPE_RUN, self::TYPE_SNOWSHOE, self::TYPE_VIRTUALRUN, self::TYPE_WALK );
|
||||
private static $speed_types = array( self::TYPE_ALPINESKI, self::TYPE_BACKCOUNTRYSKI, self::TYPE_EBIKERIDE, self::TYPE_ELLIPTICAL, self::TYPE_HANDCYCLE, self::TYPE_ICESKATE, self::TYPE_INLINESKATE, self::TYPE_KAYAKING, self::TYPE_KITESURF, self::TYPE_NORDICSKI, self::TYPE_RIDE, self::TYPE_ROCKCLIMBING, self::TYPE_ROLLERSKI, self::TYPE_ROWING, self::TYPE_SNOWBOARD, self::TYPE_STAIRSTEPPER, self::TYPE_STANDUPPADDLING, self::TYPE_SURFING, self::TYPE_VIRTUALRIDE, self::TYPE_WHEELCHAIR, self::TYPE_WINDSURF );
|
||||
|
||||
const TYPE_GROUP_WATER = 'water';
|
||||
const TYPE_GROUP_PACE = 'pace';
|
||||
const TYPE_GROUP_SPEED = 'speed';
|
||||
const TYPE_GROUP_OTHER = 'other';
|
||||
|
||||
/**
|
||||
* Get the type of activity.
|
||||
*
|
||||
* @param string $type Type provided by Strava.
|
||||
* @return string Type group (water/pace/speed/other).
|
||||
* @author Sebastian Erb <mail@sebastianerb.com>
|
||||
* @since 1.7.0
|
||||
*/
|
||||
public static function get_type_group( $type ) {
|
||||
|
||||
if ( in_array( $type, self::$pace_types, true ) ) {
|
||||
return self::TYPE_GROUP_PACE;
|
||||
}
|
||||
|
||||
if ( in_array( $type, self::$speed_types, true ) ) {
|
||||
return self::TYPE_GROUP_SPEED;
|
||||
}
|
||||
|
||||
if ( in_array( $type, self::$water_types, true ) ) {
|
||||
return self::TYPE_GROUP_WATER;
|
||||
}
|
||||
|
||||
return self::TYPE_GROUP_OTHER;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
<?php
|
||||
|
||||
abstract class WPStrava_Auth {
|
||||
|
||||
protected $auth_url = 'https://www.strava.com/oauth/authorize?response_type=code';
|
||||
protected $feedback = '';
|
||||
|
||||
/**
|
||||
* Factory method to get the correct Auth class based on specified string
|
||||
* or by the options setting.
|
||||
*
|
||||
* @param string $auth 'refresh' or 'forever' (default 'refresh').
|
||||
* @return WPStrava_Auth Instance of Auth
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
*/
|
||||
public static function get_auth( $auth = 'refresh' ) {
|
||||
if ( 'forever' === $auth ) {
|
||||
return new WPStrava_AuthForever();
|
||||
}
|
||||
// Default to refresh.
|
||||
return new WPStrava_AuthRefresh();
|
||||
}
|
||||
|
||||
abstract protected function get_authorize_url( $client_id );
|
||||
|
||||
public function hook() {
|
||||
if ( is_admin() ) {
|
||||
add_filter( 'pre_set_transient_settings_errors', array( $this, 'maybe_oauth' ) );
|
||||
add_action( 'admin_init', array( $this, 'init' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This runs after options are saved
|
||||
*/
|
||||
public function maybe_oauth( $value ) {
|
||||
$settings = WPStrava::get_instance()->settings;
|
||||
|
||||
// User is clearing to start-over, don't oauth, ignore other errors.
|
||||
|
||||
$input_args = array(
|
||||
'strava_id' => array(
|
||||
'filter' => FILTER_SANITIZE_NUMBER_INT,
|
||||
'flags' => FILTER_REQUIRE_ARRAY,
|
||||
),
|
||||
'strava_client_id' => array(
|
||||
'filter' => FILTER_SANITIZE_NUMBER_INT,
|
||||
'flags' => FILTER_REQUIRE_SCALAR,
|
||||
),
|
||||
'strava_client_secret' => FILTER_SANITIZE_STRING,
|
||||
);
|
||||
|
||||
$input = filter_input_array( INPUT_POST, $input_args );
|
||||
|
||||
if ( is_array( $input['strava_id'] ) && $settings->ids_empty( $input['strava_id'] ) ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
// Redirect only if all the right options are in place.
|
||||
if ( $settings->is_settings_updated( $value ) && $settings->is_option_page() ) {
|
||||
// Only re-auth if client ID and secret were saved.
|
||||
if ( ! empty( $input['strava_client_id'] ) && ! empty( $input['strava_client_secret'] ) ) {
|
||||
wp_redirect( $this->get_authorize_url( $input['strava_client_id'] ) );
|
||||
exit();
|
||||
}
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
public function init() {
|
||||
$settings = WPStrava::get_instance()->settings;
|
||||
|
||||
$input_args = array(
|
||||
'settings-updated' => FILTER_SANITIZE_STRING,
|
||||
'code' => FILTER_SANITIZE_STRING,
|
||||
);
|
||||
|
||||
$input = filter_input_array( INPUT_GET, $input_args );
|
||||
|
||||
//only update when redirected back from strava
|
||||
if ( ! isset( $input['settings-updated'] ) && $settings->is_settings_page() ) {
|
||||
if ( isset( $input['code'] ) ) {
|
||||
$info = $this->token_exchange_initial( $input['code'] );
|
||||
if ( isset( $info->access_token ) ) {
|
||||
// Translators: New strava token
|
||||
add_settings_error( 'strava_token', 'strava_token', sprintf( __( 'New Strava token retrieved. %s', 'wp-strava' ), $this->feedback ), 'updated' );
|
||||
} else {
|
||||
// throw new WPStrava_Exception( '' );
|
||||
add_settings_error( 'strava_token', 'strava_token', $this->feedback );
|
||||
}
|
||||
} elseif ( isset( $_GET['error'] ) ) {
|
||||
// Translators: authentication error mess
|
||||
add_settings_error( 'strava_token', 'strava_token', sprintf( __( 'Error authenticating at Strava: %s', 'wp-strava' ), str_replace( '_', ' ', $_GET['error'] ) ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function get_redirect_param() {
|
||||
$page_name = WPStrava::get_instance()->settings->get_page_name();
|
||||
return rawurlencode( admin_url( "options-general.php?page={$page_name}" ) );
|
||||
}
|
||||
|
||||
// Was fetch_token();
|
||||
private function token_exchange_initial( $code ) {
|
||||
$settings = WPStrava::get_instance()->settings;
|
||||
$client_id = $settings->client_id;
|
||||
$client_secret = $settings->client_secret;
|
||||
|
||||
$settings->delete_id_secret();
|
||||
|
||||
if ( $client_id && $client_secret ) {
|
||||
|
||||
$data = array(
|
||||
'client_id' => $client_id,
|
||||
'client_secret' => $client_secret,
|
||||
'code' => $code,
|
||||
);
|
||||
|
||||
$data = $this->add_initial_params( $data );
|
||||
|
||||
$strava_info = $this->token_request( $data );
|
||||
|
||||
if ( isset( $strava_info->access_token ) ) {
|
||||
$settings->add_id( $client_id );
|
||||
$settings->save_info( $client_id, $client_secret, $strava_info );
|
||||
|
||||
$this->feedback .= __( 'Successfully authenticated.', 'wp-strava' );
|
||||
return $strava_info;
|
||||
}
|
||||
|
||||
// Translators: error message from Strava
|
||||
$this->feedback .= sprintf( __( 'There was an error receiving data from Strava: <pre>%s</pre>', 'wp-strava' ), print_r( $strava_info, true ) ); // phpcs:ignore -- Debug output.
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
$this->feedback .= __( 'Missing Client ID or Client Secret.', 'wp-strava' );
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function token_request( $data ) {
|
||||
$api = new WPStrava_API();
|
||||
return $api->post( 'oauth/token', $data );
|
||||
}
|
||||
|
||||
protected function add_initial_params( $data ) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
/**
|
||||
* This functionality is deprecated and will be shut down on October 15, 2019
|
||||
*
|
||||
* @see https://developers.strava.com/docs/oauth-updates/#migration-instructions
|
||||
*/
|
||||
|
||||
/**
|
||||
* AuthForever Class
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @see http://developers.strava.com/docs/authentication/
|
||||
*/
|
||||
class WPStrava_AuthForever extends WPStrava_Auth {
|
||||
|
||||
/**
|
||||
* Authorize URL for old style forever tokens.
|
||||
*
|
||||
* @param int $client_id Strava API Client ID.
|
||||
* @return string URL to authorize against.
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 2.0.0
|
||||
*/
|
||||
protected function get_authorize_url( $client_id ) {
|
||||
return add_query_arg(
|
||||
array(
|
||||
'client_id' => $client_id,
|
||||
'redirect_uri' => $this->get_redirect_param(),
|
||||
'approval_prompt' => 'force',
|
||||
),
|
||||
$this->auth_url
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* AuthRefresh class
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @see http://developers.strava.com/docs/authentication/
|
||||
*/
|
||||
class WPStrava_AuthRefresh extends WPStrava_Auth {
|
||||
|
||||
/**
|
||||
* Hooks.
|
||||
*
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public function hook() {
|
||||
parent::hook();
|
||||
|
||||
// Refresh tokens via cronjob.
|
||||
add_action( 'init', array( $this, 'setup_auth_refresh_cron' ) );
|
||||
add_action( 'wp_strava_auth_refresh_cron', array( $this, 'auth_refresh' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up cron to refresh the auth token hourly (expires after 6-hours).
|
||||
*
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public function setup_auth_refresh_cron() {
|
||||
|
||||
// Schedule the cron job to purge all expired transients.
|
||||
if ( ! wp_next_scheduled( 'wp_strava_auth_refresh_cron' ) ) {
|
||||
wp_schedule_event( time(), 'hourly', 'wp_strava_auth_refresh_cron' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cron method to refresh auth tokens from Strava.
|
||||
*
|
||||
* @author Justin Foell
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public function auth_refresh() {
|
||||
$settings = WPStrava::get_instance()->settings;
|
||||
foreach ( $settings->info as $client_id => $info ) {
|
||||
if ( ! empty( $info->refresh_token ) ) {
|
||||
$this->token_exchange_refresh( $client_id, $info );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Authorize URL for new style refresh token auth.
|
||||
*
|
||||
* @param int $client_id Strava API Client ID.
|
||||
* @return string URL to authorize against.
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 2.0.0
|
||||
*/
|
||||
protected function get_authorize_url( $client_id ) {
|
||||
return add_query_arg(
|
||||
array(
|
||||
'client_id' => $client_id,
|
||||
'redirect_uri' => $this->get_redirect_param(),
|
||||
'approval_prompt' => 'auto',
|
||||
'scope' => 'activity:read,read',
|
||||
),
|
||||
$this->auth_url
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add 'authorization_code' grand type to first API request (when authenticating a new user).
|
||||
*
|
||||
* @param array $data Request array for the Strava API.
|
||||
* @return array Data array with 'grant_type' => 'authorization_code' added.
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 2.0.0
|
||||
*/
|
||||
protected function add_initial_params( $data ) {
|
||||
$data['grant_type'] = 'authorization_code';
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extend access by contacting strava with a refresh token.
|
||||
*
|
||||
* @param int $client_id
|
||||
* @param stdClass $info
|
||||
* @return boolean True if refreshed successfully, false otherwise.
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 2.0.0
|
||||
*/
|
||||
protected function token_exchange_refresh( $client_id, $info ) {
|
||||
$data = array(
|
||||
'client_id' => $client_id,
|
||||
'client_secret' => $info->client_secret,
|
||||
'refresh_token' => $info->refresh_token,
|
||||
'grant_type' => 'refresh_token',
|
||||
);
|
||||
|
||||
$strava_info = $this->token_request( $data );
|
||||
|
||||
if ( isset( $strava_info->access_token ) ) {
|
||||
// Translators: Token refresh success message.
|
||||
$this->feedback .= __( 'ID %s successfully re-authenticated.', 'wp-strava' );
|
||||
|
||||
if ( $strava_info->access_token != $info->access_token ) {
|
||||
// Translators: New token created message.
|
||||
$this->feedback .= __( 'ID %s access extended.', 'wp-strava' );
|
||||
|
||||
$settings = WPStrava::get_instance()->settings;
|
||||
$settings->save_info( $client_id, $info->client_secret, $strava_info );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// @TODO how to determine if refresh wasn't successful?
|
||||
$this->feedback .= sprintf( __( 'There was an error receiving data from Strava: <pre>%s</pre>', 'wp-strava' ), print_r( $strava_info, true ) ); // phpcs:ignore -- Debug output.
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
/**
|
||||
* WPStrava Exception(s).
|
||||
*/
|
||||
|
||||
// phpcs:disable Generic.Files.OneClassPerFile.MultipleFound, Generic.Classes.DuplicateClassName.Found
|
||||
|
||||
/*
|
||||
* PHP 5.2 Nonsense
|
||||
* @see http://php.net/manual/en/exception.getprevious.php#106020
|
||||
*/
|
||||
if ( version_compare( PHP_VERSION, '5.3.0', '>=' ) ) {
|
||||
abstract class WPStrava_Abstract_Exception extends Exception {}
|
||||
} else {
|
||||
abstract class WPStrava_52_Exception extends Exception {
|
||||
protected $previous;
|
||||
|
||||
public function __construct( $message, $code = 0, Exception $previous = null ) {
|
||||
$this->previous = $previous;
|
||||
parent::__construct( $message, $code );
|
||||
}
|
||||
|
||||
public function getPrevious() {
|
||||
return $this->previous;
|
||||
}
|
||||
}
|
||||
|
||||
abstract class WPStrava_Abstract_Exception extends WPStrava_52_Exception {}
|
||||
}
|
||||
|
||||
/*
|
||||
* Exception class for error handling/display.
|
||||
*/
|
||||
class WPStrava_Exception extends WPStrava_Abstract_Exception {
|
||||
|
||||
/**
|
||||
* Create a WPStrava_Exception from a WP_Error.
|
||||
*
|
||||
* @param WP_Error $error
|
||||
* @return WPStrava_Exception
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 1.6.0
|
||||
*/
|
||||
public static function from_wp_error( WP_Error $error ) {
|
||||
$class = __CLASS__;
|
||||
return new $class( $error->get_error_message( $error->get_error_code() ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* HTML version of this exception.
|
||||
*
|
||||
* @return string The exception string wrapped in <pre> tags.
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 1.6.0
|
||||
*/
|
||||
public function to_html() {
|
||||
return '<pre>' . $this . '</pre>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic method to convert this exception to a string.
|
||||
*
|
||||
* @return string
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 1.6.0
|
||||
*/
|
||||
public function __toString() {
|
||||
if ( WPSTRAVA_DEBUG && $this->getPrevious() ) {
|
||||
return $this->get_formatted_message( $this->getPrevious() );
|
||||
}
|
||||
|
||||
return $this->get_formatted_message( $this );
|
||||
}
|
||||
|
||||
/**
|
||||
* Exception message with extra formatting.
|
||||
*
|
||||
* @param Exception $exception
|
||||
* @return string Formatted exception message.
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 1.6.0
|
||||
*/
|
||||
public function get_formatted_message( $exception ) {
|
||||
$code = $exception->getCode();
|
||||
|
||||
if ( $exception->getPrevious() ) {
|
||||
if ( $code ) {
|
||||
// Translators: Message shown when there's an exception thrown with a code and there's more details available.
|
||||
return sprintf( __( 'WP Strava ERROR %1$s %2$s - See full error by adding<br/><code>define( \'WPSTRAVA_DEBUG\', true );</code><br/>to wp-config.php', 'wp-strava' ), $code, $this->getMessage() );
|
||||
}
|
||||
// Translators: Message shown when there's an exception thrown (no code) and there's more details available.
|
||||
return sprintf( __( 'WP Strava ERROR %1$s - See full error by adding<br/><code>define( \'WPSTRAVA_DEBUG\', true );</code><br/>to wp-config.php', 'wp-strava' ), $this->getMessage() );
|
||||
}
|
||||
|
||||
if ( $code ) {
|
||||
// Translators: Message shown when there's an exception thrown with a code.
|
||||
return sprintf( __( 'WP Strava ERROR %1$s %2$s', 'wp-strava' ), $code, $exception->getMessage() );
|
||||
}
|
||||
// Translators: Message shown when there's an exception thrown without a code.
|
||||
return sprintf( __( 'WP Strava ERROR %1$s', 'wp-strava' ), $exception->getMessage() );
|
||||
}
|
||||
}
|
||||
// phpcs:enable
|
||||
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
class WPStrava_LatestActivities {
|
||||
public static function get_activities_html( $args ) {
|
||||
if ( isset( $args['athlete_token'] ) ) {
|
||||
// Translators: Message shown when using deprecated athlete_token parameter.
|
||||
return __( 'The <code>athlete_token</code> parameter is deprecated as of WP-Strava version 2 and should be replaced with <code>client_id</code>.', 'wp-strava' );
|
||||
}
|
||||
|
||||
$defaults = array(
|
||||
'client_id' => WPStrava::get_instance()->settings->get_default_id(),
|
||||
'strava_club_id' => null,
|
||||
'quantity' => 5,
|
||||
'som' => WPStrava::get_instance()->settings->som,
|
||||
);
|
||||
|
||||
$args = wp_parse_args( $args, $defaults );
|
||||
|
||||
$som = WPStrava_SOM::get_som( $args['som'] );
|
||||
$strava_activity = WPStrava::get_instance()->activity;
|
||||
$activities = array();
|
||||
|
||||
try {
|
||||
$activities = $strava_activity->get_activities( $args['client_id'], $args['strava_club_id'], $args['quantity'] );
|
||||
} catch ( WPStrava_Exception $e ) {
|
||||
return $e->to_html();
|
||||
}
|
||||
|
||||
$response = "<ul id='activities'>";
|
||||
foreach ( $activities as $activity ) {
|
||||
$response .= "<li class='activity'>";
|
||||
$response .= empty( $activity->id ) ?
|
||||
$activity->name :
|
||||
"<a href='" . WPStrava_Activity::ACTIVITIES_URL . $activity->id . "'>" . $activity->name . '</a>';
|
||||
$response .= "<div class='activity-item'>";
|
||||
|
||||
if ( ! empty( $activity->start_date_local ) ) {
|
||||
$unixtime = strtotime( $activity->start_date_local );
|
||||
$response .= sprintf(
|
||||
// Translators: Shows something like "On <date> <[went 10 miles] [during 2 hours] [climbing 100 feet]>."
|
||||
__( 'On %1$s %2$s', 'wp-strava' ),
|
||||
date_i18n( get_option( 'date_format' ), $unixtime ),
|
||||
self::get_activity_time( $unixtime )
|
||||
);
|
||||
}
|
||||
|
||||
if ( is_numeric( $args['strava_club_id'] ) ) {
|
||||
$name = $activity->athlete->firstname . ' ' . $activity->athlete->lastname;
|
||||
$response .= empty( $activity->athlete->id ) ?
|
||||
" {$name}" :
|
||||
" <a href='" . WPStrava_Activity::ATHLETES_URL . $activity->athlete->id . "'>" . $name . '</a>';
|
||||
}
|
||||
|
||||
// Translators: "went 10 miles"
|
||||
$response .= sprintf( __( ' went %1$s %2$s', 'wp-strava' ), $som->distance( $activity->distance ), $som->get_distance_label() );
|
||||
// Translators: "during 2 hours"
|
||||
$response .= sprintf( __( ' during %1$s %2$s', 'wp-strava' ), $som->time( $activity->elapsed_time ), $som->get_time_label() );
|
||||
|
||||
if ( ! WPStrava::get_instance()->settings->hide_elevation ) {
|
||||
// Translators: "climbing 100 ft."
|
||||
$response .= sprintf( __( ' climbing %1$s %2$s', 'wp-strava' ), $som->elevation( $activity->total_elevation_gain ), $som->get_elevation_label() );
|
||||
}
|
||||
|
||||
$response .= '</div></li>';
|
||||
}
|
||||
$response .= '</ul>';
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the activity time, possibly hiding it.
|
||||
*
|
||||
* @param int $unixtime
|
||||
* @return string Formatted time, or empty string depending on hide_time option.
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 1.7.1
|
||||
*/
|
||||
public static function get_activity_time( $unixtime ) {
|
||||
if ( WPStrava::get_instance()->settings->hide_time ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return date_i18n( get_option( 'time_format' ), $unixtime );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
/**
|
||||
* Latest Activities Shortcode [activities].
|
||||
* @package WPStrava
|
||||
*/
|
||||
|
||||
/**
|
||||
* Latest Activities Shortcode class (converted from LatestRides).
|
||||
*
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 1.3.0
|
||||
*/
|
||||
class WPStrava_LatestActivitiesShortcode {
|
||||
|
||||
/**
|
||||
* Whether or not to enqueue styles (if shortcode is present).
|
||||
*
|
||||
* @var boolean
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 1.3.0
|
||||
*/
|
||||
private $add_script = false;
|
||||
|
||||
/**
|
||||
* Constructor (converted from static init()).
|
||||
*
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 1.3.0
|
||||
*/
|
||||
public function __construct() {
|
||||
add_shortcode( 'activities', array( $this, 'handler' ) );
|
||||
add_action( 'wp_footer', array( $this, 'print_scripts' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Shortcode handler for [activities].
|
||||
*
|
||||
* [activities som=metric quantity=5 client_id=xxx|strava_club_id=yyy]
|
||||
*
|
||||
* @param array $atts Array of attributes (id, som, etc.).
|
||||
* @return string Shortcode output
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 1.3.0
|
||||
*/
|
||||
public function handler( $atts ) {
|
||||
$this->add_script = true;
|
||||
return WPStrava_LatestActivities::get_activities_html( $atts );
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue style if shortcode is being used.
|
||||
*
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 1.3.0
|
||||
*/
|
||||
public function print_scripts() {
|
||||
if ( $this->add_script ) {
|
||||
wp_enqueue_style( 'wp-strava-style' );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* WP Strava Latest Activities Widget Class
|
||||
*/
|
||||
class WPStrava_LatestActivitiesWidget extends WP_Widget {
|
||||
|
||||
public function __construct() {
|
||||
$widget_ops = array(
|
||||
'classname' => 'LatestActivitiesWidget',
|
||||
'description' => __( 'Will show your latest activities from strava.com.', 'wp-strava' ),
|
||||
);
|
||||
parent::__construct( 'wp-strava', __( 'Strava Latest Activities List', 'wp-strava' ), $widget_ops );
|
||||
add_action( 'wp_enqueue_scripts', array( $this, 'maybe_enqueue' ) );
|
||||
}
|
||||
|
||||
public function maybe_enqueue() {
|
||||
if ( is_active_widget( false, false, $this->id_base ) ) {
|
||||
wp_enqueue_style( 'wp-strava-style' ); // Only load this when widget is loaded.
|
||||
}
|
||||
}
|
||||
|
||||
/** @see WP_Widget::widget */
|
||||
public function widget( $args, $instance ) {
|
||||
$title = apply_filters( 'widget_title', empty( $instance['title'] ) ? __( 'Latest Activities', 'wp-strava' ) : $instance['title'] );
|
||||
|
||||
$activities_args = array(
|
||||
'client_id' => isset( $instance['client_id'] ) ? $instance['client_id'] : null,
|
||||
'strava_club_id' => isset( $instance['strava_club_id'] ) ? $instance['strava_club_id'] : null,
|
||||
'quantity' => isset( $instance['quantity'] ) ? $instance['quantity'] : null,
|
||||
);
|
||||
|
||||
// phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped -- Widget OK.
|
||||
echo $args['before_widget'];
|
||||
if ( $title ) {
|
||||
echo $args['before_title'] . $title . $args['after_title'];
|
||||
}
|
||||
echo WPStrava_LatestActivities::get_activities_html( $activities_args );
|
||||
echo $args['after_widget'];
|
||||
// phpcs:enable WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
}
|
||||
|
||||
/** @see WP_Widget::update */
|
||||
public function update( $new_instance, $old_instance ) {
|
||||
$instance = $old_instance;
|
||||
$instance['title'] = wp_strip_all_tags( $new_instance['title'] );
|
||||
$instance['client_id'] = wp_strip_all_tags( $new_instance['client_id'] );
|
||||
$instance['strava_club_id'] = wp_strip_all_tags( $new_instance['strava_club_id'] );
|
||||
$instance['quantity'] = $new_instance['quantity'];
|
||||
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/** @see WP_Widget::form */
|
||||
public function form( $instance ) {
|
||||
$title = isset( $instance['title'] ) ? esc_attr( $instance['title'] ) : __( 'Latest Activities', 'wp-strava' );
|
||||
$all_ids = WPStrava::get_instance()->settings->get_all_ids();
|
||||
$client_id = isset( $instance['client_id'] ) ? esc_attr( $instance['client_id'] ) : WPStrava::get_instance()->settings->get_default_id();
|
||||
$strava_club_id = isset( $instance['strava_club_id'] ) ? esc_attr( $instance['strava_club_id'] ) : '';
|
||||
$quantity = isset( $instance['quantity'] ) ? absint( $instance['quantity'] ) : 5;
|
||||
|
||||
?>
|
||||
<p>
|
||||
<label for="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>"><?php esc_html_e( 'Title:', 'wp-strava' ); ?></label>
|
||||
<input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'title' ) ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>" />
|
||||
</p>
|
||||
<p>
|
||||
<label for="<?php echo esc_attr( $this->get_field_id( 'client_id' ) ); ?>"><?php esc_html_e( 'Athlete:', 'wp-strava' ); ?></label>
|
||||
<select name="<?php echo esc_attr( $this->get_field_name( 'client_id' ) ); ?>">
|
||||
<?php foreach ( $all_ids as $id => $nickname ) : ?>
|
||||
<option value="<?php echo esc_attr( $id ); ?>"<?php selected( $id, $client_id ); ?>><?php echo esc_html( $nickname ); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</p>
|
||||
<p>
|
||||
<label for="<?php echo esc_attr( $this->get_field_id( 'strava_club_id' ) ); ?>"><?php esc_html_e( 'Club ID (leave blank to show single Athlete):', 'wp-strava' ); ?></label>
|
||||
<input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'strava_club_id' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'strava_club_id' ) ); ?>" type="text" value="<?php echo esc_attr( $strava_club_id ); ?>" />
|
||||
</p>
|
||||
<p>
|
||||
<label for="<?php echo esc_attr( $this->get_field_id( 'quantity' ) ); ?>"><?php esc_html_e( 'Quantity:', 'wp-strava' ); ?></label>
|
||||
<input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'quantity' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'quantity' ) ); ?>" type="text" value="<?php echo esc_html( $quantity ); ?>" />
|
||||
</p>
|
||||
<?php
|
||||
}
|
||||
|
||||
} // class LatestActivitiesWidget
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
class WPStrava_LatestMap {
|
||||
|
||||
public static function get_map_html( $args ) {
|
||||
$defaults = array(
|
||||
'client_id' => WPStrava::get_instance()->settings->get_default_id(),
|
||||
'strava_club_id' => null,
|
||||
'distance_min' => 0,
|
||||
);
|
||||
|
||||
$args = wp_parse_args( $args, $defaults );
|
||||
|
||||
$strava_activity = WPStrava::get_instance()->activity;
|
||||
|
||||
$activities = array();
|
||||
|
||||
try {
|
||||
$activities = $strava_activity->get_activities( $args['client_id'], $args['strava_club_id'] );
|
||||
} catch ( WPStrava_Exception $e ) {
|
||||
// If athlete_token is still set, warn about that first and foremost.
|
||||
if ( isset( $args['athlete_token'] ) ) {
|
||||
// Translators: Message shown when using deprecated athlete_token parameter.
|
||||
echo wp_kses_post( __( 'The <code>athlete_token</code> parameter is deprecated as of WP-Strava version 2 and should be replaced with <code>client_id</code>.', 'wp-strava' ) );
|
||||
} else {
|
||||
echo $e->to_html(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Debug only.
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty( $activities ) ) {
|
||||
|
||||
if ( ! empty( $args['distance_min'] ) ) {
|
||||
$activities = $strava_activity->get_activities_longer_than( $activities, $args['distance_min'] );
|
||||
}
|
||||
|
||||
$activity = current( $activities );
|
||||
|
||||
echo empty( $activity->map ) ?
|
||||
// Translators: Text with activity name shown in place of image if not available.
|
||||
esc_html( sprintf( __( 'Map not available for activity "%s"', 'wp-strava' ), $activity->name ) ) :
|
||||
"<a title='" . esc_attr( $activity->name ) . "' href='" . esc_attr( WPStrava_Activity::ACTIVITIES_URL . $activity->id ) . "'>" .
|
||||
WPStrava_StaticMap::get_image_tag( $activity ) . // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Image OK.
|
||||
'</a>';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
/**
|
||||
* Latest Map Shortcode [latest_map].
|
||||
* @package WPStrava
|
||||
*/
|
||||
|
||||
/**
|
||||
* Latest Map Shortcode class.
|
||||
*
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 2.0.1
|
||||
*/
|
||||
class WPStrava_LatestMapShortcode {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 2.0.1
|
||||
*/
|
||||
public function __construct() {
|
||||
add_shortcode( 'latest_map', array( $this, 'handler' ) );
|
||||
}
|
||||
/**
|
||||
* Shortcode handler for [latest_map].
|
||||
*
|
||||
* [latest_map som=metric distance_min=10 client_id=xxx|strava_club_id=yyy]
|
||||
*
|
||||
* @param array $atts Array of attributes (client_id, som, etc.).
|
||||
* @return string Shortcode output
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 2.0.1
|
||||
*/
|
||||
public function handler( $atts ) {
|
||||
return WPStrava_LatestMap::get_map_html( $atts );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
class WPStrava_LatestMapWidget extends WP_Widget {
|
||||
|
||||
private $som;
|
||||
|
||||
public function __construct() {
|
||||
$this->som = WPStrava_SOM::get_som();
|
||||
|
||||
parent::__construct(
|
||||
false,
|
||||
__( 'Strava Latest Map', 'wp-strava' ), // Name
|
||||
array( 'description' => __( 'Strava latest activity using static google map image', 'wp-strava' ) ) // Args.
|
||||
);
|
||||
}
|
||||
|
||||
public function form( $instance ) {
|
||||
// outputs the options form on admin
|
||||
$title = isset( $instance['title'] ) ? esc_attr( $instance['title'] ) : __( 'Latest Activity Map', 'wp-strava' );
|
||||
$all_ids = WPStrava::get_instance()->settings->get_all_ids();
|
||||
$client_id = isset( $instance['client_id'] ) ? esc_attr( $instance['client_id'] ) : WPStrava::get_instance()->settings->get_default_id();
|
||||
$distance_min = isset( $instance['distance_min'] ) ? esc_attr( $instance['distance_min'] ) : '';
|
||||
$strava_club_id = isset( $instance['strava_club_id'] ) ? esc_attr( $instance['strava_club_id'] ) : '';
|
||||
|
||||
?>
|
||||
<p>
|
||||
<label for="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>">
|
||||
<?php // Translator: Widget Title. ?>
|
||||
<?php esc_html_e( 'Title:', 'wp-strava' ); ?>
|
||||
</label>
|
||||
<input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'title' ) ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>" />
|
||||
</p>
|
||||
<p>
|
||||
<label for="<?php echo esc_attr( $this->get_field_id( 'client_id' ) ); ?>"><?php esc_html_e( 'Athlete:', 'wp-strava' ); ?></label>
|
||||
<select name="<?php echo esc_attr( $this->get_field_name( 'client_id' ) ); ?>">
|
||||
<?php foreach ( $all_ids as $id => $nickname ) : ?>
|
||||
<option value="<?php echo esc_attr( $id ); ?>"<?php selected( $id, $client_id ); ?>><?php echo esc_html( $nickname ); ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</p>
|
||||
<p>
|
||||
<label for="<?php echo esc_attr( $this->get_field_id( 'distance_min' ) ); ?>">
|
||||
<?php // Translators: Label for minimum distance input. ?>
|
||||
<?php echo esc_html( sprintf( __( 'Min. Distance (%s):', 'wp-strava' ), $this->som->get_distance_label() ) ); ?>
|
||||
</label>
|
||||
<input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'distance_min' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'distance_min' ) ); ?>" type="text" value="<?php echo esc_attr( $distance_min ); ?>" />
|
||||
</p>
|
||||
<p>
|
||||
<label for="<?php echo esc_attr( $this->get_field_id( 'strava_club_id' ) ); ?>"><?php esc_html_e( 'Club ID (leave blank to show Athlete):', 'wp-strava' ); ?></label>
|
||||
<input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'strava_club_id' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'strava_club_id' ) ); ?>" type="text" value="<?php echo esc_attr( $strava_club_id ); ?>" />
|
||||
</p>
|
||||
<?php
|
||||
}
|
||||
|
||||
public function update( $new_instance, $old_instance ) {
|
||||
// Processes widget options to be saved from the admin.
|
||||
$instance = $old_instance;
|
||||
$instance['title'] = wp_strip_all_tags( $new_instance['title'] );
|
||||
$instance['client_id'] = wp_strip_all_tags( $new_instance['client_id'] );
|
||||
$instance['strava_club_id'] = wp_strip_all_tags( $new_instance['strava_club_id'] );
|
||||
$instance['distance_min'] = wp_strip_all_tags( $new_instance['distance_min'] );
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to render the widget on the front end.
|
||||
*
|
||||
* @param array $args Arguments from the widget settings.
|
||||
* @param array $instance Settings for this particular widget.
|
||||
*/
|
||||
public function widget( $args, $instance ) {
|
||||
|
||||
$title = apply_filters( 'widget_title', empty( $instance['title'] ) ? __( 'Latest Activity Map', 'wp-strava' ) : $instance['title'] );
|
||||
|
||||
$activities_args = array(
|
||||
'client_id' => isset( $instance['client_id'] ) ? $instance['client_id'] : null,
|
||||
'strava_club_id' => isset( $instance['strava_club_id'] ) ? $instance['strava_club_id'] : null,
|
||||
'distance_min' => isset( $instance['distance_min'] ) ? absint( $instance['distance_min'] ) : 0,
|
||||
);
|
||||
|
||||
// phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped -- Widget OK.
|
||||
echo $args['before_widget'];
|
||||
if ( $title ) {
|
||||
echo $args['before_title'] . $title . $args['after_title'];
|
||||
}
|
||||
echo WPStrava_LatestMap::get_map_html( $activities_args );
|
||||
echo $args['after_widget'];
|
||||
// phpcs:enable WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
<?php
|
||||
/**
|
||||
* Route Shortcode [route].
|
||||
* @package WPStrava
|
||||
*/
|
||||
|
||||
/**
|
||||
* Route Shortcode class.
|
||||
*
|
||||
* @author Daniel Lintott
|
||||
* @since 1.3.0
|
||||
*/
|
||||
class WPStrava_RouteShortcode {
|
||||
|
||||
/**
|
||||
* Whether or not to enqueue styles (if shortcode is present).
|
||||
*
|
||||
* @var boolean
|
||||
* @author Daniel Lintott
|
||||
* @since 1.3.0
|
||||
*/
|
||||
private $add_script = false;
|
||||
|
||||
/**
|
||||
* Constructor (converted from static init()).
|
||||
*
|
||||
* @author Daniel Lintott
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 1.6.0
|
||||
*/
|
||||
public function __construct() {
|
||||
add_shortcode( 'route', array( $this, 'handler' ) );
|
||||
add_action( 'wp_footer', array( $this, 'print_scripts' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Shortcode handler for [route].
|
||||
*
|
||||
* [route id=id som=metric map_width="100%" map_height="400px" markers=false]
|
||||
*
|
||||
* @param array $atts Array of attributes (id, map_width, etc.).
|
||||
* @return string Shortcode output
|
||||
* @author Daniel Lintott
|
||||
* @since 1.3.0
|
||||
*/
|
||||
public function handler( $atts ) {
|
||||
if ( isset( $atts['athlete_token'] ) ) {
|
||||
// Translators: Message shown when using deprecated athlete_token parameter.
|
||||
return __( 'The <code>athlete_token</code> parameter is deprecated as of WP-Strava version 2 and should be replaced with <code>client_id</code>.', 'wp-strava' );
|
||||
}
|
||||
|
||||
$this->add_script = true;
|
||||
|
||||
$defaults = array(
|
||||
'id' => 0,
|
||||
'som' => WPStrava::get_instance()->settings->som,
|
||||
'map_width' => '480',
|
||||
'map_height' => '320',
|
||||
'client_id' => WPStrava::get_instance()->settings->get_default_id(),
|
||||
'markers' => false,
|
||||
'image_only' => false,
|
||||
);
|
||||
|
||||
$atts = shortcode_atts( $defaults, $atts, 'route' );
|
||||
|
||||
/* Make sure boolean values are actually boolean
|
||||
* @see https://wordpress.stackexchange.com/a/119299
|
||||
*/
|
||||
$atts['markers'] = filter_var( $atts['markers'], FILTER_VALIDATE_BOOLEAN );
|
||||
$atts['image_only'] = filter_var( $atts['image_only'], FILTER_VALIDATE_BOOLEAN );
|
||||
|
||||
$route = WPStrava::get_instance()->routes;
|
||||
$route_details = null;
|
||||
|
||||
try {
|
||||
$route_details = $route->get_route( $atts['id'] );
|
||||
} catch ( WPStrava_Exception $e ) {
|
||||
return $e->to_html();
|
||||
}
|
||||
|
||||
$route_output = '';
|
||||
if ( $route_details ) {
|
||||
$route_output = '<div id="activity-header-' . $atts['id'] . '" class="wp-strava-activity-container">';
|
||||
if ( ! $atts['image_only'] ) {
|
||||
$route_output .= $this->get_table( $route_details, $atts['som'] );
|
||||
}
|
||||
|
||||
// Sanitize width & height.
|
||||
$map_width = str_replace( '%', '', $atts['map_width'] );
|
||||
$map_height = str_replace( '%', '', $atts['map_height'] );
|
||||
$map_width = str_replace( 'px', '', $map_width );
|
||||
$map_height = str_replace( 'px', '', $map_height );
|
||||
|
||||
$route_output .= '<a title="' . $route_details->name . '" href="' . WPStrava_Routes::ROUTES_URL . $route_details->id . '">' .
|
||||
WPStrava_StaticMap::get_image_tag( $route_details, $map_height, $map_width, $atts['markers'] ) .
|
||||
'</a>
|
||||
</div>';
|
||||
} // End if( $route_details ).
|
||||
return $route_output;
|
||||
}
|
||||
|
||||
/**
|
||||
* The the route details in in HTML table.
|
||||
*
|
||||
* @param string $route_details route details from the route class.
|
||||
* @param string $som System of measure (english/metric).
|
||||
* @return string HTML Table of route details.
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 1.7.0
|
||||
*/
|
||||
private function get_table( $route_details, $som ) {
|
||||
$strava_som = WPStrava_SOM::get_som( $som );
|
||||
|
||||
$elevation_title = '<th>' . __( 'Elevation Gain', 'wp-strava' ) . '</th>';
|
||||
$elevation = '<td>' . $strava_som->elevation( $route_details->elevation_gain ) . '</td>';
|
||||
$elevation_label = '<td>' . $strava_som->get_elevation_label() . '</td>';
|
||||
|
||||
if ( WPStrava::get_instance()->settings->hide_elevation ) {
|
||||
$elevation = '';
|
||||
$elevation_title = '';
|
||||
$elevation_label = '';
|
||||
}
|
||||
|
||||
return '
|
||||
<table id="activity-details-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>' . __( 'Est. Moving Time', 'wp-strava' ) . '</th>
|
||||
<th>' . __( 'Distance', 'wp-strava' ) . '</th>
|
||||
' . $elevation_title . '
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="activity-details-table-info">
|
||||
<td>' . $strava_som->time( $route_details->estimated_moving_time ) . '</td>
|
||||
<td>' . $strava_som->distance( $route_details->distance ) . '</td>
|
||||
' . $elevation . '
|
||||
</tr>
|
||||
<tr class="activity-details-table-units">
|
||||
<td>' . $strava_som->get_time_label() . '</td>
|
||||
<td>' . $strava_som->get_distance_label() . '</td>
|
||||
' . $elevation_label . '
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
';
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue style if shortcode is being used.
|
||||
*
|
||||
* @author Daniel Lintott
|
||||
* @since 1.3.0
|
||||
*/
|
||||
public function print_scripts() {
|
||||
if ( $this->add_script ) {
|
||||
wp_enqueue_style( 'wp-strava-style' );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Routes is a class wrapper for the Strava REST API functions.
|
||||
*
|
||||
* @author Daniel Lintott
|
||||
* @since 1.3.0
|
||||
*/
|
||||
class WPStrava_Routes {
|
||||
const ROUTES_URL = 'https://strava.com/routes/';
|
||||
|
||||
/**
|
||||
* Get single route by ID.
|
||||
*
|
||||
* @param int $route_id ID of activity to retrieve.
|
||||
* @return object stdClass representing this route.
|
||||
* @author Daniel Lintott
|
||||
*/
|
||||
public function get_route( $route_id ) {
|
||||
return WPStrava::get_instance()->get_api()->get( "routes/{$route_id}" );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
abstract class WPStrava_SOM {
|
||||
|
||||
/**
|
||||
* Factory method to get the correct SOM class based on specified units
|
||||
* or by the options setting.
|
||||
*
|
||||
* @param string $som 'english' or 'metric'
|
||||
* @return WPStrava_SOM Instance of SOM
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
*/
|
||||
public static function get_som( $som = null ) {
|
||||
$som = $som ? $som : WPStrava::get_instance()->settings->som;
|
||||
if ( 'english' === $som ) {
|
||||
return new WPStrava_SOMEnglish();
|
||||
}
|
||||
// Default to metric.
|
||||
return new WPStrava_SOMMetric();
|
||||
}
|
||||
|
||||
abstract public function distance( $m );
|
||||
abstract public function distance_inverse( $dist );
|
||||
abstract public function get_distance_label();
|
||||
abstract public function speed( $mps );
|
||||
abstract public function get_speed_label();
|
||||
abstract public function elevation( $m );
|
||||
abstract public function get_elevation_label();
|
||||
abstract public function pace( $mps );
|
||||
abstract public function get_pace_label();
|
||||
|
||||
/**
|
||||
* Create a time string of hours:minutes:seconds from just seconds.
|
||||
*
|
||||
* @return string Time formatted as 'H:i:s'.
|
||||
* @see https://stackoverflow.com/a/20870843/2146022
|
||||
*/
|
||||
public function time( $seconds ) {
|
||||
$zero = new DateTime( '@0' );
|
||||
$offset = new DateTime( "@{$seconds}" );
|
||||
$diff = $zero->diff( $offset );
|
||||
return sprintf( '%02d:%02d:%02d', $diff->days * 24 + $diff->h, $diff->i, $diff->s );
|
||||
}
|
||||
|
||||
/**
|
||||
* Label for hours.
|
||||
*
|
||||
* @return string 'hours'
|
||||
*/
|
||||
public function get_time_label() {
|
||||
return __( 'hours', 'wp-strava' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Abbreviated label for this system of measure's pace - Minutes Per 100 Meters: min/100m. Same for English/metric.
|
||||
*
|
||||
* @return string 'min/100m'
|
||||
*/
|
||||
public function get_swimpace_label() {
|
||||
return __( 'min/100m', 'wp-strava' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Change meters per second to Minutes Per 100 Meters. Same for English/metric.
|
||||
*
|
||||
* @param float|string $mps Meters per second.
|
||||
* @return string Minutes Per 100 Meters.
|
||||
*/
|
||||
public function swimpace( $mps ) {
|
||||
|
||||
$kmh = $mps * 3.6;
|
||||
$s = 3600 / $kmh / 10;
|
||||
$ss = $s / 60;
|
||||
$ms = floor( $ss ) * 60;
|
||||
$sec = sprintf( '%02d', round( $s - $ms ) );
|
||||
$min = floor( $ss );
|
||||
|
||||
return "{$min}:{$sec}";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* SOM English class.
|
||||
*
|
||||
* All conversions are limited to 2 decimal places.
|
||||
*/
|
||||
class WPStrava_SOMEnglish extends WPStrava_SOM {
|
||||
|
||||
/**
|
||||
* Change meters to miles.
|
||||
*
|
||||
* @param float|string $m Distance in meters.
|
||||
* @return string Distance in miles.
|
||||
*/
|
||||
public function distance( $m ) {
|
||||
return number_format_i18n( $m / 1609.344, 2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Change miles to meters.
|
||||
*
|
||||
* @param float $dist Distance in miles.
|
||||
* @return float Distance in meters.
|
||||
*/
|
||||
public function distance_inverse( $dist ) {
|
||||
return (float) number_format( $dist * 1609.344, 2, '.', '' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Abbreviated label for this system of measure's distance - Miles: mi.
|
||||
*
|
||||
* @return string 'mi.'
|
||||
*/
|
||||
public function get_distance_label() {
|
||||
return __( 'mi.', 'wp-strava' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Change meters per second to miles per hour.
|
||||
*
|
||||
* @param float|string $mps Meters per second.
|
||||
* @return string Miles per hour.
|
||||
*/
|
||||
public function speed( $mps ) {
|
||||
return number_format_i18n( $mps * 2.2369, 2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Abbreviated label for this system of measure's speed - Miles Per Hour: mph
|
||||
*
|
||||
* @return string 'mph'
|
||||
*/
|
||||
public function get_speed_label() {
|
||||
return __( 'mph', 'wp-strava' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Change meters per second to minutes per mile.
|
||||
*
|
||||
* @param float|string $mps Meters per second.
|
||||
* @return string Minutes Per Mile.
|
||||
*/
|
||||
public function pace( $mps ) {
|
||||
|
||||
if ( ! $mps ) {
|
||||
return __( 'N/A', 'wp-strava' );
|
||||
}
|
||||
|
||||
$mph = $mps * 2.2369;
|
||||
$s = 3600 / $mph;
|
||||
$ss = $s / 60;
|
||||
$ms = floor( $ss ) * 60;
|
||||
$sec = sprintf( '%02d', round( $s - $ms ) );
|
||||
$min = floor( $ss );
|
||||
|
||||
return "{$min}:{$sec}";
|
||||
}
|
||||
|
||||
/**
|
||||
* Abbreviated label for this system of measure's pace - Minutes Per Mile: min/mile
|
||||
*
|
||||
* @return string 'min/mile'
|
||||
*/
|
||||
public function get_pace_label() {
|
||||
return __( 'min/mile', 'wp-strava' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Change meters to feet.
|
||||
*
|
||||
* @param float|string $m Elevation in meters.
|
||||
* @return string Elevation in feet.
|
||||
*/
|
||||
public function elevation( $m ) {
|
||||
return number_format_i18n( $m / 0.3048, 2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Abbreviated label for this system of measure's elevation - Feet: ft.
|
||||
*
|
||||
* @return string 'ft.'
|
||||
*/
|
||||
public function get_elevation_label() {
|
||||
return __( 'ft.', 'wp-strava' );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* SOM Metric class.
|
||||
*
|
||||
* All conversions are limited to 2 decimal places.
|
||||
*/
|
||||
class WPStrava_SOMMetric extends WPStrava_SOM {
|
||||
|
||||
/**
|
||||
* Change meters to kilometers.
|
||||
*
|
||||
* @param float|string $m Distance in meters.
|
||||
* @return string Distance in kilometers.
|
||||
*/
|
||||
public function distance( $m ) {
|
||||
return number_format_i18n( $m / 1000, 2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Change kilometers to meters.
|
||||
*
|
||||
* @param float $dist Distance in kilometers.
|
||||
* @return float Distance in meters.
|
||||
*/
|
||||
public function distance_inverse( $dist ) {
|
||||
return (float) number_format( $dist * 1000, 2, '.', '' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Abbreviated label for this system of measure's distance - Kilometers: km
|
||||
*
|
||||
* @return string 'km'
|
||||
*/
|
||||
public function get_distance_label() {
|
||||
return __( 'km', 'wp-strava' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Change meters per second to kilometers per hour.
|
||||
*
|
||||
* @param float|string $mps Meters per second.
|
||||
* @return string Kilometers per hour.
|
||||
*/
|
||||
public function speed( $mps ) {
|
||||
return number_format_i18n( $mps * 3.6, 2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Abbreviated label for this system of measure's speed - Kilometers Per Hour: km/h
|
||||
*
|
||||
* @return string 'km/h'
|
||||
*/
|
||||
public function get_speed_label() {
|
||||
return __( 'km/h', 'wp-strava' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Change meters per second to minutes per kilometer.
|
||||
*
|
||||
* @param float|string $mps Meters per second.
|
||||
* @return string Minutes per kilometer.
|
||||
*/
|
||||
public function pace( $mps ) {
|
||||
|
||||
if ( ! $mps ) {
|
||||
return __( 'N/A', 'wp-strava' );
|
||||
}
|
||||
|
||||
// 4 m/s => 14,4 km/h => 4:10 min/km
|
||||
$kmh = $mps * 3.6;
|
||||
$s = 3600 / $kmh;
|
||||
$ss = $s / 60;
|
||||
$ms = floor( $ss ) * 60;
|
||||
$sec = sprintf( '%02d', round( $s - $ms ) );
|
||||
$min = floor( $ss );
|
||||
|
||||
return "{$min}:{$sec}";
|
||||
}
|
||||
|
||||
/**
|
||||
* Abbreviated label for this system of measure's speed - Minutes Per Kilometers: min/km
|
||||
*
|
||||
* @return string 'min/km'
|
||||
*/
|
||||
public function get_pace_label() {
|
||||
return __( 'min/km', 'wp-strava' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Change meters to meters };^)
|
||||
*
|
||||
* @param float|string $m Elevation in meters.
|
||||
* @return string Elevation in meters.
|
||||
*/
|
||||
public function elevation( $m ) {
|
||||
return number_format_i18n( $m, 2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Abbreviated label for this system of measure's elevation - Meters: meters
|
||||
*
|
||||
* @return string 'meters'
|
||||
*/
|
||||
public function get_elevation_label() {
|
||||
return __( 'meters', 'wp-strava' );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,761 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* V3 - http://strava.github.io/api/v3/oauth/
|
||||
*
|
||||
* Set up an "API Application" at Strava
|
||||
* Save the Client ID and Client Secret in WordPress - redirect to strava oauth/authorize URL for permission
|
||||
* Get redirected back to this settings page with ?code= or ?error=
|
||||
* Use code to retrieve auth token
|
||||
*/
|
||||
class WPStrava_Settings {
|
||||
|
||||
private $ids = array();
|
||||
private $page_name = 'wp-strava-options';
|
||||
private $option_page = 'wp-strava-settings-group';
|
||||
private $adding_athlete = true;
|
||||
|
||||
/**
|
||||
* Register actions & filters for menus and authentication.
|
||||
*
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 0.62
|
||||
*/
|
||||
public function hook() {
|
||||
// Load IDs for any subsequent actions.
|
||||
$this->ids = $this->get_ids();
|
||||
|
||||
add_action( 'admin_init', array( $this, 'register_strava_settings' ) );
|
||||
add_action( 'admin_menu', array( $this, 'add_strava_menu' ) );
|
||||
add_filter( 'plugin_action_links_' . WPSTRAVA_PLUGIN_NAME, array( $this, 'settings_link' ) );
|
||||
add_action( 'in_plugin_update_message-wp-strava/wp-strava.php', array( $this, 'plugin_update_message' ), 10, 2 );
|
||||
add_action( 'after_plugin_row_wp-strava/wp-strava.php', array( $this, 'ms_plugin_update_message' ), 10, 2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the strava settings menu.
|
||||
*
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 0.62
|
||||
*/
|
||||
public function add_strava_menu() {
|
||||
add_options_page(
|
||||
__( 'Strava Settings', 'wp-strava' ),
|
||||
__( 'Strava', 'wp-strava' ),
|
||||
'manage_options',
|
||||
$this->page_name,
|
||||
array( $this, 'print_strava_options' )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register settings using the WP Settings API.
|
||||
*
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 0.62
|
||||
*/
|
||||
public function register_strava_settings() {
|
||||
add_settings_section( 'strava_api', __( 'Strava API', 'wp-strava' ), array( $this, 'print_api_instructions' ), 'wp-strava' );
|
||||
|
||||
$this->adding_athlete = $this->is_adding_athlete();
|
||||
|
||||
if ( $this->ids_empty( $this->ids ) ) {
|
||||
register_setting( $this->option_page, 'strava_client_id', array( $this, 'sanitize_client_id' ) );
|
||||
register_setting( $this->option_page, 'strava_client_secret', array( $this, 'sanitize_client_secret' ) );
|
||||
register_setting( $this->option_page, 'strava_nickname', array( $this, 'sanitize_nickname' ) );
|
||||
|
||||
add_settings_field( 'strava_client_id', __( 'Strava Client ID', 'wp-strava' ), array( $this, 'print_client_input' ), 'wp-strava', 'strava_api' );
|
||||
add_settings_field( 'strava_client_secret', __( 'Strava Client Secret', 'wp-strava' ), array( $this, 'print_secret_input' ), 'wp-strava', 'strava_api' );
|
||||
add_settings_field( 'strava_nickname', __( 'Strava Nickname', 'wp-strava' ), array( $this, 'print_nickname_input' ), 'wp-strava', 'strava_api' );
|
||||
} else {
|
||||
register_setting( $this->option_page, 'strava_id', array( $this, 'sanitize_id' ) );
|
||||
add_settings_field( 'strava_id', __( 'Saved ID', 'wp-strava' ), array( $this, 'print_id_input' ), 'wp-strava', 'strava_api' );
|
||||
|
||||
// Add additional fields
|
||||
register_setting( $this->option_page, 'strava_client_id', array( $this, 'sanitize_client_id' ) );
|
||||
register_setting( $this->option_page, 'strava_client_secret', array( $this, 'sanitize_client_secret' ) );
|
||||
register_setting( $this->option_page, 'strava_nickname', array( $this, 'sanitize_nickname' ) );
|
||||
|
||||
add_settings_field( 'strava_client_id', __( 'Additional Athlete Client ID', 'wp-strava' ), array( $this, 'print_client_input' ), 'wp-strava', 'strava_api' );
|
||||
add_settings_field( 'strava_client_secret', __( 'Additional Athlete Client Secret', 'wp-strava' ), array( $this, 'print_secret_input' ), 'wp-strava', 'strava_api' );
|
||||
add_settings_field( 'strava_nickname', __( 'Additional Athlete Nickname', 'wp-strava' ), array( $this, 'print_nickname_input' ), 'wp-strava', 'strava_api' );
|
||||
}
|
||||
|
||||
// Google Maps API.
|
||||
register_setting( $this->option_page, 'strava_gmaps_key', array( $this, 'sanitize_gmaps_key' ) );
|
||||
add_settings_section( 'strava_gmaps', __( 'Google Maps', 'wp-strava' ), array( $this, 'print_gmaps_instructions' ), 'wp-strava' );
|
||||
add_settings_field( 'strava_gmaps_key', __( 'Static Maps Key', 'wp-strava' ), array( $this, 'print_gmaps_key_input' ), 'wp-strava', 'strava_gmaps' );
|
||||
|
||||
// System of Measurement.
|
||||
register_setting( $this->option_page, 'strava_som', array( $this, 'sanitize_som' ) );
|
||||
add_settings_section( 'strava_options', __( 'Options', 'wp-strava' ), null, 'wp-strava' );
|
||||
add_settings_field( 'strava_som', __( 'System of Measurement', 'wp-strava' ), array( $this, 'print_som_input' ), 'wp-strava', 'strava_options' );
|
||||
|
||||
// Hide Options.
|
||||
register_setting( $this->option_page, 'strava_hide_time', array( $this, 'sanitize_hide_time' ) );
|
||||
add_settings_field( 'strava_hide_time', __( 'Hide Activity Time', 'wp-strava' ), array( $this, 'print_hide_time_input' ), 'wp-strava', 'strava_options' );
|
||||
register_setting( $this->option_page, 'strava_hide_elevation', array( $this, 'sanitize_hide_elevation' ) );
|
||||
add_settings_field( 'strava_hide_elevation', __( 'Hide Activity Elevation', 'wp-strava' ), array( $this, 'print_hide_elevation_input' ), 'wp-strava', 'strava_options' );
|
||||
|
||||
// Clear cache.
|
||||
register_setting( $this->option_page, 'strava_cache_clear', array( $this, 'sanitize_cache_clear' ) );
|
||||
add_settings_section( 'strava_cache', __( 'Cache', 'wp-strava' ), null, 'wp-strava' );
|
||||
add_settings_field( 'strava_cache_clear', __( 'Clear cache (images & transient data)', 'wp-strava' ), array( $this, 'print_clear_input' ), 'wp-strava', 'strava_cache' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Print the Strava setup instructions.
|
||||
*
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 0.62
|
||||
*/
|
||||
public function print_api_instructions() {
|
||||
$settings_url = 'https://www.strava.com/settings/api';
|
||||
$icon_url = 'https://plugins.svn.wordpress.org/wp-strava/assets/icon-128x128.png';
|
||||
$blog_name = get_bloginfo( 'name' );
|
||||
|
||||
// Translators: Strava "app" name
|
||||
$app_name = sprintf( __( '%s Strava', 'wp-strava' ), $blog_name );
|
||||
$site_url = site_url();
|
||||
|
||||
// Translators: Strava "app" description
|
||||
$description = sprintf( __( 'WP-Strava for %s', 'wp-strava' ), $blog_name );
|
||||
echo wp_kses_post(
|
||||
sprintf(
|
||||
__(
|
||||
"<p>Steps:</p>
|
||||
<ol>
|
||||
<li>Create your free API Application/Connection here: <a href='%1\$s'>%2\$s</a> using the following information:</li>
|
||||
<ul>
|
||||
<li>App Icon: <strong>upload <a href='%3\$s'>this image</a></strong></li>
|
||||
<li>Application Name: <strong>%4\$s</strong></li>
|
||||
<li>Category: OK to leave at default 'other'</li>
|
||||
<li>Club: OK to leave blank</li>
|
||||
<li>Website: <strong>%5\$s</strong></li>
|
||||
<li>Application Description: <strong>%6\$s</strong></li>
|
||||
<li>Authorization Callback Domain: <strong>%7\$s</strong></li>
|
||||
</ul>
|
||||
<li>Once you've created your API Application at strava.com, enter the <strong>Client ID</strong> and <strong>Client Secret</strong> below, which can now be found on that same strava API Settings page.
|
||||
<li>After saving your Client ID and Secret, you'll be redirected to strava to authorize your API Application. If successful, your Strava ID will display in a table, next to your nickname.</li>
|
||||
<li>If you need to re-authorize your API Application, erase your Strava ID next to your nickname and click 'Save Changes' to start over.</li>
|
||||
</ol>",
|
||||
'wp-strava'
|
||||
),
|
||||
$settings_url,
|
||||
$settings_url,
|
||||
$icon_url,
|
||||
$app_name,
|
||||
$site_url,
|
||||
$description,
|
||||
wp_parse_url( $site_url, PHP_URL_HOST )
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print the google maps instructions.
|
||||
*
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 1.1
|
||||
*/
|
||||
public function print_gmaps_instructions() {
|
||||
$maps_url = 'https://developers.google.com/maps/documentation/static-maps/';
|
||||
echo wp_kses_post(
|
||||
sprintf(
|
||||
__(
|
||||
"<p>Steps:</p>
|
||||
<ol>
|
||||
<li>To use Google map images, you must create a Static Maps API Key. Create a free key by going here: <a href='%1\$s'>%2\$s</a> and clicking <strong>Get a Key</strong></li>
|
||||
<li>Once you've created your Google Static Maps API Key, enter the key below.
|
||||
</ol>",
|
||||
'wp-strava'
|
||||
),
|
||||
$maps_url,
|
||||
$maps_url
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print the settings page container.
|
||||
*
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 0.62
|
||||
*/
|
||||
public function print_strava_options() {
|
||||
include WPSTRAVA_PLUGIN_DIR . 'templates/admin-settings.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Print the client ID input
|
||||
*
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public function print_client_input() {
|
||||
?>
|
||||
<input type="text" id="strava_client_id" name="strava_client_id" value="" />
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Print the client secret input
|
||||
*
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public function print_secret_input() {
|
||||
?>
|
||||
<input type="text" id="strava_client_secret" name="strava_client_secret" value="" />
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Print the nickname input
|
||||
*
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public function print_nickname_input() {
|
||||
$nickname = $this->ids_empty( $this->ids ) ? __( 'Default', 'wp-strava' ) : '';
|
||||
?>
|
||||
<input type="text" name="strava_nickname[]" value="<?php echo esc_attr( $nickname ); ?>" />
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Print the strava ID(s).
|
||||
*
|
||||
* Renamed from print_token_input().
|
||||
*
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public function print_id_input() {
|
||||
foreach ( $this->get_all_ids() as $id => $nickname ) {
|
||||
?>
|
||||
<input type="text" name="strava_id[]" value="<?php echo esc_attr( $id ); ?>" />
|
||||
<input type="text" name="strava_nickname[]" value="<?php echo esc_attr( $nickname ); ?>" />
|
||||
<br/>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitize the client ID.
|
||||
*
|
||||
* @param string $client_id
|
||||
* @return string
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public function sanitize_client_id( $client_id ) {
|
||||
// Return early if not trying to add an additional athlete.
|
||||
if ( ! $this->adding_athlete ) {
|
||||
return $client_id;
|
||||
}
|
||||
|
||||
if ( ! is_numeric( $client_id ) ) {
|
||||
add_settings_error( 'strava_client_id', 'strava_client_id', __( 'Client ID must be a number.', 'wp-strava' ) );
|
||||
}
|
||||
return $client_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitize the client secret.
|
||||
*
|
||||
* @param string $client_secret
|
||||
* @return string
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public function sanitize_client_secret( $client_secret ) {
|
||||
// Return early if not trying to add an additional athlete.
|
||||
if ( ! $this->adding_athlete ) {
|
||||
return $client_secret;
|
||||
}
|
||||
|
||||
if ( '' === trim( $client_secret ) ) {
|
||||
add_settings_error( 'strava_client_secret', 'strava_client_secret', __( 'Client Secret is required.', 'wp-strava' ) );
|
||||
}
|
||||
return $client_secret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitize the nicknames - make sure we've got the same number of nicknames and IDs.
|
||||
*
|
||||
* @param array $nicknames Nicknames for the athletes saved.
|
||||
* @return array
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public function sanitize_nickname( $nicknames ) {
|
||||
if ( ! $this->adding_athlete ) {
|
||||
|
||||
$input_args = array(
|
||||
'strava_id' => array(
|
||||
'filter' => FILTER_SANITIZE_NUMBER_INT,
|
||||
'flags' => FILTER_REQUIRE_ARRAY,
|
||||
),
|
||||
);
|
||||
|
||||
$input = filter_input_array( INPUT_POST, $input_args );
|
||||
|
||||
// Chop $nicknames to same size as ids.
|
||||
$nicknames = array_slice( $nicknames, 0, count( $input['strava_id'] ) );
|
||||
|
||||
// Remove indexes from $nicknames that have empty ids.
|
||||
foreach ( $input['strava_id'] as $index => $id ) {
|
||||
$id = trim( $id );
|
||||
if ( empty( $id ) ) {
|
||||
unset( $nicknames[ $index ] );
|
||||
}
|
||||
}
|
||||
|
||||
// Process $nicknames so indexes start with zero.
|
||||
$nicknames = array_merge( $nicknames, array() );
|
||||
}
|
||||
|
||||
foreach ( $nicknames as $index => $nickname ) {
|
||||
if ( '' === trim( $nickname ) ) {
|
||||
add_settings_error( 'strava_nickname', 'strava_nickname', __( 'Nickname is required.', 'wp-strava' ) );
|
||||
return $nicknames;
|
||||
}
|
||||
}
|
||||
return $nicknames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitize the ID.
|
||||
*
|
||||
* Renamed from sanitize_token().
|
||||
*
|
||||
* @param string $id Client ID.
|
||||
* @return string
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 2.0
|
||||
*/
|
||||
public function sanitize_id( $id ) {
|
||||
return $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print the GMaps key input.
|
||||
*
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 1.1
|
||||
*/
|
||||
public function print_gmaps_key_input() {
|
||||
?>
|
||||
<input type="text" id="strava_gmaps_key" name="strava_gmaps_key" value="<?php echo esc_attr( $this->gmaps_key ); ?>" />
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitize GMaps key input.
|
||||
*
|
||||
* @param string $key
|
||||
* @return string
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 1.1
|
||||
*/
|
||||
public function sanitize_gmaps_key( $key ) {
|
||||
return $key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print System of Measure option.
|
||||
*
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 0.62
|
||||
*/
|
||||
public function print_som_input() {
|
||||
?>
|
||||
<select id="strava_som" name="strava_som">
|
||||
<option value="metric" <?php selected( $this->som, 'metric' ); ?>><?php esc_html_e( 'Metric', 'wp-strava' ); ?></option>
|
||||
<option value="english" <?php selected( $this->som, 'english' ); ?>><?php esc_html_e( 'English', 'wp-strava' ); ?></option>
|
||||
</select>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitize System of Measure input.
|
||||
*
|
||||
* @param string $som Input from System of Measure dropdown.
|
||||
* @return string
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 0.62
|
||||
*/
|
||||
public function sanitize_som( $som ) {
|
||||
return $som;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the Hide Time Checkbox.
|
||||
*
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 1.7.1
|
||||
*/
|
||||
public function print_hide_time_input() {
|
||||
?>
|
||||
<input type="checkbox" id="strava_hide_time" name="strava_hide_time" <?php checked( $this->hide_time, 'on' ); ?>/>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitize the Hide Time Checkbox.
|
||||
*
|
||||
* @param string $checked 'on' or null.
|
||||
* @return string 'on' if checked.
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 1.7.1
|
||||
*/
|
||||
public function sanitize_hide_time( $checked ) {
|
||||
if ( 'on' === $checked ) {
|
||||
return $checked;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the Hide Elevation Checkbox.
|
||||
*
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 1.7.2
|
||||
*/
|
||||
public function print_hide_elevation_input() {
|
||||
?>
|
||||
<input type="checkbox" id="strava_hide_elevation" name="strava_hide_elevation" <?php checked( $this->hide_elevation, 'on' ); ?>/>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitize the Hide Elevation Checkbox.
|
||||
*
|
||||
* @param string $checked 'on' or null.
|
||||
* @return string 'on' if checked.
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 1.7.2
|
||||
*/
|
||||
public function sanitize_hide_elevation( $checked ) {
|
||||
if ( 'on' === $checked ) {
|
||||
return $checked;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print checkbox option to clear cache.
|
||||
*
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 1.1
|
||||
*/
|
||||
public function print_clear_input() {
|
||||
?>
|
||||
<input type="checkbox" id="strava_cache_clear" name="strava_cache_clear" />
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear Strava cache if checkbox is checked.
|
||||
*
|
||||
* @param string $checked Clear cache checkbox status.
|
||||
* @return void
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 1.1
|
||||
*/
|
||||
public function sanitize_cache_clear( $checked ) {
|
||||
if ( 'on' === $checked ) {
|
||||
global $wpdb;
|
||||
|
||||
$wpdb->query( "DELETE FROM {$wpdb->options} WHERE `option_name` LIKE '_transient_timeout_strava_api_data_%'" );
|
||||
$wpdb->query( "DELETE FROM {$wpdb->options} WHERE `option_name` LIKE '_transient_strava_api_data_%'" );
|
||||
$wpdb->query( "DELETE FROM {$wpdb->options} WHERE `option_name` LIKE '_transient_timeout_strava_latest_map_%'" );
|
||||
$wpdb->query( "DELETE FROM {$wpdb->options} WHERE `option_name` LIKE '_transient_strava_latest_map_%'" );
|
||||
$wpdb->query( "DELETE FROM {$wpdb->options} WHERE `option_name` LIKE 'strava_latest_map%'" );
|
||||
|
||||
// Old options.
|
||||
delete_option( 'strava_token' );
|
||||
delete_option( 'strava_email' );
|
||||
delete_option( 'strava_password' );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all saved strava ids as an array.
|
||||
*
|
||||
* @return array
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public function get_ids() {
|
||||
$ids = get_option( 'strava_id' );
|
||||
if ( ! is_array( $ids ) ) {
|
||||
$ids = array( $ids );
|
||||
}
|
||||
|
||||
foreach ( $ids as $index => $id ) {
|
||||
if ( empty( $id ) ) {
|
||||
unset( $ids[ $index ] );
|
||||
$ids = array_values( $ids ); // Rebase array keys after unset @see https://stackoverflow.com/a/5943165/2146022
|
||||
}
|
||||
}
|
||||
return $ids;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns first (default) ID saved.
|
||||
*
|
||||
* @return string|null
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public function get_default_id() {
|
||||
$ids = $this->get_ids();
|
||||
return isset( $ids[0] ) ? $ids[0] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all IDs and their nicknames in one array.
|
||||
*
|
||||
* @return void
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public function get_all_ids() {
|
||||
$ids = $this->get_ids();
|
||||
$nicknames = $this->nickname;
|
||||
$all = array();
|
||||
$number = 1;
|
||||
foreach ( $ids as $index => $id ) {
|
||||
if ( ! empty( $nicknames[ $index ] ) ) {
|
||||
$all[ $id ] = $nicknames[ $index ];
|
||||
} else {
|
||||
$all[ $id ] = $this->get_default_nickname( $number );
|
||||
}
|
||||
$number++;
|
||||
}
|
||||
return $all;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns default nickname 'Default' / 'Athlete n'.
|
||||
*
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 1.2.0
|
||||
*
|
||||
* @param integer $number Athlete number (default 1).
|
||||
* @return string
|
||||
*/
|
||||
private function get_default_nickname( $number = 1 ) {
|
||||
// Translators: Athlete number if no nickname present.
|
||||
return ( 1 === $number ) ? __( 'Default', 'wp-strava' ) : sprintf( __( 'Athlete %s', 'wp-strava' ), $number );
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for valid IDs.
|
||||
*
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 1.2.0
|
||||
*
|
||||
* @param string|array Single ID or array of IDs.
|
||||
* @return boolean True if empty.
|
||||
*/
|
||||
public function ids_empty( $ids ) {
|
||||
if ( empty( $ids ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( is_array( $ids ) ) {
|
||||
foreach ( $ids as $id ) {
|
||||
if ( ! empty( $id ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an ID if it's not already there, and save to the DB.
|
||||
*
|
||||
* @param string $id
|
||||
*
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public function add_id( $id ) {
|
||||
if ( false === array_search( $id, $this->ids, true ) ) {
|
||||
$this->ids[] = $id;
|
||||
update_option( 'strava_id', $this->ids );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update options with new Client ID and Info.
|
||||
*
|
||||
* @param int $id Strava API Client ID
|
||||
* @param string $secret Strava API Client Secret
|
||||
* @param stdClass $info
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public function save_info( $id, $secret, $info ) {
|
||||
$infos = get_option( 'strava_info', array() );
|
||||
$infos = array_filter( $infos, array( $this, 'filter_by_id' ), ARRAY_FILTER_USE_KEY ); // Remove old IDs.
|
||||
|
||||
$info->client_secret = $secret;
|
||||
$infos[ $id ] = $info;
|
||||
update_option( 'strava_info', $infos );
|
||||
}
|
||||
|
||||
/**
|
||||
* array_filter() callback to remove info for IDs we no longer have.
|
||||
*
|
||||
* @param int $key Strava Client ID
|
||||
* @return boolean True if Client ID is in $this->ids, false otherwise.
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public function filter_by_id( $key ) {
|
||||
if ( in_array( $key, $this->ids ) ) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the client ID and Secret (they're saved in the strava_info option).
|
||||
*
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public function delete_id_secret() {
|
||||
delete_option( 'strava_client_id' );
|
||||
delete_option( 'strava_client_secret' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if settings have been updated.
|
||||
*
|
||||
* @param array $value Data array from pre_set_transient_settings_errors filter.
|
||||
* @return boolean
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public function is_settings_updated( $value ) {
|
||||
return ( isset( $value[0]['type'] ) && ( 'updated' === $value[0]['type'] || 'success' === $value[0]['type'] ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not we're on the options page.
|
||||
*
|
||||
* @return boolean
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public function is_option_page() {
|
||||
return filter_input( INPUT_POST, 'option_page', FILTER_SANITIZE_STRING ) === $this->option_page;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not we're on the WP-Strava settings page.
|
||||
*
|
||||
* @return boolean
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public function is_settings_page() {
|
||||
return filter_input( INPUT_GET, 'page', FILTER_SANITIZE_STRING ) === $this->page_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the WP-Strava settings page name.
|
||||
*
|
||||
* @return string
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public function get_page_name() {
|
||||
return $this->page_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not we're adding a new athlete.
|
||||
*
|
||||
* @return boolean
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 2.0.0
|
||||
*/
|
||||
private function is_adding_athlete() {
|
||||
return filter_input( INPUT_POST, 'strava_client_id', FILTER_SANITIZE_NUMBER_INT ) && filter_input( INPUT_POST, 'strava_client_secret', FILTER_SANITIZE_STRING );
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for Strava settings in wp_options.
|
||||
*
|
||||
* @param string $name Option name without the 'strava_' prefix.
|
||||
* @return mixed
|
||||
* @since 0.62
|
||||
*/
|
||||
public function __get( $name ) {
|
||||
if ( ! strpos( 'strava_', $name ) ) {
|
||||
$name = "strava_{$name}";
|
||||
}
|
||||
// Else.
|
||||
return get_option( $name );
|
||||
}
|
||||
|
||||
/**
|
||||
* Link to the settings on the plugin list page.
|
||||
*
|
||||
* @param array $links Array of plugin links.
|
||||
* @return array Links with settings added.
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 1.0
|
||||
*/
|
||||
public function settings_link( $links ) {
|
||||
$settings_link = '<a href="' . admin_url( "options-general.php?page={$this->page_name}" ) . '">' . __( 'Settings', 'wp-strava' ) . '</a>';
|
||||
$links[] = $settings_link;
|
||||
return $links;
|
||||
}
|
||||
|
||||
/**
|
||||
* Plugin Upgrade Notice.
|
||||
*
|
||||
* @param array $data Plugin data with readme additions.
|
||||
* @param array $response Response from wp.org.
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 1.7.3
|
||||
*/
|
||||
public function plugin_update_message( $data, $response ) {
|
||||
if ( isset( $data['upgrade_notice'] ) ) {
|
||||
echo wp_kses_post( $data['upgrade_notice'] );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Plugin Upgrade Notice (multisite).
|
||||
*
|
||||
* @param string $file Relative path to plugin, i.e. wp-strava/wp-strava.php.
|
||||
* @param array $plugin Plugin data with readme additions.
|
||||
* @author Justin Foell <justin@foell.org>
|
||||
* @since 1.7.3
|
||||
*/
|
||||
public function ms_plugin_update_message( $file, $plugin ) {
|
||||
if ( is_multisite() && ! is_network_admin() && version_compare( $plugin['Version'], $plugin['new_version'], '<' ) ) {
|
||||
$wp_list_table = _get_list_table( 'WP_Plugins_List_Table' );
|
||||
echo wp_kses_post(
|
||||
sprintf(
|
||||
'<tr class="plugin-update-tr"><td colspan="%s" class="plugin-update update-message notice inline notice-warning notice-alt"><div class="update-message"><h4 style="margin: 0; font-size: 14px;">%s</h4>%s</div></td></tr>',
|
||||
$wp_list_table->get_column_count(),
|
||||
$plugin['Name'],
|
||||
$plugin['upgrade_notice']
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
class WPStrava_StaticMap {
|
||||
|
||||
/**
|
||||
* Get an image tag to a static google map. Will render with
|
||||
* detailed polyline if not greater than 1865 chars, otherwise
|
||||
* rendering will use summary polyline.
|
||||
*
|
||||
* @static
|
||||
* @access public
|
||||
* @param object $activity Activity object to get image tag for.
|
||||
* @param int $height Height of map in pixels.
|
||||
* @param int $width Width of map in pixels.
|
||||
* @param bool $markers Display start and finish markers.
|
||||
* @return string HTML img tag with static map image.
|
||||
*/
|
||||
public static function get_image_tag( $activity, $height = 320, $width = 480, $markers = false, $link = true ) {
|
||||
$key = WPStrava::get_instance()->settings->gmaps_key;
|
||||
|
||||
// Short circuit if missing key or activity object doesn't have the data we need.
|
||||
if ( empty( $key ) || empty( $activity->map ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$url = "https://maps.googleapis.com/maps/api/staticmap?maptype=terrain&size={$width}x{$height}&scale=2&sensor=false&key={$key}&path=color:0xFF0000BF|weight:2|enc:";
|
||||
$url_len = strlen( $url );
|
||||
$max_chars = 1865;
|
||||
|
||||
$polyline = '';
|
||||
if ( ! empty( $activity->map->polyline ) && ( $url_len + strlen( $activity->map->polyline ) < $max_chars ) ) {
|
||||
$polyline = $activity->map->polyline;
|
||||
} elseif ( ! empty( $activity->map->summary_polyline ) ) {
|
||||
$polyline = $activity->map->summary_polyline;
|
||||
}
|
||||
$url .= $polyline;
|
||||
|
||||
if ( $markers ) {
|
||||
$points = self::decode_start_finish( $polyline );
|
||||
$markers = '&markers=color:green|' . $points['start'][0] . ',' . $points['start'][1] .
|
||||
'&markers=color:red|' . $points['finish'][0] . ',' . $points['finish'][1];
|
||||
$url .= $markers;
|
||||
}
|
||||
|
||||
return "<img class='wp-strava-img' src='{$url}' />";
|
||||
}
|
||||
|
||||
/**
|
||||
* From an encoded polyline, get the start and finish points for
|
||||
* the purposes of displaying start and finish markers.
|
||||
*
|
||||
* @static
|
||||
* @see https://developers.google.com/maps/documentation/utilities/polylinealgorithm
|
||||
* @access private
|
||||
* @param string $enc Encoded polyline.
|
||||
* @return array {
|
||||
* Indexes of start & finish containing lat/lon for each.
|
||||
* @type array $start {
|
||||
* @type float $0 Latitude
|
||||
* @type float $1 Longitude
|
||||
* }
|
||||
* @type array $finish {
|
||||
* @type float $0 Latitude
|
||||
* @type float $1 Longitude
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
private static function decode_start_finish( $enc ) {
|
||||
require_once WPSTRAVA_PLUGIN_DIR . 'includes/Polyline.php';
|
||||
$points = Polyline::decode( $enc );
|
||||
$points = Polyline::pair( $points );
|
||||
$start = $points[0];
|
||||
$finish = $points[ count( $points ) - 1 ];
|
||||
|
||||
return array(
|
||||
'start' => $start,
|
||||
'finish' => $finish,
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Autoloads files with classes when needed.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @param string $class_name Name of the class being requested.
|
||||
* @return void
|
||||
*/
|
||||
function wpstrava_autoload_classes( $class_name ) {
|
||||
$parts = explode( '_', $class_name );
|
||||
|
||||
// If our class doesn't have our namespace, don't load it.
|
||||
if ( empty( $parts[0] ) || 'WPStrava' !== $parts[0] ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// @TODO Add directory searching if they get created.
|
||||
$file = WPSTRAVA_PLUGIN_DIR . '/src/' . implode( '/', $parts ) . '.php';
|
||||
if ( file_exists( $file ) ) {
|
||||
include_once $file;
|
||||
}
|
||||
}
|
||||
spl_autoload_register( 'wpstrava_autoload_classes' );
|
||||
@@ -0,0 +1,2 @@
|
||||
<?php
|
||||
|
||||
Reference in New Issue
Block a user