Uploading files using PHP - php

I have set up an HTML form to select a file and submit it to a PHP script which will upload it. I cannot use move_uploaded_files() because Box's API requires that I add a HTTP Header for Authorization: access_token. What I've done is set up my own POST method using the cURL library.
The problem I'm running into is setting the filename correctly, as it requires the full path of the file. I cannot get the full path of the file from the HTML form and using $_FILES['filename']['tmp_name'] uploads a .tmp file which I do not want. Does anyone know the solution to this problem? Thanks a lot!
My code:
public function upload_file($file) {
$url = 'https://api.box.com/2.0/files/content';
$params = [
'filename' => '#'.$file['tmp_name'],
'folder_id' => '0'
];
$header = "Authorization: Bearer ".$this->access_token;
$data = $this->post($url, $params, $header);
}
public function post($url, $params, $header='') {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
if(!empty($header)) {
curl_setopt($ch, CURLOPT_HTTPHEADER, array($header));
}
$data = curl_exec($ch);
curl_close($ch);
return $data;
}

Suggest you do one of the following:
Use move_uploaded_files to upload file into some directory and use that location to send the file to box using curl. After successful upload you can delete the file from this directory.
Instead of uploading the file through PHP, you can upload them client side using the cors http://developers.blog.box.com/2013/05/13/uploading-files-with-cors/
Another question which I have in my mind is how are you keeping your access_token refreshed?
Vishal

I agree with what Vishal has suggested in point number one.
I have written the PHP SDK for v2
Just include the api class and initiate the class:
<?php
include('library/BoxAPI.class.php');
$client_id = 'CLIENT ID';
$client_secret = 'CLIENT SECRET';
$redirect_uri = 'REDIRECT URL';
$box = new Box_API($client_id, $client_secret, $redirect_uri);
if(!$box->load_token()){
if(isset($_GET['code'])){
$token = $box->get_token($_GET['code'], true);
if($box->write_token($token, 'file')){
$box->load_token();
}
} else {
$box->get_code();
}
}
// Upload file
$box->put_file('RELATIVE FILE URL', '0'));
?>
Have a look here
Download: BoxPHPAPI

Related

How to get API Curl authorisation to work via PHP

I am working with dr chrono API and am trying to initialized the First step which is authorisation
The API documentation is here.
Here is an Authorisation sample:
https://drchrono.com/o/authorize/?redirect_uri=REDIRECT_URI_ENCODED&response_type=code&client_id=CLIENT_ID_ENCODED&scope=SCOPES_ENCODED
Here is what I have tried:
1.) I have tried the first code below
<?php
echo "<a href='https://drchrono.com/o/authorize/?redirect_uri=https://example_site.com/return_page.php&response_type=code&client_id=myclient-id-goeshere&scope=BASE_SCOPE:[read|write]'>Authorize</a>";
?>
but when the page redirects it displays error of Invalid_scope. Below is the error link returned.
https://example_site.com/return_page.php?error=invalid_scope
2.) Using Curl
$ci = 'my-client-id-goes-here';
$ci_encode = urlencode($ci);
$uri = 'https://example_site.com/return_page.php';
$uri_encode = $uri;
$url = "https://drchrono.com/o/authorize/";
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([
'response_type'=>'code',
'client_id'=>$ci_encode,
'redirect_uri'=>$uri_encode,
'scope'=>'BASE_SCOPE:[read|write]',
]));
$response = curl_exec($ch);
curl_close($ch);
print_r($response);
Using curl code above does even redirect me at all.
I think the major problem is the scope not properly set. How can I solve this issue?
Update
Code section for curl:
$ci = 'my-client-id';
$ci_encode = urlencode($ci);
$uri = 'https://example_site.com/return_page.php';
$uri_encode = $uri;
$url = "https://drchrono.com/o/authorize/?";
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([
'response_type'=>'code',
'client_id'=>$ci,
'redirect_uri'=>$uri,
'scope'=>'patients:summary:read patients:summary:write calendar:read calendar:write clinical:read clinical:write'
]));
$response = curl_exec($ch);
curl_close($ch);
print_r($response);
Instead of BASE_SCOPE:[read|write] I would use patients:summary:read patients:summary:write calendar:read calendar:write clinical:read clinical:write
The docs say that you can choose among user, calendar, patients, patients:summary, billing, clinical and labs and compose a scope out of these values.

Dailymotion API - Can't get to a video to upload

I can't manage to get a file to upload the DailyMotion API.
I'm following these steps : https://developer.dailymotion.com/video-upload/upload-new-video-api/
The first API call runs fine and returns me the "upload_url" that I feed into the method you'll see below.
It fails on the 2nd step and the response error is :
{"error":"missing content size","seal": "[some string]"}
How am I supposed to set the content size ?
the code for the 2nd call :
<?php
namespace PierreMiniggio\YoutubeChannelCloner\Dailymotion\API;
class DailymotionFileUploader
{
public function upload(string $uploadUrl, string $filePath): ?string
{
$formattedFile = function_exists('curl_file_create')
? curl_file_create(str_replace('\\', '/', $filePath))
: sprintf("#%s", $filePath)
;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $uploadUrl);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt(
$ch,
CURLOPT_POSTFIELDS,
['file' => $formattedFile]
);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
//var_dump($response); die(); // the output I printed above
curl_close($ch);
if (empty($response)) {
return null;
}
$jsonResponse = json_decode($response, true);
if (empty($jsonResponse) || ! isset($jsonResponse['url'])) {
return null;
}
return $jsonResponse['url'];
}
}
OS : W10
I made sure the file path and the upload URL are correct.
I tried using the dailymotion/sdk lib and use the function that uploads a file instead of using my curl requests, but I get the exact same error.
Problem Solved, It was issue with curl/PHP.
I was running the script in PHP 7.4.3-dev, updated to 7.4.11 and it solved the issue.
More Info about the bug here : https://bugs.php.net/bug.php?id=79013

I can't add an image Web Service Prestashop

When I try to add an image to a product I don't get any errors, but the image doesn't get added.
This is my code:
function addImage($idProduct)
{
$key = 'XXXXXXXXXXXXXXXXXXX';
$url = "http://192.168.1.81/api/images/products/".$idProduct;
$image_path = 'image2.jpg';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_USERPWD, $key);
curl_setopt($ch, CURLOPT_POSTFIELDS, array('image' => '#'.$image_path.';type=image/jpg'));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);
echo '<h2>Image Added</h2>';
}
I also made a change on PSWebServiceLibrary.php, because Prestashop Web Service API keeps asking for authentication. This is the link where I got the code Prestashop Web Service API keeps asking for authentication .
This is the code I added:
$url .= '&ws_key=' . $this->key;
The problem is that the code to add an image was working before I made that change on PSWebServiceLibrary.php, and I don't know how to solve it.
I am using prestashop 1.6.1.5
Any help will be appreciated.
Greetings!
I think it's only a missing of "?" in your url.
If I follow your $url logic the result will be for product of ID 1234567 by example :
http://192.168.1.81/api/images/products/1234567&ws_key=ZOEJFD3429JD209AZJX0DJF20
So your server waits this url to hanlde ws_key as GET parameter :
http://192.168.1.81/api/images/products/1234567?ws_key=ZOEJFD3429JD209AZJX0DJF20
You need to add this "?" at the end of you URL like this :
$url = "http://192.168.1.81/api/images/products/".$idProduct."?";
Best Regards,
TGA
For me works like this:
curl_setopt($ch, CURLOPT_POSTFIELDS, array('image' => curl_file_create($image_path)));

Upload external file to AWS S3 bucket using PHP SDK

I want to upload a file from an external URL directly to an Amazon S3 bucket using the PHP SDK. I managed to do this with the following code:
$s3 = new AmazonS3();
$response = $s3->create_object($bucket, $destination, array(
'fileUpload' => $source,
'length' => remote_filesize($source),
'contentType' => 'image/jpeg'
));
Where the function remote_filesize is the following:
function remote_filesize($url) {
ob_start();
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_NOBODY, 1);
$ok = curl_exec($ch);
curl_close($ch);
$head = ob_get_contents();
ob_end_clean();
$regex = '/Content-Length:\s([0-9].+?)\s/';
$count = preg_match($regex, $head, $matches);
return isset($matches[1]) ? $matches[1] : "unknown";
}
However, it would be nice if I could skip setting the filesize when uploading to Amazon since this would save me a trip to my own server. But if I remove setting the 'length' property in the $s3->create_object function, I get an error saying that the 'The stream size for the streaming upload cannot be determined.' Any ideas how to solve this problem?
You can upload file from url directly to Amazon S3 like this (my example is about a jpg picture):
1. Convert the content from url in binary
$binary = file_get_contents('http://the_url_of_my_image.....');
2. Create an S3 object with a body to pass the binary into
$s3 = new AmazonS3();
$response = $s3->create_object($bucket, $filename, array(
'body' => $binary, // put the binary in the body
'contentType' => 'image/jpeg'
));
That's all and it's very fast. Enjoy!
Do you have any control over remote server/host?. If so you could set up a php server to query the file locally and pass the data to you.
If not, you could use something like curl to inspect the header like so;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://sstatic.net/so/img/logo.png');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_exec($ch);
$size = curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD);
var_dump($size);
This way, you are using a HEAD request, and not downloading the whole file -- still, you depend on the remote server send a correct Content-length header.

PHP Printing with Google Cloud Print

I am currently adding the ability to a php back-end system to allow it to print directly and I am trying to get things working with Google's Cloud Print. Imagine the app as an online shopping cart and I want it to print picking notes (completed orders) without the need for someone to login. The server is remote and the destination has Cloud Ready Printers.
So far I have been successful in getting it to print using the interfaces, as long as I am simply passing HTML, plain text or a URL to a PDF. I am able to set the print to color, marginless and the print quality.
However where I have hit a problem is, the PDF which the system creates are not publicly accessible, hence I can't pass a URL to the file, I need to pass the contents of the file.
I have been trying with no success to modify one of the examples I have found on the web HERE. However I don't know the language so am struggling with it.
Another example in python HERE again I have been trying without success!
I'm using PHP and the Zend framework to work with the interface. Here is one sample I have tried, cut down to where I am trying to prepare the file to send, like I say I'm not really sure on translating from python to php, or if the python script even works, but this is what I came up with:
<?php
// Test print a job:
$b64_pathname = PDF_PATH.'ec22c3.pdf'.'.b64';
$fileType = "application/pdf";
// Open the original file and base64 encode it:
$dataHandle = fopen(PDF_PATH.'ec22c3.pdf', "rb");
$dataContent = fread($dataHandle, filesize(PDF_PATH.'ec22ed167763a15e8591a3776f3c65c3.pdf'));
fclose($dataHandle);
$b64data = $fileType.base64_encode($dataContent);
// Store the base64 encoded file:
$ourFileHandle = fopen($b64_pathname, 'w');
fwrite($ourFileHandle, $b64data);
fclose($ourFileHandle);
// Read the contents of the base64 encoded file and delete it:
$fileHandle = fopen($b64_pathname, "rb");
$fileContent = fread($fileHandle, filesize($b64_pathname));
fclose($fileHandle);
unlink($b64_pathname);
// URL encode the file contents:
$file = urlencode($fileContent);
// Add the file and send to the printer:
$client->setParameterPost('content', $file);
$client->setParameterPost('contentType', $fileType);
$client->request(Zend_Http_Client::POST);
?>
Here's a method in php using cUrl (note, I have object level variables called _auth, _username, _password & _printerId).
First, build a function to post with cUrl:
function processRequest($url, $postFields, $referer) {
$ret = "";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_USERAGENT, "");
if(!is_null($postFields)) {
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS,
$postFields);
// http_build_query() will properly escape the fields and
// build a query string.
}
if(strlen($this->_auth) > 0) {
$headers = array(
"Authorization: GoogleLogin auth=". $this->_auth,
//"GData-Version: 3.0",
"X-CloudPrint-Proxy", "yourappname"
);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
}
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_REFERER, $referer);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$ret = curl_exec ($ch);
curl_close ($ch);
return $ret;
}
Then, a function to authorize against Google:
public function authorize() {
$url = "https://www.google.com/accounts/ClientLogin";
$post = array("accountType" => "HOSTED_OR_GOOGLE",
"Email" => $this->_username,
"Passwd" => $this->_password,
"service" => "cloudprint",
"source" => "yourappname");
$resp = $this->processRequest($url, $post, "");
preg_match("/Auth=([a-z0-9_\-]+)/i", $resp, $matches);
$this->_auth = $matches[1];
}
Finally, build a function to submit to the cloud printer:
function printDocument($title, $docBytes)
{
$url = "http://www.google.com/cloudprint/submit?printerid=". $this->_printerId."&output=json";
$post = array(
"printerid" => $this->_printerId,
"capabilities" => "",
"contentType" => "dataUrl",
"title" => $title,
"content" => 'data:application/pdf;base64,'. base64_encode($docBytes)
);
$ret = $this->processRequest($url, $post, "");
echo $ret;
}
In use, call authorize() to get the authentication token. Then just read your file (from wherever) into a variable and pass it to printDocument with the title.
In order to send base64 encoded content you need to send another parameter in submit request:
$client->setParameterPost('contentTransferEncoding', 'base64');

Categories