Merge pull request #9 from cmanon/feature/multi-user

Feature/multi user
This commit is contained in:
Justin Foell
2017-12-08 12:50:18 -06:00
committed by GitHub
12 changed files with 494 additions and 156 deletions
+2
View File
@@ -0,0 +1,2 @@
.gitattributes export-ignore
.gitignore export-ignore
+1
View File
@@ -1,2 +1,3 @@
*~
.svn
.vscode
+24 -14
View File
@@ -9,7 +9,7 @@ class WPStrava_API {
//const STRAVA_V2_API = 'http://www.strava.com/api/v2/'; //rides/:ride_id/map_details
const STRAVA_V3_API = 'https://www.strava.com/api/v3/';
public function __construct( $access_token ) {
public function __construct( $access_token = null ) {
$this->access_token = $access_token;
}
@@ -19,11 +19,13 @@ class WPStrava_API {
$args = array(
'body' => http_build_query( $data ),
'sslverify' => false,
'headers' => array(
'Authorization' => 'Bearer ' . $this->access_token,
)
'headers' => array(),
);
if ( $this->access_token ) {
$args['headers']['Authorization'] = 'Bearer ' . $this->access_token;
}
$response = wp_remote_post( $url . $uri, $args );
if ( is_wp_error( $response ) )
@@ -38,9 +40,12 @@ class WPStrava_API {
else
$error = print_r( $response, true );
return new WP_Error( 'wp-strava_post',
sprintf( __( 'ERROR %s %s - %s', 'wp-strava'), $response['response']['code'], $response['response']['message'], $error ),
$response );
return new WP_Error(
'wp-strava_post',
// translators: message shown when there's a problem with ab HTTP POST to the Strava API.
sprintf( __( 'ERROR %1$s %2$s - See full error by adding <code>define( \'WP_STRAVA_DEBUG\' true );</code> to wp-config.php', 'wp-strava' ), $response['response']['code'], $response['response']['message'] ),
$error
);
}
return json_decode( $response['body'] );
@@ -51,14 +56,16 @@ class WPStrava_API {
$url .= $uri;
if ( ! empty( $args ) )
if ( ! empty( $args ) ) {
$url = add_query_arg( $args, $url );
}
$get_args = array(
'headers' => array(
'Authorization' => 'Bearer ' . $this->access_token,
)
'headers' => array(),
);
if ( $this->access_token ) {
$get_args['headers']['Authorization'] = 'Bearer ' . $this->access_token;
}
$response = wp_remote_get( $url, $get_args );
@@ -76,9 +83,12 @@ class WPStrava_API {
else
$error = print_r( $response, true );
return new WP_Error( 'wp-strava_get',
sprintf( __( 'ERROR %s %s - %s', 'wp-strava' ), $response['response']['code'], $response['response']['message'], $error ),
$response );
return new WP_Error(
'wp-strava_get',
// translators: message shown when there's a problem with an HTTP GET to the Strava API.
sprintf( __( 'ERROR %1$s %2$s - See full error by adding <code>define( \'WP_STRAVA_DEBUG\' true );</code> to wp-config.php', 'wp-strava' ), $response['response']['code'], $response['response']['message'] ),
$error
);
}
return json_decode( $response['body'] );
@@ -1,6 +1,6 @@
<?php
class WPStrava_RideShortcode {
class WPStrava_ActivityShortcode {
private static $add_script;
public static function init() {
@@ -15,22 +15,23 @@ class WPStrava_RideShortcode {
self::$add_script = true;
$defaults = array(
'id' => 0,
'som' => WPStrava::get_instance()->settings->som,
'map_width' => '480',
'map_height' => '320',
'id' => 0,
'som' => WPStrava::get_instance()->settings->som,
'map_width' => '480',
'map_height' => '320',
'athlete_token' => WPStrava::get_instance()->settings->get_default_token(),
);
extract( shortcode_atts( $defaults, $atts ) );
$strava_som = WPStrava_SOM::get_som( $som );
$strava_ride = WPStrava::get_instance()->rides;
$ride_details = $strava_ride->getRide( $id );
$activity = WPStrava::get_instance()->rides;
$ride_details = $activity->getRide( $athlete_token, $id );
//sanitize width & height
$map_width = str_replace( '%', '', $map_width );
$map_width = str_replace( '%', '', $map_width );
$map_height = str_replace( '%', '', $map_height );
$map_width = str_replace( 'px', '', $map_width );
$map_width = str_replace( 'px', '', $map_width );
$map_height = str_replace( 'px', '', $map_height );
if ( $ride_details ) {
@@ -82,4 +83,4 @@ class WPStrava_RideShortcode {
}
// Initialize short code
WPStrava_RideShortcode::init();
WPStrava_ActivityShortcode::init();
+91 -17
View File
@@ -10,13 +10,15 @@ class WPStrava_LatestMapWidget extends WP_Widget {
parent::__construct(
false,
__( 'Strava Latest Map', 'wp-strava' ), // Name
array( 'description' => __( 'Strava latest ride using static google map image', 'wp-strava' ) ) // Args.
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', 'wp-strava' );
$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'] ) : '';
@@ -28,6 +30,14 @@ class WPStrava_LatestMapWidget extends WP_Widget {
<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 esc_attr_e( $nickname ); ?></option>
<?php endforeach; ?>
</select>
</p>
<p>
<label for="<?php echo $this->get_field_id( 'distance_min' ); ?>"><?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; ?>" />
@@ -43,6 +53,7 @@ class WPStrava_LatestMapWidget extends WP_Widget {
// 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;
@@ -51,23 +62,25 @@ class WPStrava_LatestMapWidget extends WP_Widget {
public function widget( $args, $instance ) {
extract( $args );
$title = apply_filters( 'widget_title', empty( $instance['title'] ) ? __( 'Latest Activity', 'wp-strava' ) : $instance['title'] );
$distance_min = $instance['distance_min'];
$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;
// Try our transient first.
$ride_transient = get_transient( 'strava_latest_map_ride' );
$ride_option = get_option( 'strava_latest_map_ride' );
$ride_transient = get_transient( 'strava_latest_map_activity_' . $athlete_token );
$ride_option = get_option( 'strava_latest_map_activity_' . $athlete_token );
$ride = $ride_transient ?: null;
$ride = $ride_transient ? $ride_transient : null;
if ( ! $ride ) {
$strava_rides = WPStrava::get_instance()->rides;
$rides = $strava_rides->getRides( $strava_club_id );
$rides = $strava_rides->getRides( $athlete_token, $strava_club_id );
if ( is_wp_error( $rides ) ) {
echo $before_widget;
if ( $title ) echo $before_title . $title . $after_title;
if ( WPSTRAVA_DEBUG ) {
echo '<pre>';
print_r($rides);
@@ -86,14 +99,16 @@ class WPStrava_LatestMapWidget extends WP_Widget {
$ride = current( $rides );
//update transients & options
// Compare transient (temporary storage) to option (more permenant).
// If the option isn't set or the transient is different, update the option.
if ( empty( $ride_option->id ) || $ride->id != $ride_option->id ) {
$build_new = true;
update_option( 'strava_latest_map_ride', $ride );
$this->update_activity( $athlete_token, $ride );
}
// Update the transient if it needs updating.
if ( empty( $ride_transient->id ) || $ride->id != $ride_transient->id ) {
set_transient( 'strava_latest_map_ride', $ride, HOUR_IN_SECONDS );
$this->update_activity_transient( $athlete_token, $ride );
}
}
}
@@ -102,22 +117,81 @@ class WPStrava_LatestMapWidget extends WP_Widget {
echo $before_widget;
if ( $title ) echo $before_title . $title . $after_title;
?><a title="<?php echo $ride->name ?>" target="_blank" href="http://app.strava.com/activities/<?php echo $ride->id ?>"><?php
echo $this->getStaticImage( $ride->id, $build_new );
echo $this->getStaticImage( $athlete_token, $ride, $build_new );
?></a><?php
echo $after_widget;
}
}
private function getStaticImage( $ride_id, $build_new ) {
$img = get_option( 'strava_latest_map' );
/**
* Get image for specific ride using Static Maps class.
*
* @author Justin Foell
*
* @param string $athlete_token Token for athelete.
* @param int $ride_id Club ID (optional).
* @param boolean $build_new Whether to refresh the image from cache.
* @return string Image tag.
*/
private function getStaticImage( $athlete_token, $ride, $build_new ) {
$img = get_option( 'strava_latest_map_' . $athlete_token );
if ( $build_new || ! $img ) {
$ride = WPStrava::get_instance()->rides->getRide( $ride_id );
$img = WPStrava_StaticMap::get_image_tag( $ride );
update_option( 'strava_latest_map', $img );
$this->update_map( $athlete_token, $img );
}
return $img;
}
/**
* Update map in option to cache.
*
* @author Justin Foell
* @since 1.2.0
*
* @param string $athlete_token Token for athelete.
* @param string $img Image tag.
*/
private function update_map( $athlete_token, $img ) {
// Remove old (pre 1.2.0) cached maps.
if ( get_option( 'strava_latest_map' ) ) {
delete_option( 'strava_latest_map' );
}
update_option( 'strava_latest_map_' . $athlete_token, $img );
}
/**
* Update activity in option to cache.
*
* @author Justin Foell
* @since 1.2.0
*
* @param string $athlete_token Token for athelete.
* @param object $activity stdClass Strava activity object.
*/
private function update_activity( $athlete_token, $activity ) {
// Remove old (pre 1.2.0) option.
if ( get_option( 'strava_latest_map_ride' ) ) {
delete_option( 'strava_latest_map_ride' );
}
update_option( 'strava_latest_map_activity_' . $athlete_token, $activity );
}
/**
* Update activity in transient to cache.
*
* @author Justin Foell
* @since 1.2.0
*
* @param string $athlete_token Token for athelete.
* @param object $activity stdClass Strava activity object.
*/
private function update_activity_transient( $athlete_token, $activity ) {
// Remove old (pre 1.2.0) transient.
if ( get_transient( 'strava_latest_map_ride' ) ) {
delete_transient( 'strava_latest_map_ride' );
}
set_transient( 'strava_latest_map_activity_' . $athlete_token, $activity, HOUR_IN_SECONDS );
}
}
+23 -11
View File
@@ -7,7 +7,7 @@ class WPStrava_LatestRidesWidget extends WP_Widget {
public function __construct() {
$widget_ops = array( 'classname' => 'LatestRidesWidget', 'description' => __( 'Will publish your latest rides activity from strava.com.', 'wp-strava' ) );
parent::__construct( 'wp-strava', $name = __( 'Strava Latest Rides', 'wp-strava' ), $widget_ops );
parent::__construct( 'wp-strava', $name = __( 'Strava Latest Activity List', 'wp-strava' ), $widget_ops );
add_action( 'wp_enqueue_scripts', array( $this, 'maybe_enqueue' ) );
}
@@ -22,15 +22,15 @@ class WPStrava_LatestRidesWidget extends WP_Widget {
extract( $args );
//$widget_id = $args['widget_id'];
$title = apply_filters( 'widget_title', empty( $instance['title'] ) ? __( 'Rides', 'wp-strava' ) : $instance['title'] );
$title = apply_filters( 'widget_title', empty( $instance['title'] ) ? __( 'Activity', 'wp-strava' ) : $instance['title'] );
$athlete_token = isset( $instance['athlete_token'] ) ? $instance['athlete_token'] : WPStrava::get_instance()->settings->get_default_token();
$strava_club_id = empty( $instance['strava_club_id'] ) ? '' : $instance['strava_club_id'];
$quantity = empty( $instance['quantity'] ) ? '5' : $instance['quantity'];
$this->som = WPStrava_SOM::get_som();
?>
<?php echo $before_widget; ?>
<?php if ( $title ) echo $before_title . $title . $after_title; ?>
<?php echo $this->strava_request_handler( $strava_club_id, $quantity ); ?>
<?php echo $this->strava_request_handler( $athlete_token, $strava_club_id, $quantity ); ?>
<?php echo $after_widget; ?>
<?php
}
@@ -39,6 +39,7 @@ class WPStrava_LatestRidesWidget extends WP_Widget {
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'];
@@ -47,7 +48,9 @@ class WPStrava_LatestRidesWidget extends WP_Widget {
/** @see WP_Widget::form */
public function form( $instance ) {
$title = isset( $instance['title'] ) ? esc_attr( $instance['title'] ) : __( 'Rides', 'wp-strava' );
$title = isset( $instance['title'] ) ? esc_attr( $instance['title'] ) : __( 'Activity', '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;
@@ -57,7 +60,15 @@ class WPStrava_LatestRidesWidget extends WP_Widget {
<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( 'strava_club_id' ); ?>"><?php _e( 'Club ID (leave blank to show Athlete):', 'wp-strava' ); ?></label>
<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 esc_attr_e( $nickname ); ?></option>
<?php endforeach; ?>
</select>
</p>
<p>
<label for="<?php echo $this->get_field_id( 'strava_club_id' ); ?>"><?php _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>
@@ -69,11 +80,12 @@ class WPStrava_LatestRidesWidget extends WP_Widget {
// The handler to the ajax call, we will avoid this if Strava support jsonp request and we can do it
// the parsing directly on the jQuery ajax call, the returned text will be enclosed in the $response variable.
private function strava_request_handler( $strava_club_id, $quantity ) {
private function strava_request_handler( $athlete_token, $strava_club_id, $quantity ) {
$som = WPStrava_SOM::get_som();
$strava_rides = WPStrava::get_instance()->rides;
$rides = $strava_rides->getRides( $strava_club_id, $quantity );
$rides = $strava_rides->getRides( $athlete_token, $strava_club_id, $quantity );
if ( is_wp_error( $rides ) )
return $rides->get_error_message();
@@ -89,9 +101,9 @@ class WPStrava_LatestRidesWidget extends WP_Widget {
$response .= " <a href='" . WPStrava_Rides::ATHLETES_URL . $ride->athlete_id . "'>" . $ride->athlete_name . '</a>';
}
$response .= sprintf( __( ' rode %s %s', 'wp-strava' ), $this->som->distance( $ride->distance ), $this->som->get_distance_label() );
$response .= sprintf( __( ' during %s %s', 'wp-strava' ), $this->som->time( $ride->elapsed_time ), $this->som->get_time_label() );
$response .= sprintf( __( ' climbing %s %s', 'wp-strava' ), $this->som->elevation( $ride->total_elevation_gain ), $this->som->get_elevation_label() );
$response .= sprintf( __( ' rode %s %s', 'wp-strava' ), $som->distance( $ride->distance ), $som->get_distance_label() );
$response .= sprintf( __( ' during %s %s', 'wp-strava' ), $som->time( $ride->elapsed_time ), $som->get_time_label() );
$response .= sprintf( __( ' climbing %s %s', 'wp-strava' ), $som->elevation( $ride->total_elevation_gain ), $som->get_elevation_label() );
$response .= "</div>";
$response .= "</li>";
}
+26 -6
View File
@@ -7,12 +7,30 @@ class WPStrava_Rides {
const RIDES_URL = 'http://app.strava.com/rides/';
const ATHLETES_URL = 'http://app.strava.com/athletes/';
public function getRide( $rideId ) {
return WPStrava::get_instance()->api->get( "activities/{$rideId}" );
/**
* 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 activty.
* @author Justin Foell
*/
public function getRide( $athlete_token, $activity_id ) {
return WPStrava::get_instance()->get_api( $athlete_token )->get( "activities/{$activity_id}" );
} // getRideDetails
public function getRides( $club_id = null, $quantity = null ) {
$api = WPStrava::get_instance()->api;
/**
* Get activity list from Strava API.
*
* @author Justin Foell
*
* @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|WP_Error Array of rides or WP_Error.
*/
public function getRides( $athlete_token, $club_id = null, $quantity = null ) {
$api = WPStrava::get_instance()->get_api( $athlete_token );
$data = null;
@@ -25,11 +43,13 @@ class WPStrava_Rides {
$data = $api->get( 'athlete/activities', $args );
}
if ( is_wp_error( $data ) )
if ( is_wp_error( $data ) ) {
return $data;
}
if ( is_array( $data ) )
if ( is_array( $data ) ) {
return $data;
}
return array();
+267 -57
View File
@@ -1,7 +1,7 @@
<?php
/**
* v3 - http://strava.github.io/api/v3/oauth/
* 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
@@ -12,9 +12,10 @@
class WPStrava_Settings {
private $feedback;
private $token;
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() {
@@ -22,6 +23,7 @@ class WPStrava_Settings {
add_action( 'admin_menu', array( $this, 'add_strava_menu' ) );
add_filter( 'pre_set_transient_settings_errors', array( $this, 'maybe_oauth' ) );
add_filter( 'plugin_action_links_' . WPSTRAVA_PLUGIN_NAME, array( $this, 'settings_link' ) );
add_action( 'admin_enqueue_scripts', array( $this, 'settings_scripts' ) );
//for process debugging
//add_action( 'all', array( $this, 'hook_debug' ) );
//add_filter( 'all', array( $this, 'hook_debug' ) );
@@ -34,26 +36,24 @@ class WPStrava_Settings {
/**
* This runs after options are saved
*/
public function maybe_oauth( $value ) {
public function maybe_oauth( $value ) {
// User is clearing to start-over, don't oauth, ignore other errors.
if ( isset( $_POST['strava_token'] ) && $this->tokens_empty( $_POST['strava_token'] ) )
return array();
// Redirect only if all the right options are in place.
if ( isset( $value[0]['type'] ) && $value[0]['type'] == 'updated' ) { // Make sure there were no settings errors.
if ( isset( $value[0]['type'] ) && 'updated' == $value[0]['type'] ) { // Make sure there were no settings errors.
if ( isset( $_POST['option_page'] ) && $_POST['option_page'] == $this->option_page ) { // Make sure we're on our settings page.
// User is clearing to start-over, don't oauth.
if ( isset( $_POST['strava_token'] ) && empty( $_POST['strava_token'] ) )
return;
// Only re-auth if client ID and secret were shown.
// Only re-auth if client ID and secret were saved.
if ( ! empty( $_POST['strava_client_id'] ) && ! empty( $_POST['strava_client_secret'] ) ) {
$client_id = get_option( 'strava_client_id' );
$client_secret = get_option( 'strava_client_secret' );
$client_id = $_POST['strava_client_id'];
$client_secret = $_POST['strava_client_secret'];
if ( $client_id && $client_secret ) {
$redirect = admin_url( "options-general.php?page={$this->page_name}" );
$url = "https://www.strava.com/oauth/authorize?client_id={$client_id}&response_type=code&redirect_uri={$redirect}&approval_prompt=force";
wp_redirect( $url );
exit();
}
$redirect = admin_url( "options-general.php?page={$this->page_name}" );
$url = "https://www.strava.com/oauth/authorize?client_id={$client_id}&response_type=code&redirect_uri={$redirect}&approval_prompt=force";
wp_redirect( $url );
exit();
}
}
}
@@ -61,30 +61,37 @@ class WPStrava_Settings {
}
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' ) );
add_options_page(
__( 'Strava Settings', 'wp-strava' ),
__( 'Strava', 'wp-strava' ),
'manage_options',
$this->page_name,
array( $this, 'print_strava_options' )
);
}
public function init() {
$this->tokens = $this->get_tokens();
// Only validate additional athlete information if all fields are present.
$this->adding_athlete = ! ( empty( $_POST['strava_client_id'] ) && empty( $_POST['strava_client_secret'] ) );
//only update when redirected back from strava
if ( ! isset( $_GET['settings-updated'] ) && isset( $_GET['page'] ) && $_GET['page'] == $this->page_name ) {
if ( isset( $_GET['code'] ) ) {
$token = $this->get_token( $_GET['code'] );
$token = $this->fetch_token( $_GET['code'] );
if ( $token ) {
add_settings_error( 'strava_token', 'strava_token', sprintf( __( 'New Strava token retrieved. %s', 'wp-strava' ), $this->feedback ) , 'updated' );
update_option( 'strava_token', $token );
$this->add_token( $token );
update_option( 'strava_token', $this->tokens );
} else {
add_settings_error( 'strava_token', 'strava_token', $this->feedback );
}
} else if ( isset( $_GET['error'] ) ) {
} 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'] ) ) );
}
}
$this->token = get_option( 'strava_token' );
}
public function register_strava_settings() {
@@ -92,15 +99,26 @@ class WPStrava_Settings {
add_settings_section( 'strava_api', __( 'Strava API', 'wp-strava' ), array( $this, 'print_api_instructions' ), 'wp-strava' );
if ( ! $this->token ) {
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.
@@ -122,30 +140,42 @@ class WPStrava_Settings {
public function print_api_instructions() {
$signup_url = 'http://www.strava.com/developers';
$settings_url = 'https://www.strava.com/settings/api';
$blog_name = get_bloginfo( 'name' );
$app_name = sprintf( esc_html( '%s Strava', 'wp-strava' ), $blog_name );
$icon_url = 'https://plugins.svn.wordpress.org/wp-strava/assets/icon-128x128.png';
$blog_name = get_bloginfo( 'name' );
$app_name = sprintf( esc_html( '%s Strava', 'wp-strava' ), $blog_name );
$site_url = site_url();
$description = 'WP-Strava for ' . $blog_name;
printf( __( "<p>Steps:</p>
printf( __( "<p>Steps:</p>
<ol>
<li>Create your free API Application/Connection here: <a href='%s' target='_blank'>%s</a> using the following information:</li>
<li>Create your free API Application/Connection here: <a href='%1\$s' target='_blank'>%2\$s</a> using the following information:</li>
<ul>
<li>Application Name: <strong>%s</strong></li>
<li>Website: <strong>%s</strong></li>
<li>Application Description: <strong>%s</strong></li>
<li>Authorization Callback Domain: <strong>%s</strong></li>
<li>App Icon: <strong>upload <a href='%3\$s' target='_blank'>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, $app_name, $site_url, $description, $site_url );
</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>
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='%s' target='_blank'>%s</a> and clicking <strong>Get a Key</strong></li>
<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' target='_blank'>%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 );
@@ -155,14 +185,14 @@ class WPStrava_Settings {
?>
<div class="wrap">
<div id="icon-options-general" class="icon32"><br/></div>
<h2><?php _e( 'Strava Settings', 'wp-strava' ); ?></h2>
<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 _e( 'Save Changes', 'wp-strava' ); ?>" />
<input type="submit" class="button-primary" value="<?php esc_html_e( 'Save Changes', 'wp-strava' ); ?>" />
</p>
</form>
</div>
@@ -170,18 +200,34 @@ class WPStrava_Settings {
}
public function print_client_input() {
?><input type="text" id="strava_client_id" name="strava_client_id" value="<?php echo get_option( 'strava_client_id' ); ?>" /><?php
?><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 echo get_option( 'strava_client_secret' ); ?>" /><?php
?><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() {
?><input type="text" id="strava_token" name="strava_token" value="<?php echo get_option( 'strava_token' ); ?>" /><?php
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' ) );
}
@@ -189,23 +235,61 @@ class WPStrava_Settings {
}
public function sanitize_client_secret( $client_secret ) {
if ( trim( $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;
}
private function get_token( $code ) {
$client_id = get_option( 'strava_client_id' );
$client_secret = get_option( 'strava_client_secret' );
private function fetch_token( $code ) {
$client_id = $this->client_id;
$client_secret = $this->client_secret;
delete_option( 'strava_client_id' );
delete_option( 'strava_client_secret' );
if ( $client_id && $client_secret ) {
require_once WPSTRAVA_PLUGIN_DIR . 'lib/API.class.php';
$api = new WPStrava_API();
$data = array( 'client_id' => $client_id, 'client_secret' => $client_secret, 'code' => $code );
$strava_info = WPStrava::get_instance()->api->post( 'oauth/token', $data );
$strava_info = $api->post( 'oauth/token', $data );
if ( $strava_info ) {
if ( isset( $strava_info->access_token ) ) {
@@ -222,11 +306,11 @@ class WPStrava_Settings {
} else {
$this->feedback .= __( 'Missing Client ID or Client Secret.', 'wp-strava' );
return false;
}
} // End if.
}
public function print_gmaps_key_input() {
?><input type="text" id="strava_gmaps_key" name="strava_gmaps_key" value="<?php echo get_option( 'strava_gmaps_key' ); ?>" /><?php
?><input type="text" id="strava_gmaps_key" name="strava_gmaps_key" value="<?php echo $this->gmaps_key; ?>" /><?php
}
public function sanitize_gmaps_key( $key ) {
@@ -234,11 +318,10 @@ class WPStrava_Settings {
}
public function print_som_input() {
$strava_som = get_option( 'strava_som' );
?>
<select id="strava_som" name="strava_som">
<option value="metric" <?php selected( $strava_som, 'metric' ); ?>><?php _e( 'Metric', 'wp-strava' )?></option>
<option value="english" <?php selected( $strava_som, 'english' ); ?>><?php _e( 'English', 'wp-strava' )?></option>
<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
}
@@ -253,16 +336,137 @@ class WPStrava_Settings {
public function sanitize_cache_clear( $checked ) {
if ( 'on' === $checked ) {
// Clear these values:
// Clear these (pre 1.2.0) values:
delete_transient( 'strava_latest_map_ride' );
delete_option( 'strava_latest_map_ride' );
delete_option( 'strava_latest_map' );
// Remove activity transients and options.
foreach ( $this->get_tokens() as $token ) {
delete_transient( 'strava_latest_map_activity_' . $token );
delete_option( 'strava_latest_map_activity_' . $token );
delete_option( 'strava_latest_map_' . $token );
}
}
return null;
}
/**
* Gets all saved strava tokens as an array.
*
* @return array
* @author Justin Foell
* @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
* @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
* @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
* @since 1.2.0
*
* @param integer $number Athlete number (default 1).
* @return string
*/
private function get_default_nickname( $number = 1 ) {
// Translators: Athelete number if no nickname present.
return ( 1 == $number ) ? __( 'Default', 'wp-strava' ) : sprintf( __( 'Athlete %s', 'wp-strava' ), $number );
}
/**
* Checks for valid tokens.
*
* @author Justin Foell
* @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
* @since 1.2.0
*/
public function add_token( $token ) {
if ( false === array_search( $token, $this->tokens ) ) {
$this->tokens[] = $token;
}
}
public function __get( $name ) {
return get_option( "strava_{$name}" );
if ( ! strpos( 'strava_', $name ) ) {
$name = "strava_{$name}";
}
// Else.
return get_option( $name );
}
public function settings_link( $links ) {
@@ -271,4 +475,10 @@ class WPStrava_Settings {
return $links;
}
public function settings_scripts() {
$screen = get_current_screen();
if ( "settings_page_{$this->page_name}" === $screen->id ) {
wp_enqueue_script( 'wp-strava-settings', WPSTRAVA_PLUGIN_URL . 'js/wp-strava-settings.js', array( 'jquery' ) );
}
}
}
+1 -1
View File
@@ -27,7 +27,7 @@ class WPStrava_StaticMap {
if ( ! empty( $ride->map->polyline ) && ( $url_len + strlen( $ride->map->polyline ) < $max_chars ) ) {
$url .= $ride->map->polyline;
} else {
} elseif ( ! empty( $ride->map->summary_polyline ) ) {
$url .= $ride->map->summary_polyline;
}
+12 -12
View File
@@ -4,14 +4,14 @@ require_once WPSTRAVA_PLUGIN_DIR . 'lib/Settings.class.php';
require_once WPSTRAVA_PLUGIN_DIR . 'lib/SOM.class.php';
require_once WPSTRAVA_PLUGIN_DIR . 'lib/LatestRidesWidget.class.php';
require_once WPSTRAVA_PLUGIN_DIR . 'lib/LatestMapWidget.class.php';
require_once WPSTRAVA_PLUGIN_DIR . 'lib/RideShortcode.class.php';
require_once WPSTRAVA_PLUGIN_DIR . 'lib/ActivityShortcode.class.php';
require_once WPSTRAVA_PLUGIN_DIR . 'lib/StaticMap.class.php';
class WPStrava {
private static $instance = null;
private $settings = null;
private $api = null;
private $api = array(); // Holds an array of APIs.
private $rides = null;
private function __construct() {
@@ -38,10 +38,6 @@ class WPStrava {
public function __get( $name ) {
// On-demand classes.
if ( $name == 'api' ) {
return $this->get_api();
}
if ( $name == 'rides' ) {
return $this->get_rides();
}
@@ -53,13 +49,17 @@ class WPStrava {
return null;
}
public function get_api() {
if ( ! $this->api ) {
require_once WPSTRAVA_PLUGIN_DIR . 'lib/API.class.php';
$this->api = new WPStrava_API( get_option( 'strava_token' ) );
public function get_api( $token = null ) {
if ( ! $token ) {
$token = $this->settings->get_default_token();
}
return $this->api;
if ( empty( $this->api[ $token ] ) ) {
require_once WPSTRAVA_PLUGIN_DIR . 'lib/API.class.php';
$this->api[$token] = new WPStrava_API( $token );
}
return $this->api[$token];
}
public function get_rides() {
@@ -75,4 +75,4 @@ class WPStrava {
// Register a personalized stylesheet
wp_register_style( 'wp-strava-style', WPSTRAVA_PLUGIN_URL . 'css/wp-strava.css' );
}
}
}
+35 -27
View File
@@ -2,57 +2,65 @@
Contributors: cmanon, jrfoell, lancewillett
Tags: strava, bicycle, cycling, biking, running, run, swimming, swim, gps, shortcode, widget, plugin
Requires at least: 4.6
Tested up to: 4.7
Stable tag: 1.1.1
Tested up to: 4.9
Stable tag: 1.2.0
License: GPLv2 or later
Show your Strava activity on your WordPress site.
== Description ==
This plugin uses the Strava V3 API to embed maps and activity for
athletes and clubs on your WordPress site. Included are several
widgets and shortcodes for showing maps and activity summaries.
This plugin uses the Strava API to embed maps and activity for athletes and clubs on your WordPress site. Included are several widgets and shortcodes for showing maps and activity summaries.
= Shortcodes =
[activity id=NUMBER] - add to any page or post. Also takes the following
optional parameters:
[activity id=NUMBER] - add to any page or post. Shows a summary of the activity plus a map if a google maps key has been added.
* som - english/metric (system of measure - override from default setting)
* map_width - width (width of image in pixels)
* map_height - height (height of image in pixels)
Also takes the following optional parameters:
* som - english/metric (system of measure - override from default setting).
* map_width - width (width of image in pixels).
* map_height - height (height of image in pixels).
* athlete_token - specify a different athlete (you can copy this value from https://www.strava.com/settings/api or the wp-strava settings page at /wp-admin/options-general.php?page=wp-strava-options).
[ride] is an alias for [activity] and will accept the same parameters (kept for backwards compatibility).
= Widgets =
Strava Latest Rides - shows a list of the last few activities
Strava Latest Activity List - shows a list of the last few activities.
Strava Latest Map - shows map of latest activity with option to limit
latest map to activities of a certain minimum distance
Strava Latest Map - shows map of latest activity with option to limit latest map to activities of a certain minimum distance.
== Changelog ==
= 1.2.0 =
Added multi-athlete configuration.
Additional transitions from Ride -> Activity.
Updated setup instructions to reflect latest Strava API set up process.
Backwards Compatibility - removed PHP 5.3+ specific operator (should work with PHP 5.2 now - versions 1.1 and 1.1.1 don't).
Reworked error reporting and formatting.
= 1.1.1 =
Changes to better support translations through https://translate.wordpress.org
Cleaned up formatting
Changes to better support translations through https://translate.wordpress.org.
Cleaned up formatting.
= 1.1 =
Added [activity] shortcode to deprecate [ride] in the future
Fixed static method call error in shortcode
Added title to Strava Latest Map Widget
Added Lance Willett to contributors
Added target="_blank" to widget hrefs
Added Google Maps Key to settings (required for map images)
Added cache clear option to remove transient & image data
Cleaned up formatting
Added [activity] shortcode to deprecate [ride] in the future.
Fixed static method call error in shortcode.
Added title to Strava Latest Map Widget.
Added Lance Willett to contributors.
Added target="_blank" to widget hrefs.
Added Google Maps Key to settings (required for map images).
Added cache clear option to remove transient & image data.
Cleaned up formatting.
= 1.0 =
Change to Strava API V3
Switch ride shortcode to use static map
Change to Strava API V3.
Switch ride shortcode to use static map.
= 0.70 =
Use WordPress HTTP API for all remote calls
Use WordPress Settings API for settings page
Use WordPress HTTP API for all remote calls.
Use WordPress Settings API for settings page.
= 0.62 =
Refactor some code.
+1 -1
View File
@@ -3,7 +3,7 @@
* Plugin Name: WP Strava
* Plugin URI: https://wordpress.org/plugins/wp-strava/
* Description: Plugin to show your strava.com information in your wordpress blog. Some Icons are Copyright © Yusuke Kamiyamane. All rights reserved. Licensed under a Creative Commons Attribution 3.0 license.
* Version: 1.1.1
* Version: 1.2.0
* Author: Carlos Santa Cruz, Justin Foell, Lance Willet
* License: GPL2
* Text Domain: wp-strava