| @@ -21,9 +21,9 @@ | ||
| 21 | 21 | * Holds the base class object. |
| 22 | 22 | * |
| 23 | 23 | * @since 3.4.7 |
| 24 | 24 | * |
| 25 | - * @var object. | |
| 25 | + * @var object | |
| 26 | 26 | */ |
| 27 | 27 | public $base; |
| 28 | 28 | |
| 29 | 29 | /** |
| @@ -30,9 +30,9 @@ | ||
| 30 | 30 | * Holds the Buffer Application's Client ID |
| 31 | 31 | * |
| 32 | 32 | * @since 3.3.3 |
| 33 | 33 | * |
| 34 | - * @var string. | |
| 34 | + * @var string | |
| 35 | 35 | */ |
| 36 | 36 | private $client_id = 'd1Lk26lma4iEgb-20v1BWmdKrlopiGwP9pu9ri7JG0e'; |
| 37 | 37 | |
| 38 | 38 | /** |
| @@ -39,9 +39,9 @@ | ||
| 39 | 39 | * Holds the oAuth Authorize URL |
| 40 | 40 | * |
| 41 | 41 | * @since 6.0.0 |
| 42 | 42 | * |
| 43 | - * @var string. | |
| 43 | + * @var string | |
| 44 | 44 | */ |
| 45 | 45 | private $oauth_authorize_url = 'https://auth.buffer.com/'; |
| 46 | 46 | |
| 47 | 47 | /** |
| @@ -48,27 +48,18 @@ | ||
| 48 | 48 | * Holds the oAuth Gateway endpoint, used to exchange a code for an access token |
| 49 | 49 | * |
| 50 | 50 | * @since 3.3.3 |
| 51 | 51 | * |
| 52 | - * @var string. | |
| 52 | + * @var string | |
| 53 | 53 | */ |
| 54 | 54 | private $redirect_uri = 'https://www.wpzinc.com/?oauth=bufferv2'; |
| 55 | 55 | |
| 56 | 56 | /** |
| 57 | - * Holds the Proxy endpoint, which might be used to pass requests through | |
| 58 | - * | |
| 59 | - * @since 4.2.1 | |
| 60 | - * | |
| 61 | - * @var string. | |
| 62 | - */ | |
| 63 | - private $proxy_endpoint = 'https://proxy.wpzinc.net/'; | |
| 64 | - | |
| 65 | - /** | |
| 66 | 57 | * Holds the API endpoint |
| 67 | 58 | * |
| 68 | 59 | * @since 3.4.7 |
| 69 | 60 | * |
| 70 | - * @var string. | |
| 61 | + * @var string | |
| 71 | 62 | */ |
| 72 | 63 | private $api_endpoint = 'https://api.buffer.com/'; |
| 73 | 64 | |
| 74 | 65 | /** |
| @@ -93,9 +84,9 @@ | ||
| 93 | 84 | * Token Expiry Timestamp |
| 94 | 85 | * |
| 95 | 86 | * @since 3.5.0 |
| 96 | 87 | * |
| 97 | - * @var int | |
| 88 | + * @var int|bool | |
| 98 | 89 | */ |
| 99 | 90 | public $token_expires = false; |
| 100 | 91 | |
| 101 | 92 | /** |
| @@ -352,9 +343,9 @@ | ||
| 352 | 343 | * |
| 353 | 344 | * @since 6.0.0 |
| 354 | 345 | * |
| 355 | 346 | * @param string $authorization_code Authorization Code, returned from get_oauth_url() flow. |
| 356 | - * @return WP_Error|array | |
| 347 | + * @return \WP_Error|array | |
| 357 | 348 | */ |
| 358 | 349 | public function get_access_token( $authorization_code ) { |
| 359 | 350 | |
| 360 | 351 | $result = $this->oauth_request( |
| @@ -397,18 +388,19 @@ | ||
| 397 | 388 | * @since 2.0.0 |
| 398 | 389 | */ |
| 399 | 390 | public function refresh_token() { |
| 400 | 391 | |
| 401 | - // Bail if no refresh token is available to use, otherwise we'll | |
| 402 | - // send a request to Buffer with an empty refresh_token, which | |
| 403 | - // will fail. | |
| 392 | + // Bail if we don't have a refresh token. | |
| 404 | 393 | if ( empty( $this->refresh_token ) ) { |
| 405 | - return new \WP_Error( | |
| 406 | - $this->base->plugin->filter_name . '_api_refresh_token_error', | |
| 407 | - __( 'No refresh token available; cannot refresh access token.', 'wp-to-buffer' ) | |
| 408 | - ); | |
| 394 | + return new \WP_Error( 'missing_refresh_token', __( 'No refresh token exists', 'wp-to-buffer' ) ); | |
| 409 | 395 | } |
| 410 | 396 | |
| 397 | + // Bail if the access token hasn't yet expired. | |
| 398 | + if ( strtotime( '+15 minutes' ) < $this->token_expires ) { | |
| 399 | + return false; | |
| 400 | + } | |
| 401 | + | |
| 402 | + // Send request. | |
| 411 | 403 | $result = $this->oauth_request( |
| 412 | 404 | $this->oauth_authorize_url . 'token', |
| 413 | 405 | array( |
| 414 | 406 | 'client_id' => $this->client_id, |
| @@ -423,9 +415,9 @@ | ||
| 423 | 415 | * Perform any actions when refreshing an expired access token fails. |
| 424 | 416 | * |
| 425 | 417 | * @since 6.0.0 |
| 426 | 418 | * |
| 427 | - * @param WP_Error $result Error from API. | |
| 419 | + * @param \WP_Error $result Error from API. | |
| 428 | 420 | * @param string $client_id OAuth Client ID. |
| 429 | 421 | * @param string $access_token Access Token. |
| 430 | 422 | * @param string $refresh_token Refresh Token. |
| 431 | 423 | */ |
| @@ -467,9 +459,9 @@ | ||
| 467 | 459 | * @since 6.0.1 |
| 468 | 460 | * |
| 469 | 461 | * @param bool $force Force API call (false = use stored option). |
| 470 | 462 | * |
| 471 | - * @return WP_Error|array | |
| 463 | + * @return \WP_Error|array | |
| 472 | 464 | */ |
| 473 | 465 | public function organizations( $force = false ) { |
| 474 | 466 | |
| 475 | 467 | // Return stored organizations from the non-autoloaded option, unless |
| @@ -529,9 +521,9 @@ | ||
| 529 | 521 | * |
| 530 | 522 | * @since 6.0.0 |
| 531 | 523 | * |
| 532 | 524 | * @param string $account_id Account ID. |
| 533 | - * @return WP_Error|array | |
| 525 | + * @return \WP_Error|array | |
| 534 | 526 | */ |
| 535 | 527 | public function account( $account_id = '' ) { |
| 536 | 528 | |
| 537 | 529 | $organizations = $this->organizations( false ); |
| @@ -560,9 +552,9 @@ | ||
| 560 | 552 | * @since 3.0.0 |
| 561 | 553 | * |
| 562 | 554 | * @param bool $force Force API call (false = use stored option). |
| 563 | 555 | * @param string $account_id Account ID. |
| 564 | - * @return WP_Error|array | |
| 556 | + * @return \WP_Error|array | |
| 565 | 557 | */ |
| 566 | 558 | public function profiles( $force = false, $account_id = 'default' ) { |
| 567 | 559 | |
| 568 | 560 | // Return stored profiles if available and not forcing a refresh. |
| @@ -647,9 +639,9 @@ | ||
| 647 | 639 | * |
| 648 | 640 | * @since 6.0.0 |
| 649 | 641 | * |
| 650 | 642 | * @param string $post_id Post ID. |
| 651 | - * @return WP_Error|array | |
| 643 | + * @return \WP_Error|array | |
| 652 | 644 | */ |
| 653 | 645 | public function get_post( $post_id ) { |
| 654 | 646 | |
| 655 | 647 | $query = ' |
| @@ -693,9 +685,9 @@ | ||
| 693 | 685 | * @since 3.0.0 |
| 694 | 686 | * |
| 695 | 687 | * @param array $params Params. |
| 696 | 688 | * @param string $service Service. |
| 697 | - * @return WP_Error|array | |
| 689 | + * @return \WP_Error|array | |
| 698 | 690 | */ |
| 699 | 691 | public function updates_create( $params, $service ) { |
| 700 | 692 | |
| 701 | 693 | // Build GraphQL variables. |
| @@ -759,8 +751,13 @@ | ||
| 759 | 751 | // First Comment. |
| 760 | 752 | if ( ! empty( $params['first_comment'] ) ) { |
| 761 | 753 | $metadata['firstComment'] = $params['first_comment']; |
| 762 | 754 | } |
| 755 | + | |
| 756 | + // Shop Grid Link. | |
| 757 | + if ( ! empty( $params['url'] ) ) { | |
| 758 | + $metadata['link'] = $params['url']; | |
| 759 | + } | |
| 763 | 760 | break; |
| 764 | 761 | |
| 765 | 762 | case 'facebook': |
| 766 | 763 | $metadata = array( |
| @@ -773,14 +770,10 @@ | ||
| 773 | 770 | } |
| 774 | 771 | |
| 775 | 772 | // OpenGraph / Link Attachment. |
| 776 | 773 | if ( $params['post_type'] === 'link' && ! empty( $params['url'] ) ) { |
| 777 | - $assets = array( | |
| 778 | - array( | |
| 779 | - 'link' => array( | |
| 780 | - 'url' => $params['url'], | |
| 781 | - ), | |
| 782 | - ), | |
| 774 | + $metadata['linkAttachment'] = array( | |
| 775 | + 'url' => $params['url'], | |
| 783 | 776 | ); |
| 784 | 777 | } |
| 785 | 778 | |
| 786 | 779 | // Annotations. |
| @@ -796,14 +789,10 @@ | ||
| 796 | 789 | } |
| 797 | 790 | |
| 798 | 791 | // OpenGraph / Link Attachment. |
| 799 | 792 | if ( $params['post_type'] === 'link' && ! empty( $params['url'] ) ) { |
| 800 | - $assets = array( | |
| 801 | - array( | |
| 802 | - 'link' => array( | |
| 803 | - 'url' => $params['url'], | |
| 804 | - ), | |
| 805 | - ), | |
| 793 | + $metadata['linkAttachment'] = array( | |
| 794 | + 'url' => $params['url'], | |
| 806 | 795 | ); |
| 807 | 796 | } |
| 808 | 797 | |
| 809 | 798 | // Annotations. |
| @@ -814,13 +803,11 @@ | ||
| 814 | 803 | |
| 815 | 804 | case 'twitter': |
| 816 | 805 | // First Comment. |
| 817 | 806 | if ( ! empty( $params['first_comment'] ) ) { |
| 818 | - $metadata = array( | |
| 819 | - 'thread' => array( | |
| 820 | - array( | |
| 821 | - 'text' => $params['first_comment'], | |
| 822 | - ), | |
| 807 | + $metadata['thread'] = array( | |
| 808 | + array( | |
| 809 | + 'text' => $params['first_comment'], | |
| 823 | 810 | ), |
| 824 | 811 | ); |
| 825 | 812 | } |
| 826 | 813 | |
| @@ -878,24 +865,18 @@ | ||
| 878 | 865 | |
| 879 | 866 | case 'threads': |
| 880 | 867 | // OpenGraph / Link Attachment. |
| 881 | 868 | if ( $params['post_type'] === 'link' && ! empty( $params['url'] ) ) { |
| 882 | - $assets = array( | |
| 883 | - array( | |
| 884 | - 'link' => array( | |
| 885 | - 'url' => $params['url'], | |
| 886 | - ), | |
| 887 | - ), | |
| 869 | + $metadata['linkAttachment'] = array( | |
| 870 | + 'url' => $params['url'], | |
| 888 | 871 | ); |
| 889 | 872 | } |
| 890 | 873 | |
| 891 | 874 | // First Comment. |
| 892 | 875 | if ( ! empty( $params['first_comment'] ) ) { |
| 893 | - $metadata = array( | |
| 894 | - 'thread' => array( | |
| 895 | - array( | |
| 896 | - 'text' => $params['first_comment'], | |
| 897 | - ), | |
| 876 | + $metadata['thread'] = array( | |
| 877 | + array( | |
| 878 | + 'text' => $params['first_comment'], | |
| 898 | 879 | ), |
| 899 | 880 | ); |
| 900 | 881 | } |
| 901 | 882 | break; |
| @@ -902,24 +883,18 @@ | ||
| 902 | 883 | |
| 903 | 884 | case 'bluesky': |
| 904 | 885 | // OpenGraph / Link Attachment. |
| 905 | 886 | if ( $params['post_type'] === 'link' && ! empty( $params['url'] ) ) { |
| 906 | - $assets = array( | |
| 907 | - array( | |
| 908 | - 'link' => array( | |
| 909 | - 'url' => $params['url'], | |
| 910 | - ), | |
| 911 | - ), | |
| 887 | + $metadata['linkAttachment'] = array( | |
| 888 | + 'url' => $params['url'], | |
| 912 | 889 | ); |
| 913 | 890 | } |
| 914 | 891 | |
| 915 | 892 | // First Comment. |
| 916 | 893 | if ( ! empty( $params['first_comment'] ) ) { |
| 917 | - $metadata = array( | |
| 918 | - 'thread' => array( | |
| 919 | - array( | |
| 920 | - 'text' => $params['first_comment'], | |
| 921 | - ), | |
| 894 | + $metadata['thread'] = array( | |
| 895 | + array( | |
| 896 | + 'text' => $params['first_comment'], | |
| 922 | 897 | ), |
| 923 | 898 | ); |
| 924 | 899 | } |
| 925 | 900 | break; |
| @@ -926,13 +901,11 @@ | ||
| 926 | 901 | |
| 927 | 902 | case 'mastodon': |
| 928 | 903 | // First Comment. |
| 929 | 904 | if ( ! empty( $params['first_comment'] ) ) { |
| 930 | - $metadata = array( | |
| 931 | - 'thread' => array( | |
| 932 | - array( | |
| 933 | - 'text' => $params['first_comment'], | |
| 934 | - ), | |
| 905 | + $metadata['thread'] = array( | |
| 906 | + array( | |
| 907 | + 'text' => $params['first_comment'], | |
| 935 | 908 | ), |
| 936 | 909 | ); |
| 937 | 910 | } |
| 938 | 911 | |
| @@ -963,18 +936,19 @@ | ||
| 963 | 936 | |
| 964 | 937 | // Build assets array. |
| 965 | 938 | $assets = array(); |
| 966 | 939 | foreach ( $params['media_urls'] as $media ) { |
| 940 | + // Skip anything that isn't an image, so we never send null asset data. | |
| 941 | + if ( ! is_array( $media ) || empty( $media['image'] ) ) { | |
| 942 | + continue; | |
| 943 | + } | |
| 944 | + | |
| 967 | 945 | $assets[] = array( |
| 968 | 946 | 'image' => array( |
| 969 | 947 | 'url' => $media['image'], |
| 970 | 948 | 'thumbnailUrl' => $media['thumbnail'], |
| 971 | 949 | 'metadata' => array( |
| 972 | - 'altText' => $media['alt_text'], | |
| 973 | - 'dimensions' => array( | |
| 974 | - 'width' => $media['width'], | |
| 975 | - 'height' => $media['height'], | |
| 976 | - ), | |
| 950 | + 'altText' => $media['alt_text'], | |
| 977 | 951 | ), |
| 978 | 952 | ), |
| 979 | 953 | ); |
| 980 | 954 | } |
| @@ -1056,9 +1030,9 @@ | ||
| 1056 | 1030 | * @since 3.0.0 |
| 1057 | 1031 | * |
| 1058 | 1032 | * @param string $url URL. |
| 1059 | 1033 | * @param array $params Parameters (optional). |
| 1060 | - * @return WP_Error|array | |
| 1034 | + * @return \WP_Error|array | |
| 1061 | 1035 | */ |
| 1062 | 1036 | private function oauth_request( $url, $params = array() ) { |
| 1063 | 1037 | |
| 1064 | 1038 | // Send request. |
| @@ -1095,13 +1069,25 @@ | ||
| 1095 | 1069 | * @since 6.0.0 |
| 1096 | 1070 | * |
| 1097 | 1071 | * @param string $query GraphQL Query. |
| 1098 | 1072 | * @param array $variables GraphQL Variables. |
| 1099 | - * @param bool $is_retry Whether this is a retry following a token refresh. | |
| 1100 | - * @return WP_Error|array | |
| 1073 | + * @return \WP_Error|array | |
| 1101 | 1074 | */ |
| 1102 | - private function graphql_query( $query, $variables = array(), $is_retry = false ) { | |
| 1075 | + private function graphql_query( $query, $variables = array() ) { | |
| 1103 | 1076 | |
| 1077 | + // Check required parameters exist. | |
| 1078 | + if ( empty( $this->access_token ) ) { | |
| 1079 | + return new \WP_Error( 'missing_access_token', __( 'No access token was specified', 'wp-to-buffer' ) ); | |
| 1080 | + } | |
| 1081 | + | |
| 1082 | + // Fetch a new access token and refresh token. | |
| 1083 | + $result = $this->refresh_token(); | |
| 1084 | + | |
| 1085 | + // Bail if something went wrong. | |
| 1086 | + if ( is_wp_error( $result ) ) { | |
| 1087 | + return $result; | |
| 1088 | + } | |
| 1089 | + | |
| 1104 | 1090 | // Build body. |
| 1105 | 1091 | $body = array( 'query' => $query ); |
| 1106 | 1092 | if ( ! empty( $variables ) ) { |
| 1107 | 1093 | $body['variables'] = $variables; |
| @@ -1122,38 +1108,11 @@ | ||
| 1122 | 1108 | if ( is_wp_error( $result ) ) { |
| 1123 | 1109 | return $result; |
| 1124 | 1110 | } |
| 1125 | 1111 | |
| 1126 | - // Parse result. | |
| 1127 | - $response = $this->parse_response( $result ); | |
| 1112 | + // Parse and return the response. | |
| 1113 | + return $this->parse_response( $result ); | |
| 1128 | 1114 | |
| 1129 | - // If this is a retry, return the parsed response. | |
| 1130 | - // This prevents an infinite loop of retries when a token refresh fails. | |
| 1131 | - if ( $is_retry ) { | |
| 1132 | - return $response; | |
| 1133 | - } | |
| 1134 | - | |
| 1135 | - // If the request was successful, return the response. | |
| 1136 | - if ( ! is_wp_error( $response ) ) { | |
| 1137 | - return $response; | |
| 1138 | - } | |
| 1139 | - | |
| 1140 | - // If the error isn't an unauthenticated error, return it. | |
| 1141 | - if ( strtolower( $response->get_error_code() ) !== 'unauthenticated' ) { | |
| 1142 | - return $response; | |
| 1143 | - } | |
| 1144 | - | |
| 1145 | - // Attempt to refresh the token. | |
| 1146 | - $refresh_result = $this->refresh_token(); | |
| 1147 | - | |
| 1148 | - // Bail if the refresh token attempt failed. | |
| 1149 | - if ( is_wp_error( $refresh_result ) ) { | |
| 1150 | - return $refresh_result; | |
| 1151 | - } | |
| 1152 | - | |
| 1153 | - // Attempt the request again, now we have a new access token. | |
| 1154 | - return $this->graphql_query( $query, $variables, true ); | |
| 1155 | - | |
| 1156 | 1115 | } |
| 1157 | 1116 | |
| 1158 | 1117 | /** |
| 1159 | 1118 | * Returns the headers to use in an authenticated GraphQL API request. |
| @@ -1240,15 +1199,15 @@ | ||
| 1240 | 1199 | |
| 1241 | 1200 | } |
| 1242 | 1201 | |
| 1243 | 1202 | /** |
| 1244 | - * Parses the response body, returning a WP_Error | |
| 1203 | + * Parses the response body, returning a \WP_Error | |
| 1245 | 1204 | * if the response body contains an error. |
| 1246 | 1205 | * |
| 1247 | 1206 | * @since 3.9.8 |
| 1248 | 1207 | * |
| 1249 | - * @param string $response Response Body. | |
| 1250 | - * @return WP_Error|array | |
| 1208 | + * @param array|\WP_Error $response HTTP Response. | |
| 1209 | + * @return \WP_Error|array | |
| 1251 | 1210 | */ |
| 1252 | 1211 | private function parse_response( $response ) { |
| 1253 | 1212 | |
| 1254 | 1213 | // Get HTTP code and body. |