Use value returned from cURL to make a subsequent call as an Authorization header - php-curl

I am making a call to an api with cURL and I get a successful call but the api requires that I use the successful call to make subsequent calls, specifically: use the value returned to make the subsequent call as an Authorization header.
I am not sure what exactly to try. I am getting the correct response in the body of the page, just through curl_exec($ch); but i'm not sure where to proceed.
<?php
//Set Variables
$username = 'my_username';
$password = 'my_password';
$showcode = 'my_showcode';
//Set url variable with showcode as a query string
$url = "https://api.mysstaging.com/mysRest/v2/Authorize/?showCode=$showcode";
// create a new cURL resource
$ch = curl_init();
// set URL and other appropriate options
curl_setopt($ch, CURLOPT_URL, $url );
//Set un/pw for basic auth
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
// grab URL and pass it to the browser
curl_exec($ch);
//Expect to store and use variable but not sure how
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Authorization: ' . mysGUID,
));
// close cURL resource, and free up system resources
curl_close($ch);
?>
From curl_exec($ch), I get a response in the body with mysGUID, and this is where I think I should/can pass it as a variable but i'm not sure how to store the response as a variable in php and then make a subsequent call using it? I apologize I am still pretty green with API's but hopefully I am on the right track?

I was able to sort this out. In case anyone else is stuck the approach I took was to set CURLOPT_RETURNTRANSFER so I could utilize the values. Then I created a variable for returned key and value (I am calling this the GUID). I then used this variable to convert the output to an array which then allowed me to get just the value from the returned GUID, which I then stored in a variable I can use for subsequent calls.
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// create variable for authorization output, this gives us the GUID we need.
$authOutput = curl_exec($ch);
// Convert JSON string to Array to pull the GUID value only
$outputArray = json_decode($authOutput, true);
//create variable for myResult variable
$myResult= $outputArray[0]["myResult"];
echo "My Result = $myResult";
// close cURL resource, and free up system resources
curl_close($ch);

Related

Is there a way for postman to read the response data from a GET request and then use an IF THEN statement to run a POST request?

I am trying to run a script where postman sends a Get request, and if the get response contains a certain variable to then run a Post request. How do i do this?
(also is there a way to run a get request hourly)
In pre-requisite add:
// set initial value
const method = pm.variables.get("method")
// set initial value as GET if method is undefined
method ? null : pm.variables.set("method", "GET")
// Set this as method
pm.request.method =method
in test script add :
// the condition check
if (pm.response.json().somevalue === "somevalue") {
//then change the method
pm.variables.set("method", "POST")
//call the same request again using setNExtRequest
// pm.info.reqeustName gives current request's name
postman.setNextRequest(pm.info.requestName)
}

Download PhpSpreadsheet file without save it before

I'm using PhpSpreadsheet to generate an Excel file in Symfony 4. My code is:
$spreadsheet = $this->generateExcel($content);
$writer = new Xlsx($spreadsheet);
$filename = "myFile.xlsx";
$writer->save($filename); // LINE I WANT TO AVOID
$response = new BinaryFileResponse($filename);
$response->headers->set('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
$response->setContentDisposition(
ResponseHeaderBag::DISPOSITION_ATTACHMENT,
$filename
);
But I don't want to save the file and then read it to return to the user. I would like to download Excel content directly. Is there a way to do It?
I've searched how to generate a stream of the content (as this answer says) but I hadn't success.
Thanks in advance and sorry about my English
As I understand you are generating the content in your code.
You can stream the response in Symfony and configure PhpSpreadsheet Writer to save to 'php://output' (see here the official doc Redirect output to a client's web browser).
Here is an working example using Symfony 4.1 and Phpspreadsheet 1.3:
<?php
namespace App\Controller;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use Symfony\Component\HttpFoundation\StreamedResponse;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use PhpOffice\PhpSpreadsheet\Writer as Writer;
class TestController extends Controller
{
/**
* #Route("/save")
*/
public function index()
{
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->setCellValue('A1', 'Hello World !');
$writer = new Writer\Xls($spreadsheet);
$response = new StreamedResponse(
function () use ($writer) {
$writer->save('php://output');
}
);
$response->headers->set('Content-Type', 'application/vnd.ms-excel');
$response->headers->set('Content-Disposition', 'attachment;filename="ExportScan.xls"');
$response->headers->set('Cache-Control','max-age=0');
return $response;
}
}
This is the solution for Laravel. But it still uses Symfony\Component\HttpFoundation\StreamedResponse in the end.
$contentDisposition = 'attachment; filename="' . $fileName . '"';
$contentType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
$response = response()->streamDownload(function () use ($spreadsheet) {
$writer = new Xlsx($spreadsheet);
$writer->save('php://output');
});
$response->setStatusCode(200);
$response->headers->set('Content-Type', $contentType);
$response->headers->set('Content-Disposition', $contentDisposition);
Then you can send the response directly as a stream with
$response->send();
or just return it back in the controller
return $response;

Uploading image file through API using Symfony2 & FOSRESTBundle

I have been coding an API for a photo sharing app like Instagram using Symfony2, FOSRESTBundle, and Vichuploader for file uploads.
I'm able to work around GET and POST requests, but I can't find an example of how to attach to a POST request, the actual image so that in my case, Vichuploader can grab it and help me out with the file upload.
By the way, I can upload a file without issue using the stack mentioned through the use of a normal form.
I have been looking for a solution about the exact same problem. Here is what I did.
First let me explain my constraints. I wanted my API to be full JSON and to take power of the HTTP protocol (headers, methods, etc.). I chose to use:
Symfony2 for the "everything is almost done for you, just code your business logic".
Doctrine2 because by default with Symfony2 and provide a way to integrate with most popular DBMS by changing one line.
FOSRestBundle to handle the REST part of my API (do the maximum with annotations, body listener, auto format for the response with JMSSerializer support, etc.).
KnpGaufretteBundle because I wanted to be allowed to change the way I store blob file quickly.
First solution envisaged: base64
My first thought, because I was thinking JSON everytime, was to encode all the incoming images in base64, then decode them inside my API and store them.
The advantage with this solution is that you can pass images along with other data. For instance upload a whole user's profile in one API call. But I read that encoding images in base64 make them grow by 33% of their initial size. I did not wanted my users to be out of mobile data after sending 3 images.
Second solution envisaged: form
Then I thought using forms as described above. But I did not know how my clients could send both JSON data (for instance {"last_name":"Litz"}) and image data (for instance image/png one). I know that you can deal with an Content-Type: multipart/form-data but nothing more.
Plus I was not using forms in my API since the beginning and I wanted it to be uniform in all my code. [mini-edit: hoho, something I just discovered, here]
Third and last solution: use HTTP..
Then, one night, the revelation. I'm using Content-Type: application/json for send JSON data. Why not use image/* to send images? So easy that I searched for days before coming with this idea. This is how I did it (simplified code). Let suppose that the user is calling PUT /api/me/image with a Content-Type: image/*
UserController::getUserImageAction(Request $request) - Catching the Request
// get the service to handle the image
$service = $this->get('service.user_image');
$content = $request->getContent();
$userImage = $service->updateUserImage($user, $content);
// get the response from FOSRestBundle::View
$response = $this->view()->getResponse();
$response->setContent($content);
$response->headers->set('Content-Type', $userImage->getMimeType());
return $response;
UserImageService::updateUserImage($user, $content) - Business Logic (I put everything here to be simplier to read)
// Create a temporary file on the disk
// the temp file will be delete at the end of the script
// see http://www.php.net/manual/en/function.tmpfile.php
$file = tmpfile();
if ($file === false)
throw new \Exception('File can not be opened.');
// Put content in this file
$path = stream_get_meta_data($file)['uri'];
file_put_contents($path, $content);
// the UploadedFile of the user image
// referencing the temp file (used for validation only)
$uploadedFile = new UploadedFile($path, $path, null, null, null, true);
// the UserImage to return
$userImage = $user->getUserImage();
if (is_null($userImage))
{
$userImage = new UserImage();
$userImage->setOwner($user);
// auto persist with my configuration
// plus generation of a unique ID that allows
// me to retrieve the image at anytime
$userImage->setKey(/*random string*/);
}
// fill the UserImage properties
$userImage->setImage($uploadedFile);
$userImage->setMimeType($uploadedFile->getMimeType());
/** #var ConstraintViolationInterface $validationError */
if (count($this->getValidator()->validate($userImage)) > 0)
throw new \Exception('Validation');
// if no error we can write the file definitively
// [KnpGaufretteBundle code to store on disk]
// [use the UserImage::key to store]
$this->getEntityManager()->flush();
return $userImage;
You use form types for posts with the FOSRestBundle:
For example you have this form type:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('facebook_id',
'text',
array(
'mapped' => FALSE
)
)
->add('profile_pic',
'text',
array(
'mapped' => FALSE
)
)
;
$builder->addValidator(new CallbackValidator(function(FormInterface $form)
{
if ($form["facebook_id"]->getData() === '' || $form["facebook_id"]->getData() === NULL)
{
$form->get('facebook_id')->addError(new FormError('facebook_id should not be empty'));
}
if ($form["profile_pic"]->getData() === '' || $form["profile_pic"]->getData() === NULL)
{
$form->get('profile_pic')->addError(new FormError('profile_pic should not be empty'));
}
})
);
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
// 'validation_constraint' => $collectionConstraint,
'csrf_protection' => FALSE,
));
}
public function getName()
{
return 'data';
}
Then what you can do is post JSON to the API. Don't forget to set the header as "Content-type = application/json" when you do a POST.
The JSON structure would look like this:
{
"data": {
"facebook_id": "12345",
"profile_pic": "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"
}
}
Why is this json wrapped in "data"? Because your form type also has "data" in getName so it will use validation and etc.
What I always do is I encode my pictures as a base64 string while sending them to the API.
Then in the post function you just convert it back:
$base64 = $form['profile_pic']->getData();
//decode back to image data and create image
$image = imagecreatefromstring(base64_decode($base64));
imagepng($image, $path);
This is a full upload from api code bit. This does upload the file, but I am still having trouble with validating the uploaded file. Hope this helps.
This uses fosrest bundle for REST.
private function addResource(Entity $resource) {
$em = $this->getDoctrine()->getManager();
$em->persist($resource);
$em->flush();
}
private function processForm(Entity $resource)
{
$em = $this->getDoctrine()->getManager();
$uploadedFile = null;
$form = $this->createForm(new EntityForm(), $resource);
foreach ($_FILES as $file) {
$uploadedFile = new UploadedFile(
$file['tmp_name'],
$file['name'], $file['type'],
$file['size'], $file['error'],
$test = false);
}
$submitData = array(
"file" => $uploadedFile,
);
$form->submit($submitData);
if ($form->isValid()) {
$repository = $this->getDoctrine()
->getRepository('AcmeBundle:Product');
$view = View::create();
$resource->setFile($uploadedFile);
// handling api requests
if ($this->getRequest()->getMethod() == "POST") {
$this->addResource($resource);
// store image url
$resource = $repository->find($resource->getId());
if ($resource->getImage()) {
$fs = new Filesystem();
if ($fs->exists($resource->getWebPath())) {
$resource->setImagePath($resource->getWebPath());
}
$this->addResource($resource);
}
$view->setData($resource);
}
return $view;
}
return View::create($form);
}
An example for a upload method exepting post requests:
public function uploadAction() {
$em = $this->getDoctrine()->getManager();
$document = new Document();
foreach ($_FILES as $file) {
$document->setTitle($file['name']);
$document->file = new UploadedFile($file['tmp_name'],
$file['name'], $file['type'],
$file['size'], $file['error'], $test = false);
$em->persist($document);
$em->flush();
break;
}
$serializer = $this->get('jms_serializer');
$data = $serializer->serialize(
$document, 'json',
SerializationContext::create()->setGroups(array('someGroup')));
return new Response($data);
}
So this action first stores the document on the server and returns a json response containing document meta data and path. I used the response for further processing in my web application.
I am not familiar with VichUploader, the above code is native Symfony2 code using Symfony\Component\HttpFoundation\File\UploadedFile.
Read: http://symfony.com/doc/current/cookbook/doctrine/file_uploads.html

How to retrieve list views of any salesforce object using API?

I want to retrieve all list views of any salesforce object through API. How to do that?
This is an old question, but, using the REST API and Salesforce's query language, you could use the endpoint:
{your instance url}/services/data/v32.0/query?q=SELECT Id,Name FROM {object type}
OR
Use the endpoint:
{your instance url}/services/data/v32.0/sobjects/{object type}/listviews
Some examples:
To get all listviews: https://na16.salesforce.com/services/data/v32.0/query?q=SELECT Id,Name FROM ListView
To get all listviews with object type of account: https://na16.salesforce.com/services/data/v32.0/sobjects/Account/listviews
In PHP:
$url = "{your instance url}/services/data/v32.0/sobjects/Account/listviews";
$headers = array('Authorization: OAuth ' . {your access token});
$ch = curl_init ();
curl_setopt ( $ch, CURLOPT_URL, $url );
curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, TRUE );
curl_setopt ( $ch, CURLOPT_FOLLOWLOCATION, TRUE );
curl_setopt ( $ch, CURLOPT_HTTPHEADER, $headers);
$requestBody = curl_exec ($ch);
$result = json_decode($requestBody, true);
Of course you'll need to login first through OAUTH to get an access token and instance URL.
If it's SOAP api that you are looking for, it's called describeSObject - for specific object, or 'describeGlobal' - for all your org's data.
See the reference link below for SOAP message:
http://wiki.developerforce.com/page/Sample_SOAP_Messages_(10.0_API)
Create a StandardSetController for given object (the query you'll use to instantiate it can have "LIMIT 1" or something, no need to select all records). Then use getListViewOptions().
Remember that it will return views visible for current user (so only the public ones + ones marked as "visible only to me').
EDIT:
To access it from outside (via SOAP or REST API)...
I'm not aware of method to get these with REST calls I'm afraid. You might have to write a bit of Apex and expose a custom REST resource that will return this data. It's not that hard, see http://www.salesforce.com/us/developer/docs/apexcode/index_Left.htm#StartTopic=Content/apex_rest_code_sample_basic.htm for examples.

Magento API V2 - add an additional attribute to API response

I'm using the Magento API V2.
When I call salesOrderCreditmemoInfo, I get a response with the credit memo details and a list of the products associated with the order.
But in the list of product items there is no product_type attribute.
I want to manually edit the response to add this attribute.
I tried editing:
app\code\core\Mage\Sales\Model\Order\Creditmemo\Api.php
And replaced:
public function info($creditmemoIncrementId)
{
...
$result['items'] = array();
foreach ($creditmemo->getAllItems() as $item) {
$result['items'][] = $this->_getAttributes($item, 'creditmemo_item');
}
With the following - (basically appending an extra attribute to the array):
public function info($creditmemoIncrementId)
{
...
$result['items'] = array();
foreach ($creditmemo->getAllItems() as $item) {
$product_type = '1'; //test value to check if works
$attribs = $this->_getAttributes($item, 'creditmemo_item');
$attribs['product_type'] = $product_type;
$result['items'][] = $attribs;
}
When I do mage::log($result), the extra attribute seems to be added correctly to the array.
(also indicating that this function is the one getting called)
But it has no impact on the actual API response.
Am I totally looking in the wrong place or is there something else I need to update?
Since You were using SOAP V2, you should update the wsdl.xml to get the output.
For your case it is product_type and refresh cache on server. /tmp to load the new wsdl.xml that already updated. don't forget to go to System -> Cache Management clear all cache.