Renamed lib to includes

This commit is contained in:
Justin Foell
2019-04-01 15:17:27 -05:00
parent 3ce9d26e88
commit 2265e73f83
26 changed files with 6 additions and 6 deletions
+153
View File
@@ -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();
}
}
+168
View File
@@ -0,0 +1,168 @@
<?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( 'forever' );
if ( is_admin() ) {
$this->settings->hook();
$this->auth->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' ) );
}
/**
* Get a singleton instance.
*
* @return WPStrava
*/
public static function get_instance() {
if ( ! self::$instance ) {
$class = __CLASS__;
self::$instance = new $class();
}
return self::$instance;
}
/**
* 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 athlete token.
*
* @param string $token Athlete token.
* @return WPStrava_API
*/
public function get_api( $token = null ) {
if ( ! $token ) {
$token = $this->settings->get_default_token();
}
if ( empty( $this->api[ $token ] ) ) {
$this->api[ $token ] = new WPStrava_API( $token );
}
return $this->api[ $token ];
}
/**
* 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' );
}
/**
* 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();
}
}
+105
View File
@@ -0,0 +1,105 @@
<?php
/*
* API class for all remote calls.
*/
class WPStrava_API {
const STRAVA_V3_API = 'https://www.strava.com/api/v3/';
public function __construct( $access_token = null ) {
$this->access_token = $access_token;
}
public function post( $uri, $data = null ) {
$url = self::STRAVA_V3_API;
$args = array(
'body' => http_build_query( $data ),
'sslverify' => false,
'headers' => array(),
'timeout' => 30,
);
if ( $this->access_token ) {
$args['headers']['Authorization'] = 'Bearer ' . $this->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'] );
}
public function get( $uri, $args = null ) {
$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,
);
if ( $this->access_token ) {
$get_args['headers']['Authorization'] = 'Bearer ' . $this->access_token;
}
$response = wp_remote_get( $url, $get_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;
} 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'] );
}
} // Class API.
+75
View File
@@ -0,0 +1,75 @@
<?php
/*
* Activity is a class wrapper for the Strava REST API functions.
*/
class WPStrava_Activity {
const ACTIVITIES_URL = 'http://strava.com/activities/';
const ATHLETES_URL = 'http://strava.com/athletes/';
/**
* Get single activity by ID.
*
* @param string $athlete_token Token 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( $athlete_token, $activity_id ) {
return WPStrava::get_instance()->get_api( $athlete_token )->get( "activities/{$activity_id}" );
}
/**
* Get activity list from Strava API.
*
* @author Justin Foell <justin@foell.org>
* @param string $athlete_token Token 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( $athlete_token, $club_id = null, $quantity = null ) {
$api = WPStrava::get_instance()->get_api( $athlete_token );
$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;
}
}
+183
View File
@@ -0,0 +1,183 @@
<?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 ) {
$this->add_script = true;
$defaults = array(
'id' => 0,
'som' => WPStrava::get_instance()->settings->som,
'map_width' => '480',
'map_height' => '320',
'athlete_token' => WPStrava::get_instance()->settings->get_default_token(),
'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['athlete_token'], $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_speed = '';
$max_speed = '';
$speed_label = '';
$avg_title = '<th>' . __( 'Average Speed', 'wp-strava' ) . '</th>';
$max_title = '<th>' . __( 'Max Speed', 'wp-strava' ) . '</th>';
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;
}
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 . '
<th>' . __( 'Elevation Gain', 'wp-strava' ) . '</th>
</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 . '
<td>' . $strava_som->elevation( $activity_details->total_elevation_gain ) . '</td>
</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 . '
<td>' . $strava_som->get_elevation_label() . '</td>
</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' );
}
}
}
+84
View File
@@ -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;
}
}
+119
View File
@@ -0,0 +1,119 @@
<?php
abstract class WPStrava_Auth {
protected $auth_url = 'https://www.strava.com/oauth/authorize?response_type=code';
private $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() {
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.
if ( isset( $_POST['strava_token'] ) && $settings->tokens_empty( $_POST['strava_token'] ) ) {
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( $_POST['strava_client_id'] ) && ! empty( $_POST['strava_client_secret'] ) ) {
wp_redirect( $this->get_authorize_url( $_POST['strava_client_id'] ) );
exit();
}
}
return $value;
}
public function init() {
$settings = WPStrava::get_instance()->settings;
//only update when redirected back from strava
if ( ! isset( $_GET['settings-updated'] ) && $settings->is_settings_page() ) {
if ( isset( $_GET['code'] ) ) {
$info = $this->token_exchange_initial( $_GET['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' );
$settings->add_token( $info->access_token );
$settings->update_token();
} 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,
);
$strava_info = $this->token_request( $data );
if ( isset( $strava_info->access_token ) ) {
$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 );
}
}
+25
View File
@@ -0,0 +1,25 @@
<?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
*/
class WPStrava_AuthForever extends WPStrava_Auth {
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
);
}
}
+47
View File
@@ -0,0 +1,47 @@
<?php
/**
* AuthRefresh class
*
* @since 2.0.0
*/
class WPStrava_AuthRefresh extends WPStrava_Auth {
public function hook() {
parent::hook();
// @TODO Need cronjob.
}
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' => 'read,activity:read',
),
$this->auth_url
);
}
protected function token_exchange_refresh() {
$data = array(
'client_id' => $client_id,
'client_secret' => $client_secret,
'refresh_token' => $refresh_token,
'grant_type' => 'refresh_token',
);
$strava_info = $this->token_request( $data );
if ( isset( $strava_info->access_token ) ) {
$this->feedback .= __( 'Successfully re-authenticated.', 'wp-strava' );
return $strava_info;
}
$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;
}
}
+103
View File
@@ -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
+76
View File
@@ -0,0 +1,76 @@
<?php
class WPStrava_LatestActivities {
public static function get_activities_html( $args ) {
$defaults = array(
'athlete_token' => WPStrava::get_instance()->settings->get_default_token(),
'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['athlete_token'], $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 );
// Translators: Shows something like "On <date> <[went 10 miles] [during 2 hours] [climbing 100 feet]>."
$response .= sprintf( __( '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() );
// 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 athlete_token=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,84 @@
<?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 wigit 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(
'athlete_token' => isset( $instance['athlete_token'] ) ? $instance['athlete_token'] : null,
'strava_club_id' => isset( $instance['strava_club_id'] ) ? $instance['strava_club_id'] : null,
'quantity' => isset( $instance['quantity'] ) ? $instance['quantity'] : null,
);
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'];
}
/** @see WP_Widget::update */
public function update( $new_instance, $old_instance ) {
$instance = $old_instance;
$instance['title'] = strip_tags( $new_instance['title'] );
$instance['athlete_token'] = strip_tags( $new_instance['athlete_token'] );
$instance['strava_club_id'] = strip_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_tokens = WPStrava::get_instance()->settings->get_all_tokens();
$athlete_token = isset( $instance['athlete_token'] ) ? esc_attr( $instance['athlete_token'] ) : WPStrava::get_instance()->settings->get_default_token();
$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 $this->get_field_id( 'title' ); ?>"><?php _e( 'Title:', 'wp-strava' ); ?></label>
<input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo $title; ?>" />
</p>
<p>
<label for="<?php echo $this->get_field_id( 'athlete_token' ); ?>"><?php _e( 'Athlete:', 'wp-strava' ); ?></label>
<select name="<?php echo $this->get_field_name( 'athlete_token' ); ?>">
<?php foreach ( $all_tokens as $token => $nickname ) : ?>
<option value="<?php echo $token; ?>"<?php selected( $token, $athlete_token ); ?>><?php echo $nickname; ?></option>
<?php endforeach; ?>
</select>
</p>
<p>
<label for="<?php echo $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 $this->get_field_id( 'strava_club_id' ); ?>" name="<?php echo $this->get_field_name( 'strava_club_id' ); ?>" type="text" value="<?php echo $strava_club_id; ?>" />
</p>
<p>
<label for="<?php echo $this->get_field_id( 'quantity' ); ?>"><?php esc_html_e( 'Quantity:', 'wp-strava' ); ?></label>
<input class="widefat" id="<?php echo $this->get_field_id( 'quantity' ); ?>" name="<?php echo $this->get_field_name( 'quantity' ); ?>" type="text" value="<?php echo $quantity; ?>" />
</p>
<?php
}
} // class LatestActivitiesWidget
+191
View File
@@ -0,0 +1,191 @@
<?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_tokens = WPStrava::get_instance()->settings->get_all_tokens();
$athlete_token = isset( $instance['athlete_token'] ) ? esc_attr( $instance['athlete_token'] ) : WPStrava::get_instance()->settings->get_default_token();
$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 $this->get_field_id( 'title' ); ?>">
<?php // Translator: Widget Title. ?>
<?php esc_html_e( 'Title:', 'wp-strava' ); ?>
</label>
<input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo $title; ?>" />
</p>
<p>
<label for="<?php echo $this->get_field_id( 'athlete_token' ); ?>"><?php _e( 'Athlete:', 'wp-strava' ); ?></label>
<select name="<?php echo $this->get_field_name( 'athlete_token' ); ?>">
<?php foreach ( $all_tokens as $token => $nickname ) : ?>
<option value="<?php echo $token; ?>"<?php selected( $token, $athlete_token ); ?>><?php echo $nickname; ?></option>
<?php endforeach; ?>
</select>
</p>
<p>
<label for="<?php echo $this->get_field_id( 'distance_min' ); ?>">
<?php // Translators: Label for minimum distance input. ?>
<?php echo sprintf( __( 'Min. Distance (%s):', 'wp-strava' ), $this->som->get_distance_label() ); ?>
</label>
<input class="widefat" id="<?php echo $this->get_field_id( 'distance_min' ); ?>" name="<?php echo $this->get_field_name( 'distance_min' ); ?>" type="text" value="<?php echo $distance_min; ?>" />
</p>
<p>
<label for="<?php echo $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 $this->get_field_id( 'strava_club_id' ); ?>" name="<?php echo $this->get_field_name( 'strava_club_id' ); ?>" type="text" value="<?php echo $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'] = strip_tags( $new_instance['title'] );
$instance['athlete_token'] = strip_tags( $new_instance['athlete_token'] );
$instance['strava_club_id'] = strip_tags( $new_instance['strava_club_id'] );
$instance['distance_min'] = strip_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'] );
$athlete_token = isset( $instance['athlete_token'] ) ? $instance['athlete_token'] : WPStrava::get_instance()->settings->get_default_token();
$distance_min = empty( $instance['distance_min'] ) ? 0 : absint( $instance['distance_min'] );
$strava_club_id = empty( $instance['strava_club_id'] ) ? null : $instance['strava_club_id'];
$build_new = false;
$id = empty( $strava_club_id ) ? $athlete_token : $strava_club_id;
// Try our transient first.
$activity_transient = get_transient( 'strava_latest_map_activity_' . $id );
$activity_option = get_option( 'strava_latest_map_activity_' . $id );
$activity = $activity_transient ? $activity_transient : null;
echo $args['before_widget'];
if ( $title ) {
echo $args['before_title'] . $title . $args['after_title'];
}
if ( ! $activity || empty( $activity->map ) ) {
$strava_activity = WPStrava::get_instance()->activity;
$activities = array();
try {
$activities = $strava_activity->get_activities( $athlete_token, $strava_club_id );
} catch ( WPStrava_Exception $e ) {
echo $e->to_html();
}
if ( ! empty( $activities ) ) {
if ( ! empty( $distance_min ) ) {
$activities = $strava_activity->get_activities_longer_than( $activities, $distance_min );
}
$activity = current( $activities );
// Compare transient (temporary storage) to option (more permanent).
// If the option isn't set or the transient is different, update the option.
if ( empty( $activity_option->id ) || $activity->id != $activity_option->id ) { // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
$build_new = true;
$this->update_activity( $id, $activity );
}
// Update the transient if it needs updating.
if ( empty( $activity_transient->id ) || $activity->id != $activity_transient->id ) { // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
$this->update_activity_transient( $id, $activity );
}
}
}
if ( $activity ) {
echo empty( $activity->map ) ?
// Translators: Text with activity name shown in place of image if not available.
sprintf( __( 'Map not available for activity "%s"', 'wp-strava' ), $activity->name ) :
"<a title='{$activity->name}' href='" . WPStrava_Activity::ACTIVITIES_URL . "{$activity->id}'>" .
$this->get_static_image( $id, $activity, $build_new ) .
'</a>';
}
echo $args['after_widget'];
}
/**
* Get image for specific activity using Static Maps class.
*
* @author Justin Foell <justin@foell.org>
* @param string $id Athlete Token or Club ID.
* @param object $activity Activity to get image for.
* @param boolean $build_new Whether to refresh the image from cache.
* @return string Image tag.
*/
private function get_static_image( $id, $activity, $build_new ) {
$img = get_option( 'strava_latest_map_' . $id );
if ( $build_new || ! $img ) {
$img = WPStrava_StaticMap::get_image_tag( $activity );
$this->update_map( $id, $img );
}
return $img;
}
/**
* Update map in option to cache.
*
* @author Justin Foell <justin@foell.org>
* @since 1.2.0
* @param string $id Athlete Token or Club ID.
* @param string $img Image tag.
*/
private function update_map( $id, $img ) {
update_option( 'strava_latest_map_' . $id, $img );
}
/**
* Update activity in option to cache.
*
* @author Justin Foell <justin@foell.org>
* @since 1.2.0
* @param string $id Athlete Token or Club ID.
* @param object $activity stdClass Strava activity object.
*/
private function update_activity( $id, $activity ) {
update_option( 'strava_latest_map_activity_' . $id, $activity );
}
/**
* Update activity in transient to cache.
*
* @author Justin Foell <justin@foell.org>
* @since 1.2.0
* @param string $id Athlete Token or Club ID.
* @param object $activity stdClass Strava activity object.
*/
private function update_activity_transient( $id, $activity ) {
set_transient( 'strava_latest_map_activity_' . $id, $activity, HOUR_IN_SECONDS );
}
}
+144
View File
@@ -0,0 +1,144 @@
<?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 ) {
$this->add_script = true;
$defaults = array(
'id' => 0,
'som' => WPStrava::get_instance()->settings->som,
'map_width' => '480',
'map_height' => '320',
'athlete_token' => WPStrava::get_instance()->settings->get_default_token(),
'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 );
return '
<table id="activity-details-table">
<thead>
<tr>
<th>' . __( 'Est. Moving Time', 'wp-strava' ) . '</th>
<th>' . __( 'Distance', 'wp-strava' ) . '</th>
<th>' . __( 'Elevation Gain', 'wp-strava' ) . '</th>
</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>
<td>' . $strava_som->elevation( $route_details->elevation_gain ) . '</td>
</tr>
<tr class="activity-details-table-units">
<td>' . $strava_som->get_time_label() . '</td>
<td>' . $strava_som->get_distance_label() . '</td>
<td>' . $strava_som->get_elevation_label() . '</td>
</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' );
}
}
}
+22
View File
@@ -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 = 'http://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}" );
}
}
+76
View File
@@ -0,0 +1,76 @@
<?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'.
*/
public function time( $seconds ) {
return date( 'H:i:s', mktime( 0, 0, $seconds ) );
}
/**
* 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}";
}
}
+107
View File
@@ -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( $m / 1609.344, 2 );
}
/**
* Change miles to meters.
*
* @param float|string $dist Distance in miles.
* @return string Distance in meters.
*/
public function distance_inverse( $dist ) {
return 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( $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( $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' );
}
}
+108
View File
@@ -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( $m / 1000, 2 );
}
/**
* Change kilometers to meters.
*
* @param float|string $dist Distance in kilometers.
* @return string Distance in meters.
*/
public function distance_inverse( $dist ) {
return 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( $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( $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' );
}
}
+494
View File
@@ -0,0 +1,494 @@
<?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 $tokens = array();
private $page_name = 'wp-strava-options';
private $option_page = 'wp-strava-settings-group';
private $adding_athlete = true;
//register admin menus
public function hook() {
add_action( 'admin_init', array( $this, 'register_strava_settings' ), 20 );
add_action( 'admin_menu', array( $this, 'add_strava_menu' ) );
add_filter( 'plugin_action_links_' . WPSTRAVA_PLUGIN_NAME, array( $this, 'settings_link' ) );
}
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' )
);
}
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();
$this->tokens = $this->get_tokens();
if ( $this->tokens_empty( $this->tokens ) ) {
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_token', array( $this, 'sanitize_token' ) );
add_settings_field( 'strava_token', __( 'Strava Token', 'wp-strava' ), array( $this, 'print_token_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 Time Option.
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' );
// 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' );
}
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 );
printf( __( "<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 Token will display instead of Client ID and Client Secret.</li>
<li>If you need to re-authorize your API Application, erase your Strava Token here 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 )
);
}
public function print_gmaps_instructions() {
$maps_url = 'https://developers.google.com/maps/documentation/static-maps/';
printf( __( "<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 );
}
public function print_strava_options() {
?>
<div class="wrap">
<div id="icon-options-general" class="icon32"><br/></div>
<h2><?php esc_html_e( 'Strava Settings', 'wp-strava' ); ?></h2>
<form method="post" action="<?php echo admin_url( 'options.php' ); ?>">
<?php settings_fields( $this->option_page ); ?>
<?php do_settings_sections( 'wp-strava' ); ?>
<p class="submit">
<input type="submit" class="button-primary" value="<?php esc_html_e( 'Save Changes', 'wp-strava' ); ?>" />
</p>
</form>
</div>
<?php
}
public function print_client_input() {
?>
<input type="text" id="strava_client_id" name="strava_client_id" value="" />
<?php
}
public function print_secret_input() {
?>
<input type="text" id="strava_client_secret" name="strava_client_secret" value="" />
<?php
}
public function print_nickname_input() {
$nickname = $this->tokens_empty( $this->tokens ) ? __( 'Default', 'wp-strava' ) : '';
?>
<input type="text" name="strava_nickname[]" value="<?php echo $nickname; ?>" />
<?php
}
public function print_token_input() {
foreach ( $this->get_all_tokens() as $token => $nickname ) {
?>
<input type="text" name="strava_token[]" value="<?php echo $token; ?>" />
<input type="text" name="strava_nickname[]" value="<?php echo $nickname; ?>" />
<br/>
<?php
}
}
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;
}
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;
}
public function sanitize_nickname( $nicknames ) {
if ( ! $this->adding_athlete ) {
// Chop $nicknames to same size as tokens.
$nicknames = array_slice( $nicknames, 0, count( $_POST['strava_token'] ) );
// Remove indexes from $nicknames that have empty tokens.
foreach ( $_POST['strava_token'] as $index => $token ) {
$token = trim( $token );
if ( empty( $token ) ) {
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;
}
public function sanitize_token( $token ) {
return $token;
}
public function print_gmaps_key_input() {
?>
<input type="text" id="strava_gmaps_key" name="strava_gmaps_key" value="<?php echo $this->gmaps_key; ?>" />
<?php
}
public function sanitize_gmaps_key( $key ) {
return $key;
}
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
}
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;
}
public function print_clear_input() {
?>
<input type="checkbox" id="strava_cache_clear" name="strava_cache_clear" />
<?php
}
public function sanitize_cache_clear( $checked ) {
if ( 'on' === $checked ) {
global $wpdb;
$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%'" );
}
return null;
}
/**
* Gets all saved strava tokens as an array.
*
* @return array
* @author Justin Foell <justin@foell.org>
* @since 1.2.0
*/
public function get_tokens() {
$tokens = get_option( 'strava_token' );
if ( ! is_array( $tokens ) ) {
$tokens = array( $tokens );
}
foreach ( $tokens as $index => $token ) {
if ( empty( $token ) ) {
unset( $tokens[ $index ] );
$tokens = array_values( $tokens ); // Rebase array keys after unset @see https://stackoverflow.com/a/5943165/2146022
}
}
return $tokens;
}
/**
* Returns first (default) token saved.
*
* @return string|null
* @author Justin Foell <justin@foell.org>
* @since 1.2.0
*/
public function get_default_token() {
$tokens = $this->get_tokens();
return isset( $tokens[0] ) ? $tokens[0] : null;
}
/**
* Get all tokens and their nicknames in one array.
*
* @return void
* @author Justin Foell <justin@foell.org>
* @since 1.2.0
*/
public function get_all_tokens() {
$tokens = $this->get_tokens();
$nicknames = $this->nickname;
$all = array();
$number = 1;
foreach ( $tokens as $index => $token ) {
if ( ! empty( $nicknames[ $index ] ) ) {
$all[ $token ] = $nicknames[ $index ];
} else {
$all[ $token ] = $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 tokens.
*
* @author Justin Foell <justin@foell.org>
* @since 1.2.0
*
* @param string|array Single token or array of tokens.
* @return boolean True if empty.
*/
public function tokens_empty( $tokens ) {
if ( empty( $tokens ) ) {
return true;
}
if ( is_array( $tokens ) ) {
foreach ( $tokens as $token ) {
if ( ! empty( $token ) ) {
return false;
}
}
}
return true;
}
/**
* Only add a token if it's not already there.
*
* @param string $token
*
* @author Justin Foell <justin@foell.org>
* @since 1.2.0
*/
public function add_token( $token ) {
if ( false === array_search( $token, $this->tokens, true ) ) {
$this->tokens[] = $token;
}
}
/**
* Undocumented function
*
* @param array $token
* @author Justin Foell <justin@foell.org>
* @since 2.0.0
*/
public function update_token() {
update_option( 'strava_token', $this->tokens );
}
/**
* Undocumented function
*
* @return void
* @author Justin Foell <justin.foell@webdevstudios.com>
* @since 2.0.0
*/
public function delete_id_secret() {
delete_option( 'strava_client_id' );
delete_option( 'strava_client_secret' );
}
/**
* Undocumented function
*
* @param [type] $value
* @return boolean
* @author Justin Foell <justin.foell@webdevstudios.com>
* @since 2.0.0
*/
public function is_settings_updated( $value ) {
return isset( $value[0]['type'] ) && 'updated' === $value[0]['type'];
}
/**
* Undocumented function
*
* @return boolean
* @author Justin Foell <justin.foell@webdevstudios.com>
* @since 2.0.0
*/
public function is_option_page() {
return isset( $_POST['option_page'] ) && $_POST['option_page'] === $this->option_page;
}
/**
* Undocumented function
*
* @return boolean
* @author Justin Foell <justin.foell@webdevstudios.com>
* @since 2.0.0
*/
public function is_settings_page() {
return isset( $_GET['page'] ) && $_GET['page'] === $this->page_name;
}
public function get_page_name() {
return $this->page_name;
}
/**
* Undocumented function
*
* @return boolean
* @author Justin Foell <justin.foell@webdevstudios.com>
* @since 2.0.0
*/
private function is_adding_athlete() {
return ! ( empty( $_POST['strava_client_id'] ) && empty( $_POST['strava_client_secret'] ) );
}
public function __get( $name ) {
if ( ! strpos( 'strava_', $name ) ) {
$name = "strava_{$name}";
}
// Else.
return get_option( $name );
}
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;
}
}
+81
View File
@@ -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}&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,
);
}
}
+24
View File
@@ -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 . '/includes/' . implode( '/', $parts ) . '.php';
if ( file_exists( $file ) ) {
include_once $file;
}
}
spl_autoload_register( 'wpstrava_autoload_classes' );