Post Multipart and Json together with Guzzle in Laravel - laravel

I'm trying to POST multipart and json data with Guzzle to build my apps with Phonegap Build API. I've tried many adjustment but still got error results. Here's the latest function I'm using:
public function testBuild(Request $request)
{
$zip_path = storage_path('zip/testing.zip');
$upload = $this->client->request('POST', 'apps',
['json' =>
['data' => array(
'title' => $request->title,
'create_method' => 'file',
'share' => 'true',
'private' => 'false',
)],
'multipart' =>
['name' => 'file',
'contents' => fopen($zip_path, 'r')
]
]);
$result = $upload->getBody();
return $result;
}
This is my the correct curl format that has success result from the API, but with file I have in my desktop:
curl -F file=#/Users/dedenbangkit/Desktop/testing.zip
-u email#email.com
-F 'data={"title":"API V1 App","version":"0.1.0","create_method":"file"}'
https://build.phonegap.com/api/v1/apps

As mentioned before, you cannot use multipart and json together.
In your curl example it's just a multipart form, so use the same in Guzzle:
$this->client->request('POST', 'apps', [
'multipart' => [
[
'name' => 'file',
'contents' => fopen($zip_path, 'r'),
],
[
'name' => 'data',
'contents' => json_encode(
[
'title' => $request->title,
'create_method' => 'file',
'share' => 'true',
'private' => 'false',
]
),
]
]
]);

Related

Laravel Phpunit testing a request that take give output based on the request

I'm still new to laravel and I have a simple app and aSo I have a route that will store data based on the request in my controller.
public funtion store(Request $request, $id){
if ($request->has('work_experiences')) {
WorkExperience::create([
'user_id' => $user->id,
'position' => $request->work_experiences['position'],
'company' => $request->work_experiences['company'],
'start_date' => $request->work_experiences['start_date'],
'end_date' => $request->work_experiences['end_date'],
]);
}
if ($request->has('education')) {
Education::create([
'user_id' => $user->id,
'degree' => $request->education['degree'],
'university' => $request->education['university'],
'start_date' => $request->education['start_date'],
'end_date' => $request->education['end_date'],
]);
}
if ($request->has('job_interests')) {
JobInterest::create([
'user_id' => $user->id,
'job_position' => $request->job_interests['position'],
]);
}}
}
and in my test
public function test_authenticated_user_can_edit_education_profile()
{
$this->withoutExceptionHandling();
$user = User::factory()->create();
$this->actingAs($user);
$response = $this->post('/candidate' . '/' . $user->id, [
'user_id' => $user->id,
'position' => 'position',
'company' => 'company',
'start_date' => Carbon::now(),
'end_date' => Carbon::now(),
]);
$this->assertCount(1, WorkExperience::all());
}
when I run the test, the assertCount seems to fail because the response didn't work/insert the data to DB. where do I do wrong?
Well, the test is right.
It should fail because there is no work_experiences key in your request data.
The test request should look like:
$response = $this->post('/candidate' . '/' . $user->id, [
'work_experiences' => [
'user_id' => $user->id,
'position' => 'position',
'company' => 'company',
'start_date' => Carbon::now(),
'end_date' => Carbon::now(),
]
]);
So your data should go under a work_experiences key such that $request->has('work_experiences') returns true and executes the WorkExperience::create() statement.
Currently your endpoint only allows for a single "work experience" to be created. Seeing that you've named it work_experiences I assume you'd want to pass in an array/collection of "work experiences" - but that won't work with the current implementation; you'll have to loop over them instead - something like this:
if ($request->has('work_experiences')) {
foreach ($request->input('work_experiences') as $experience) {
WorkExperience::create([
'user_id' => $request->user()->id,
'position' => $experience['position'],
'company' => $experience['company'],
'start_date' => $experience['start_date'],
'end_date' => $experience['end_date'],
]);
}
}
And then your test should look something like this:
$response = $this->post('/candidate' . '/' . $user->id, [
'work_experiences' => [
[
'user_id' => $user->id,
'position' => 'position',
'company' => 'company',
'start_date' => Carbon::now(),
'end_date' => Carbon::now(),
],
// more "work experiences"
]
]);

Laravel: Add custom data to resource

First I get the translator by his id using this line of code
$translator = Translator::where('id', $translator_id)->first();
Then I send a notification to him by this code:
$response = Http::withHeaders([
'Authorization' => 'key=myKey',
'Content-Type' => 'application/json'
])->post('https://fcm.googleapis.com/fcm/send', [
"notification" => [
"title" => "title",
"body" => "body",
],
"data" => [
"title" => "title",
"body" => "body",
],
"to" => $token,
]);
Everything works fine but my problem is that when I return the TranslatorResource I want to add the notification response to it, so I do this in my controller
$resource = new TranslatorResource($translator);
$resource->notif = $response;
return $resource;
And in TranslatorResource I have this code:
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'phone' => $this->phone,
'cv' => $this->cv,
'specialization' => $this->specialization,
'tr_languages' => $this->tr_languages,
'all_languages' => $this->all_languages,
'isVerified' => $this->isVerified == 0 ? false : true,
'isActive' => $this->isActive == 0 ? false : true,
'completed_orders' => $this->completed_orders,
'canceled_orders' => $this->canceled_orders,
'rejected_orders' => $this->rejected_orders,
'current_orders' => $this->current_orders,
'isTranslator' => true,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
];
}
But I only get the data specified in the resource, the notif key isn't added, anyone know how to add this data to my resource when I return it ?
You can use additional method provided by laravel.
return (new TranslatorResource($translator))->additional(['notif ' => $response]);
Reference: Eloquent: API Resources
You can look for the section Adding Meta Data When Constructing Resources.

laravel client api with guzzle

I'm using API from RapidAPI face verification https://rapidapi.com/HiBrainy/api/face-recognition4 and
I have difficulty using the API
this example code PHP from RapidAPI
$client = new http\Client;
$request = new http\Client\Request;
$body = new http\Message\Body;
$body->addForm(array(
'photo1' => array(
'value' => 'image2.jpg',
'data' => 'data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAQ=='
),
'photo2' => array(
'value' => 'image2.jpg',
'data' => 'data:image/jpeg;base64,/9j/4AAQSkZ630QAMXaf//Z'
)
), NULL);
$request->setRequestUrl('https://face-recognition4.p.rapidapi.com/FaceVerification');
$request->setRequestMethod('POST');
$request->setBody($body);
$request->setHeaders(array(
'x-rapidapi-host' => 'face-recognition4.p.rapidapi.com',
'x-rapidapi-key' => $my_api_key,
'content-type' => 'multipart/form-data'
));
$client->enqueue($request)->send();
$response = $client->getResponse();
echo $response->getBody();
I applied to laravel with the guzzle package
my code
try {
...other code...
$client = new Client();
$response = $client->post('https://face-recognition4.p.rapidapi.com/FaceVerification', [
'headers' => [
'x-rapidapi-host' => 'face-recognition4.p.rapidapi.com',
'x-rapidapi-key' => $my_api_key,
'content-type' => 'multipart/form-data'
],
'multipart' => [
[
'name' => 'photo1',
'contents' => $image1,
'filename' => 'image1.jpg'
],
[
'name' => 'photo2',
'contents' => $image2,
'filename' => 'image2.jpg'
]
]
]);
}catch (\Exception $error){
dd($error);
}
I got error
#message: """
Client error: `POST https://face-recognition4.p.rapidapi.com/FaceVerification` resulted in a `400 Bad Request` response:
{"type":"https://tools.ietf.org/html/rfc7231#section-6.5.1","title":"One or more validation errors occurred.","status":4 (truncated...)
You should consider removing your API key from the code you're sharing
Try to have a look at the raw request to have further details and verify that your request have been formatted correctly

CakePHP IntegrationTestTrait Post Returns HTTP Status 302

I am trying to perform a simple test from posting data onto a table in CakePHP. I am using IntegrationTestTrait.
I am not able to POST data successfully. My $this->_response is yielding:
object(Cake\Http\Response) {
'status' => (int) 302,
'contentType' => 'text/html',
'headers' => [
'Content-Type' => [
(int) 0 => 'text/html; charset=UTF-8'
],
'Location' => [
(int) 0 => '/'
]
],
'file' => null,
'fileRange' => [],
'cookies' => object(Cake\Http\Cookie\CookieCollection) {
[protected] cookies => []
},
'cacheDirectives' => [],
'body' => ''
}
My TestCase code looks like this:
public function testAddStudentSuccess() {
$data = [
'last_name' => 'Test',
'first_name' => '05',
'middle_name' => '',
'preferred_name' => '',
'id_number' => '10005',
'contact_id' => '',
'users[0][email]' => 'test_05#email.com'
];
//Test Pre-condition
$query = $this->Students->find('all')->where([
'id_number' => $data['id_number']
]);
$this->post('/students/add', $data);
debug($this->_response);
}
I debugged further and found that the Test is not even invoking the Controller add() functions.
I thought the issue was an Authentication Issue is I tried following all the authentication work arounds prescribed in the documentation. However, it did not work.
Does anyone know how I can debug this further? Any help is appreciated. Thank you.

Call to undefined method Chatkit\Chatkit::sendMultipartMessage()

I have chatkit version 1.1 installed. I used sendMessage() method to send text message. Now i want to use sendMultipartMessage() method but got "Call to undefined method Chatkit\Chatkit::sendMultipartMessage()". sendSimpleMessage is not working as well.
Chatkit Version
"pusher/pusher-chatkit-server": "^1.1",
"pusher/pusher-php-server": "^3.4",
public function SendMessage(Request $request){
//return $request->all();
$user = $this->LoggedInUser();
$chatkit = $this->Authenticate();
$room_id = Session::get($user->username);
$chatkit->sendMultipartMessage([
'sender_id' => $user->username,
'room_id' => $room_id,
//'text' => $request->message,
'parts' => [
[ 'type' => 'image/png',
'url' => 'https://placekitten.com/200/300' ],
[ 'type' => 'text/plain',
'content' => 'simple text' ],
[ 'type' => 'binary/octet-stream',
'file' => file_get_contents('https://placekitten.com/200/300'),
'name' => 'kitten',
'customData' => [ "some" => "json" ],
'origin' => 'http://example.com'
]
]
]);
Pusher Authentication:
public function Authenticate(){
return new Chatkit([
'instance_locator' => config('services.chatkit.locator'),
'key' => config('services.chatkit.key'),
]);
}
You will need to upgrade your Chatkit library. The method you are using was introduced in v1.2. See the changelog for details.

Resources