From 8fc5ea34077cc1edf27b6d7a6441fa5f0539abf3 Mon Sep 17 00:00:00 2001 From: Justin Foell Date: Fri, 21 Jul 2017 16:12:15 -0500 Subject: [PATCH 1/9] Working multi tokens with nicknames --- .gitignore | 1 + lib/API.class.php | 17 ++-- lib/Settings.class.php | 200 ++++++++++++++++++++++++++++++++--------- lib/Strava.class.php | 16 ++-- 4 files changed, 173 insertions(+), 61 deletions(-) diff --git a/.gitignore b/.gitignore index e0c38e3..2e8a44a 100755 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ *~ .svn +.vscode diff --git a/lib/API.class.php b/lib/API.class.php index 7df3aa0..79c9e77 100755 --- a/lib/API.class.php +++ b/lib/API.class.php @@ -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 ) ) @@ -55,10 +57,11 @@ class WPStrava_API { $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 ); diff --git a/lib/Settings.class.php b/lib/Settings.class.php index 4161fa8..4db719c 100644 --- a/lib/Settings.class.php +++ b/lib/Settings.class.php @@ -12,7 +12,7 @@ class WPStrava_Settings { private $feedback; - private $token; + private $tokens = array(); private $page_name = 'wp-strava-options'; private $option_page = 'wp-strava-settings-group'; @@ -22,6 +22,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 +35,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(); } } } @@ -69,22 +68,24 @@ class WPStrava_Settings { } public function init() { + $this->tokens = $this->get_tokens(); + //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'] ); 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 +93,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,18 +134,18 @@ 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 ); + $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( __( "

Steps:

    -
  1. Create your free API Application/Connection here: %s using the following information:
  2. +
  3. Create your free API Application/Connection here: %2\$s using the following information:
  4. Once you've created your API Application at strava.com, enter the Client ID and Client Secret below, which can now be found on that same strava API Settings page.
  5. 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.
  6. @@ -145,7 +157,7 @@ class WPStrava_Settings { $maps_url = 'https://developers.google.com/maps/documentation/static-maps/'; printf( __( "

    Steps:

      -
    1. To use Google map images, you must create a Static Maps API Key. Create a free key by going here: %s and clicking Get a Key
    2. +
    3. To use Google map images, you must create a Static Maps API Key. Create a free key by going here: %2\$s and clicking Get a Key
    4. Once you've created your Google Static Maps API Key, enter the key below.
    ", 'wp-strava' ), $maps_url, $maps_url ); @@ -155,14 +167,14 @@ class WPStrava_Settings { ?>

    -

    +

    option_page ); ?>

    - +

    @@ -170,15 +182,29 @@ class WPStrava_Settings { } public function print_client_input() { - ?>tokens_empty( $this->tokens ) ? __( 'default', 'wp-strava' ) : ''; + ?>nickname; + foreach ( $this->get_tokens() as $index => $token ) { + ?> + + + + +
    + 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 +264,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() { - ?> $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; + } + + /** + * Checks for valid tokens. + * + * @author Justin Foell + * @since NEXT + * + * @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 NEXT + */ + 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 +377,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' ) ); + } + } } diff --git a/lib/Strava.class.php b/lib/Strava.class.php index cb8f9f1..bf1a3e6 100644 --- a/lib/Strava.class.php +++ b/lib/Strava.class.php @@ -11,7 +11,7 @@ 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,13 @@ class WPStrava { return null; } - public function get_api() { - if ( ! $this->api ) { + public function get_api( $id = '0' ) { + if ( ! $this->api[$id] ) { require_once WPSTRAVA_PLUGIN_DIR . 'lib/API.class.php'; - $this->api = new WPStrava_API( get_option( 'strava_token' ) ); + $this->api[$id] = new WPStrava_API( $this->settings->get_setting( 'strava_token', $id ) ); } - return $this->api; + return $this->api[$id]; } public function get_rides() { @@ -75,4 +71,4 @@ class WPStrava { // Register a personalized stylesheet wp_register_style( 'wp-strava-style', WPSTRAVA_PLUGIN_URL . 'css/wp-strava.css' ); } -} \ No newline at end of file +} From 07b8b51762733bfd520611d9e3be7043a6a4d546 Mon Sep 17 00:00:00 2001 From: Justin Foell Date: Fri, 21 Jul 2017 23:20:43 -0500 Subject: [PATCH 2/9] Updated token/nickname saving. --- lib/Settings.class.php | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/lib/Settings.class.php b/lib/Settings.class.php index 4db719c..b5d5042 100644 --- a/lib/Settings.class.php +++ b/lib/Settings.class.php @@ -15,6 +15,7 @@ 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() { @@ -70,6 +71,9 @@ class WPStrava_Settings { 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'] ) ) { @@ -199,7 +203,7 @@ class WPStrava_Settings { foreach ( $this->get_tokens() as $index => $token ) { ?> - +
    @@ -208,6 +212,11 @@ class WPStrava_Settings { } 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' ) ); } @@ -215,6 +224,11 @@ class WPStrava_Settings { } 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' ) ); } @@ -222,7 +236,21 @@ class WPStrava_Settings { } public function sanitize_nickname( $nicknames ) { - foreach ( $nicknames as $nickname ) { + $second2last = $last = false; + if ( ! $this->adding_athlete ) { + // Reemove last (blank) entry if not trying to add an additional athlete. + $last = array_pop( $nicknames ); + $second2last = end( $nicknames ); + + $token_index = count( $nicknames ) - 1; + if ( $last === '' && $second2last === '' && + empty( $_POST['strava_token'][ $token_index ] ) ) { + // Remove one more + array_pop( $nicknames ); + } + } + + foreach ( $nicknames as $index => $nickname ) { if ( '' == trim( $nickname ) ) { add_settings_error( 'strava_nickname', 'strava_nickname', __( 'Nickname is required.', 'wp-strava' ) ); return $nicknames; From 4f696b8c19338388ad0fe1ccdbce03c3d874194e Mon Sep 17 00:00:00 2001 From: Justin Foell Date: Fri, 11 Aug 2017 17:28:29 -0500 Subject: [PATCH 3/9] Updated Latest Map and Latest Activity widgets to work with new multiple athlete settings. --- lib/LatestMapWidget.class.php | 97 +++++++++++++++++++++++++++++---- lib/LatestRidesWidget.class.php | 28 +++++++--- lib/Rides.class.php | 32 +++++++++-- lib/Settings.class.php | 87 +++++++++++++++++++++++------ lib/StaticMap.class.php | 2 +- lib/Strava.class.php | 14 +++-- readme.txt | 3 + wp-strava.php | 2 +- 8 files changed, 215 insertions(+), 50 deletions(-) diff --git a/lib/LatestMapWidget.class.php b/lib/LatestMapWidget.class.php index 65b7940..d81d1ff 100644 --- a/lib/LatestMapWidget.class.php +++ b/lib/LatestMapWidget.class.php @@ -17,6 +17,8 @@ class WPStrava_LatestMapWidget extends WP_Widget { public function form( $instance ) { // outputs the options form on admin $title = isset( $instance['title'] ) ? esc_attr( $instance['title'] ) : __( 'Latest 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(); $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 {

    +

    + + +

    @@ -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; @@ -52,19 +63,20 @@ class WPStrava_LatestMapWidget extends WP_Widget { extract( $args ); $title = apply_filters( 'widget_title', empty( $instance['title'] ) ? __( 'Latest Activity', 'wp-strava' ) : $instance['title'] ); + $athlete_token = isset( $instance['athlete_token'] ) ? $instance['athlete_token'] : WPStrava::get_instance()->settings->get_default_token(); $distance_min = $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; 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; @@ -86,14 +98,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 +116,81 @@ class WPStrava_LatestMapWidget extends WP_Widget { echo $before_widget; if ( $title ) echo $before_title . $title . $after_title; ?>getStaticImage( $ride->id, $build_new ); + echo $this->getStaticImage( $athlete_token, $ride, $build_new ); ?>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 ); + } } diff --git a/lib/LatestRidesWidget.class.php b/lib/LatestRidesWidget.class.php index bcbaf42..32f95e0 100644 --- a/lib/LatestRidesWidget.class.php +++ b/lib/LatestRidesWidget.class.php @@ -23,14 +23,14 @@ class WPStrava_LatestRidesWidget extends WP_Widget { //$widget_id = $args['widget_id']; $title = apply_filters( 'widget_title', empty( $instance['title'] ) ? __( 'Rides', '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(); ?> - strava_request_handler( $strava_club_id, $quantity ); ?> + strava_request_handler( $athlete_token, $strava_club_id, $quantity ); ?> 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 {

    - + + +

    +

    +

    @@ -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 .= " " . $ride->athlete_name . ''; } - $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 .= ""; $response .= ""; } diff --git a/lib/Rides.class.php b/lib/Rides.class.php index 4b237ff..0fb5bd1 100755 --- a/lib/Rides.class.php +++ b/lib/Rides.class.php @@ -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(); diff --git a/lib/Settings.class.php b/lib/Settings.class.php index b5d5042..c311c89 100644 --- a/lib/Settings.class.php +++ b/lib/Settings.class.php @@ -77,7 +77,7 @@ class WPStrava_Settings { //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' ); $this->add_token( $token ); @@ -194,18 +194,15 @@ class WPStrava_Settings { } public function print_nickname_input() { - $nickname = $this->tokens_empty( $this->tokens ) ? __( 'default', 'wp-strava' ) : ''; + $nickname = $this->tokens_empty( $this->tokens ) ? __( 'Default', 'wp-strava' ) : ''; ?>nickname; - foreach ( $this->get_tokens() as $index => $token ) { + foreach ( $this->get_all_tokens() as $token => $nickname ) { ?> - - - +
    adding_athlete ) { - // Reemove last (blank) entry if not trying to add an additional athlete. - $last = array_pop( $nicknames ); - $second2last = end( $nicknames ); + + $last = end( $nicknames ); + $second2last = prev( $nicknames ); $token_index = count( $nicknames ) - 1; - if ( $last === '' && $second2last === '' && + if ( $last === '' && $second2last !== '' && empty( $_POST['strava_token'][ $token_index ] ) ) { - // Remove one more + // Remove last (blank) entry if not trying to add an additional athlete. array_pop( $nicknames ); } } @@ -263,7 +260,7 @@ class WPStrava_Settings { return $token; } - private function get_token( $code ) { + private function fetch_token( $code ) { $client_id = $this->client_id; $client_secret = $this->client_secret; @@ -322,10 +319,17 @@ 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; } @@ -335,7 +339,7 @@ class WPStrava_Settings { * * @return array * @author Justin Foell - * @since NEXT + * @since 1.2.0 */ public function get_tokens() { $tokens = get_option( 'strava_token' ); @@ -352,11 +356,60 @@ class WPStrava_Settings { 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 + * @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 NEXT + * @since 1.2.0 * * @param string|array Single token or array of tokens. * @return boolean True if empty. @@ -383,7 +436,7 @@ class WPStrava_Settings { * @param string $token * * @author Justin Foell - * @since NEXT + * @since 1.2.0 */ public function add_token( $token ) { if ( false === array_search( $token, $this->tokens ) ) { diff --git a/lib/StaticMap.class.php b/lib/StaticMap.class.php index bb214c9..38a9e29 100644 --- a/lib/StaticMap.class.php +++ b/lib/StaticMap.class.php @@ -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; } diff --git a/lib/Strava.class.php b/lib/Strava.class.php index bf1a3e6..b0fb7e3 100644 --- a/lib/Strava.class.php +++ b/lib/Strava.class.php @@ -49,13 +49,17 @@ class WPStrava { return null; } - public function get_api( $id = '0' ) { - if ( ! $this->api[$id] ) { - require_once WPSTRAVA_PLUGIN_DIR . 'lib/API.class.php'; - $this->api[$id] = new WPStrava_API( $this->settings->get_setting( 'strava_token', $id ) ); + public function get_api( $token = null ) { + if ( ! $token ) { + $token = $this->settings->get_default_token(); } - return $this->api[$id]; + 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() { diff --git a/readme.txt b/readme.txt index 69f308f..1e330ed 100755 --- a/readme.txt +++ b/readme.txt @@ -32,6 +32,9 @@ latest map to activities of a certain minimum distance == Changelog == += 1.2.0 = +Added multi-athlete configuration + = 1.1.1 = Changes to better support translations through https://translate.wordpress.org Cleaned up formatting diff --git a/wp-strava.php b/wp-strava.php index 622caa1..6341ef6 100755 --- a/wp-strava.php +++ b/wp-strava.php @@ -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-beta1 * Author: Carlos Santa Cruz, Justin Foell, Lance Willet * License: GPL2 * Text Domain: wp-strava From 5f162ec215595b9e2431360360f5801d0ab65f2b Mon Sep 17 00:00:00 2001 From: Justin Foell Date: Fri, 29 Sep 2017 09:37:14 -0500 Subject: [PATCH 4/9] Revert elvis conditional for PHP 5.2 compatibility --- lib/LatestMapWidget.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/LatestMapWidget.class.php b/lib/LatestMapWidget.class.php index d81d1ff..2ccb33b 100644 --- a/lib/LatestMapWidget.class.php +++ b/lib/LatestMapWidget.class.php @@ -72,7 +72,7 @@ class WPStrava_LatestMapWidget extends WP_Widget { $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; From 080b59295dbaed31dd2df7fdd287f2ab604e8e1d Mon Sep 17 00:00:00 2001 From: Justin Foell Date: Fri, 29 Sep 2017 10:52:57 -0500 Subject: [PATCH 5/9] Update activity shortcode to handle multiple athletes --- ....class.php => ActivityShortcode.class.php} | 21 ++++++++++--------- lib/Strava.class.php | 2 +- 2 files changed, 12 insertions(+), 11 deletions(-) rename lib/{RideShortcode.class.php => ActivityShortcode.class.php} (83%) diff --git a/lib/RideShortcode.class.php b/lib/ActivityShortcode.class.php similarity index 83% rename from lib/RideShortcode.class.php rename to lib/ActivityShortcode.class.php index 975e392..92289db 100644 --- a/lib/RideShortcode.class.php +++ b/lib/ActivityShortcode.class.php @@ -1,6 +1,6 @@ 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(); diff --git a/lib/Strava.class.php b/lib/Strava.class.php index b0fb7e3..375f751 100644 --- a/lib/Strava.class.php +++ b/lib/Strava.class.php @@ -4,7 +4,7 @@ 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 { From 78443d5ea9c1c0da82a07df39865bacba0c56da9 Mon Sep 17 00:00:00 2001 From: Justin Foell Date: Fri, 29 Sep 2017 11:25:22 -0500 Subject: [PATCH 6/9] Updated instructions and changelog --- lib/LatestMapWidget.class.php | 6 ++-- lib/LatestRidesWidget.class.php | 6 ++-- lib/Settings.class.php | 22 ++++++++++--- readme.txt | 55 +++++++++++++++++---------------- 4 files changed, 52 insertions(+), 37 deletions(-) diff --git a/lib/LatestMapWidget.class.php b/lib/LatestMapWidget.class.php index 2ccb33b..bb4234f 100644 --- a/lib/LatestMapWidget.class.php +++ b/lib/LatestMapWidget.class.php @@ -10,13 +10,13 @@ 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'] ) : ''; @@ -62,7 +62,7 @@ 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'] ); + $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 = $instance['distance_min']; $strava_club_id = empty( $instance['strava_club_id'] ) ? null : $instance['strava_club_id']; diff --git a/lib/LatestRidesWidget.class.php b/lib/LatestRidesWidget.class.php index 32f95e0..2a3174f 100644 --- a/lib/LatestRidesWidget.class.php +++ b/lib/LatestRidesWidget.class.php @@ -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,7 +22,7 @@ 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']; @@ -48,7 +48,7 @@ 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'] ) : ''; diff --git a/lib/Settings.class.php b/lib/Settings.class.php index c311c89..71e9a2e 100644 --- a/lib/Settings.class.php +++ b/lib/Settings.class.php @@ -138,6 +138,7 @@ class WPStrava_Settings { public function print_api_instructions() { $signup_url = 'http://www.strava.com/developers'; $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' ); $app_name = sprintf( esc_html( '%s Strava', 'wp-strava' ), $blog_name ); $site_url = site_url(); @@ -146,15 +147,26 @@ class WPStrava_Settings {

    1. Create your free API Application/Connection here: %2\$s using the following information:
      • -
      • Application Name: %3\$s
      • -
      • Website: %4\$s
      • -
      • Application Description: %5\$s
      • -
      • Authorization Callback Domain: %6\$s
      • +
      • App Icon: upload this image
      • +
      • Application Name: %4\$s
      • +
      • Category: OK to leave at default 'other'
      • +
      • Club: OK to leave blank
      • +
      • Website: %5\$s
      • +
      • Application Description: %6\$s
      • +
      • Authorization Callback Domain: %7\$s
    2. Once you've created your API Application at strava.com, enter the Client ID and Client Secret below, which can now be found on that same strava API Settings page.
    3. 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.
    4. If you need to re-authorize your API Application, erase your Strava Token here and click 'Save Changes' to start over.
    5. -
    ", 'wp-strava' ), $settings_url, $settings_url, $app_name, $site_url, $description, $site_url ); +
", '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() { diff --git a/readme.txt b/readme.txt index 1e330ed..724c062 100755 --- a/readme.txt +++ b/readme.txt @@ -10,52 +10,55 @@ 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 +Added multi-athlete configuration. +Additional transitions from Ride -> Activity. +Updated setup instructions to reflect latest Strava API set up process. = 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. From 7f65a6c145e981dbab19c58bd7d4efe5ff7deb73 Mon Sep 17 00:00:00 2001 From: Justin Foell Date: Fri, 29 Sep 2017 11:37:43 -0500 Subject: [PATCH 7/9] Ignore .gitignore on export --- .gitattributes | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..0508865 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +.gitattributes export-ignore +.gitignore export-ignore From 4668b4fc4e8287520e121916d7ed87dac628195a Mon Sep 17 00:00:00 2001 From: Justin Foell Date: Fri, 8 Dec 2017 12:33:29 -0600 Subject: [PATCH 8/9] Added check for distance_min and make sure it's a positive integer - fixes Issue #7 Revise name/token update settings Minor formatting --- lib/API.class.php | 21 ++++++++++++------ lib/LatestMapWidget.class.php | 3 ++- lib/Settings.class.php | 41 ++++++++++++++++++++--------------- readme.txt | 6 +++-- 4 files changed, 43 insertions(+), 28 deletions(-) diff --git a/lib/API.class.php b/lib/API.class.php index 79c9e77..66e8e73 100755 --- a/lib/API.class.php +++ b/lib/API.class.php @@ -40,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 define( \'WP_STRAVA_DEBUG\' true ); to wp-config.php', 'wp-strava' ), $response['response']['code'], $response['response']['message'] ), + $error + ); } return json_decode( $response['body'] ); @@ -53,8 +56,9 @@ class WPStrava_API { $url .= $uri; - if ( ! empty( $args ) ) + if ( ! empty( $args ) ) { $url = add_query_arg( $args, $url ); + } $get_args = array( 'headers' => array(), @@ -79,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 define( \'WP_STRAVA_DEBUG\' true ); to wp-config.php', 'wp-strava' ), $response['response']['code'], $response['response']['message'] ), + $error + ); } return json_decode( $response['body'] ); diff --git a/lib/LatestMapWidget.class.php b/lib/LatestMapWidget.class.php index bb4234f..89d925a 100644 --- a/lib/LatestMapWidget.class.php +++ b/lib/LatestMapWidget.class.php @@ -64,7 +64,7 @@ class WPStrava_LatestMapWidget extends WP_Widget { $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 = $instance['distance_min']; + $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; @@ -80,6 +80,7 @@ class WPStrava_LatestMapWidget extends WP_Widget { if ( is_wp_error( $rides ) ) { echo $before_widget; + if ( $title ) echo $before_title . $title . $after_title; if ( WPSTRAVA_DEBUG ) { echo '
';
 					print_r($rides);
diff --git a/lib/Settings.class.php b/lib/Settings.class.php
index 71e9a2e..368f94e 100644
--- a/lib/Settings.class.php
+++ b/lib/Settings.class.php
@@ -1,7 +1,7 @@
 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() {
@@ -143,7 +145,7 @@ class WPStrava_Settings {
 		$app_name = sprintf( esc_html( '%s Strava', 'wp-strava' ), $blog_name );
 		$site_url = site_url();
 		$description = 'WP-Strava for ' . $blog_name;
-	   	printf( __( "

Steps:

+ printf( __( "

Steps:

  1. Create your free API Application/Connection here: %2\$s using the following information:
    • @@ -171,7 +173,7 @@ class WPStrava_Settings { public function print_gmaps_instructions() { $maps_url = 'https://developers.google.com/maps/documentation/static-maps/'; - printf( __( "

      Steps:

      + printf( __( "

      Steps:

      1. To use Google map images, you must create a Static Maps API Key. Create a free key by going here: %2\$s and clicking Get a Key
      2. Once you've created your Google Static Maps API Key, enter the key below. @@ -184,7 +186,7 @@ class WPStrava_Settings {

        - +
        option_page ); ?> @@ -245,18 +247,21 @@ class WPStrava_Settings { } public function sanitize_nickname( $nicknames ) { - $second2last = $last = false; if ( ! $this->adding_athlete ) { - $last = end( $nicknames ); - $second2last = prev( $nicknames ); + // Chop $nicknames to same size as tokens. + $nicknames = array_slice( $nicknames, 0, count( $_POST['strava_token'] ) ); - $token_index = count( $nicknames ) - 1; - if ( $last === '' && $second2last !== '' && - empty( $_POST['strava_token'][ $token_index ] ) ) { - // Remove last (blank) entry if not trying to add an additional athlete. - array_pop( $nicknames ); + // 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 ) { @@ -409,7 +414,7 @@ class WPStrava_Settings { * @author Justin Foell * @since 1.2.0 * - * @param integer $number + * @param integer $number Athlete number (default 1). * @return string */ private function get_default_nickname( $number = 1 ) { diff --git a/readme.txt b/readme.txt index 724c062..9b553a5 100755 --- a/readme.txt +++ b/readme.txt @@ -2,8 +2,8 @@ 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. @@ -37,6 +37,8 @@ Strava Latest Map - shows map of latest activity with option to limit latest map 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. From 06078382ef92aa6dadc4a932dc6faf6efceb7296 Mon Sep 17 00:00:00 2001 From: Justin Foell Date: Fri, 8 Dec 2017 12:48:35 -0600 Subject: [PATCH 9/9] Updated to 1.2.0 --- wp-strava.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wp-strava.php b/wp-strava.php index 6341ef6..f78bfa5 100755 --- a/wp-strava.php +++ b/wp-strava.php @@ -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.2.0-beta1 + * Version: 1.2.0 * Author: Carlos Santa Cruz, Justin Foell, Lance Willet * License: GPL2 * Text Domain: wp-strava