3

I have made an API call with wp_remote_post and tried to retrieve the body with wp_remote_retrieve_body. But the response only showing headers and the body is protected.

below code, I have used to make an API call.

$args = array(
                'LocationId' => $loc_id,
                'AppId' => $app_id
               );
    $response = wp_remote_post( 'https://www.apiurl.com?APIKEY='."$api_key".'', $args );

$responceData = json_decode(wp_remote_retrieve_body( $response ), TRUE );
print_r($response);

and the printed response (just starting piece of data) is :

Array ( [headers] => Requests_Utility_CaseInsensitiveDictionary Object ( [data:protected]

I am developing the wordpress plugin in localhost. How to solve this error.

Full Response :

Array ( [headers] => Requests_Utility_CaseInsensitiveDictionary Object ( [data:protected] => Array ( [cache-control] => no-cache, no-store [pragma] => no-cache [content-type] => application/json; charset=utf-8 [expires] => -1 [server] => Microsoft-IIS/10.0 [access-control-allow-origin] => * [x-aspnet-version] => 4.0.30319 [x-powered-by] => ASP.NET [date] => Fri, 13 Jul 2018 06:24:16 GMT [content-length] => 1858 ) ) [body] => {"Already10Questions":{"Count":1,"ResponseErrors":[{"Already10Questions":null,"AlreadyEmailErrorMessage":null,"AuthorizationError":null,"CaseNo":"[180712-23:24:16]_3D94D663C0DB","ErrorMessage":null,"SuccessMsg":null,"UserRegisterSuccessMsg":null}]},"AlreadyEmailErrorMessages":{"Count":1,"ResponseErrors":[{"Already10Questions":null,"AlreadyEmailErrorMessage":null,"AuthorizationError":null,"CaseNo":"[180712-23:24:16]_3D94D663C0DB","ErrorMessage":null,"SuccessMsg":null,"UserRegisterSuccessMsg":null}]},"AuthorizationError":{"Count":1,"ResponseErrors":[{"Already10Questions":null,"AlreadyEmailErrorMessage":null,"AuthorizationError":null,"CaseNo":"[180712-23:24:16]_3D94D663C0DB","ErrorMessage":null,"SuccessMsg":null,"UserRegisterSuccessMsg":null}]},"ErrorMessages":{"Count":1,"ResponseErrors":[{"Already10Questions":null,"AlreadyEmailErrorMessage":null,"AuthorizationError":null,"CaseNo":"[180712-23:24:16]_3D94D663C0DB","ErrorMessage":null,"SuccessMsg":null,"UserRegisterSuccessMsg":null}]},"ExistPhoneNumber":{"Count":1,"ResponseErrors":[{"Already10Questions":null,"AlreadyEmailErrorMessage":null,"AuthorizationError":null,"CaseNo":"[180712-23:24:16]_3D94D663C0DB","ErrorMessage":null,"SuccessMsg":null,"UserRegisterSuccessMsg":null}]},"SuccessMsg":{"Count":1,"ResponseErrors":[{"Already10Questions":null,"AlreadyEmailErrorMessage":null,"AuthorizationError":null,"CaseNo":"[180712-23:24:16]_3D94D663C0DB","ErrorMessage":null,"SuccessMsg":null,"UserRegisterSuccessMsg":null}]},"UserRegisterSuccessmessages":{"Count":1,"ResponseErrors":[{"Already10Questions":null,"AlreadyEmailErrorMessage":null,"AuthorizationError":null,"CaseNo":"[180712-23:24:16]_3D94D663C0DB","ErrorMessage":null,"SuccessMsg":null,"UserRegisterSuccessMsg":null}]},"CheckUserLocationAccessByLocationIdList":null,"ItemsCount":0,"RestaurantTotalCountByFilterList":null,"appDetails":null} 

UPDATE: Problem is solved with the below code. In my understanding, the problem is with sending arguments to the API in a wrong way. Thanks For Helping Sally Cj

$postData = array(
    'LocationId' => $loc_id,
    'AppId' => $app_id,
);
$context = array(
        'method' => 'POST',
        'headers' => "Authorization:\r\n".
            "Content-Type: application/json\r\n",
        'httpversion' => '1.0',
        'redirection' => 5,
        'timeout' => 60,
        'blocking' => true,
        'body' => json_encode($postData)
    );
            $response = wp_remote_post( 'apiurl.com?APIKEY='."$api_key".'', $context);
            $currency = wp_remote_post( 'apiurl.com?APIKEY='."$api_key".'', $context);

if ( is_wp_error( $response ) ) {
   $error_message = $response->get_error_message();
   echo "Something went wrong: $error_message";
} else {
    $responceData = json_decode(wp_remote_retrieve_body($response), true);
    $currencyData = json_decode(wp_remote_retrieve_body($currency), true);
Anonymous
  • 119
  • 2
  • 3
  • 13
  • Can you print `$response` ? – Sudharshan Nair Jul 13 '18 at 06:08
  • Array ( [headers] => Requests_Utility_CaseInsensitiveDictionary Object ( [data:protected] <<<< this is the responce i have printed using `print_r ($response);` – Anonymous Jul 13 '18 at 06:11
  • @SudharshanNair are you asking for full response??? – Anonymous Jul 13 '18 at 06:12
  • Can you also post Full response in question itself ? – Sudharshan Nair Jul 13 '18 at 06:25
  • @SudharshanNair I have Updated Full response. – Anonymous Jul 13 '18 at 06:29
  • Can you have a look at this link https://stackoverflow.com/questions/9930843/get-string-within-protected-object – Sudharshan Nair Jul 13 '18 at 06:37
  • `function getData() { return $response; } $responceData = getData(); ` Is this how I need to change. – Anonymous Jul 13 '18 at 06:51
  • Try Reflection part – Sudharshan Nair Jul 13 '18 at 06:52
  • I have tried the reflection and many methods which are available in stackoverflow on how to get protected data from an array, still didn't worked. Can you explain me what actually happens with reflection. – Anonymous Jul 13 '18 at 10:08
  • The "protected body" is *not* the response body. Instead, it's a `protected` property of the [`Requests_Utility_CaseInsensitiveDictionary` class](https://developer.wordpress.org/reference/classes/requests_utility_caseinsensitivedictionary/) instance. The actual body is in `$response['body']` - try to `echo` it and you'd see the raw response body. – Sally CJ Jul 13 '18 at 14:10
  • But you should *use the `wp_remote_retrieve_body()` function to retrieve the response body*. And actually, you've already done that - see the `$responceData = ...` in your question. So with that variable, you could do `echo $responceData['ItemsCount'];` or `var_dump( $responceData )` to see the *array*'s items. – Sally CJ Jul 13 '18 at 14:11
  • var_dump($responceData) is giving the same output which i have ipdated in the question – Anonymous Jul 13 '18 at 14:31
  • I was referring to `$responceData = json_decode( wp_remote_retrieve_body( $response ), TRUE ); var_dump( $responceData );` try once more. – Sally CJ Jul 13 '18 at 15:40
  • var_dump($responceData) returns first level array only. I have made same API call with PHP method file_get_contents and received multi dimentional array. Where is the problem??? – Anonymous Jul 14 '18 at 13:09

1 Answers1

5

The Problem

It's not about the response body being "protected". But you're not getting the expected response data because the request body was incomplete — i.e. it did not contain the data in $args (e.g. AppId).

Because $args is the request body; so it should be passed to wp_remote_post() like this:

$response = wp_remote_post( 'https://www.apiurl.com?APIKEY='."$api_key".'', array(
    'body' => $args
) );

See https://codex.wordpress.org/Function_Reference/wp_remote_post#Parameters

The Fixed Code

(Re-indented for clarity; and there were also other changes)

// Request body.
$body = array(
    'LocationId' => $loc_id,
    'AppId'      => $app_id
);
$response = wp_remote_post( 'https://www.apiurl.com?APIKEY='."$api_key".'', array(
    'body' => $body
) );

// Response body.
$body = wp_remote_retrieve_body( $response );

// On success (i.e. `$body` is a valid JSON string), `$responceData` would be an
// `ARRAY`.
$responceData = ( ! is_wp_error( $response ) ) ? json_decode( $body, true ) : null;
var_dump( $responceData );

Additional Note

Here, $responceData would be an array because you set the second parameter to true:

$responceData = json_decode(wp_remote_retrieve_body( $response ), TRUE );

So if you wanted $responceData to be an object, then simply omit the second parameter:

$responceData = json_decode(wp_remote_retrieve_body( $response ) );
//$responceData = json_decode(wp_remote_retrieve_body( $response ), false ); // equivalent to above

See the PHP manual for json_decode() for further details.

Sally CJ
  • 15,362
  • 2
  • 16
  • 34
  • 1
    The problem is solved with this [code] (https://pastebin.com/AT3XCziN) . Thank you so much for your response. – Anonymous Jul 15 '18 at 12:15
  • I guess yesterday I missed the `Content-Type: application/json` header.. but anyway, thanks also for accepting my answer. – Sally CJ Jul 15 '18 at 12:36