I'm in a situation where I need to call the same method if any exception is thrown to ensure I'm not duplicating any code. However, it's not working as I thought. Here's the relevant code:
public static function getFolderObject($folder_id)
{
$client = new Client('https://api.box.com/{version}/folders', [
'version' => '2.0',
'request.options' => [
'headers' => [
'Authorization' => 'Bearer ' . self::getAccessToken(),
]
]
]);
$request = $client->get($folder_id);
try {
$response = $request->send();
$result = $response->json();
$files = $result['item_collection']['entries'];
} catch (BadResponseException $e) {
$result = $e->getResponse()->getStatusCode();
if ($result === 401) {
self::regenerateAccessToken();
self::getFolderObject();
}
}
return count($files) ? $files : false;
}
As you can see I'm calling the method from the method method under the if condition self::getFolderObject(); to prevent duplicate code again in under the if statement from beginning of the method. However, if I duplicate the code it works as expected. Is there any solution to achieve what I want?
You have missed to return the value and assign the folder_id:
public static function getFolderObject($folder_id)
{
$client = new Client('https://api.box.com/{version}/folders', [
'version' => '2.0',
'request.options' => [
'headers' => [
'Authorization' => 'Bearer ' . self::getAccessToken(),
]
]
]);
$request = $client->get($folder_id);
try {
$response = $request->send();
$result = $response->json();
$files = $result['item_collection']['entries'];
} catch (BadResponseException $e) {
$result = $e->getResponse()->getStatusCode();
if ($result === 401) {
self::regenerateAccessToken();
return self::getFolderObject($folder_id);
}
}
return count($files) ? $files : false;
}
Related
I'm trying to fetch data by GET request with using Guzzle client. I'm using both header with JWT token and query params like below:
function fetchUserByEmployeeId(string $employeeId): JsonResponse
{
$headers = $this->getHeaders();
$query = ['$filter' => "employeeId eq $employeeId", '$select' => 'displayName,givenName,postalCode,employeeId,id'];
try {
$result = $this->client->request('GET', self::FIND_USER_BY_EMPLOYEE_ID_URL, [
'headers' => $headers,
'query' => $query,
'debug' => true
]);
return JsonResponse::fromJsonString($result->getBody()->getContents());
} catch (RequestException $exception) {
throw $exception;
}
}
Unfortunaletely I've received an error like below:
If I delete $query it will work. Is there something wrong with my query params? I have no idea. Based on Guzzle documantation it seems to be ok: https://docs.guzzlephp.org/en/stable/request-options.html#query
Fortunately I have solved this issue. Problem was with passing param. $employeeId, should be in quotes. Like below:
function fetchUserByEmployeeId(string $employeeId): JsonResponse
{
$headers = $this->getHeaders();
$query = ["\$filter" => "employeeId eq '$employeeId'", "\$select" => "displayName,givenName,postalCode,employeeId,id"];
try {
$result = $this->client->request('GET', self::FIND_USER_BY_EMPLOYEE_ID_URL, [
RequestOptions::HEADERS => $headers,
RequestOptions::QUERY => $query,
'debug' => true
]);
return JsonResponse::fromJsonString($result->getBody()->getContents());
} catch (RequestException $exception) {
throw $exception;
}
}
I am developing my unit tests for an API created in Symfony4
Reading the Guzzle documentation I generated the following code:
File SecurityControllerTest.php
$client = new Client([
'base_uri' => 'http://localhost/sacrepad/sacrepad-api/public/index.php/',
'timeout' => 2.0,
]);
$data = array();
$data['email'] = 'admin#admin.com';
$data['password'] = '12345678';
$data2 = array();
$data2['json'] = $data;
$formData = json_encode($data);
$response = $client->request('POST', 'login', [
'headers' => ['Content-Type' => 'application/x-www-form-urlencoded'],
'form_params' => [
'json' => $formData,
]
]);
$body = json_decode($response->getBody(), true);
File SecurityController.php
/**
* #Route("/login", name="login", methods={"POST"})
*/
public function login(Request $request,Helpers $helpers,ValidatorInterface $validator, JwtAuth $jwtauth) {
$data = array(
'status' => 'error',
'code' => 400,
'msg' => 'data not received'
);
$json = $request->request->get('json');
$params = json_decode($json);
}
When I run the tests with the phpunit command, I get the following error:
1) App\Tests\SecurityControllerTest::testAuth GuzzleHttp\Exception\ServerException: Server error: `POST http://localhost/sacrepad/sacrepad-api/public/index.php/login` resulted in a `500 Internal Server Error` response:
If I change the name of the request:
$json = $request->request->get('json2');
It works and it returns me the following:
array(3) {
["status"]=>
string(5) "error"
["code"]=>
int(400)
["msg"]=>
string(18) "data not received"
}
Any ideas on how to make it work and send the parameters?
i build a class for working with guzzle
use Exception;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
class Api
{
protected $client;
protected $url;
public function __construct()
{
$this->client = new Client([
'verify'=>false
]);
$this->url = 'http://localhost/sacrepad/sacrepad-api/public/';
}
public function get($endpoint, $params = [], $headers = [])
{
$response = $this->sendRequest(
'GET',
$this->url . $endpoint,
$params,
$headers
);
return $response;
}
public function post($endpoint, $params = [], $headers = [])
{
$response = $this->sendRequest(
'POST',
$this->url . $endpoint,
$params,
$headers
);
return $response;
}
public function sendRequest($type, $url, $params = [], $headers = [])
{
if ($type == 'GET') {
$data = [
'query' => $params
];
} elseif ($type == 'FILE') {
$type = 'POST';
$data = [
'multipart' => $params // TODO implements later
];
} else {
$data = [
'json' => $params
];
}
if (!empty($headers)) {
$data['headers'] = $headers;
}
$data['headers']['X-REAL-IP'] = $_SERVER['REMOTE_ADDR'];
$data['headers']['User-Agent'] = $_SERVER['HTTP_USER_AGENT'];;
$data['headers']['X-Platform'] = 'web';
try {
$response = $this->client->request(
$type,
$url,
$data
);
if (in_array($response->getStatusCode(), ['200', '403', '404'])) {
return json_decode($response->getBody());
}
return false;
} catch (RequestException $re) {
if (in_array($re->getResponse()->getStatusCode(), ['403', '404', '422'])) {
return json_decode($re->getResponse()->getBody());
}
return json_decode($re->getResponse()->getBody());
} catch (Exception $e) {
return false;
}
}
}
when i want to send a post request it would be like this
$response = (new Api())->post('index.php/',[
'email'=> 'admin#admin.com',
'password' => '123456'
]);
now it will send a post request to index.php and send email and password data i hope it would be helpful
These are my controllers
<?php
public static function getAccessToken()
{
$url = 'http://api.tech/oauth/authenticate';
$query = [
'grant_type' => 'client_credentials',
'client_id' => 'E3PuC',
'client_secret' => 'IhvkpkvMdAL7gqpL',
'scope' => 'bookings.read,images.create,images.read,images.update,locations.read,rates.read,rates.update,reports.read,reviews.read,rooms.create,rooms.delete,properties.read',
];
$client = new Client();
$response = $client->get($url, ['query' => $query]);
$content = json_decode($response->getBody()->getContents());
if ($content) {
return $content->access_token;
} else {
return null;
}
}
public function getReviews()
{
$client = new Client();
$access_token = $this->getAccessToken();
$url = 'http://api.tech/hotels/88244/reviews';
$query = [
'access_token' => $access_token,
];
$response = $client->get($url, ['query' => $query]);
$content = json_decode($response->getBody()->getContents());
if ($content->status == 'success') {
// return $content->access_token;
return $content->data;
// return $response;
} else {
return null;
}
}
public function index()
{
$content = $this->getReviews();
return view('channel.channel', [
'content' => $content
]);
}
When i try to output the content in my blade as a link, it says ---
htmlspecialchars() expects parameter 1 to be string, array given
and this is my blade file
This
It also throws an error when i try to output it like thus
{{$content}}
Please How can i solve the error
My question isn't a duplicate cause once i dd it shows an array and i want a link to show the array on a different page
Try Using:
{! $content !}
Or Use:
#json($content)
i trying to post data as Async with using Guzzle 6(latest ver)
$client = new Client();
$request = $client->postAsync($url, [
'json' => [
'company_name' => 'update Name'
],
]);
but i am not getting any request form Guzzle like post request on terminal
Because it's a promise, you need to put then
and the promise will not called unless you put $promise->wait()
This is a simple post request using postAsync based on your question:
$client = new Client();
$promise = $client->postAsync($url, [
'json' => [
'company_name' => 'update Name'
],
])->then(
function (ResponseInterface $res){
$response = json_decode($res->getBody()->getContents());
return $response;
},
function (RequestException $e) {
$response = [];
$response->data = $e->getMessage();
return $response;
}
);
$response = $promise->wait();
echo json_encode($response);
Have you tried to send the request?
http://guzzle.readthedocs.org/en/latest/index.html?highlight=async
$client = new Client();
$request = new Request('POST', $url, [
"json" => [
'company_name' => 'update Name']
]);
$promise = $client->sendAsync($request)->then(function ($response) {
echo 'I completed! ' . $response->getBody();
});
$promise->wait();
Guzzle 6 has very little practical examples/documentation for developers to refer. I am sharing an example on how to use postAsync and Pool object. This allows concurrent async requests using guzzle 6. ( I was not able to find a direct example and spent 2 days to get working code )
function postInBulk($inputs)
{
$client = new Client([
'base_uri' => 'https://a.b.com'
]);
$headers = [
'Authorization' => 'Bearer token_from_directus_user'
];
$requests = function ($a) use ($client, $headers) {
for ($i = 0; $i < count($a); $i++) {
yield function() use ($client, $headers) {
return $client->postAsync('https://a.com/project/items/collection', [
'headers' => $headers,
'json' => [
"snippet" => "snippet",
"rank" => "1",
"status" => "published"
]
]);
};
}
};
$pool = new Pool($client, $requests($inputs),[
'concurrency' => 5,
'fulfilled' => function (Response $response, $index) {
// this is delivered each successful response
},
'rejected' => function (RequestException $reason, $index) {
// this is delivered each failed request
},
]);
$pool->promise()->wait();
}
most likely you'll need to call wait();
$request->wait();
I am trying to use Guzzle pool in PHP. But I am having difficulty in dealing with ASYNC request. Below is the code snippet.
$client = new \GuzzleHttp\Client();
function test()
{
$client = new \GuzzleHttp\Client();
$request = $client->createRequest('GET', 'http://l/?n=0', ['future' => true]);
$client->send($request)->then(function ($response) {
//echo 'Got a response! ' . $response;
return "\n".$response->getBody();
});
}
$res = test();
var_dump($res); // echoes null - I know why it does so but how to resolve the issue.
Does anybody how can I make function wait and get the correct result.
If you could return it it wouldn't be async in code style. Return the promise and unwrap it on the outside.
function test()
{
$client = new \GuzzleHttp\Client();
$request = $client->createRequest('GET', 'http://l/?n=0', ['future' => true]);
// note the return
return $client->send($request)->then(function ($response) {
//echo 'Got a response! ' . $response;
return "\n".$response->getBody();
});
}
test()->then(function($body){
echo $body; // access body here inside `then`
});
One other example I wanted to share using guzzle 6, postAsync and Pool.
function postInBulk($inputs)
{
$client = new Client([
'base_uri' => 'https://a.b.com'
]);
$headers = [
'Authorization' => 'Bearer token_from_directus_user'
];
$requests = function ($a) use ($client, $headers) {
for ($i = 0; $i < count($a); $i++) {
yield function() use ($client, $headers) {
return $client->postAsync('https://a.com/project/items/collection', [
'headers' => $headers,
'json' => [
"snippet" => "snippet",
"rank" => "1",
"status" => "published"
]
]);
};
}
};
$pool = new Pool($client, $requests($inputs),[
'concurrency' => 5,
'fulfilled' => function (Response $response, $index) {
// this is delivered each successful response
},
'rejected' => function (RequestException $reason, $index) {
// this is delivered each failed request
},
]);
$pool->promise()->wait();
}