From 3ce9d26e88a8bc80417bf912e2c448f603d6a42c Mon Sep 17 00:00:00 2001
From: Justin Foell
Date: Mon, 1 Apr 2019 14:50:36 -0500
Subject: [PATCH 01/12] Auth WIP
---
lib/WPStrava.php | 10 ++-
lib/WPStrava/Auth.php | 119 +++++++++++++++++++++++++
lib/WPStrava/AuthForever.php | 25 ++++++
lib/WPStrava/AuthRefresh.php | 47 ++++++++++
lib/WPStrava/Settings.php | 168 ++++++++++++++++-------------------
readme.txt | 4 +
6 files changed, 280 insertions(+), 93 deletions(-)
create mode 100644 lib/WPStrava/Auth.php
create mode 100644 lib/WPStrava/AuthForever.php
create mode 100644 lib/WPStrava/AuthRefresh.php
mode change 100644 => 100755 readme.txt
diff --git a/lib/WPStrava.php b/lib/WPStrava.php
index c68a999..1ee5400 100644
--- a/lib/WPStrava.php
+++ b/lib/WPStrava.php
@@ -16,6 +16,12 @@ class WPStrava {
*/
private $settings = null;
+ /**
+ * Authorization object.
+ * @var WPStrava_Auth
+ */
+ private $auth = null;
+
/**
* Array of WPStrava_API objects (one for each athlete).
*
@@ -40,9 +46,11 @@ class WPStrava {
*/
private function __construct() {
$this->settings = new WPStrava_Settings();
+ $this->auth = WPStrava_Auth::get_auth( 'forever' );
if ( is_admin() ) {
$this->settings->hook();
+ $this->auth->hook();
} else {
add_action( 'init', array( $this, 'register_shortcodes' ) );
add_action( 'wp_enqueue_scripts', array( $this, 'register_scripts' ) );
@@ -90,7 +98,7 @@ class WPStrava {
}
/**
- * Get an API object for the given athelete token.
+ * Get an API object for the given athlete token.
*
* @param string $token Athlete token.
* @return WPStrava_API
diff --git a/lib/WPStrava/Auth.php b/lib/WPStrava/Auth.php
new file mode 100644
index 0000000..208e1e1
--- /dev/null
+++ b/lib/WPStrava/Auth.php
@@ -0,0 +1,119 @@
+
+ */
+ public static function get_auth( $auth = 'refresh' ) {
+ if ( 'forever' === $auth ) {
+ return new WPStrava_AuthForever();
+ }
+ // Default to refresh.
+ return new WPStrava_AuthRefresh();
+ }
+
+ abstract protected function get_authorize_url( $client_id );
+
+ public function hook() {
+ add_filter( 'pre_set_transient_settings_errors', array( $this, 'maybe_oauth' ) );
+ add_action( 'admin_init', array( $this, 'init' ) );
+ }
+
+ /**
+ * This runs after options are saved
+ */
+ public function maybe_oauth( $value ) {
+ $settings = WPStrava::get_instance()->settings;
+
+ // User is clearing to start-over, don't oauth, ignore other errors.
+ if ( isset( $_POST['strava_token'] ) && $settings->tokens_empty( $_POST['strava_token'] ) ) {
+ return array();
+ }
+
+ // Redirect only if all the right options are in place.
+ if ( $settings->is_settings_updated( $value ) && $settings->is_option_page() ) {
+ // Only re-auth if client ID and secret were saved.
+ if ( ! empty( $_POST['strava_client_id'] ) && ! empty( $_POST['strava_client_secret'] ) ) {
+ wp_redirect( $this->get_authorize_url( $_POST['strava_client_id'] ) );
+ exit();
+ }
+ }
+ return $value;
+ }
+
+ public function init() {
+ $settings = WPStrava::get_instance()->settings;
+
+ //only update when redirected back from strava
+ if ( ! isset( $_GET['settings-updated'] ) && $settings->is_settings_page() ) {
+ if ( isset( $_GET['code'] ) ) {
+ $info = $this->token_exchange_initial( $_GET['code'] );
+ if ( isset( $info->access_token ) ) {
+ // Translators: New strava token
+ add_settings_error( 'strava_token', 'strava_token', sprintf( __( 'New Strava token retrieved. %s', 'wp-strava' ), $this->feedback ), 'updated' );
+ $settings->add_token( $info->access_token );
+ $settings->update_token();
+ } else {
+ // throw new WPStrava_Exception( '' );
+ add_settings_error( 'strava_token', 'strava_token', $this->feedback );
+ }
+ } elseif ( isset( $_GET['error'] ) ) {
+ // Translators: authentication error mess
+ add_settings_error( 'strava_token', 'strava_token', sprintf( __( 'Error authenticating at Strava: %s', 'wp-strava' ), str_replace( '_', ' ', $_GET['error'] ) ) );
+ }
+ }
+ }
+
+ protected function get_redirect_param() {
+ $page_name = WPStrava::get_instance()->settings->get_page_name();
+ return rawurlencode( admin_url( "options-general.php?page={$page_name}" ) );
+ }
+
+ // was fetch_token();
+ private function token_exchange_initial( $code ) {
+ $settings = WPStrava::get_instance()->settings;
+ $client_id = $settings->client_id;
+ $client_secret = $settings->client_secret;
+
+ $settings->delete_id_secret();
+
+ if ( $client_id && $client_secret ) {
+
+ $data = array(
+ 'client_id' => $client_id,
+ 'client_secret' => $client_secret,
+ 'code' => $code,
+ );
+
+ $strava_info = $this->token_request( $data );
+
+ if ( isset( $strava_info->access_token ) ) {
+ $this->feedback .= __( 'Successfully authenticated.', 'wp-strava' );
+ return $strava_info;
+ }
+
+ // Translators: error message from Strava
+ $this->feedback .= sprintf( __( 'There was an error receiving data from Strava: %s ', 'wp-strava' ), print_r( $strava_info, true ) ); // phpcs:ignore -- Debug output.
+ return false;
+
+ }
+
+ $this->feedback .= __( 'Missing Client ID or Client Secret.', 'wp-strava' );
+ return false;
+ }
+
+ protected function token_request( $data ) {
+ $api = new WPStrava_API();
+ return $api->post( 'oauth/token', $data );
+ }
+
+}
diff --git a/lib/WPStrava/AuthForever.php b/lib/WPStrava/AuthForever.php
new file mode 100644
index 0000000..f0a2cad
--- /dev/null
+++ b/lib/WPStrava/AuthForever.php
@@ -0,0 +1,25 @@
+ $client_id,
+ 'redirect_uri' => $this->get_redirect_param(),
+ 'approval_prompt' => 'force',
+ ),
+ $this->auth_url
+ );
+ }
+}
diff --git a/lib/WPStrava/AuthRefresh.php b/lib/WPStrava/AuthRefresh.php
new file mode 100644
index 0000000..a2397d8
--- /dev/null
+++ b/lib/WPStrava/AuthRefresh.php
@@ -0,0 +1,47 @@
+ $client_id,
+ 'redirect_uri' => $this->get_redirect_param(),
+ 'approval_prompt' => 'auto',
+ 'scope' => 'read,activity:read',
+ ),
+ $this->auth_url
+ );
+ }
+
+ protected function token_exchange_refresh() {
+ $data = array(
+ 'client_id' => $client_id,
+ 'client_secret' => $client_secret,
+ 'refresh_token' => $refresh_token,
+ 'grant_type' => 'refresh_token',
+ );
+
+ $strava_info = $this->token_request( $data );
+
+ if ( isset( $strava_info->access_token ) ) {
+ $this->feedback .= __( 'Successfully re-authenticated.', 'wp-strava' );
+ return $strava_info;
+ }
+
+ $this->feedback .= sprintf( __( 'There was an error receiving data from Strava: %s ', 'wp-strava' ), print_r( $strava_info, true ) ); // phpcs:ignore -- Debug output.
+ return false;
+ }
+
+}
+
diff --git a/lib/WPStrava/Settings.php b/lib/WPStrava/Settings.php
index 28e0326..9ea8605 100644
--- a/lib/WPStrava/Settings.php
+++ b/lib/WPStrava/Settings.php
@@ -11,7 +11,6 @@
class WPStrava_Settings {
- private $feedback;
private $tokens = array();
private $page_name = 'wp-strava-options';
private $option_page = 'wp-strava-settings-group';
@@ -19,40 +18,11 @@ class WPStrava_Settings {
//register admin menus
public function hook() {
- add_action( 'admin_init', array( $this, 'register_strava_settings' ) );
+ add_action( 'admin_init', array( $this, 'register_strava_settings' ), 20 );
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' ) );
}
- /**
- * This runs after options are saved
- */
- 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'] ) && '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.
-
- // Only re-auth if client ID and secret were saved.
- if ( ! empty( $_POST['strava_client_id'] ) && ! empty( $_POST['strava_client_secret'] ) ) {
- $client_id = $_POST['strava_client_id'];
- $client_secret = $_POST['strava_client_secret'];
-
- $redirect = rawurlencode( 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();
- }
- }
- }
- return $value;
- }
-
public function add_strava_menu() {
add_options_page(
__( 'Strava Settings', 'wp-strava' ),
@@ -63,36 +33,12 @@ 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'] ) ) {
- $token = $this->fetch_token( $_GET['code'] );
- if ( $token ) {
- // Translators: strava token
- add_settings_error( 'strava_token', 'strava_token', sprintf( __( 'New Strava token retrieved. %s', 'wp-strava' ), $this->feedback ), 'updated' );
- $this->add_token( $token );
- update_option( 'strava_token', $this->tokens );
- } else {
- add_settings_error( 'strava_token', 'strava_token', $this->feedback );
- }
- } elseif ( isset( $_GET['error'] ) ) {
- // Translators: authentication error mess
- add_settings_error( 'strava_token', 'strava_token', sprintf( __( 'Error authenticating at Strava: %s', 'wp-strava' ), str_replace( '_', ' ', $_GET['error'] ) ) );
- }
- }
- }
-
public function register_strava_settings() {
- $this->init();
-
add_settings_section( 'strava_api', __( 'Strava API', 'wp-strava' ), array( $this, 'print_api_instructions' ), 'wp-strava' );
+ $this->adding_athlete = $this->is_adding_athlete();
+ $this->tokens = $this->get_tokens();
+
if ( $this->tokens_empty( $this->tokens ) ) {
register_setting( $this->option_page, 'strava_client_id', array( $this, 'sanitize_client_id' ) );
register_setting( $this->option_page, 'strava_client_secret', array( $this, 'sanitize_client_secret' ) );
@@ -136,7 +82,6 @@ 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' );
@@ -180,7 +125,6 @@ class WPStrava_Settings {
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
Once you've created your Google Static Maps API Key, enter the key below.
", 'wp-strava' ), $maps_url, $maps_url );
-
}
public function print_strava_options() {
@@ -285,38 +229,6 @@ class WPStrava_Settings {
return $token;
}
- 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 ) {
- $api = new WPStrava_API();
- $data = array(
- 'client_id' => $client_id,
- 'client_secret' => $client_secret,
- 'code' => $code,
- );
-
- $strava_info = $api->post( 'oauth/token', $data );
-
- if ( isset( $strava_info->access_token ) ) {
- $this->feedback .= __( 'Successfully authenticated.', 'wp-strava' );
- return $strava_info->access_token;
- }
-
- // Translators: error message from Strava
- $this->feedback .= sprintf( __( 'There was an error receiving data from Strava: %s ', 'wp-strava' ), print_r( $strava_info, true ) ); // phpcs:ignore -- Debug output.
- return false;
-
- }
-
- $this->feedback .= __( 'Missing Client ID or Client Secret.', 'wp-strava' );
- return false;
- }
-
public function print_gmaps_key_input() {
?>
@@ -494,6 +406,78 @@ class WPStrava_Settings {
}
}
+ /**
+ * Undocumented function
+ *
+ * @param array $token
+ * @author Justin Foell
+ * @since 2.0.0
+ */
+ public function update_token() {
+ update_option( 'strava_token', $this->tokens );
+ }
+
+ /**
+ * Undocumented function
+ *
+ * @return void
+ * @author Justin Foell
+ * @since 2.0.0
+ */
+ public function delete_id_secret() {
+ delete_option( 'strava_client_id' );
+ delete_option( 'strava_client_secret' );
+ }
+
+ /**
+ * Undocumented function
+ *
+ * @param [type] $value
+ * @return boolean
+ * @author Justin Foell
+ * @since 2.0.0
+ */
+ public function is_settings_updated( $value ) {
+ return isset( $value[0]['type'] ) && 'updated' === $value[0]['type'];
+ }
+
+ /**
+ * Undocumented function
+ *
+ * @return boolean
+ * @author Justin Foell
+ * @since 2.0.0
+ */
+ public function is_option_page() {
+ return isset( $_POST['option_page'] ) && $_POST['option_page'] === $this->option_page;
+ }
+
+ /**
+ * Undocumented function
+ *
+ * @return boolean
+ * @author Justin Foell
+ * @since 2.0.0
+ */
+ public function is_settings_page() {
+ return isset( $_GET['page'] ) && $_GET['page'] === $this->page_name;
+ }
+
+ public function get_page_name() {
+ return $this->page_name;
+ }
+
+ /**
+ * Undocumented function
+ *
+ * @return boolean
+ * @author Justin Foell
+ * @since 2.0.0
+ */
+ private function is_adding_athlete() {
+ return ! ( empty( $_POST['strava_client_id'] ) && empty( $_POST['strava_client_secret'] ) );
+ }
+
public function __get( $name ) {
if ( ! strpos( 'strava_', $name ) ) {
$name = "strava_{$name}";
diff --git a/readme.txt b/readme.txt
old mode 100644
new mode 100755
index 41fd568..a20f7bd
--- a/readme.txt
+++ b/readme.txt
@@ -79,6 +79,10 @@ WP-Strava caches activity for one hour so your site doesn't hit the Strava API o
== Changelog ==
+= 2.0.0 =
+Added new Strava "refresh tokens" ala https://developers.strava.com/docs/oauth-updates/#migration-instructions
+
+
= 1.7.1 =
Added PHPUnit tests for all System of Measure calculations.
From 2265e73f834e3c485fbe655375aff2b914fee630 Mon Sep 17 00:00:00 2001
From: Justin Foell
Date: Mon, 1 Apr 2019 15:17:27 -0500
Subject: [PATCH 02/12] Renamed lib to includes
---
{lib => includes}/Polyline.php | 0
{lib => includes}/WPStrava.php | 0
{lib => includes}/WPStrava/API.php | 0
{lib => includes}/WPStrava/Activity.php | 0
{lib => includes}/WPStrava/ActivityShortcode.php | 0
{lib => includes}/WPStrava/ActivityType.php | 0
{lib => includes}/WPStrava/Auth.php | 0
{lib => includes}/WPStrava/AuthForever.php | 0
{lib => includes}/WPStrava/AuthRefresh.php | 0
{lib => includes}/WPStrava/Exception.php | 0
{lib => includes}/WPStrava/LatestActivities.php | 0
{lib => includes}/WPStrava/LatestActivitiesShortcode.php | 0
{lib => includes}/WPStrava/LatestActivitiesWidget.php | 0
{lib => includes}/WPStrava/LatestMapWidget.php | 0
{lib => includes}/WPStrava/RouteShortcode.php | 0
{lib => includes}/WPStrava/Routes.php | 0
{lib => includes}/WPStrava/SOM.php | 0
{lib => includes}/WPStrava/SOMEnglish.php | 0
{lib => includes}/WPStrava/SOMMetric.php | 0
{lib => includes}/WPStrava/Settings.php | 0
{lib => includes}/WPStrava/StaticMap.php | 2 +-
{lib => includes}/autoload.php | 2 +-
phpcs.xml | 2 +-
phpunit.xml | 2 +-
tests/bootstrap.php | 2 +-
wp-strava.php | 2 +-
26 files changed, 6 insertions(+), 6 deletions(-)
rename {lib => includes}/Polyline.php (100%)
rename {lib => includes}/WPStrava.php (100%)
rename {lib => includes}/WPStrava/API.php (100%)
rename {lib => includes}/WPStrava/Activity.php (100%)
rename {lib => includes}/WPStrava/ActivityShortcode.php (100%)
rename {lib => includes}/WPStrava/ActivityType.php (100%)
rename {lib => includes}/WPStrava/Auth.php (100%)
rename {lib => includes}/WPStrava/AuthForever.php (100%)
rename {lib => includes}/WPStrava/AuthRefresh.php (100%)
rename {lib => includes}/WPStrava/Exception.php (100%)
rename {lib => includes}/WPStrava/LatestActivities.php (100%)
rename {lib => includes}/WPStrava/LatestActivitiesShortcode.php (100%)
rename {lib => includes}/WPStrava/LatestActivitiesWidget.php (100%)
rename {lib => includes}/WPStrava/LatestMapWidget.php (100%)
rename {lib => includes}/WPStrava/RouteShortcode.php (100%)
rename {lib => includes}/WPStrava/Routes.php (100%)
rename {lib => includes}/WPStrava/SOM.php (100%)
rename {lib => includes}/WPStrava/SOMEnglish.php (100%)
rename {lib => includes}/WPStrava/SOMMetric.php (100%)
rename {lib => includes}/WPStrava/Settings.php (100%)
rename {lib => includes}/WPStrava/StaticMap.php (97%)
rename {lib => includes}/autoload.php (87%)
diff --git a/lib/Polyline.php b/includes/Polyline.php
similarity index 100%
rename from lib/Polyline.php
rename to includes/Polyline.php
diff --git a/lib/WPStrava.php b/includes/WPStrava.php
similarity index 100%
rename from lib/WPStrava.php
rename to includes/WPStrava.php
diff --git a/lib/WPStrava/API.php b/includes/WPStrava/API.php
similarity index 100%
rename from lib/WPStrava/API.php
rename to includes/WPStrava/API.php
diff --git a/lib/WPStrava/Activity.php b/includes/WPStrava/Activity.php
similarity index 100%
rename from lib/WPStrava/Activity.php
rename to includes/WPStrava/Activity.php
diff --git a/lib/WPStrava/ActivityShortcode.php b/includes/WPStrava/ActivityShortcode.php
similarity index 100%
rename from lib/WPStrava/ActivityShortcode.php
rename to includes/WPStrava/ActivityShortcode.php
diff --git a/lib/WPStrava/ActivityType.php b/includes/WPStrava/ActivityType.php
similarity index 100%
rename from lib/WPStrava/ActivityType.php
rename to includes/WPStrava/ActivityType.php
diff --git a/lib/WPStrava/Auth.php b/includes/WPStrava/Auth.php
similarity index 100%
rename from lib/WPStrava/Auth.php
rename to includes/WPStrava/Auth.php
diff --git a/lib/WPStrava/AuthForever.php b/includes/WPStrava/AuthForever.php
similarity index 100%
rename from lib/WPStrava/AuthForever.php
rename to includes/WPStrava/AuthForever.php
diff --git a/lib/WPStrava/AuthRefresh.php b/includes/WPStrava/AuthRefresh.php
similarity index 100%
rename from lib/WPStrava/AuthRefresh.php
rename to includes/WPStrava/AuthRefresh.php
diff --git a/lib/WPStrava/Exception.php b/includes/WPStrava/Exception.php
similarity index 100%
rename from lib/WPStrava/Exception.php
rename to includes/WPStrava/Exception.php
diff --git a/lib/WPStrava/LatestActivities.php b/includes/WPStrava/LatestActivities.php
similarity index 100%
rename from lib/WPStrava/LatestActivities.php
rename to includes/WPStrava/LatestActivities.php
diff --git a/lib/WPStrava/LatestActivitiesShortcode.php b/includes/WPStrava/LatestActivitiesShortcode.php
similarity index 100%
rename from lib/WPStrava/LatestActivitiesShortcode.php
rename to includes/WPStrava/LatestActivitiesShortcode.php
diff --git a/lib/WPStrava/LatestActivitiesWidget.php b/includes/WPStrava/LatestActivitiesWidget.php
similarity index 100%
rename from lib/WPStrava/LatestActivitiesWidget.php
rename to includes/WPStrava/LatestActivitiesWidget.php
diff --git a/lib/WPStrava/LatestMapWidget.php b/includes/WPStrava/LatestMapWidget.php
similarity index 100%
rename from lib/WPStrava/LatestMapWidget.php
rename to includes/WPStrava/LatestMapWidget.php
diff --git a/lib/WPStrava/RouteShortcode.php b/includes/WPStrava/RouteShortcode.php
similarity index 100%
rename from lib/WPStrava/RouteShortcode.php
rename to includes/WPStrava/RouteShortcode.php
diff --git a/lib/WPStrava/Routes.php b/includes/WPStrava/Routes.php
similarity index 100%
rename from lib/WPStrava/Routes.php
rename to includes/WPStrava/Routes.php
diff --git a/lib/WPStrava/SOM.php b/includes/WPStrava/SOM.php
similarity index 100%
rename from lib/WPStrava/SOM.php
rename to includes/WPStrava/SOM.php
diff --git a/lib/WPStrava/SOMEnglish.php b/includes/WPStrava/SOMEnglish.php
similarity index 100%
rename from lib/WPStrava/SOMEnglish.php
rename to includes/WPStrava/SOMEnglish.php
diff --git a/lib/WPStrava/SOMMetric.php b/includes/WPStrava/SOMMetric.php
similarity index 100%
rename from lib/WPStrava/SOMMetric.php
rename to includes/WPStrava/SOMMetric.php
diff --git a/lib/WPStrava/Settings.php b/includes/WPStrava/Settings.php
similarity index 100%
rename from lib/WPStrava/Settings.php
rename to includes/WPStrava/Settings.php
diff --git a/lib/WPStrava/StaticMap.php b/includes/WPStrava/StaticMap.php
similarity index 97%
rename from lib/WPStrava/StaticMap.php
rename to includes/WPStrava/StaticMap.php
index 14b4894..341bd6a 100644
--- a/lib/WPStrava/StaticMap.php
+++ b/includes/WPStrava/StaticMap.php
@@ -66,7 +66,7 @@ class WPStrava_StaticMap {
* }
*/
private static function decode_start_finish( $enc ) {
- require_once WPSTRAVA_PLUGIN_DIR . 'lib/Polyline.php';
+ require_once WPSTRAVA_PLUGIN_DIR . 'includes/Polyline.php';
$points = Polyline::decode( $enc );
$points = Polyline::pair( $points );
$start = $points[0];
diff --git a/lib/autoload.php b/includes/autoload.php
similarity index 87%
rename from lib/autoload.php
rename to includes/autoload.php
index c1a9a6c..863d5df 100644
--- a/lib/autoload.php
+++ b/includes/autoload.php
@@ -16,7 +16,7 @@ function wpstrava_autoload_classes( $class_name ) {
}
// @TODO Add directory searching if they get created.
- $file = WPSTRAVA_PLUGIN_DIR . '/lib/' . implode( '/', $parts ) . '.php';
+ $file = WPSTRAVA_PLUGIN_DIR . '/includes/' . implode( '/', $parts ) . '.php';
if ( file_exists( $file ) ) {
include_once $file;
}
diff --git a/phpcs.xml b/phpcs.xml
index 3fe964c..78c2892 100644
--- a/phpcs.xml
+++ b/phpcs.xml
@@ -8,7 +8,7 @@
- ./lib
+ ./includes
./wp-strava.php
*/vendor/*
diff --git a/phpunit.xml b/phpunit.xml
index 45eedc3..5cb52bb 100644
--- a/phpunit.xml
+++ b/phpunit.xml
@@ -16,7 +16,7 @@
- lib
+ includes
diff --git a/tests/bootstrap.php b/tests/bootstrap.php
index 1d5410e..24408ee 100644
--- a/tests/bootstrap.php
+++ b/tests/bootstrap.php
@@ -4,7 +4,7 @@ if ( ! defined( 'WPSTRAVA_PLUGIN_DIR' ) ) {
define( 'WPSTRAVA_PLUGIN_DIR', dirname( __FILE__ ) . '/../' );
}
-require_once dirname( __FILE__ ) . '/../lib/autoload.php';
+require_once dirname( __FILE__ ) . '/../includes/autoload.php';
require_once dirname( __FILE__ ) . '/../vendor/autoload.php';
WP_Mock::bootstrap();
diff --git a/wp-strava.php b/wp-strava.php
index 1c08fa9..caa1020 100755
--- a/wp-strava.php
+++ b/wp-strava.php
@@ -35,7 +35,7 @@ if ( ! defined( 'WPSTRAVA_DEBUG' ) ) {
define( 'WPSTRAVA_DEBUG', false );
}
-require_once WPSTRAVA_PLUGIN_DIR . 'lib/autoload.php';
+require_once WPSTRAVA_PLUGIN_DIR . 'includes/autoload.php';
// Load the plugin and multilingual support.
function wpstrava_load_plugin_textdomain() {
From 15de60d76460579b5762dd7e47fa2051ed8136ce Mon Sep 17 00:00:00 2001
From: Justin Foell
Date: Mon, 1 Apr 2019 16:21:13 -0500
Subject: [PATCH 03/12] Moved from token being the identifier to Client ID
---
includes/WPStrava/Auth.php | 7 +-
includes/WPStrava/Settings.php | 148 ++++++++++++++++-----------------
includes/template-tags.php | 2 +
templates/admin-settings.php | 13 +++
4 files changed, 93 insertions(+), 77 deletions(-)
create mode 100644 includes/template-tags.php
create mode 100644 templates/admin-settings.php
diff --git a/includes/WPStrava/Auth.php b/includes/WPStrava/Auth.php
index 208e1e1..0cd3e49 100644
--- a/includes/WPStrava/Auth.php
+++ b/includes/WPStrava/Auth.php
@@ -35,7 +35,7 @@ abstract class WPStrava_Auth {
$settings = WPStrava::get_instance()->settings;
// User is clearing to start-over, don't oauth, ignore other errors.
- if ( isset( $_POST['strava_token'] ) && $settings->tokens_empty( $_POST['strava_token'] ) ) {
+ if ( isset( $_POST['strava_id'] ) && $settings->ids_empty( $_POST['strava_id'] ) ) {
return array();
}
@@ -60,8 +60,6 @@ abstract class WPStrava_Auth {
if ( isset( $info->access_token ) ) {
// Translators: New strava token
add_settings_error( 'strava_token', 'strava_token', sprintf( __( 'New Strava token retrieved. %s', 'wp-strava' ), $this->feedback ), 'updated' );
- $settings->add_token( $info->access_token );
- $settings->update_token();
} else {
// throw new WPStrava_Exception( '' );
add_settings_error( 'strava_token', 'strava_token', $this->feedback );
@@ -97,6 +95,9 @@ abstract class WPStrava_Auth {
$strava_info = $this->token_request( $data );
if ( isset( $strava_info->access_token ) ) {
+ $settings->add_id( $client_id );
+ $settings->save_info( $client_id, $strava_info );
+
$this->feedback .= __( 'Successfully authenticated.', 'wp-strava' );
return $strava_info;
}
diff --git a/includes/WPStrava/Settings.php b/includes/WPStrava/Settings.php
index 9ea8605..56a46fa 100644
--- a/includes/WPStrava/Settings.php
+++ b/includes/WPStrava/Settings.php
@@ -11,7 +11,7 @@
class WPStrava_Settings {
- private $tokens = array();
+ private $ids = array();
private $page_name = 'wp-strava-options';
private $option_page = 'wp-strava-settings-group';
private $adding_athlete = true;
@@ -37,9 +37,9 @@ class WPStrava_Settings {
add_settings_section( 'strava_api', __( 'Strava API', 'wp-strava' ), array( $this, 'print_api_instructions' ), 'wp-strava' );
$this->adding_athlete = $this->is_adding_athlete();
- $this->tokens = $this->get_tokens();
+ $this->ids = $this->get_ids();
- if ( $this->tokens_empty( $this->tokens ) ) {
+ if ( $this->ids_empty( $this->ids ) ) {
register_setting( $this->option_page, 'strava_client_id', array( $this, 'sanitize_client_id' ) );
register_setting( $this->option_page, 'strava_client_secret', array( $this, 'sanitize_client_secret' ) );
register_setting( $this->option_page, 'strava_nickname', array( $this, 'sanitize_nickname' ) );
@@ -48,8 +48,8 @@ class WPStrava_Settings {
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' );
+ register_setting( $this->option_page, 'strava_id', array( $this, 'sanitize_id' ) );
+ add_settings_field( 'strava_id', __( 'Saved ID', 'wp-strava' ), array( $this, 'print_id_input' ), 'wp-strava', 'strava_api' );
// Add additional fields
register_setting( $this->option_page, 'strava_client_id', array( $this, 'sanitize_client_id' ) );
@@ -105,8 +105,8 @@ class WPStrava_Settings {
Authorization Callback Domain: %7\$s
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.
- 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.
- If you need to re-authorize your API Application, erase your Strava Token here and click 'Save Changes' to start over.
+ After saving your Client ID and Secret, you'll be redirected to strava to authorize your API Application. If successful, your Strava ID will display in a table, next to your nickname.
+ If you need to re-authorize your API Application, erase your Strava ID next to your nickname and click 'Save Changes' to start over.
", 'wp-strava' ),
$settings_url,
$settings_url,
@@ -128,21 +128,7 @@ class WPStrava_Settings {
}
public function print_strava_options() {
- ?>
-
- tokens_empty( $this->tokens ) ? __( 'Default', 'wp-strava' ) : '';
+ $nickname = $this->ids_empty( $this->ids ) ? __( 'Default', 'wp-strava' ) : '';
?>
get_all_tokens() as $token => $nickname ) {
+ public function print_id_input() {
+ foreach ( $this->get_all_ids() as $id => $nickname ) {
?>
-
-
+
+
adding_athlete ) {
- // Chop $nicknames to same size as tokens.
- $nicknames = array_slice( $nicknames, 0, count( $_POST['strava_token'] ) );
+ // Chop $nicknames to same size as ids.
+ $nicknames = array_slice( $nicknames, 0, count( $_POST['strava_id'] ) );
- // Remove indexes from $nicknames that have empty tokens.
- foreach ( $_POST['strava_token'] as $index => $token ) {
- $token = trim( $token );
- if ( empty( $token ) ) {
+ // Remove indexes from $nicknames that have empty ids.
+ foreach ( $_POST['strava_id'] as $index => $id ) {
+ $id = trim( $id );
+ if ( empty( $id ) ) {
unset( $nicknames[ $index ] );
}
}
@@ -225,8 +211,8 @@ class WPStrava_Settings {
return $nicknames;
}
- public function sanitize_token( $token ) {
- return $token;
+ public function sanitize_id( $id ) {
+ return $id;
}
public function print_gmaps_key_input() {
@@ -292,61 +278,63 @@ class WPStrava_Settings {
$wpdb->query( "DELETE FROM {$wpdb->options} WHERE `option_name` LIKE '_transient_timeout_strava_latest_map_%'" );
$wpdb->query( "DELETE FROM {$wpdb->options} WHERE `option_name` LIKE '_transient_strava_latest_map_%'" );
$wpdb->query( "DELETE FROM {$wpdb->options} WHERE `option_name` LIKE 'strava_latest_map%'" );
+
+ delete_option( 'strava_token' );
}
return null;
}
/**
- * Gets all saved strava tokens as an array.
+ * Gets all saved strava ids as an array.
*
* @return array
* @author Justin Foell
- * @since 1.2.0
+ * @since 2.0.0
*/
- public function get_tokens() {
- $tokens = get_option( 'strava_token' );
- if ( ! is_array( $tokens ) ) {
- $tokens = array( $tokens );
+ public function get_ids() {
+ $ids = get_option( 'strava_id' );
+ if ( ! is_array( $ids ) ) {
+ $ids = array( $ids );
}
- 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
+ foreach ( $ids as $index => $id ) {
+ if ( empty( $id ) ) {
+ unset( $ids[ $index ] );
+ $ids = array_values( $ids ); // Rebase array keys after unset @see https://stackoverflow.com/a/5943165/2146022
}
}
- return $tokens;
+ return $ids;
}
/**
- * Returns first (default) token saved.
+ * Returns first (default) ID 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;
+ public function get_default_id() {
+ $ids = $this->get_ids();
+ return isset( $ids[0] ) ? $ids[0] : null;
}
/**
- * Get all tokens and their nicknames in one array.
+ * Get all IDs and their nicknames in one array.
*
* @return void
* @author Justin Foell
- * @since 1.2.0
+ * @since 2.0.0
*/
- public function get_all_tokens() {
- $tokens = $this->get_tokens();
+ public function get_all_ids() {
+ $ids = $this->get_ids();
$nicknames = $this->nickname;
$all = array();
$number = 1;
- foreach ( $tokens as $index => $token ) {
+ foreach ( $ids as $index => $id ) {
if ( ! empty( $nicknames[ $index ] ) ) {
- $all[ $token ] = $nicknames[ $index ];
+ $all[ $id ] = $nicknames[ $index ];
} else {
- $all[ $token ] = $this->get_default_nickname( $number );
+ $all[ $id ] = $this->get_default_nickname( $number );
}
$number++;
}
@@ -368,22 +356,22 @@ class WPStrava_Settings {
}
/**
- * Checks for valid tokens.
+ * Checks for valid IDs.
*
* @author Justin Foell
* @since 1.2.0
*
- * @param string|array Single token or array of tokens.
+ * @param string|array Single ID or array of IDs.
* @return boolean True if empty.
*/
- public function tokens_empty( $tokens ) {
- if ( empty( $tokens ) ) {
+ public function ids_empty( $ids ) {
+ if ( empty( $ids ) ) {
return true;
}
- if ( is_array( $tokens ) ) {
- foreach ( $tokens as $token ) {
- if ( ! empty( $token ) ) {
+ if ( is_array( $ids ) ) {
+ foreach ( $ids as $id ) {
+ if ( ! empty( $id ) ) {
return false;
}
}
@@ -393,28 +381,33 @@ class WPStrava_Settings {
}
/**
- * Only add a token if it's not already there.
+ * Add an ID if it's not already there, and save to the DB.
*
- * @param string $token
+ * @param string $id
*
* @author Justin Foell
- * @since 1.2.0
+ * @since 2.0.0
*/
- public function add_token( $token ) {
- if ( false === array_search( $token, $this->tokens, true ) ) {
- $this->tokens[] = $token;
+ public function add_id( $id ) {
+ if ( false === array_search( $id, $this->ids, true ) ) {
+ $this->ids[] = $id;
+ update_option( 'strava_id', $this->ids );
}
}
/**
* Undocumented function
*
- * @param array $token
- * @author Justin Foell
+ * @param [type] $id
+ * @param [type] $info
+ * @return void
+ * @author Justin Foell
* @since 2.0.0
*/
- public function update_token() {
- update_option( 'strava_token', $this->tokens );
+ public function save_info( $id, $info ) {
+ $infos = get_option( 'strava_info', array() );
+ $infos[ $id ] = $info;
+ update_option( 'strava_info', $infos );
}
/**
@@ -463,6 +456,13 @@ class WPStrava_Settings {
return isset( $_GET['page'] ) && $_GET['page'] === $this->page_name;
}
+ /**
+ * Undocumented function
+ *
+ * @return string
+ * @author Justin Foell
+ * @since 2.0.0
+ */
public function get_page_name() {
return $this->page_name;
}
diff --git a/includes/template-tags.php b/includes/template-tags.php
new file mode 100644
index 0000000..a4abe2d
--- /dev/null
+++ b/includes/template-tags.php
@@ -0,0 +1,2 @@
+
+
+
+
+
+
From cfdf3aae9e98eed20ee92ee2ba37be9ab630f3ff Mon Sep 17 00:00:00 2001
From: Justin Foell
Date: Mon, 3 Jun 2019 14:27:14 -0500
Subject: [PATCH 04/12] Added refresh cron and refresh method
---
includes/WPStrava.php | 5 +-
includes/WPStrava/Auth.php | 14 +++--
includes/WPStrava/AuthForever.php | 9 ++++
includes/WPStrava/AuthRefresh.php | 90 ++++++++++++++++++++++++++++---
includes/WPStrava/Settings.php | 25 +++++++--
5 files changed, 128 insertions(+), 15 deletions(-)
diff --git a/includes/WPStrava.php b/includes/WPStrava.php
index 1ee5400..e905e0c 100644
--- a/includes/WPStrava.php
+++ b/includes/WPStrava.php
@@ -46,11 +46,12 @@ class WPStrava {
*/
private function __construct() {
$this->settings = new WPStrava_Settings();
- $this->auth = WPStrava_Auth::get_auth( 'forever' );
+ $this->auth = WPStrava_Auth::get_auth( 'refresh' );
+
+ $this->auth->hook();
if ( is_admin() ) {
$this->settings->hook();
- $this->auth->hook();
} else {
add_action( 'init', array( $this, 'register_shortcodes' ) );
add_action( 'wp_enqueue_scripts', array( $this, 'register_scripts' ) );
diff --git a/includes/WPStrava/Auth.php b/includes/WPStrava/Auth.php
index 0cd3e49..88719e7 100644
--- a/includes/WPStrava/Auth.php
+++ b/includes/WPStrava/Auth.php
@@ -24,8 +24,10 @@ abstract class WPStrava_Auth {
abstract protected function get_authorize_url( $client_id );
public function hook() {
- add_filter( 'pre_set_transient_settings_errors', array( $this, 'maybe_oauth' ) );
- add_action( 'admin_init', array( $this, 'init' ) );
+ if ( is_admin() ) {
+ add_filter( 'pre_set_transient_settings_errors', array( $this, 'maybe_oauth' ) );
+ add_action( 'admin_init', array( $this, 'init' ) );
+ }
}
/**
@@ -92,11 +94,13 @@ abstract class WPStrava_Auth {
'code' => $code,
);
+ $data = $this->add_initial_params( $data );
+
$strava_info = $this->token_request( $data );
if ( isset( $strava_info->access_token ) ) {
$settings->add_id( $client_id );
- $settings->save_info( $client_id, $strava_info );
+ $settings->save_info( $client_id, $client_secret, $strava_info );
$this->feedback .= __( 'Successfully authenticated.', 'wp-strava' );
return $strava_info;
@@ -117,4 +121,8 @@ abstract class WPStrava_Auth {
return $api->post( 'oauth/token', $data );
}
+ protected function add_initial_params( $data ) {
+ return $data;
+ }
+
}
diff --git a/includes/WPStrava/AuthForever.php b/includes/WPStrava/AuthForever.php
index f0a2cad..bb11813 100644
--- a/includes/WPStrava/AuthForever.php
+++ b/includes/WPStrava/AuthForever.php
@@ -9,9 +9,18 @@
* AuthForever Class
*
* @since 2.0.0
+ * @see http://developers.strava.com/docs/authentication/
*/
class WPStrava_AuthForever extends WPStrava_Auth {
+ /**
+ * Authorize URL for old style forever tokens.
+ *
+ * @param int $client_id Strava API Client ID.
+ * @return string URL to authorize against.
+ * @author Justin Foell
+ * @since 2.0.0
+ */
protected function get_authorize_url( $client_id ) {
return add_query_arg(
array(
diff --git a/includes/WPStrava/AuthRefresh.php b/includes/WPStrava/AuthRefresh.php
index a2397d8..998879c 100644
--- a/includes/WPStrava/AuthRefresh.php
+++ b/includes/WPStrava/AuthRefresh.php
@@ -4,14 +4,61 @@
* AuthRefresh class
*
* @since 2.0.0
+ * @see http://developers.strava.com/docs/authentication/
*/
class WPStrava_AuthRefresh extends WPStrava_Auth {
+ /**
+ * Hooks.
+ *
+ * @author Justin Foell
+ * @since 2.0.0
+ */
public function hook() {
parent::hook();
- // @TODO Need cronjob.
+
+ // Refresh tokens via cronjob.
+ add_action( 'init', array( $this, 'setup_auth_refresh_cron' ) );
+ add_action( 'wp_strava_auth_refresh_cron', array( $this, 'auth_refresh' ) );
}
+ /**
+ * Set up cron to refresh the auth token hourly (expires after 6-hours).
+ *
+ * @author Justin Foell
+ * @since 2.0.0
+ */
+ public function setup_auth_refresh_cron() {
+
+ // Schedule the cron job to purge all expired transients.
+ if ( ! wp_next_scheduled( 'wp_strava_auth_refresh_cron' ) ) {
+ wp_schedule_event( time(), 'hourly', 'wp_strava_auth_refresh_cron' );
+ }
+ }
+
+ /**
+ * Cron method to refresh auth tokens from Strava.
+ *
+ * @author Justin Foell
+ * @since 2.0.0
+ */
+ public function auth_refresh() {
+ $settings = WPStrava::get_instance()->settings;
+ foreach ( $settings->info as $client_id => $info ) {
+ if ( ! empty( $info->refresh_token ) ) {
+ $this->token_exchange_refresh( $client_id, $info );
+ }
+ }
+ }
+
+ /**
+ * Authorize URL for new style refresh token auth.
+ *
+ * @param int $client_id Strava API Client ID.
+ * @return string URL to authorize against.
+ * @author Justin Foell
+ * @since 2.0.0
+ */
protected function get_authorize_url( $client_id ) {
return add_query_arg(
array(
@@ -24,21 +71,52 @@ class WPStrava_AuthRefresh extends WPStrava_Auth {
);
}
- protected function token_exchange_refresh() {
+ /**
+ * Add 'authorization_code' grand type to first API request (when authenticating a new user).
+ *
+ * @param array $data Request array for the Strava API.
+ * @return array Data array with 'grant_type' => 'authorization_code' added.
+ * @author Justin Foell
+ * @since 2.0.0
+ */
+ protected function add_initial_params( $data ) {
+ $data['grant_type'] = 'authorization_code';
+ return $data;
+ }
+
+ /**
+ * Extend access by contacting strava with a refresh token.
+ *
+ * @param int $client_id
+ * @param stdClass $info
+ * @return boolean True if refreshed successfully, false otherwise.
+ * @author Justin Foell
+ * @since 2.0.0
+ */
+ protected function token_exchange_refresh( $client_id, $info ) {
$data = array(
'client_id' => $client_id,
- 'client_secret' => $client_secret,
- 'refresh_token' => $refresh_token,
+ 'client_secret' => $info->client_secret,
+ 'refresh_token' => $info->refresh_token,
'grant_type' => 'refresh_token',
);
$strava_info = $this->token_request( $data );
if ( isset( $strava_info->access_token ) ) {
- $this->feedback .= __( 'Successfully re-authenticated.', 'wp-strava' );
- return $strava_info;
+ $this->feedback .= __( 'ID %s successfully re-authenticated.', 'wp-strava' );
+
+ if ( $strava_info->access_token != $info->access_token ) {
+ $this->feedback .= __( 'ID %s access extended.', 'wp-strava' );
+
+ $settings = WPStrava::get_instance()->settings;
+ $settings->save_info( $client_id, $info->client_secret, $strava_info );
+ }
+
+ return true;
}
+ // @TODO how to determine if refresh wasn't successful?
$this->feedback .= sprintf( __( 'There was an error receiving data from Strava: %s ', 'wp-strava' ), print_r( $strava_info, true ) ); // phpcs:ignore -- Debug output.
return false;
}
diff --git a/includes/WPStrava/Settings.php b/includes/WPStrava/Settings.php
index 56a46fa..6638284 100644
--- a/includes/WPStrava/Settings.php
+++ b/includes/WPStrava/Settings.php
@@ -398,18 +398,35 @@ class WPStrava_Settings {
/**
* Undocumented function
*
- * @param [type] $id
- * @param [type] $info
- * @return void
+ * @param int $id Strava API Client ID
+ * @param string $secret Strava API Client Secret
+ * @param stdClass $info
* @author Justin Foell
* @since 2.0.0
*/
- public function save_info( $id, $info ) {
+ public function save_info( $id, $secret, $info ) {
$infos = get_option( 'strava_info', array() );
+ $infos = array_filter( $infos, array( $this, 'filter_by_id' ), ARRAY_FILTER_USE_KEY ); // Remove old IDs.
+ $info->client_secret = $secret;
$infos[ $id ] = $info;
update_option( 'strava_info', $infos );
}
+ /**
+ * array_filter() callback to remove info for IDs we no longer have.
+ *
+ * @param int $key Strava Client ID
+ * @return boolean True if Client ID is in $this->ids, false otherwise.
+ * @author Justin Foell
+ * @since 2.0.0
+ */
+ public function filter_by_id( $key ) {
+ if ( in_array( $key, $this->ids ) ) {
+ return true;
+ }
+ return false;
+ }
+
/**
* Undocumented function
*
From 520bd1b64903cc079e1506b3e32a44bf8f5bc784 Mon Sep 17 00:00:00 2001
From: Justin Foell
Date: Mon, 3 Jun 2019 16:07:15 -0500
Subject: [PATCH 05/12] Switch calls to use Client ID instead of Access Token
---
includes/WPStrava.php | 12 ++--
includes/WPStrava/API.php | 67 +++++++++++++++++--
includes/WPStrava/Activity.php | 18 ++---
includes/WPStrava/ActivityShortcode.php | 9 ++-
includes/WPStrava/LatestActivities.php | 9 ++-
.../WPStrava/LatestActivitiesShortcode.php | 2 +-
includes/WPStrava/LatestActivitiesWidget.php | 16 ++---
includes/WPStrava/LatestMapWidget.php | 20 +++---
includes/WPStrava/RouteShortcode.php | 19 ++++--
readme.txt | 10 +--
10 files changed, 125 insertions(+), 57 deletions(-)
diff --git a/includes/WPStrava.php b/includes/WPStrava.php
index e905e0c..c862bee 100644
--- a/includes/WPStrava.php
+++ b/includes/WPStrava.php
@@ -104,16 +104,16 @@ class WPStrava {
* @param string $token Athlete token.
* @return WPStrava_API
*/
- public function get_api( $token = null ) {
- if ( ! $token ) {
- $token = $this->settings->get_default_token();
+ public function get_api( $id = null ) {
+ if ( ! $id ) {
+ $id = $this->settings->get_default_id();
}
- if ( empty( $this->api[ $token ] ) ) {
- $this->api[ $token ] = new WPStrava_API( $token );
+ if ( empty( $this->api[ $id ] ) ) {
+ $this->api[ $id ] = new WPStrava_API( $id );
}
- return $this->api[ $token ];
+ return $this->api[ $id ];
}
/**
diff --git a/includes/WPStrava/API.php b/includes/WPStrava/API.php
index c4fd011..6e8603f 100755
--- a/includes/WPStrava/API.php
+++ b/includes/WPStrava/API.php
@@ -7,10 +7,27 @@ class WPStrava_API {
const STRAVA_V3_API = 'https://www.strava.com/api/v3/';
- public function __construct( $access_token = null ) {
- $this->access_token = $access_token;
+ private $client_id = null;
+
+ /**
+ * Constructor.
+ *
+ * @param int $client_id Strava API Client ID representing an athlete.
+ * @author Justin Foell
+ */
+ public function __construct( $client_id = null ) {
+ $this->client_id = $client_id;
}
+ /**
+ * POST something to the Strava API.
+ *
+ * @param string $uri Path within the Strava API.
+ * @param array $data Data to POST.
+ * @return stdClass Strava API response.
+ * @throws WPStrava_Exception
+ * @author Justin Foell
+ */
public function post( $uri, $data = null ) {
$url = self::STRAVA_V3_API;
@@ -21,8 +38,9 @@ class WPStrava_API {
'timeout' => 30,
);
- if ( $this->access_token ) {
- $args['headers']['Authorization'] = 'Bearer ' . $this->access_token;
+ $access_token = $this->get_access_token();
+ if ( $access_token ) {
+ $args['headers']['Authorization'] = 'Bearer ' . $access_token;
}
$response = wp_remote_post( $url . $uri, $args );
@@ -53,6 +71,15 @@ class WPStrava_API {
return json_decode( $response['body'] );
}
+ /**
+ * GET something from the Strava API.
+ *
+ * @param string $uri Path within the Strava API.
+ * @param array $args Request arguments.
+ * @return stdClass Strava API response.
+ * @throws WPStrava_Exception
+ * @author Justin Foell
+ */
public function get( $uri, $args = null ) {
$url = self::STRAVA_V3_API;
@@ -68,8 +95,9 @@ class WPStrava_API {
'timeout' => 30,
);
- if ( $this->access_token ) {
- $get_args['headers']['Authorization'] = 'Bearer ' . $this->access_token;
+ $access_token = $this->get_access_token();
+ if ( $access_token ) {
+ $get_args['headers']['Authorization'] = 'Bearer ' . $access_token;
}
$response = wp_remote_get( $url, $get_args );
@@ -102,4 +130,29 @@ class WPStrava_API {
return json_decode( $response['body'] );
}
-} // Class API.
+ /**
+ * Get the (ever changing) access token based on current Client ID.
+ *
+ * @return string|null String for access token, null if not found.
+ * @author Justin Foell
+ * @since 2.0.0
+ */
+ private function get_access_token() {
+ static $access_token = null;
+
+ // If client_id not set (OAuth set-up), don't even look.
+ if ( ! $this->client_id ) {
+ return null;
+ }
+
+ if ( ! $access_token ) {
+ $settings = WPStrava::get_instance()->settings;
+ $info = $settings->info;
+
+ if ( ! empty( $info[ $this->client_id ]->access_token ) ) {
+ $access_token = $info[ $this->client_id ]->access_token;
+ }
+ }
+ return $access_token;
+ }
+}
diff --git a/includes/WPStrava/Activity.php b/includes/WPStrava/Activity.php
index 9572dc3..086fea4 100755
--- a/includes/WPStrava/Activity.php
+++ b/includes/WPStrava/Activity.php
@@ -10,26 +10,26 @@ class WPStrava_Activity {
/**
* Get single activity by ID.
*
- * @param string $athlete_token Token of athlete to retrieve for
+ * @param string $client_id Client ID of athlete to retrieve for
* @param int $activity_id ID of activity to retrieve.
- * @return object stdClass representing this activity.
+ * @return object stdClass Representing this activity.
* @author Justin Foell
*/
- public function get_activity( $athlete_token, $activity_id ) {
- return WPStrava::get_instance()->get_api( $athlete_token )->get( "activities/{$activity_id}" );
+ public function get_activity( $client_id, $activity_id ) {
+ return WPStrava::get_instance()->get_api( $client_id )->get( "activities/{$activity_id}" );
}
/**
* Get activity list from Strava API.
*
* @author Justin Foell
- * @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).
+ * @param string $client_id Client ID of athlete to retrieve for
+ * @param int $club_id Club ID of all club riders (optional).
+ * @param int|null $quantity Number of records to retrieve (optional).
* @return array Array of activities.
*/
- public function get_activities( $athlete_token, $club_id = null, $quantity = null ) {
- $api = WPStrava::get_instance()->get_api( $athlete_token );
+ public function get_activities( $client_id, $club_id = null, $quantity = null ) {
+ $api = WPStrava::get_instance()->get_api( $client_id );
$data = null;
diff --git a/includes/WPStrava/ActivityShortcode.php b/includes/WPStrava/ActivityShortcode.php
index 8b5a459..1bbb3bd 100644
--- a/includes/WPStrava/ActivityShortcode.php
+++ b/includes/WPStrava/ActivityShortcode.php
@@ -51,13 +51,18 @@ class WPStrava_ActivityShortcode {
'som' => WPStrava::get_instance()->settings->som,
'map_width' => '480',
'map_height' => '320',
- 'athlete_token' => WPStrava::get_instance()->settings->get_default_token(),
+ 'client_id' => WPStrava::get_instance()->settings->get_default_id(),
'markers' => false,
'image_only' => false,
);
$atts = shortcode_atts( $defaults, $atts, 'activity' );
+ if ( isset( $atts['athlete_token'] ) ) {
+ // Translators: Message shown when using deprecated athlete_token parameter.
+ return __( 'The athlete_token parameter is deprecated as of version 2 and should be replaced with client_id.', 'wp-strava' );
+ }
+
/* Make sure boolean values are actually boolean
* @see https://wordpress.stackexchange.com/a/119299
*/
@@ -68,7 +73,7 @@ class WPStrava_ActivityShortcode {
$activity_details = null;
try {
- $activity_details = $activity->get_activity( $atts['athlete_token'], $atts['id'] );
+ $activity_details = $activity->get_activity( $atts['client_id'], $atts['id'] );
} catch ( WPStrava_Exception $e ) {
return $e->to_html();
}
diff --git a/includes/WPStrava/LatestActivities.php b/includes/WPStrava/LatestActivities.php
index 0117532..d8c9cbf 100644
--- a/includes/WPStrava/LatestActivities.php
+++ b/includes/WPStrava/LatestActivities.php
@@ -4,7 +4,7 @@ class WPStrava_LatestActivities {
public static function get_activities_html( $args ) {
$defaults = array(
- 'athlete_token' => WPStrava::get_instance()->settings->get_default_token(),
+ 'client_id' => WPStrava::get_instance()->settings->get_default_id(),
'strava_club_id' => null,
'quantity' => 5,
'som' => WPStrava::get_instance()->settings->som,
@@ -12,12 +12,17 @@ class WPStrava_LatestActivities {
$args = wp_parse_args( $args, $defaults );
+ if ( isset( $args['athlete_token'] ) ) {
+ // Translators: Message shown when using deprecated athlete_token parameter.
+ return __( 'The athlete_token parameter is deprecated as of version 2 and should be replaced with client_id.', 'wp-strava' );
+ }
+
$som = WPStrava_SOM::get_som( $args['som'] );
$strava_activity = WPStrava::get_instance()->activity;
$activities = array();
try {
- $activities = $strava_activity->get_activities( $args['athlete_token'], $args['strava_club_id'], $args['quantity'] );
+ $activities = $strava_activity->get_activities( $args['client_id'], $args['strava_club_id'], $args['quantity'] );
} catch ( WPStrava_Exception $e ) {
return $e->to_html();
}
diff --git a/includes/WPStrava/LatestActivitiesShortcode.php b/includes/WPStrava/LatestActivitiesShortcode.php
index 05fec95..db24387 100644
--- a/includes/WPStrava/LatestActivitiesShortcode.php
+++ b/includes/WPStrava/LatestActivitiesShortcode.php
@@ -35,7 +35,7 @@ class WPStrava_LatestActivitiesShortcode {
/**
* Shortcode handler for [activities].
*
- * [activities som=metric quantity=5 athlete_token=xxx|strava_club_id=yyy]
+ * [activities som=metric quantity=5 client_id=xxx|strava_club_id=yyy]
*
* @param array $atts Array of attributes (id, som, etc.).
* @return string Shortcode output
diff --git a/includes/WPStrava/LatestActivitiesWidget.php b/includes/WPStrava/LatestActivitiesWidget.php
index c8f942f..d5783f3 100644
--- a/includes/WPStrava/LatestActivitiesWidget.php
+++ b/includes/WPStrava/LatestActivitiesWidget.php
@@ -25,7 +25,7 @@ class WPStrava_LatestActivitiesWidget extends WP_Widget {
$title = apply_filters( 'widget_title', empty( $instance['title'] ) ? __( 'Latest Activities', 'wp-strava' ) : $instance['title'] );
$activities_args = array(
- 'athlete_token' => isset( $instance['athlete_token'] ) ? $instance['athlete_token'] : null,
+ 'client_id' => isset( $instance['client_id'] ) ? $instance['client_id'] : null,
'strava_club_id' => isset( $instance['strava_club_id'] ) ? $instance['strava_club_id'] : null,
'quantity' => isset( $instance['quantity'] ) ? $instance['quantity'] : null,
);
@@ -42,7 +42,7 @@ class WPStrava_LatestActivitiesWidget 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['client_id'] = strip_tags( $new_instance['client_id'] );
$instance['strava_club_id'] = strip_tags( $new_instance['strava_club_id'] );
$instance['quantity'] = $new_instance['quantity'];
@@ -52,8 +52,8 @@ class WPStrava_LatestActivitiesWidget extends WP_Widget {
/** @see WP_Widget::form */
public function form( $instance ) {
$title = isset( $instance['title'] ) ? esc_attr( $instance['title'] ) : __( 'Latest Activities', 'wp-strava' );
- $all_tokens = WPStrava::get_instance()->settings->get_all_tokens();
- $athlete_token = isset( $instance['athlete_token'] ) ? esc_attr( $instance['athlete_token'] ) : WPStrava::get_instance()->settings->get_default_token();
+ $all_ids = WPStrava::get_instance()->settings->get_all_ids();
+ $client_id = isset( $instance['client_id'] ) ? esc_attr( $instance['client_id'] ) : WPStrava::get_instance()->settings->get_default_token();
$strava_club_id = isset( $instance['strava_club_id'] ) ? esc_attr( $instance['strava_club_id'] ) : '';
$quantity = isset( $instance['quantity'] ) ? absint( $instance['quantity'] ) : 5;
@@ -63,10 +63,10 @@ class WPStrava_LatestActivitiesWidget extends WP_Widget {
-
-
- $nickname ) : ?>
- >
+
+
+ $nickname ) : ?>
+ >
diff --git a/includes/WPStrava/LatestMapWidget.php b/includes/WPStrava/LatestMapWidget.php
index 1eef15d..9608c31 100644
--- a/includes/WPStrava/LatestMapWidget.php
+++ b/includes/WPStrava/LatestMapWidget.php
@@ -17,8 +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 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();
+ $all_ids = WPStrava::get_instance()->settings->get_all_ids();
+ $client_id = isset( $instance['client_id'] ) ? esc_attr( $instance['client_id'] ) : WPStrava::get_instance()->settings->get_default_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'] ) : '';
@@ -31,10 +31,10 @@ class WPStrava_LatestMapWidget extends WP_Widget {
-
-
- $nickname ) : ?>
- >
+
+
+ $nickname ) : ?>
+ >
@@ -56,7 +56,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['client_id'] = strip_tags( $new_instance['client_id'] );
$instance['strava_club_id'] = strip_tags( $new_instance['strava_club_id'] );
$instance['distance_min'] = strip_tags( $new_instance['distance_min'] );
return $instance;
@@ -71,12 +71,12 @@ class WPStrava_LatestMapWidget extends WP_Widget {
public function widget( $args, $instance ) {
$title = apply_filters( 'widget_title', empty( $instance['title'] ) ? __( 'Latest Activity Map', 'wp-strava' ) : $instance['title'] );
- $athlete_token = isset( $instance['athlete_token'] ) ? $instance['athlete_token'] : WPStrava::get_instance()->settings->get_default_token();
+ $client_id = isset( $instance['client_id'] ) ? $instance['client_id'] : WPStrava::get_instance()->settings->get_default_id();
$distance_min = empty( $instance['distance_min'] ) ? 0 : absint( $instance['distance_min'] );
$strava_club_id = empty( $instance['strava_club_id'] ) ? null : $instance['strava_club_id'];
$build_new = false;
- $id = empty( $strava_club_id ) ? $athlete_token : $strava_club_id;
+ $id = empty( $strava_club_id ) ? $client_id : $strava_club_id;
// Try our transient first.
$activity_transient = get_transient( 'strava_latest_map_activity_' . $id );
@@ -95,7 +95,7 @@ class WPStrava_LatestMapWidget extends WP_Widget {
$activities = array();
try {
- $activities = $strava_activity->get_activities( $athlete_token, $strava_club_id );
+ $activities = $strava_activity->get_activities( $client_id, $strava_club_id );
} catch ( WPStrava_Exception $e ) {
echo $e->to_html();
}
diff --git a/includes/WPStrava/RouteShortcode.php b/includes/WPStrava/RouteShortcode.php
index a0a9a51..a3a758e 100644
--- a/includes/WPStrava/RouteShortcode.php
+++ b/includes/WPStrava/RouteShortcode.php
@@ -47,17 +47,22 @@ class WPStrava_RouteShortcode {
$this->add_script = true;
$defaults = array(
- 'id' => 0,
- 'som' => WPStrava::get_instance()->settings->som,
- 'map_width' => '480',
- 'map_height' => '320',
- 'athlete_token' => WPStrava::get_instance()->settings->get_default_token(),
- 'markers' => false,
- 'image_only' => false,
+ 'id' => 0,
+ 'som' => WPStrava::get_instance()->settings->som,
+ 'map_width' => '480',
+ 'map_height' => '320',
+ 'client_id' => WPStrava::get_instance()->settings->get_default_id(),
+ 'markers' => false,
+ 'image_only' => false,
);
$atts = shortcode_atts( $defaults, $atts, 'route' );
+ if ( isset( $atts['athlete_token'] ) ) {
+ // Translators: Message shown when using deprecated athlete_token parameter.
+ return __( 'The athlete_token parameter is deprecated as of version 2 and should be replaced with client_id.', 'wp-strava' );
+ }
+
/* Make sure boolean values are actually boolean
* @see https://wordpress.stackexchange.com/a/119299
*/
diff --git a/readme.txt b/readme.txt
index ccb9d88..75b1316 100755
--- a/readme.txt
+++ b/readme.txt
@@ -27,7 +27,7 @@ Also takes the following optional parameters:
* som - english/metric (system of measure - override from default setting).
* map_width - width (width of image in pixels). Note both width and height parameters are limited to 640px except on premium API plans: https://developers.google.com/maps/documentation/maps-static/dev-guide#Imagesizes
* map_height - height (height of image in pixels). See note above on max height.
-* 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).
+* client_id - 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).
* markers - Display markers at the start/finish point (true/false, defaults to false).
* image_only - Display only the map image and not the table (true/false, defaults to false).
@@ -43,7 +43,7 @@ This also takes the same optional parameters as the [activity] shortcode above.
* som - english/metric (system of measure - override from default setting).
* quantity - number of activities to show.
-* 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).
+* client_id - 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).
* strava_club_id - Will display activity from the specified Strava club ID instead of an athlete.
@@ -57,7 +57,7 @@ Strava Latest Map - shows map of latest activity with option to limit latest map
= Why am I getting "ERROR 401 Unauthorized"? =
-When you have multiple athletes saved, the first is considered to be the default athlete. If you use a shortcode to display activity from anyone other than the default athlete, you must add the athlete token (found on the wp-strava settings page) to the shortcode, such as athlete_token=c764a2b199cff281e39f24671760c1b9c9fe005e. If you've recently had to re-authorize with Strava, your athlete token may have changed and will need to be updated in your shortcodes and widgets. For widgets, re-select the athlete you'd like to display and click Save.
+When you have multiple athletes saved, the first is considered to be the default athlete. If you use a shortcode to display activity from anyone other than the default athlete, you must add the athlete token (found on the wp-strava settings page) to the shortcode, such as client_id=17791. If you've recently had to re-authorize with Strava, your athlete token may have changed and will need to be updated in your shortcodes and widgets. For widgets, re-select the athlete you'd like to display and click Save.
= Why is my Google Map not showing up? =
@@ -75,11 +75,11 @@ WP-Strava caches activity for one hour so your site doesn't hit the Strava API o
4. Latest Map Widget - shows a map of your most recent activity.
5. Latest Map Widget Settings - settings for the Latest Map Widget. You can limit your activity by minimum distance to show only longer efforts.
6. Activity Shortcode - Shows a map of activity with some statistics.
-7. Activity Shortcode Settings - An example activity shortcode. The athlete_token parameter is only needed if your site is connected to multiple athlete accounts.
+7. Activity Shortcode Settings - An example activity shortcode. The client_id parameter is only needed if your site is connected to multiple athlete accounts.
8. Route Shortcode - Shows a map of a route.
9. Route Shortcode Settings - An example route shortcode. Add markers=true to show green/red start/stop points.
10. Activities Shortcode - Shows latest athlete activity in a page or post.
-11. Activities Shortcode Settings - An example activities shortcode. The athlete_token parameter is only needed if your site is connected to multiple athlete accounts.
+11. Activities Shortcode Settings - An example activities shortcode. The client_id parameter is only needed if your site is connected to multiple athlete accounts.
== Changelog ==
From 74f19709373f24fbc9325f6890eb147e1efb616f Mon Sep 17 00:00:00 2001
From: Justin Foell
Date: Fri, 2 Aug 2019 10:36:36 -0500
Subject: [PATCH 06/12] Switch calls from get_default_token() to
get_default_id()
---
includes/WPStrava/LatestActivitiesWidget.php | 2 +-
includes/WPStrava/LatestMapWidget.php | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/includes/WPStrava/LatestActivitiesWidget.php b/includes/WPStrava/LatestActivitiesWidget.php
index d5783f3..ee259d9 100644
--- a/includes/WPStrava/LatestActivitiesWidget.php
+++ b/includes/WPStrava/LatestActivitiesWidget.php
@@ -53,7 +53,7 @@ class WPStrava_LatestActivitiesWidget extends WP_Widget {
public function form( $instance ) {
$title = isset( $instance['title'] ) ? esc_attr( $instance['title'] ) : __( 'Latest Activities', 'wp-strava' );
$all_ids = WPStrava::get_instance()->settings->get_all_ids();
- $client_id = isset( $instance['client_id'] ) ? esc_attr( $instance['client_id'] ) : WPStrava::get_instance()->settings->get_default_token();
+ $client_id = isset( $instance['client_id'] ) ? esc_attr( $instance['client_id'] ) : WPStrava::get_instance()->settings->get_default_id();
$strava_club_id = isset( $instance['strava_club_id'] ) ? esc_attr( $instance['strava_club_id'] ) : '';
$quantity = isset( $instance['quantity'] ) ? absint( $instance['quantity'] ) : 5;
diff --git a/includes/WPStrava/LatestMapWidget.php b/includes/WPStrava/LatestMapWidget.php
index 9608c31..e911743 100644
--- a/includes/WPStrava/LatestMapWidget.php
+++ b/includes/WPStrava/LatestMapWidget.php
@@ -18,7 +18,7 @@ class WPStrava_LatestMapWidget extends WP_Widget {
// outputs the options form on admin
$title = isset( $instance['title'] ) ? esc_attr( $instance['title'] ) : __( 'Latest Activity Map', 'wp-strava' );
$all_ids = WPStrava::get_instance()->settings->get_all_ids();
- $client_id = isset( $instance['client_id'] ) ? esc_attr( $instance['client_id'] ) : WPStrava::get_instance()->settings->get_default_token();
+ $client_id = isset( $instance['client_id'] ) ? esc_attr( $instance['client_id'] ) : WPStrava::get_instance()->settings->get_default_id();
$distance_min = isset( $instance['distance_min'] ) ? esc_attr( $instance['distance_min'] ) : '';
$strava_club_id = isset( $instance['strava_club_id'] ) ? esc_attr( $instance['strava_club_id'] ) : '';
From 408454ad3a22c86e847fd9909d4aec33a60fa3de Mon Sep 17 00:00:00 2001
From: Justin Foell
Date: Fri, 2 Aug 2019 10:40:43 -0500
Subject: [PATCH 07/12] Updated readme
---
readme.txt | 1 +
1 file changed, 1 insertion(+)
diff --git a/readme.txt b/readme.txt
index 75b1316..0908be7 100755
--- a/readme.txt
+++ b/readme.txt
@@ -84,6 +84,7 @@ WP-Strava caches activity for one hour so your site doesn't hit the Strava API o
== Changelog ==
= 2.0.0 =
+
Added new Strava "refresh tokens" ala https://developers.strava.com/docs/oauth-updates/#migration-instructions
From 9d8e071f9633622b85521a88e2d2a0c44e3ad8fc Mon Sep 17 00:00:00 2001
From: Justin Foell
Date: Sat, 21 Sep 2019 17:59:40 -0500
Subject: [PATCH 08/12] Load API IDs in Settings constructor Make sure auth
token is correct for Client ID Add a one-time 404 auth_refresh and retry
---
includes/WPStrava/API.php | 30 +++++++++++++++++++-----------
includes/WPStrava/AuthRefresh.php | 2 +-
includes/WPStrava/Settings.php | 12 +++++++++++-
readme.txt | 11 ++++++++++-
4 files changed, 41 insertions(+), 14 deletions(-)
diff --git a/includes/WPStrava/API.php b/includes/WPStrava/API.php
index 6e8603f..ad701e0 100755
--- a/includes/WPStrava/API.php
+++ b/includes/WPStrava/API.php
@@ -81,8 +81,9 @@ class WPStrava_API {
* @author Justin Foell
*/
public function get( $uri, $args = null ) {
- $url = self::STRAVA_V3_API;
+ static $retry = true;
+ $url = self::STRAVA_V3_API;
$url .= $uri;
if ( ! empty( $args ) ) {
@@ -101,11 +102,22 @@ class WPStrava_API {
}
$response = wp_remote_get( $url, $get_args );
-
if ( is_wp_error( $response ) ) {
throw WPStrava_Exception::from_wp_error( $response );
}
+ // Try *one* real-time token refresh if 404.
+ if ( $retry && 404 == $response['response']['code'] ) {
+ $retry = false;
+ $auth = WPStrava::get_instance()->auth;
+ if ( $auth instanceof WPStrava_AuthRefresh ) {
+ $auth->auth_refresh();
+ }
+ return $this->get( $uri, $args );
+ } else {
+ $retry = true;
+ }
+
if ( 200 != $response['response']['code'] ) { // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
// See if there's useful info in the body.
@@ -138,21 +150,17 @@ class WPStrava_API {
* @since 2.0.0
*/
private function get_access_token() {
- static $access_token = null;
-
// If client_id not set (OAuth set-up), don't even look.
if ( ! $this->client_id ) {
return null;
}
- if ( ! $access_token ) {
- $settings = WPStrava::get_instance()->settings;
- $info = $settings->info;
+ $settings = WPStrava::get_instance()->settings;
+ $info = $settings->info;
- if ( ! empty( $info[ $this->client_id ]->access_token ) ) {
- $access_token = $info[ $this->client_id ]->access_token;
- }
+ if ( ! empty( $info[ $this->client_id ]->access_token ) ) {
+ return $info[ $this->client_id ]->access_token;
}
- return $access_token;
+ return null;
}
}
diff --git a/includes/WPStrava/AuthRefresh.php b/includes/WPStrava/AuthRefresh.php
index 998879c..2604a50 100644
--- a/includes/WPStrava/AuthRefresh.php
+++ b/includes/WPStrava/AuthRefresh.php
@@ -65,7 +65,7 @@ class WPStrava_AuthRefresh extends WPStrava_Auth {
'client_id' => $client_id,
'redirect_uri' => $this->get_redirect_param(),
'approval_prompt' => 'auto',
- 'scope' => 'read,activity:read',
+ 'scope' => 'activity:read,read',
),
$this->auth_url
);
diff --git a/includes/WPStrava/Settings.php b/includes/WPStrava/Settings.php
index 582c21d..e3fcb3d 100644
--- a/includes/WPStrava/Settings.php
+++ b/includes/WPStrava/Settings.php
@@ -16,6 +16,17 @@ class WPStrava_Settings {
private $option_page = 'wp-strava-settings-group';
private $adding_athlete = true;
+
+ /**
+ * Settings constructor.
+ *
+ * @author Justin Foell
+ * @since 2.0
+ */
+ public function __construct() {
+ $this->ids = $this->get_ids();
+ }
+
/**
* Register actions & filters for menus and authentication.
*
@@ -54,7 +65,6 @@ class WPStrava_Settings {
add_settings_section( 'strava_api', __( 'Strava API', 'wp-strava' ), array( $this, 'print_api_instructions' ), 'wp-strava' );
$this->adding_athlete = $this->is_adding_athlete();
- $this->ids = $this->get_ids();
if ( $this->ids_empty( $this->ids ) ) {
register_setting( $this->option_page, 'strava_client_id', array( $this, 'sanitize_client_id' ) );
diff --git a/readme.txt b/readme.txt
index a791f85..48ba11e 100755
--- a/readme.txt
+++ b/readme.txt
@@ -10,12 +10,16 @@ License: GPLv2 or later
Show your Strava activity on your WordPress site.
-
== Description ==
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.
+= Cron =
+
+Using WP-Strava after September 2019 requires a working WordPress cron configuration. By default, WordPress has a built-in cron system to run scheduled events, but it relies on your website getting frequent visitors. The Strava authentication token system expires after 6 hours if not refreshed. If you think your site will not get any visitors over the span on 6 hours, you might want to set up a _real_ cron: https://developer.wordpress.org/plugins/cron/hooking-wp-cron-into-the-system-task-scheduler/. Setting up this sort of cron is beyond the scope of support for this free plugin, so you should seek assistance through your host.
+
+
= Shortcodes =
[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.
@@ -53,20 +57,24 @@ 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.
+
== Frequently Asked Questions ==
= Why am I getting "ERROR 401 Unauthorized"? =
When you have multiple athletes saved, the first is considered to be the default athlete. If you use a shortcode to display activity from anyone other than the default athlete, you must add the athlete token (found on the wp-strava settings page) to the shortcode, such as client_id=17791. If you've recently had to re-authorize with Strava, your athlete token may have changed and will need to be updated in your shortcodes and widgets. For widgets, re-select the athlete you'd like to display and click Save.
+
= Why is my Google Map not showing up? =
If your API key works with other Google Maps plugins but not WP Strava, you may need to enable the "Static Maps" functionality on your google account. This is especially true for people using G Suite accounts (not just a @gmail.com address). While logged into your G Suite email, visit https://console.developers.google.com/apis/library/static-maps-backend.googleapis.com/?q=static and make sure the "Static Maps API" is enabled. For more details see https://wordpress.org/support/topic/no-data-errors/
+
= I recently uploaded an activity, why is it not showing on my site? =
WP-Strava caches activity for one hour so your site doesn't hit the Strava API on every page load. If you recently uploaded activity and want to see it right away, go to the Settings -> Strava in the wp-admin dashboard, check the checkbox labeled "Clear cache (images & transient data)" and then click Save Changes.
+
== Screenshots ==
1. WP Strava settings - this walks you through connecting the WP Strava plugin to your strava account. You can connect multiple accounts by authenticating each one here. Add your Google Maps key for map display here. You can also set the system of measurement (miles/kilometers) and clear any saved data.
@@ -81,6 +89,7 @@ WP-Strava caches activity for one hour so your site doesn't hit the Strava API o
10. Activities Shortcode - Shows latest athlete activity in a page or post.
11. Activities Shortcode Settings - An example activities shortcode. The client_id parameter is only needed if your site is connected to multiple athlete accounts.
+
== Changelog ==
= 2.0.0 =
From 7621c5ca6598d6f950fb7a5348acfab25f7db62e Mon Sep 17 00:00:00 2001
From: Justin Foell
Date: Sat, 21 Sep 2019 21:43:52 -0500
Subject: [PATCH 09/12] Don't retry unless using refresh auth
---
includes/WPStrava/API.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/includes/WPStrava/API.php b/includes/WPStrava/API.php
index ad701e0..fefb220 100755
--- a/includes/WPStrava/API.php
+++ b/includes/WPStrava/API.php
@@ -112,8 +112,8 @@ class WPStrava_API {
$auth = WPStrava::get_instance()->auth;
if ( $auth instanceof WPStrava_AuthRefresh ) {
$auth->auth_refresh();
+ return $this->get( $uri, $args );
}
- return $this->get( $uri, $args );
} else {
$retry = true;
}
From 2c6a1e6eb36611877c4d3294b43436b3222c15a8 Mon Sep 17 00:00:00 2001
From: Justin Foell
Date: Sat, 21 Sep 2019 23:41:18 -0500
Subject: [PATCH 10/12] Updated visibility of auth feedback Updated readme
Updated version to beta1
---
includes/WPStrava/Auth.php | 2 +-
readme.txt | 9 +++++++--
wp-strava.php | 2 +-
3 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/includes/WPStrava/Auth.php b/includes/WPStrava/Auth.php
index 88719e7..14f6574 100644
--- a/includes/WPStrava/Auth.php
+++ b/includes/WPStrava/Auth.php
@@ -3,7 +3,7 @@
abstract class WPStrava_Auth {
protected $auth_url = 'https://www.strava.com/oauth/authorize?response_type=code';
- private $feedback;
+ protected $feedback = '';
/**
* Factory method to get the correct Auth class based on specified string
diff --git a/readme.txt b/readme.txt
index 675b442..ee0512e 100755
--- a/readme.txt
+++ b/readme.txt
@@ -4,7 +4,7 @@ Contributors: cmanon, jrfoell, lancewillett, dlintott, sebastianerb
Tags: strava, activity, bicycle, cycling, biking, running, run, swimming, swim, paddle, kayak, gps, shortcode, widget, plugin
Requires at least: 4.6
Tested up to: 5.1
-Stable tag: 1.7.3
+Stable tag: 2.0
Requires PHP: 5.2
License: GPLv2 or later
@@ -246,6 +246,11 @@ Initial version.
== Upgrade Notice ==
+= 2.0 =
+
+Version 2.0 is mandatory after October 15th, 2019. 2.0 settings upgrade instructions: https://github.com/cmanon/wp-strava/wiki/2.0-Upgrade .
+
+
= 1.7.3 =
-Version 2.0 will be mandatory after October 15th, 2019. Try the 2.0 beta: https://github.com/cmanon/wp-strava/releases . 2.0 settings upgrade instructions: https://github.com/cmanon/wp-strava/wiki/2.0-Upgrade .
+Version 2.0 is mandatory after October 15th, 2019. Try the 2.0 beta: https://github.com/cmanon/wp-strava/releases . 2.0 settings upgrade instructions: https://github.com/cmanon/wp-strava/wiki/2.0-Upgrade .
diff --git a/wp-strava.php b/wp-strava.php
index e8c9c53..9f9fd1c 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: Show your strava.com activity on your WordPress site. Some Icons are Copyright © Yusuke Kamiyamane. All rights reserved. Licensed under a Creative Commons Attribution 3.0 license.
- * Version: 1.7.3
+ * Version: 2.0b1
* Author: Carlos Santa Cruz, Justin Foell, Lance Willett, Daniel Lintott, Sebastian Erb
* License: GPL2
* Text Domain: wp-strava
From 90884664cbd3a763fc0d9009a1da9ace088bae95 Mon Sep 17 00:00:00 2001
From: Justin Foell
Date: Sat, 21 Sep 2019 23:50:43 -0500
Subject: [PATCH 11/12] Update export settings
---
.gitattributes | 2 ++
1 file changed, 2 insertions(+)
diff --git a/.gitattributes b/.gitattributes
index 823697c..60bbd80 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -3,3 +3,5 @@
composer.json export-ignore
composer.lock export-ignore
phpcs.xml export-ignore
+tests export-ignore
+phpunit.xml export-ignore
From a9c5c3b223d6be719233cf66db96449aeb18b602 Mon Sep 17 00:00:00 2001
From: Justin Foell
Date: Sat, 21 Sep 2019 23:51:43 -0500
Subject: [PATCH 12/12] Removed unused autoload
---
vendor/autoload.php | 7 -------
1 file changed, 7 deletions(-)
delete mode 100644 vendor/autoload.php
diff --git a/vendor/autoload.php b/vendor/autoload.php
deleted file mode 100644
index 2375b1e..0000000
--- a/vendor/autoload.php
+++ /dev/null
@@ -1,7 +0,0 @@
-