Creating a http Client in Cake 3 - php

I am having trouble getting a response from an API using a http Client in Cake PHP 3
I want to send the following GET request but I cannot manage to return a result. If visit this url with a browser i get a response.
http://XX.XX.XX.XX:8020/mvapireq/?apientry=newuseru&authkey=XXXXXXXXXX&u_username=NEWUSERNAME&u_password=PASSWORD&u_name=NAME&u_email=EMAIL&u_phone=PHONE&u_currency=USD&u_country=USA&u_address=x&deviceid=DEVICEID&now=555
When I try to send the same request with http Client my reponse object is always null
use Cake\Network\Http\Client;
use Cake\Network\Http\Response;
public function foo(){
$http = new Client();
$data = [
'apientry' => 'newuseru',
'authkey' => 'XXXXXXXX',
'u_username' => 'NEWUSERNAME',
'u_password' => 'PASSWORD',
'u_name' => 'NAME',
'u_email' => 'EMAIL',
'u_phone' => 'PHONE',
'u_currency' => 'USD',
'u_country' => 'USA',
'u_address' => 'x',
'deviceid' => 'DEVICEID',
'now' => '555'
];
$response = $http->get('http://XX.XX.XX.XX:8020/mvapireq', $data);
debug($response->body);
debug($response->code);
debug($response->headers);
}
This is the results from the debug() it seems to me like the request is not being sent.
Notice (8): Trying to get property of non-object [APP/Controller/UsersController.php, line 1159]
/src/Controller/UsersController.php (line 1159)
null
Notice (8): Trying to get property of non-object [APP/Controller/UsersController.php, line 1160]
/src/Controller/UsersController.php (line 1160)
null
Notice (8): Trying to get property of non-object [APP/Controller/UsersController.php, line 1161]
/src/Controller/UsersController.php (line 1161)
null
/src/Controller/UsersController.php (line 1163)
null
I've tried many different ways of structuring $http and all of them have returned the same result. I really can't figure out whats going wrong. Any help would be great.

You can specify hostname and port in the constructor of the Client:
<?php
use Cake\Network\Http\Client;
// ....
public function foo(){
$http = new Client([
'hostname' => 'XX.XX.XX.XX',
'port' => '8020'
]);
$data = [
'apientry' => 'newuseru',
//....
'now' => '555'
];
$response = $http->get('/mvapireq', $data);
// ...
}
And check your system:
firewall (os)
allow_url_fopen (in your php runtime configuration)

Related

Error: Failure when receiving data from the peer php GuzzleHttp

I'm trying to make post request and the post request is working but I'm not getting the response
$client = new \GuzzleHttp\Client(['headers' => ['Authorization' => 'Basic ' . 'token==']]);
$data = $client->post(
'url',
[
'form_params' => [
'address' => 'addreww',
'name' => 'Zia Sultan',
'phone_number' => '2136000000',
]
]
);
return $data;
What I'm getting in my insomnia
Error: Failure when receiving data from the peer
You're code is working, post method returns ResponseInterface, we need to fetch the content from it, we need to first fetch the StreamInterface by calling getBody() and chaining it will getContents() gives us the actual response. Keep debug mode On, to get find the exact error for Error: Failure when receiving data from the peer, and when this error occurs, share the entire trace with us
try {
$response = (new \GuzzleHttp\Client())->post(
'url',
[
'headers' => [
'Authorization' => 'Basic ' . 'token=='
],
'form_params' => [
'address' => 'addreww',
'name' => 'Zia Sultan',
'phone_number' => '2136000000',
],
// 'http_errors' => false, // Set to false to disable throwing exceptions on an HTTP protocol errors (i.e., 4xx and 5xx responses)
// 'debug' => true,
// 'connect_timeout' => 30 // number of seconds to wait while trying to connect to a server, Use 0 to wait indefinitely (the default behavior)
// 'read_timeout' => 10 // timeout to use when reading a streamed body, default value is default_socket_timeout in php.ini
// 'timeout' => 30 // the total timeout of the request in seconds. Use 0 to wait indefinitely (the default behavior).
]
);
return $response->getBody()->getContents();
} catch (Throwable $exception) {
print_r($exception);
}
I was returning the data only but I needed to return getBody() like this way
$data->getBody()
Its working now

Assign value to object from within Guzzle on_stats

stupid and brief question here,
I've been messing around with trying to get endpoints working on my website for a while now, where an action triggers an endpoint call. I would like to collect stats on call success and average response time and stuff like that, so I create a model prior to making the request, and then attempt to assign object values once the request on_stats stage is reached. The problem is, when I attempt to assign the variables from inside the request, it can't access the object, throwing a Creating default object from empty value error. Guzzle has ways to make things synchronous, using promises, but I've tried and failed to implement them after a variety of errors and attempts to debug. Is there no way to make what I'm attempting to do in the code below work? How could I access the object and assign values from within the request itself?
$call = new EndpointCall;
$call->endpoint_rel_id = $endpt->id;
// Initiate GuzzleHTTP Client
$client = new Client();
$requestQuery = $endpt->endpoint_url;
$response = $client->request('POST', $requestQuery, [
'allow_redirects' => false,
'json' => $obj,
'headers' => [
'api-secret' => $user->api_sending_secret,
'Accept' => 'application/json',
],
'synchronous' => true,
'http_errors' => false,
'on_stats' => function (TransferStats $stats) {
$call->response_time = $stats->getTransferTime();
if ($stats->hasResponse()) {
$call->response = $stats->getResponse()->getStatusCode();
}
$call->save();
}
]);
Try adding use($call) to the function declaration like this:
$call = new EndpointCall;
$call->endpoint_rel_id = $endpt->id;
// Initiate GuzzleHTTP Client
$client = new Client();
$requestQuery = $endpt->endpoint_url;
$response = $client->request('POST', $requestQuery, [
'allow_redirects' => false,
'json' => $obj,
'headers' => [
'api-secret' => $user->api_sending_secret,
'Accept' => 'application/json',
],
'synchronous' => true,
'http_errors' => false,
'on_stats' => function (TransferStats $stats) use($call) {
$call->response_time = $stats->getTransferTime();
if ($stats->hasResponse()) {
$call->response = $stats->getResponse()->getStatusCode();
}
$call->save();
}
]);
About the use keyword
Variables are not accessible inside functions unless they are declared as global. In much the same way, variables from the child scope are not accessible from within the closure unless explicitly stated using the use keyword.

How can I send cookie while using REST API?

Using Laravel 5 and trying to send some data from my site to another one, which provides me with the REST API. But they use cookies as a authorization. For this moment, I've passed auth successfully. And stuck on how should I send this cookie to API interface via POST method? Here is my listing.
Thanx in advance.
P.S. All things are going on inside the controller.
if (Cookie::get('amoauth') !== null) {
//COOKIE IS HERE
$client = new Client();
$newlead = $client->post('https://domain.amocrm.ru/private/api/v2/json/leads/set', [
'add' => [
'add/name' => 'TEST LEAD',
'add/date_create' => time(),
'add/last_modified' => time(),
'add/status_id' => '1',
'add/price' => 5000
]
]);
} else {
$client = new Client();
$auth = $client->post('https://domain.amocrm.ru/private/api/auth.php',[
'USER_LOGIN' => 'login',
'USER_HASH' => 'hash',
'type' => 'json'
]);
$auth = $auth->getHeaders('Set-Cookie');
Cookie::queue('amoauth', $auth, 15);
return redirect('/test');
}
Now it returns me the following:
Client error: `POST https://domain.amocrm.ru/private/api/v2/json/leads/set` resulted in a `401 Unauthorized` response.
Found the solution: switched to ixudra/curl.

Laravel - Class 'App\Http\Controllers\Object' not found

I am currently trying to figure out why I get this error:
FatalThrowableError: Class 'App\Http\Controllers\Object' not found in Operators.php line 23
This is the Operators.php controller from where the error is coming from:
public function getOperatorData()
{
$api = new Client([
'base_uri' => 'https://www.space-track.org',
'cookies' => true,
]); $api->post('ajaxauth/login', [
'form_params' => [
'identity' => '#',
'password' => '#',
],
]);
$response = $api->get('basicspacedata/query/class/satcat/orderby/INTLDES%20desc/limit/1/metadata/false');
$mydata = json_decode($response->getBody()->getContents());
$object = new Object();
$object->intldes = $mydata->INTLDES;
$object->satname = $mydata->SATNAME;
$object->save();
return view('pages/satellite-database', compact('object'));
}
The specific line from where the error comes from is:
$object = new Object();
The line shown above should be creating a new model for querying`in a blade file later on.
I am usually able to solve these (either I forgot the 'use' or something), but I have been unable to solve this error.
Turns out the problem lay in the $mydata = json_decode($response->getBody()->getContents());.
Once I changed $mydata to return, I managed to make the JSON format properly and get the $object array to work.

PHP SoapClient returns NULL (cakephp)

So, I have following problem:
I am using plugin CakeSoap for get data from SAP.
If I test with my internal link (in house) it is working, but if I try with external link I am geting following error:
"Failed to open stream: Could not connect because the target computer denied the connection." and "I/O warning : failed to load external entity "http://..."
Also, if I try to load this link directly from browser it is working.
I have read all threads on StackOverflow and in my options parameter "trace" is setted to "true"
here is the example of my connection
private function getDataSAP($SAPcustomerID, $SAPdestinationIDS){
$soap = new CakeSoap([
'wsdl' => Configure::read('SAP_WSDL_CUSTOMER'),
'login' => Configure::read('SAP_USERNAME'),
'password' => Configure::read('SAP_PASS'),
'location' => Configure::read('SAP_WS_CUSTOMER'),
]);
//Collect all products from specific user and his destinations
$all_data = [];
foreach($SAPdestinationIDS as $data){
$all_data[] = $soap->sendRequest('ZGetCustomerData', [
'ZGetCustomerData' => [
'ICustomer' => $SAPcustomerID->customer_number,
'ItLocation' => [
'item' => [
'Servloc' => $data->destination_number
]
]
],
]
);
}
$all_destinations = [];
foreach($all_data as $my_containers){
$all_destinations[] = json_decode(json_encode($my_containers->EtLocation->item), true);
}
return $all_destinations;
}
And there are options from my CakeSoap.php file
$options = [
// 'trace' => Configure::read('debug'),
'trace' => true,
'stream_context' => $context,
'cache_wsdl' => WSDL_CACHE_NONE
];
Additional I have tried to make request using SoapUI software and it is working.
So my question is why this link doesnt work in php?
Thank you for helping!

Categories