PluginProbe
Social Media Auto Poster – Schedule & Publish to Buffer / 6.2.5
Social Media Auto Poster – Schedule & Publish to Buffer v6.2.5
6.2.5 6.2.4 6.2.3 6.2.2 6.2.1 6.2.0 6.1.2 6.1.1 6.1.0 6.0.9 6.0.8 6.0.7 6.0.6 6.0.5 6.0.4 6.0.3 6.0.2 6.0.1 6.0.0 3.8.1 3.8.2 3.8.3 3.8.4 3.8.5 3.8.6 All 126 releases
← All changes | includes/class-buffer-api.php +82 -4 6.2.36.2.5 View file →
@@ -116,9 +116,9 @@
116 116 ?>
117 117 <div class="wpzinc-option">
118 118 <div class="full">
119 119 <a href="<?php echo esc_attr( $this->get_oauth_url() ); ?>" class="button button-primary">
120 - <?php esc_html_e( 'Connect a Buffer Account', 'wp-to-buffer' ); ?>
120 + <?php esc_html_e( 'Connect an additional Buffer Account', 'wp-to-buffer' ); ?>
121 121 </a>
122 122 </div>
123 123 </div>
124 124 <?php
@@ -331,8 +331,13 @@
331 331 * @param bool|int $token_expires Token Expiry.
332 332 */
333 333 public function set_tokens( $access_token = '', $refresh_token = '', $token_expires = false ) {
334 334
335 + $this->base->get_class( 'log' )->add_to_debug_log( 'Buffer API: set_tokens(): Started.' );
336 + $this->base->get_class( 'log' )->add_to_debug_log( 'Buffer API: set_tokens(): access_token = ' . $access_token );
337 + $this->base->get_class( 'log' )->add_to_debug_log( 'Buffer API: set_tokens(): refresh_token = ' . $refresh_token );
338 + $this->base->get_class( 'log' )->add_to_debug_log( 'Buffer API: set_tokens(): token_expires = ' . $token_expires );
339 +
335 340 $this->access_token = $access_token;
336 341 $this->refresh_token = $refresh_token;
337 342 $this->token_expires = $token_expires;
338 343
@@ -388,18 +393,29 @@
388 393 * @since 2.0.0
389 394 */
390 395 public function refresh_token() {
391 396
397 + $this->base->get_class( 'log' )->add_to_debug_log( 'Buffer API: refresh_token(): Started.' );
398 +
392 399 // Bail if we don't have a refresh token.
393 400 if ( empty( $this->refresh_token ) ) {
401 + $this->base->get_class( 'log' )->add_to_debug_log( 'Buffer API: refresh_token(): Error: No refresh token available; cannot refresh.' );
394 402 return new \WP_Error( 'missing_refresh_token', __( 'No refresh token exists', 'wp-to-buffer' ) );
395 403 }
396 404
405 + $this->base->get_class( 'log' )->add_to_debug_log( 'Buffer API: refresh_token(): access_token = ' . $this->access_token );
406 + $this->base->get_class( 'log' )->add_to_debug_log( 'Buffer API: refresh_token(): refresh_token = ' . $this->refresh_token );
407 + $this->base->get_class( 'log' )->add_to_debug_log( 'Buffer API: refresh_token(): token_expires = ' . $this->token_expires );
408 + $this->base->get_class( 'log' )->add_to_debug_log( 'Buffer API: refresh_token(): token_expires = ' . ( $this->token_expires && time() > (int) $this->token_expires ? 'expired ' . ( time() - (int) $this->token_expires ) . 's ago' : 'expires in ' . ( (int) $this->token_expires - time() ) . 's' ) );
409 +
397 410 // Bail if the access token hasn't yet expired.
398 411 if ( strtotime( '+15 minutes' ) < $this->token_expires ) {
412 + $this->base->get_class( 'log' )->add_to_debug_log( 'Buffer API: refresh_token(): Skipped: Access token not yet within the 15 minute refresh window.' );
399 413 return false;
400 414 }
401 415
416 + $this->base->get_class( 'log' )->add_to_debug_log( 'Buffer API: refresh_token(): Requesting new access token.' );
417 +
402 418 // Send request.
403 419 $result = $this->oauth_request(
404 420 $this->oauth_authorize_url . 'token',
405 421 array(
@@ -410,8 +426,10 @@
410 426 );
411 427
412 428 // If an error occured, log and return it now.
413 429 if ( is_wp_error( $result ) ) {
430 + $this->base->get_class( 'log' )->add_to_debug_log( sprintf( 'Buffer API: refresh_token(): Error: [%s] %s', $result->get_error_code(), $result->get_error_message() ) );
431 +
414 432 /**
415 433 * Perform any actions when refreshing an expired access token fails.
416 434 *
417 435 * @since 6.0.0
@@ -432,8 +450,14 @@
432 450 'refresh_token' => $result['refresh_token'],
433 451 'token_expires' => strtotime( '+' . $result['expires_in'] . ' seconds' ),
434 452 );
435 453
454 + $this->base->get_class( 'log' )->add_to_debug_log( 'Buffer API: refresh_token(): Success' );
455 + $this->base->get_class( 'log' )->add_to_debug_log( 'Buffer API: refresh_token(): New access_token = ' . $result['access_token'] );
456 + $this->base->get_class( 'log' )->add_to_debug_log( 'Buffer API: refresh_token(): New refresh_token = ' . $result['refresh_token'] );
457 + $this->base->get_class( 'log' )->add_to_debug_log( 'Buffer API: refresh_token(): New token_expires = ' . $result['token_expires'] );
458 + $this->base->get_class( 'log' )->add_to_debug_log( 'Buffer API: refresh_token(): New token_expires = ' . ( $result['token_expires'] && time() > (int) $result['token_expires'] ? 'expired ' . ( time() - (int) $result['token_expires'] ) . 's ago' : 'expires in ' . ( (int) $result['token_expires'] - time() ) . 's' ) );
459 +
436 460 /**
437 461 * Perform any actions with the new access token, such as saving it.
438 462 *
439 463 * @since 6.0.0
@@ -560,11 +584,14 @@
560 584 // Return stored profiles if available and not forcing a refresh.
561 585 $option_name = $this->base->plugin->name . '-profiles-' . $account_id;
562 586 $profiles = get_option( $option_name );
563 587 if ( ! $force && is_array( $profiles ) ) {
588 + $this->base->get_class( 'log' )->add_to_debug_log( sprintf( 'Buffer API: profiles(): account=%s: returning %d cached profile(s).', $account_id, count( $profiles ) ) );
564 589 return $profiles;
565 590 }
566 591
592 + $this->base->get_class( 'log' )->add_to_debug_log( sprintf( 'Buffer API: profiles(): account=%s: fetching profiles from Buffer (force=%s).', $account_id, $force ? 'yes' : 'no' ) );
593 +
567 594 // Build GraphQL query.
568 595 $query = '
569 596 query GetChannels($organizationId: OrganizationId!) {
570 597 channels(input: { organizationId: $organizationId }) {
@@ -595,8 +622,9 @@
595 622 );
596 623
597 624 // Check for errors.
598 625 if ( is_wp_error( $results ) ) {
626 + $this->base->get_class( 'log' )->add_to_debug_log( sprintf( 'Buffer API: profiles(): account=%s: FAILED to fetch profiles: [%s] %s', $account_id, $results->get_error_code(), $results->get_error_message() ) );
599 627 return $results;
600 628 }
601 629
602 630 // Build profiles array from results.
@@ -743,9 +771,9 @@
743 771 switch ( $service ) {
744 772
745 773 case 'instagram':
746 774 $metadata = array(
747 - 'type' => $params['post_type'] === 'story' ? 'story' : 'post',
775 + 'type' => in_array( $params['post_type'], array( 'story', 'video_story' ), true ) ? 'story' : 'post',
748 776 'shouldShareToFeed' => true,
749 777 );
750 778
751 779 // First Comment.
@@ -952,8 +980,25 @@
952 980 ),
953 981 );
954 982 }
955 983 break;
984 +
985 + case 'video':
986 + case 'video_story':
987 + // Bail if no video URL is defined.
988 + if ( empty( $params['video_url'] ) ) {
989 + break;
990 + }
991 +
992 + // Buffer fetches the video from a public URL, so we only send the URL.
993 + $assets = array(
994 + array(
995 + 'video' => array(
996 + 'url' => $params['video_url'],
997 + ),
998 + ),
999 + );
1000 + break;
956 1001 }
957 1002
958 1003 // Include assets. Always overwrites the default empty array
959 1004 // initialised above, if the service branch built any.
@@ -1073,10 +1118,19 @@
1073 1118 * @return \WP_Error|array
1074 1119 */
1075 1120 private function graphql_query( $query, $variables = array() ) {
1076 1121
1122 + $this->base->get_class( 'log' )->add_to_debug_log( 'Buffer API: graphql_query(): Started.' );
1123 + $this->base->get_class( 'log' )->add_to_debug_log( 'Buffer API: graphql_query(): query = ' . $query );
1124 + $this->base->get_class( 'log' )->add_to_debug_log( 'Buffer API: graphql_query(): variables = ' . print_r( $variables, true ) ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
1125 + $this->base->get_class( 'log' )->add_to_debug_log( 'Buffer API: graphql_query(): access_token = ' . $this->access_token );
1126 + $this->base->get_class( 'log' )->add_to_debug_log( 'Buffer API: graphql_query(): refresh_token = ' . $this->refresh_token );
1127 + $this->base->get_class( 'log' )->add_to_debug_log( 'Buffer API: graphql_query(): token_expires = ' . $this->token_expires );
1128 + $this->base->get_class( 'log' )->add_to_debug_log( 'Buffer API: graphql_query(): token_expires = ' . ( $this->token_expires && time() > (int) $this->token_expires ? 'expired ' . ( time() - (int) $this->token_expires ) . 's ago' : 'expires in ' . ( (int) $this->token_expires - time() ) . 's' ) );
1129 +
1077 1130 // Check required parameters exist.
1078 1131 if ( empty( $this->access_token ) ) {
1132 + $this->base->get_class( 'log' )->add_to_debug_log( 'Buffer API: graphql_query(): Error: No access token was specified' );
1079 1133 return new \WP_Error( 'missing_access_token', __( 'No access token was specified', 'wp-to-buffer' ) );
1080 1134 }
1081 1135
1082 1136 // Fetch a new access token and refresh token.
@@ -1083,11 +1137,17 @@
1083 1137 $result = $this->refresh_token();
1084 1138
1085 1139 // Bail if something went wrong.
1086 1140 if ( is_wp_error( $result ) ) {
1141 + $this->base->get_class( 'log' )->add_to_debug_log( 'Buffer API: graphql_query(): Error: ' . $result->get_error_message() );
1087 1142 return $result;
1088 1143 }
1089 1144
1145 + $this->base->get_class( 'log' )->add_to_debug_log( 'Buffer API: graphql_query(): access_token = ' . $this->access_token );
1146 + $this->base->get_class( 'log' )->add_to_debug_log( 'Buffer API: graphql_query(): refresh_token = ' . $this->refresh_token );
1147 + $this->base->get_class( 'log' )->add_to_debug_log( 'Buffer API: graphql_query(): token_expires = ' . $this->token_expires );
1148 + $this->base->get_class( 'log' )->add_to_debug_log( 'Buffer API: graphql_query(): token_expires = ' . ( $this->token_expires && time() > (int) $this->token_expires ? 'expired ' . ( time() - (int) $this->token_expires ) . 's ago' : 'expires in ' . ( (int) $this->token_expires - time() ) . 's' ) );
1149 +
1090 1150 // Build body.
1091 1151 $body = array( 'query' => $query );
1092 1152 if ( ! empty( $variables ) ) {
1093 1153 $body['variables'] = $variables;
@@ -1105,14 +1165,22 @@
1105 1165 );
1106 1166
1107 1167 // If an error occured, return it now.
1108 1168 if ( is_wp_error( $result ) ) {
1169 + $this->base->get_class( 'log' )->add_to_debug_log( sprintf( 'Buffer API: graphql_query(): Error: [%s] %s', $result->get_error_code(), $result->get_error_message() ) );
1109 1170 return $result;
1110 1171 }
1111 1172
1112 - // Parse and return the response.
1113 - return $this->parse_response( $result );
1173 + // Parse the response.
1174 + $response = $this->parse_response( $result );
1114 1175
1176 + // Log any API error, so failures that would otherwise be silent are captured.
1177 + if ( is_wp_error( $response ) ) {
1178 + $this->base->get_class( 'log' )->add_to_debug_log( sprintf( 'Buffer API: graphql_query(): API returned error: [%s] %s', $response->get_error_code(), $response->get_error_message() ) );
1179 + }
1180 +
1181 + return $response;
1182 +
1115 1183 }
1116 1184
1117 1185 /**
1118 1186 * Returns the headers to use in an authenticated GraphQL API request.
@@ -1222,10 +1290,20 @@
1222 1290 '403 Forbidden'
1223 1291 );
1224 1292 }
1225 1293
1294 + // Retain-and-retry on server errors: return without touching stored tokens.
1295 + if ( $http_code >= 500 ) {
1296 + return new \WP_Error( 'buffer_api_server_error', $http_code . ' server error' );
1297 + }
1298 +
1226 1299 // Decode response.
1227 1300 $body = json_decode( $http_body, true );
1301 +
1302 + // Bail if the response isn't valid JSON.
1303 + if ( ! is_array( $body ) ) {
1304 + return new \WP_Error( 'buffer_api_invalid_response', 'Invalid API response' );
1305 + }
1228 1306
1229 1307 // If an error is detected, return it.
1230 1308 if ( array_key_exists( 'error', $body ) ) {
1231 1309 return new \WP_Error(