GET data from Couchdb using Guzzle in php - php

I'm getting data from Couchdb to PHP using Guzzle library. Now I fetch data in POST format like this:
But I need response like this:
{
"status": 200,
"message": "Success",
"device_info": {
"_id": "00ab897bcb0c26a706afc959d35f6262",
"_rev": "2-4bc737bdd29bb2ee386b967fc7f5aec9",
"parent_id": "PV-409",
"child_device_id": "2525252525",
"app_name": "Power Clean - Antivirus & Phone Cleaner App",
"package_name": "com.lionmobi.powerclean",
"app_icon": "https://lh3.googleusercontent.com/uaC_9MLfMwUy6pOyqntqywd4HyniSSxmTfsiJkF2jQs9ihMyNLvsCuiOqrNxNYFq5ko=s3840",
"last_app_used_time": "12:40:04",
"last_app_used_date": "2019-03-12"
"bookmark": "g1AAAABweJzLYWBgYMpgSmHgKy5JLCrJTq2MT8lPzkzJBYorGBgkJllYmiclJxkkG5klmhuYJaYlW5paphibppkZmRmB9HHA9BGlIwsAq0kecQ",
"warning": "no matching index found, create an index to optimize query time"
} }
I only remove "docs": [{}] -> Anyone know I remove this ?
check My code:
$response = $client->post(
"/child_activity_stat/_find",
[GuzzleHttp\RequestOptions::JSON => ['selector' => ['parent_id' => ['$eq' => $userid], 'child_device_id' => ['$eq' => $deviceid]],]]
);
if ($response->getStatusCode() == 200) {
$result = json_decode($response->getBody());
$r = $response->getBody();
json_output(200, array(
'status' => 200,
'message' => 'Success',
"device_info" => $result
));
}

You just need to modify your data structure.
NOTE: Maybe you should add a limit of 1 if you want to only get one document. You will also need to validate that the result['docs'] is not empty.
Example:
<?php
$response = $client->post(
"/child_activity_stat/_find",
[GuzzleHttp\ RequestOptions::JSON => ['selector' => ['parent_id' => ['$eq' => $userid], 'child_device_id' => ['$eq' => $deviceid]], ]]
);
if ($response->getStatusCode() == 200) {
// Parse as array
$result = json_decode($response->getBody(),true);
// Get the first document.
$firstDoc = $result['docs'][0];
// Remove docs from the response
unset($result['docs']);
//Merge sanitized $result with $deviceInfo
$deviceInfo = array_merge_recursive($firstDoc,$result);
json_output(200, array(
'status' => 200,
'message' => 'Success',
"device_info" => $deviceInfo
));
}

In couchdb use PUT request is used to edit or to add data and DELETE remove data
$client = new GuzzleHttp\Client();
// Put request for edit
$client->put('http://your_url', [
'body' => [
'parent_id' => ['$eq' => $userid],
'child_device_id' => ['$eq' => $deviceid]
],
'allow_redirects' => false,
'timeout' => 5
]);
// To delete
$client->delete('htt://my-url', [
'body' = [
data
]
]);

Related

How to Post with request to create new data from form using guzzle - Laravel

I have this function in my controller:
public function store(Request $request)
{
$client = new Client();
$headers = [
'Authorization' => $token,
'Content-Type' => 'application/json'
];
$body = '{
"DocNo": 1167722,
"AOQty": 0,
"TL": [
{
"Key": 11678,
"Code": "Screw Hex",
"Detail": true,
"DTL": []
}
]
}';
$request = new Psr7Request('POST', 'http://example.com/api/Order/', $headers, $body);
$res = $client->sendAsync($request)->wait();
echo $res->getBody();
}
that will store the data to the external API
but i want to POST the data from a form
when i work with normal routing (not API) i usually do this:
'Key' => $request->Key,
how can i achieve the above with guzzle?
currently when i submit the form from the view it will submit the above function (store) as static data, how can i submit the data from the form?
UPDATE:
When i use Http as showing below:
$store = Http::withHeaders([
'Content-Type' => 'application/json',
'Authorization' => $token,
])->post('http://example.com/api/Order/', [
'DocNo' => "SO-000284",
'AOQty' => 0.0,
'TL[Key]' => 11678,
'TL[Code]' => "SCREW HEX CAPHEAD 6X30MM",
'TL[Detail]' => true,
'TL[DTL]' => [],
]);
echo $store;
it will store everything before [TL] Array, it won't store anything of:
'TL[Key]' => 11678,
'TL[Code]' => "SCREW HEX CAPHEAD 6X30MM",
'TL[Detail]' => true,
'TL[DTL]' => [],
am i doing it wrong?
You can use HTTP client provided by Laravel.
$response = Http::withToken($token)->post('http://example.com/users', $request->only(['request_param_1', 'request_param_2']));
Or
$data = [];
$data['param_1'] = $request->get('param_1');
$data['param_2'] = $request->get('param_2');
$data['param_3'] = $request->get('param_3');
$response = Http::withToken($token)->post('http://example.com/users', $data);
Edit
$data = [
'DocNo' => "SO-000284",
'AOQty' => 0.0,
'TL' => [
'key' => 11678,
'Code' => "SCREW HEX CAPHEAD 6X30MM",
'Detail' => true,
'DTL' => [],
]
];
SOLUTION:
Using Http client:
'TL' => array ([
'Dtl' => "",
'Code' => "Screw Hex",
'IsDetail' => true,
"DTL" => [],
])
]);

How we can insert header and footer in google docs with google docs api using PHP code

I want to insert header and footer in my google docs with google docs api in PHP code. I am doing it like this-
$requests = new Google_Service_Docs_Request(array(
'createHeader' => [
'type' => 'TITLE',
'sectionBreakLocation' => [
'index' => 0
],
],
)),
$batchUpdateRequest = new Google_Service_Docs_BatchUpdateDocumentRequest(array(
'requests' => $requests
));
$response = $service->documents->batchUpdate($documentId, $batchUpdateRequest);
but, i am getting this error-
PHP Fatal error: Uncaught Google\Service\Exception: {
"error": {
"code": 400,
"message": "Invalid value at 'requests[5].create_header.type' (type.googleapis.com/google.apps.docs.v1.HeaderFooterType), \"TITLE\"",
"errors": [
{
"message": "Invalid value at 'requests[5].create_header.type' (type.googleapis.com/google.apps.docs.v1.HeaderFooterType), \"TITLE\"",
"reason": "invalid"
}
],
"status": "INVALID_ARGUMENT",
"details": [
{
"#type": "type.googleapis.com/google.rpc.BadRequest",
"fieldViolations": [
{
"field": "requests[5].create_header.type",
"description": "Invalid value at 'requests[5].create_header.type' (type.googleapis.com/google.apps.docs.v1.HeaderFooterType), \"TITLE\""
}
]
}
]
}
}
Please help me out with this, That how we can insert texts in header and footer in google docs using PHP.
In your script, how about the following modification?
Create header:
I thought that the reason of the error message of Invalid value at 'requests[5].create_header.type' (type.googleapis.com/google.apps.docs.v1.HeaderFooterType), \"TITLE\"" is due to 'type' => 'TITLE',. But when I saw your script, $requests is required to be an array. So how about the following modification?
From:
$requests = new Google_Service_Docs_Request(array(
'createHeader' => [
'type' => 'TITLE',
'sectionBreakLocation' => [
'index' => 0
],
],
)),
$batchUpdateRequest = new Google_Service_Docs_BatchUpdateDocumentRequest(array(
'requests' => $requests
));
To:
$requests = new Google_Service_Docs_Request(array(
'createHeader' => [
'type' => 'DEFAULT',
'sectionBreakLocation' => [
'index' => 0
],
],
));
$batchUpdateRequest = new Google_Service_Docs_BatchUpdateDocumentRequest(array(
'requests' => array($requests)
));
Create footer:
In this case, please replace createHeader to createFooter in the above $requests.
Note:
As additional information, when you want to use the first page header and footer, you can use the following request.
$requests = new Google_Service_Docs_Request(array(
'updateDocumentStyle' => [
'documentStyle' => [
'useFirstPageHeaderFooter' => true,
],
'fields' => 'useFirstPageHeaderFooter',
],
));
References:
CreateHeaderRequest
CreateFooterRequest

Guzzle: Sending POST with Nested JSON to an API

I am trying to hit a POST API Endpoint with Guzzle in PHP (Wordpress CLI) to calculate shipping cost. The route expects a RAW JSON data in the following format:
{
"startCountryCode": "CH"
"endCountryCode": "US",
"products": {
"quantity": 1,
"vid": x //Variable ID
}
}
Link to the API I am consuming: https://developers.cjdropshipping.com/api2.0/v1/logistic/freightCalculate
$body = [
"endCountryCode" => "US",
"startCountryCode" => "CN",
"products" => [
'vid' => $vid,
'quantity' => 1
],
];
$request = $this->client->request(
'POST', 'https://developers.cjdropshipping.com/api2.0/v1/logistic/freightCalculate',
[
'headers' => [
'CJ-Access-Token' => $this->auth_via_cj(), // unnecessary, no auth required. Ignore this header
],
'body' => json_encode( $body )
],
);
I've also tried using 'json' => $body instead of the 'body' parameter.
I am getting 400 Bad Request error.
Any ideas?
Try to give body like this.
"json" => json_encode($body)
I spent so many hours on this to just realise that products is actually expecting array of objects. I've been sending just a one-dimensional array and that was causing the 'Bad Request' error.
In order to fix this, just encapsulate 'vid' and 'quantity' into an array and voila!
You don't need to convert data in json format, Guzzle take care of that.
Also you can use post() method of Guzzle library to achieve same result of request. Here is exaple...
$client = new Client();
$params['headers'] = ['Content-Type' => 'application/json'];
$params['json'] = array("endCountryCode" => "US", "startCountryCode" => "CN", "products" => array("vid" => $vid, "quantity" => 1));
$response = $client->post('https://developers.cjdropshipping.com/api2.0/v1/logistic/freightCalculate', $params);

PHP / Docusign - Verify HMAC signature on completed event

I'm trying to secure my callback url when completed event is triggered.
My Controller:
public function callbackSubscriptionCompleted(
int $subscriptionId,
DocusignService $docusignService,
Request $request
) {
$signature = $request->headers->get("X-DocuSign-Signature-1");
$payload = file_get_contents('php://input');
$isValid = $docusignService->isValidHash($signature, $payload);
if (!$isValid) {
throw new ApiException(
Response::HTTP_BAD_REQUEST,
'invalid_subscription',
'Signature not OK'
);
}
return new Response("Signature OK", Response::HTTP_OK);
}
My DocusignService functions:
private function createEnvelope(Company $company, Subscription $subscription, LegalRepresentative $legalRepresentative, Correspondent $correspondent, $correspondents) : array
{
// ...
$data = [
'disableResponsiveDocument' => 'false',
'emailSubject' => 'Your Subscription',
'emailBlurb' => 'Subscription pending',
'status' => 'sent',
'notification' => [
'useAccountDefaults' => 'false',
'reminders' => [
'reminderEnabled' => 'true',
'reminderDelay' => '1',
'reminderFrequency' => '1'
],
'expirations' => [
'expireEnabled' => 'True',
'expireAfter' => '250',
'expireWarn' => '2'
]
],
'compositeTemplates' => [
[
'serverTemplates' => [
[
'sequence' => '1',
'templateId' => $this->templateId
]
],
'inlineTemplates' => [
[
'sequence' => '2',
'recipients' => [
'signers' => [
[
'email' => $legalRepresentative->getEmail(),
'name' => $legalRepresentative->getLastname(),
'recipientId' => '1',
'recipientSignatureProviders' => [
[
'signatureProviderName' => 'universalsignaturepen_opentrust_hash_tsp',
'signatureProviderOptions' => [
'sms' => substr($legalRepresentative->getCellphone(), 0, 3) == '+33' ? $legalRepresentative->getCellphone() : '+33' . substr($legalRepresentative->getCellphone(), 1),
]
]
],
'roleName' => 'Client',
'clientUserId' => $legalRepresentative->getId(),
'tabs' => [
'textTabs' => $textTabs,
'radioGroupTabs' => $radioTabs,
'checkboxTabs' => $checkboxTabs
]
]
]
]
]
]
]
],
'eventNotification' => [
"url" => $this->router->generate("api_post_subscription_completed_callback", [
"subscriptionId" => $subscription->getId()
], UrlGeneratorInterface::ABSOLUTE_URL),
"includeCertificateOfCompletion" => "false",
"includeDocuments" => "true",
"includeDocumentFields" => "true",
"includeHMAC" => "true",
"requireAcknowledgment" => "true",
"envelopeEvents" => [
[
"envelopeEventStatusCode" => "completed"
]
]
]
];
$response = $this->sendRequest(
'POST',
$this->getBaseUri() . '/envelopes',
[
'Accept' => 'application/json',
'Content-Type' => 'application/json',
'Authorization' => 'Bearer ' . $this->getCacheToken()
],
json_encode($data)
);
}
public function isValidHash(string $signature, string $payload): bool
{
$hexHash = hash_hmac('sha256',utf8_encode($payload),utf8_encode($this->hmacKey));
$base64Hash = base64_encode(hex2bin($hexHash));
return $signature === $base64Hash;
}
I've created my hmac key in my Docusign Connect and i'm receiving the signature in the header and the payload but the verification always failed.
I've followed the Docusign documentation here
What's wrong ?
PS: Sorry for my bad english
Your code looks good to me. Make sure that you are only sending one HMAC signature. That way your hmacKey is the correct one.
As a check, I'd print out the utf8_encode($payload) and check that it looks right (it should be the incoming XML, no headers). Also, I don't think it should have a CR/NL in it at the beginning. That's the separator between the HTTP header and body.
Update
I have verified that the PHP code from the DocuSign web site works correctly.
The payload value must not contain either a leading or trailing newline. It should start with <?xml and end with >
I suspect that your software is adding a leading or trailing newline.
The secret (from DocuSign) ends with an =. It is a Base64 encoded value. Do not decode it. Just use it as a string.
Another update
The payload (the body of the request) contains zero new lines.
If you're printing the payload, you'll need to wrap it in <pre> since it includes < characters. Or look at the page source.
It contains UTF-8 XML such as
<?xml version="1.0" encoding="utf-8"?><DocuSignEnvelopeInformation xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.docusign.net/API/3.0"><EnvelopeStatus><RecipientStatuses><RecipientStatus><Type>Signer</Type><Email>larry#worldwidecorp.us</Email><UserName>Larry Kluger</UserName><RoutingOrder>1</RoutingOrder><Sent>2020-08-05T03:11:13.057</Sent><Delivered>2020-08-05T03:11:27.657</Delivered><DeclineReason xsi:nil="true" /><Status>Delivered</Status><RecipientIPAddress>5.102.239.40</RecipientIPAddress><CustomFields /><TabStatuses><TabStatus><TabType>Custom</TabType><Status>Active</Status><XPosition>223</XPosition><YPosition>744....
We've done some more testing, and the line
$payload = file_get_contents('php://input');
should be very early in your script. The problem is that a framework can munge the php://input stream so it won't work properly thereafter.
Note this page from the Symfony site -- it indicates that the right way to get the request body is:
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\ParameterBag;
$app->before(function (Request $request) {
$payload = $request->getContent();
hmac_verify($payload, $secret);
});
I would try to use the Symfony code instead of file_get_contents('php://input');

php full text search in elasticsearch

I have a json file which I looped through it and index it in elastic. and after that I want to be able to search through my data.
this is my json file :
https://github.com/mhndev/iran-geography/blob/master/tehran_intersection.json
which looks like :
{
"RECORDS":[
{
"first":{
"name":"ابن بابویه",
"slug":"Ibn Babawayh"
},
"second":{
"name":"میرعابدینی",
"slug":"Myrabdyny"
},
"latitude":"35.601605",
"longitude":"51.444208",
"type":"intersection",
"id":1,
"search":"ابن بابویه میرعابدینی,Ibn Babawayh Myrabdyny,ابن بابویه تقاطع میرعابدینی,Ibn Babawayh taghato Myrabdyny",
"name":"ابن بابویه میرعابدینی",
"slug":"Ibn Babawayh Myrabdyny"
},
...
]
}
when my query is : "mir", I expect my result to be records which has "mirabedini", "mirdamad", "samir", and every other word which contains this string.
but I just get words which are exactly "mir"
and this is my php code for search :
$fields = ['search','slug'];
$params = [
'index' => 'digipeyk',
'type' => 'location',
'body' => [
'query' => [
'match' => [
'fields' => $fields,
'query' => $_GET['query']
]
],
'from' => 0,
'size' => 10
]
];
$client = ClientBuilder::create()->build();
$response = $client->search($params);
and also this my php code for indexing documents.
$client = ClientBuilder::create()->build();
$deleteParams = ['index' => 'digipeyk'];
$response = $client->indices()->delete($deleteParams);
$intersections = json_decode(file_get_contents('data/tehran_intersection.json'), true)['RECORDS'];
$i = 1;
foreach($intersections as $intersection){
echo $i."\n";
$params['index'] = 'digipeyk';
$params['id'] = $intersection['id'];
$params['type'] = 'location';
$params['body'] = $intersection;
$response = $client->index($params);
$i++;
}
I'm using php 7 and elasticsearch 2.3
match query doesn't support wildcard query by default, so you have to use wildcard instead of that.
$fields = ['search','slug'];
$params = [
'index' => 'digipeyk',
'type' => 'location',
'body' => [
'query' => [
'wildcard' => [
'query' => '*'.$_GET['query'].'*'
]
],
'from' => 0,
'size' => 10
]
];
$client = ClientBuilder::create()->build();
$response = $client->search($params);
For more information about wildcard in elastic visit following link : https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-wildcard-query.html
For that:
'query' => $_GET['query']
You will be burn in hell :D

Categories