I am using guzzle to call to Street View Image API from my laravel application. I want to be able to retrieve the status code from my request as explained in the end of the docs.
I specifically want to catch the:
{
"status" : "ZERO_RESULTS"
}
here is my Guzzle code from my controller (am including guzzle correctly in namespace). The address in the get call is generating a "Sorry we have no imagery here":
$client = new Client();
$res = $client->get('https://maps.googleapis.com/maps/api/streetview?size=800x600&location=78.648401,14.194336&key=my-API-key&fov=120&heading=90');
$res->getStatusCode();
dd($res->getBody());
BUT. As u can see in the pic the meta-data is empty. When I dd the $res->getStatusCode(); it gives me a 200.
How do I catch the ZERO_RESULT ?
Sir, please note that there are two different endpoints; one for metadata and one for image retrieval. You only used the image retrieval. Here is an example method checking if a given coordinate has an image
private function coordinateHasImage($coordinate)
{
$client = new Client();
$res = $client->get( 'https://maps.googleapis.com/maps/api/streetview/metadata?size=600x300&location=' . $coordinate . '&fov=90&heading=235&pitch=10&key=YOUR_KEY_HERE');
return json_decode($res->getBody()->getContents())->status == "OK";
}
Related
I am trying to send an image to my laravel APIs from postman.
I added the file(280KB) on the request body like so:
On the server side I am trying to catch the file and save it, but it returns that there is no file.
public function uploadImage(Request $request)
{
//returns false
$request->hasFile('profile_image');
//returns profile_image is required
$request->validate(['profile_image' => 'required|image:jpeg,png,jpg,gif,svg']);
//returns null
$request->file('profile_image');
}
I am calling the function from api.php like so:
Route::put('/creators/{id}/upload_image',[CreatorController::class,'uploadImage']);
I thought maybe I shouldn't put the file in Body, but couldn't find an alternative.
Also I am finally trying to send the file from a vue client, but I had the same Issue when trying to send the file from there.
How do I get the server to catch the file?
Edit: adjusted typo in example code
new code sample
I changed the method from put to post, since I wanted to test the post method as well. I also tried _method put in postman beforehand.
Here is the code sample on Laravel:
//api.php
Route::put('/creators/{id}/upload_image',[CreatorController::class,'uploadImage']);
//CreatorController.php
public function uploadImage(Request $request)
{
if($request->hasFile('profile_image')){
$allowedfileExtension=['gif','jpg','png'];
$file = $request->file('profile_image');
$extension = $file->getClientOriginalExtension();
if(in_array($extension,$allowedfileExtension)) {
$path = $file->store('public/images/profile');
$path_url = $path;
return ["image_url" => $path_url, "image" => $request->file('profile_image')];
}
return false;
}
}
The $request->hasFile('profile_image') returns true, but then $request->file('profile_image') returns null, failing to save the image.
My vue client side code (if it might turn useful):
if(this.profile_image != null){
let data = new FormData();
data.append('profile_image', this.profile_image)
axios
.post('http://localhost:8000/api/creators/'+uid+'/upload_image', data, head)
.then(
response => (
//successfully receives the image_url
this.creatorData.image_url = response.data.image_url,
console.log(response.data)
),
)
.catch(
error => (
localStorage.setItem('error', error),
console.log(error.response)
),
this.loading = false,
)
}
The client side actually receives the "image_url" but the image is not saved on laravel.
laravel dose not support put method directly.
you must use post method then pass _method to your laravel project
like this picture
I tried update my image, but it isn´t update.
I have the method upload , it works in a store method
private function upload($image)
{
$path_info = pathinfo($image->getClientOriginalName());`
$post_path = 'images/post';
$rename = uniqid() . '.' . $path_info['extension'];
$image->move(public_path() . "/$post_path", $rename);
return "$post_path/$rename";
}
I tried update the new image, but the message update successfully apears but not update
public function update(Request $request, Car $car)
{
if (!empty($request->file('image_url'))) {
$url_image = $this->upload($request->file('image_url'));
$car->image_url = $url_image;
}
$res = $car->save();
if ($res) {
return response()->json(['message' => 'Car update succesfully']);
}
return response()->json(['message' => 'Error to update car'], 500);
}
La actualización es correcta pero en la BDD no actualiza
Imagen de actualización con POSTMAN
Try changing the method in postman to POST and add this query string parameter to the URL: its name is _method and the value is PUT.
Your API consumers will call the endpoint in this way but you will keep the route definition with the PUT verb. Read more about it here
The request PUT doesnt have a body like the method POST as of the RFCs (Something with the Content-Length, dont remember correctly).
Even if your API can handle PUT methods with body, your postman will try to send the file in the query field (URL) and that will mostly break the file. You can check the URL called by postman in the request Headers.
Laravel has a workaround for this, you send the parameter _method=PUT in a POST request and the router will handle it as a PUT request (if you declared it so).
I have a guitar lessons site where there is an exercises table. The original developers placed some functions in ExercisePresenter to retrieve other bits of data associated with an exercise, such as its url.
Here is a function in ExercisePresenter that returns url for an exercise:
public function url()
{
return '/guitar-lesson-ex/' . $this->urlName() . '/' . $this->id;
}
So now I am creating an event on new exercise created so I can use pusher notifications. In the EventServiceProvider I have this:
public function boot(DispatcherContract $events)
{
parent::boot($events);
Exercise::created(function ($exercise) {
// need to update lesson difficulty
$lesid = $exercise->lesson_id;
$les = \App\Lesson::find($lesid);
$dif = $les->difficulty();
DB::table('lessons')
->where('id', $lesid)
->update(['difficulty' => $dif]);
// lets trigger NewExerciseEvent to send pusher notifications
$url = $exercise->url;
event(new NewExerciseEvent($message));
});
}
I thought in above code $url = $exercise->url; would work since I see $exercise->url used successfully in exercise views. But it is returning $url as null. Now, there is no url column in the exercise database, so I figure somehow when $exercise->url; is used in a view, laravel is figuring out that the ExercisePresenter is able to return the url.
I am debugging through PHPStorm, but when I get to $url = $exercise->url; and step in, I am just taken through various bits of laravel code that looks for a method, etc. I am not savvy enough with laravel to figure out what it is doing here differently than in the view (too bad we can't debug views...), but each time I try this $url is returned as null.
Any idea how to get this to work properly in my EventServiceProvider?
Thanks!
Figured it out:
$url = $exercise->present()->url;
I had been searching for how to use presenters but having just read (Laravel View Presenters From Scratch), everything is clear!
Sorry for posting prematurely.
I am trying to download files from Google Drive using PHP client v2.0 with Drive API V3.
Is it possible to retrieve file's body and metadata in a single HTTP request?
Supplying 'alt=media' to ->files->get() returns GuzzleHttp\Psr7\Response upon which I can run ->getBody()->__toString().
If I do not provide 'alt=media', then Google_Service_Drive_DriveFile is returned that has all the metadata, but does not have body.
Question.
Is it possible to get both metadata and body in the same request?
Try something like this:
<?php
// Look at this first: https://developers.google.com/api-client-library/php/auth/web-app
require_once __DIR__ . '/vendor/autoload.php';
//change to your timezone
date_default_timezone_set('Pacific/Auckland');
$client = new Google_Client();
$client->setAuthConfig('client_secrets.json');
$client->setAccessType('offline');
$client->setApprovalPrompt('force');
$client->setIncludeGrantedScopes(true);
//change scopes to the ones you need
$client->addScope(Google_Service_Drive::DRIVE_FILE, Google_Service_Drive::DRIVE_APPDATA, Google_Service_Drive::DRIVE, Google_Service_Drive::DRIVE_METADATA);
$accessToken = json_decode(file_get_contents('credentials.json'), true);
$client->setAccessToken($accessToken);
//Refresh the token if it's expired. Google expires it after an hour so necessary
if ($client->isAccessTokenExpired()) {
$client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
file_put_contents('credentials.json', json_encode($client->getAccessToken()));
}
$service = new Google_Service_Drive($client);
$results = $service->files->listFiles($optParams);
$fileId = 'yourfileid;
$file = $service->files->get($fileId, array('alt' => 'media'));
file_put_contents("hello.pdf",$file->getBody());
?>
I'm having a simple problem while retrieving user's contact's images. So I make a request to
$url = 'https://www.google.com/m8/feeds/contacts/default/full?alt=json&max-results=9999&oauth_token=' . $accessToken;
And then I get huge JSON from which I have extracted full name and email. Then I tried getting contact's image, and haven't had any success.
I get with all contacts, and everyone has following structure:
entry [id, updated, category, title, link, gd$email].
In the link section, I got four links, of which first two are some kind of link to an image content but I cannot retrieve it.
Any body had any success in doing this kind of work !?
Tnx alot!
BTW: If some data from my case is missing, please report and I'll add it too!
EDIT: I have also tried to reach the image with URL
http://profiles.google.com/s2/photos/profile/" + userid + "?sz=" + size;
but the problem is I cannot get userId from contacts JSON.
You must call the photo endpoint and append to it a valid access token as a query parameter.
Example:
https://www.google.com/m8/feeds/photos/media/name.surname%40gmail.com/0?access_token=ACCESS_TOKEN
Docs:
https://developers.google.com/google-apps/contacts/v3/#contact_photo_management
Make a request again if the mentioned tags are available as given below.
$add = new Google_HttpRequest("https://www.google.com/m8/feeds/contacts/default/full?alt=json&v=3.0&max-results=500&access_token='.$token->access_token");
$add->setRequestMethod("GET");
$add->setRequestHeaders(array('GData-Version' => '3.0', 'content-type' => 'application/atom+xml; charset=UTF-8; type=feed'));
$submit = $client->getIo()->authenticatedRequest($add);
$sub_response = $submit->getResponseBody();
$temp = json_decode($sub_response, true);
foreach ($temp['feed']['entry'] as $image) {
$google_contact_id = $image['link'][2]['href'];
if (isset($image['link'][0]['href'])) {
$photo = new Google_HttpRequest($image['link'][0]['href']);
$photo_val = $client->getIo()->authenticatedRequest($photo);
$photo_return = $photo_val->getResponseBody();
$imgData = base64_encode($photo_return);
$pro_image = 'data:image/jpeg;base64, ' . $imgData . '';
}
}