From 2aaa87d0c9642705bfce25b842a4552bbc0eaaf3 Mon Sep 17 00:00:00 2001 From: Justin Foell <630830+jrfoell@users.noreply.github.com> Date: Fri, 1 Nov 2019 15:33:10 -0500 Subject: [PATCH 1/4] Add 1 hour transient caching to all API calls --- includes/WPStrava/API.php | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/includes/WPStrava/API.php b/includes/WPStrava/API.php index 1943230..42ad021 100755 --- a/includes/WPStrava/API.php +++ b/includes/WPStrava/API.php @@ -72,7 +72,7 @@ class WPStrava_API { } /** - * GET something from the Strava API. + * GET something from the Strava API - checking the cache first. * * @param string $uri Path within the Strava API. * @param array $args Request arguments. @@ -81,6 +81,36 @@ class WPStrava_API { * @author Justin Foell */ public function get( $uri, $args = null ) { + + // @see https://stackoverflow.com/a/3764390/2146022 + $arg_suffix = is_array( $args ) ? '_' . substr( md5( wp_json_encode( $args ), true ), 0, 12 ) : ''; + + $transient_key = 'strava_api_data_' . $uri . $arg_suffix; + + $data = get_transient( $transient_key ); + + if ( $data ) { + return $data; + } + + $data = $this->remote_get( $uri, $args ); + + set_transient( $transient_key, $data, HOUR_IN_SECONDS ); + + return $data; + } + + /** + * GET something from the Strava API. + * + * @param string $uri Path within the Strava API. + * @param array $args Request arguments. + * @return stdClass Strava API response. + * @throws WPStrava_Exception + * @author Justin Foell + * @since 2.0.1 + */ + private function remote_get( $uri, $args = null ) { static $retry = true; $url = self::STRAVA_V3_API; @@ -112,7 +142,7 @@ class WPStrava_API { $auth = WPStrava::get_instance()->auth; if ( $auth instanceof WPStrava_AuthRefresh ) { $auth->auth_refresh(); - return $this->get( $uri, $args ); + return $this->remote_get( $uri, $args ); } } else { $retry = true; From 7680149bddf6e61f697713dd4d7a32653d657991 Mon Sep 17 00:00:00 2001 From: Justin Foell <630830+jrfoell@users.noreply.github.com> Date: Fri, 1 Nov 2019 15:33:41 -0500 Subject: [PATCH 2/4] Add new transients to cache clear --- includes/WPStrava/Settings.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/includes/WPStrava/Settings.php b/includes/WPStrava/Settings.php index 41692ca..237e8a3 100644 --- a/includes/WPStrava/Settings.php +++ b/includes/WPStrava/Settings.php @@ -8,7 +8,6 @@ * Get redirected back to this settings page with ?code= or ?error= * Use code to retrieve auth token */ - class WPStrava_Settings { private $ids = array(); @@ -469,6 +468,8 @@ class WPStrava_Settings { if ( 'on' === $checked ) { global $wpdb; + $wpdb->query( "DELETE FROM {$wpdb->options} WHERE `option_name` LIKE '_transient_timeout_strava_api_data_%'" ); + $wpdb->query( "DELETE FROM {$wpdb->options} WHERE `option_name` LIKE '_transient_strava_api_data_%'" ); $wpdb->query( "DELETE FROM {$wpdb->options} WHERE `option_name` LIKE '_transient_timeout_strava_latest_map_%'" ); $wpdb->query( "DELETE FROM {$wpdb->options} WHERE `option_name` LIKE '_transient_strava_latest_map_%'" ); $wpdb->query( "DELETE FROM {$wpdb->options} WHERE `option_name` LIKE 'strava_latest_map%'" ); From 9371d1e7f0b94da757d5b08ca0e2932871b869dc Mon Sep 17 00:00:00 2001 From: Justin Foell <630830+jrfoell@users.noreply.github.com> Date: Fri, 1 Nov 2019 15:34:05 -0500 Subject: [PATCH 3/4] Remove old map caching now that all activity is cached --- includes/WPStrava/LatestMap.php | 123 ++++++-------------------------- 1 file changed, 20 insertions(+), 103 deletions(-) diff --git a/includes/WPStrava/LatestMap.php b/includes/WPStrava/LatestMap.php index 58b68f1..9b1cb75 100644 --- a/includes/WPStrava/LatestMap.php +++ b/includes/WPStrava/LatestMap.php @@ -3,8 +3,6 @@ class WPStrava_LatestMap { public static function get_map_html( $args ) { - $build_new = false; - $defaults = array( 'client_id' => WPStrava::get_instance()->settings->get_default_id(), 'strava_club_id' => null, @@ -13,117 +11,36 @@ class WPStrava_LatestMap { $args = wp_parse_args( $args, $defaults ); - $id = empty( $args['strava_club_id'] ) ? $args['client_id'] : $args['strava_club_id']; + $strava_activity = WPStrava::get_instance()->activity; - // Try our transient first. - $activity_transient = get_transient( 'strava_latest_map_activity_' . $id ); - $activity_option = get_option( 'strava_latest_map_activity_' . $id ); + $activities = array(); - $activity = $activity_transient ? $activity_transient : null; - - if ( ! $activity || empty( $activity->map ) ) { - $strava_activity = WPStrava::get_instance()->activity; - - $activities = array(); - - try { - $activities = $strava_activity->get_activities( $args['client_id'], $args['strava_club_id'] ); - } catch ( WPStrava_Exception $e ) { - // If athlete_token is still set, warn about that first and foremost. - if ( isset( $args['athlete_token'] ) ) { - // Translators: Message shown when using deprecated athlete_token parameter. - echo wp_kses_post( __( 'The athlete_token parameter is deprecated as of WP-Strava version 2 and should be replaced with client_id.', 'wp-strava' ) ); - } else { - echo $e->to_html(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Debug only. - } - } - - if ( ! empty( $activities ) ) { - - if ( ! empty( $args['distance_min'] ) ) { - $activities = $strava_activity->get_activities_longer_than( $activities, $args['distance_min'] ); - } - - $activity = current( $activities ); - - // Compare transient (temporary storage) to option (more permanent). - // If the option isn't set or the transient is different, update the option. - if ( empty( $activity_option->id ) || $activity->id != $activity_option->id ) { // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison - $build_new = true; - self::update_activity( $id, $activity ); - } - - // Update the transient if it needs updating. - if ( empty( $activity_transient->id ) || $activity->id != $activity_transient->id ) { // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison - self::update_activity_transient( $id, $activity ); - } + try { + $activities = $strava_activity->get_activities( $args['client_id'], $args['strava_club_id'] ); + } catch ( WPStrava_Exception $e ) { + // If athlete_token is still set, warn about that first and foremost. + if ( isset( $args['athlete_token'] ) ) { + // Translators: Message shown when using deprecated athlete_token parameter. + echo wp_kses_post( __( 'The athlete_token parameter is deprecated as of WP-Strava version 2 and should be replaced with client_id.', 'wp-strava' ) ); + } else { + echo $e->to_html(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Debug only. } } - if ( $activity ) { + if ( ! empty( $activities ) ) { + + if ( ! empty( $args['distance_min'] ) ) { + $activities = $strava_activity->get_activities_longer_than( $activities, $args['distance_min'] ); + } + + $activity = current( $activities ); + echo empty( $activity->map ) ? // Translators: Text with activity name shown in place of image if not available. esc_html( sprintf( __( 'Map not available for activity "%s"', 'wp-strava' ), $activity->name ) ) : "" . - self::get_static_image( $id, $activity, $build_new ) . // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Image OK. + WPStrava_StaticMap::get_image_tag( $activity ) . // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Image OK. ''; } - - } - - /** - * Get image for specific activity using Static Maps class. - * - * @author Justin Foell - * @param string $id Client ID or Club ID. - * @param object $activity Activity to get image for. - * @param boolean $build_new Whether to refresh the image from cache. - * @return string Image tag. - */ - private static function get_static_image( $id, $activity, $build_new ) { - $img = get_option( 'strava_latest_map_' . $id ); - - if ( $build_new || ! $img ) { - $img = WPStrava_StaticMap::get_image_tag( $activity ); - self::update_map( $id, $img ); - } - - return $img; - } - - /** - * Update map in option to cache. - * - * @author Justin Foell - * @since 1.2.0 - * @param string $id Client ID or Club ID. - * @param string $img Image tag. - */ - private static function update_map( $id, $img ) { - update_option( 'strava_latest_map_' . $id, $img ); - } - - /** - * Update activity in option to cache. - * - * @author Justin Foell - * @since 1.2.0 - * @param string $id Client ID or Club ID. - * @param object $activity stdClass Strava activity object. - */ - private static function update_activity( $id, $activity ) { - update_option( 'strava_latest_map_activity_' . $id, $activity ); - } - - /** - * Update activity in transient to cache. - * - * @author Justin Foell - * @since 1.2.0 - * @param string $id CLient ID or Club ID. - * @param object $activity stdClass Strava activity object. - */ - private static function update_activity_transient( $id, $activity ) { - set_transient( 'strava_latest_map_activity_' . $id, $activity, HOUR_IN_SECONDS ); } } From 8b20f75aa81ad9dd899359555149173e4fa8d441 Mon Sep 17 00:00:00 2001 From: Justin Foell <630830+jrfoell@users.noreply.github.com> Date: Fri, 1 Nov 2019 15:44:39 -0500 Subject: [PATCH 4/4] Include client_id in transient to avoid multiple athelete collisions --- includes/WPStrava/API.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/WPStrava/API.php b/includes/WPStrava/API.php index 42ad021..c67c9cd 100755 --- a/includes/WPStrava/API.php +++ b/includes/WPStrava/API.php @@ -83,9 +83,9 @@ class WPStrava_API { public function get( $uri, $args = null ) { // @see https://stackoverflow.com/a/3764390/2146022 - $arg_suffix = is_array( $args ) ? '_' . substr( md5( wp_json_encode( $args ), true ), 0, 12 ) : ''; + $arg_suffix = is_array( $args ) ? '_' . substr( md5( wp_json_encode( $args ) ), 0, 12 ) : ''; - $transient_key = 'strava_api_data_' . $uri . $arg_suffix; + $transient_key = 'strava_api_data_' . $this->client_id . '_' . $uri . $arg_suffix; $data = get_transient( $transient_key );