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');
Related
Cannot grab pictures from the specific site with PHP, but with PYTHON is working for this site, how to download images via PHP?
image URL is https://www.autoopt.ru/product_pictures/big/bcb/054511.jpg
If I paste another URL, of another site, the picture is downloading, but this site doesn't work.
i try with file put content and so on, my last code is
<?php
function downloadImage($img_url){
$image = file_get_contents($img_url);
$img_save_path = realpath(dirname(__FILE__)) . '/assets/upload_products/';
$image_name = basename($img_url);
$image_fullpath = $img_save_path.$image_name;
$ch = curl_init ($img_url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_BINARYTRANSFER,1);
$raw=curl_exec($ch);
curl_close ($ch);
if(file_exists($image_fullpath)){
unlink($image_fullpath);
}
$fp = fopen($image_fullpath,'x');
fwrite($fp, $raw);
fclose($fp);
return true;
}
downloadImage('https://www.autoopt.ru/product_pictures/big/bcb/054511.jpg');
You dont need to do all that to save the picture if your going to use file_get_contents. It can be done by only using:
file_put_contents($image_fullpath, file_get_contents($img_url));
Also, like mentioned by OMi Shash in the comments, you'll need to pass header info to file_get_contents for it to work with that url. I've just done the test and it worked.
//set header info
$opts = array('http'=>array('header' => "User-Agent:MyAgent/1.0\r\n"));
//Basically adding headers to the request
$context = stream_context_create($opts);
file_put_contents($image_fullpath, file_get_contents($img_url, false, $context));
I'm trying do retrieve and download a file (image) from a remote location.
Inside the php.ini the allow_url_fopen is enabled, but i can't download the image.
Code i'm using is described below
$local_file = "test.jpg";
$remote_file = "http://somehost:6346/cgi-bin/CGIProxy.fcgi?cmd=snapPicture2&usr=xxxx&pwd=xxxx";
$ch = curl_init();
$fp = fopen ($local_file, 'w+');
$ch = curl_init($remote_file);
curl_setopt($ch, CURLOPT_TIMEOUT, 50);
curl_setopt($ch, CURLOPT_FILE, $fp);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_ENCODING, "");
curl_exec($ch);
curl_close($ch);
fclose($fp);
with any other url that contains a real jpg file, it's working perfectly, i suppose that the issue is that the url use some special characters that doesn't like to curl.
If i try to execute the php snippet above,page load for almost 1 minute,and it seems that no error are displayed,the image test.jpg is created, but it's empty.
Do you have any suggestion?
Thanks!
Try this
$local_file = "test.jpg";
$remote_file = "http://somehost:6346/cgi-bin/CGIProxy.fcgi?cmd=snapPicture2&usr=xxxx&pwd=xxxx";
function getPage($url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_REFERER, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
function saveToFile($base, $decode=false, $output_file)
{
$ifp = fopen($output_file, "wb");
if ($decode){
fwrite($ifp, base64_decode($base));
}else{
fwrite($ifp, $base);
}
fclose($ifp);
return($output_file);
}
$remote_page = getPage($remote_file);
$saved_file = saveToFile($remote_page , false, $local_file);
when debugging issues like this, set CURLOPT_VERBOSE, it will probably reveal why the page loaded for almost 1 minute, with no apparent output.
i suppose that the issue is that the url use some special characters - this is fully possible, for example your username and password, they're supposed to be urlencoded. urlencoding is binary safe, meaning you can have any special characters you'd like, you just need to encode it properly. use urlencode() or http_build_query() for that, eg
$remote_file = "http://somehost:6346/cgi-bin/CGIProxy.fcgi?" . http_build_query ( array (
'cmd' => 'snapPicture2',
'usr' => 'username',
'pwd' => 'password'
) );
now http_build_query will properly urlencode any special characters in your username and password (for example, if your username is an email address, the # becomes %40).
if that doesn't fix it, what does CURLOPT_VERBOSE say?
also, final note, here you're sending the download request with credentials in a GET request. that's very unusual, the vast majority of websites want you to login with a POST request, and there are good security-related reasons for that, are you sure your website allows sending credentials in GET parameters? the vast majority of websites doesn't allow it... (and the best way to find out, is to record a browser logging in, does the browser use GET parameters, or POST parameters?)
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
I have an sms android app that works remotely using a http server, It need to get a formed url request like this :
http://server.com:9090/sendsms?phone=123456789&text=foobar&pass=123456
When i type that url in the browser address bar and hit enter, the app sends the sms.
I'm new to curl, and I dont know how to test it, here is my code so far:
$phonenumber= '12321321321'
$msgtext = 'lorem ipsum'
$pass = '1234'
$url = 'http://server.com:9090/sendsms?phone=' . urlencode($phonenumber) . '&text=' . urlencode($msgtext) . '&password=' . urlencode($pass);
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => $url
));
So my questions are, is the code correct? and how to test it?
Altough this is a simple GET, I cannot fully agree with hek2mgl. There are many situations, when you have to take care of timeouts, http response codes, etc. and this is what cURL is for.
This is a basic setup:
$handler = curl_init();
curl_setopt($handler, CURLOPT_URL, $url);
curl_setopt($handler, CURLOPT_RETURNTRANSFER, true);
curl_setopt($handler, CURLOPT_FOLLOWLOCATION, true);
// curl_setopt($handler, CURLOPT_MAXREDIRS, 10); // optional
// curl_setopt($handler, CURLOPT_TIMEOUT, 10); // optional
$response = curl_exec($handler);
curl_close($handler);
If you can access the url using the address bar in browser, then it is a HTTP GET request. The simplest thing to do that in PHP would be using file_get_contents() since it can operate on urls as well:
$url = 'http://server.com:9090/sendsms?phone=123456789&text=foobar&pass=123456';
$response = file_get_contents($url);
if($response === FALSE) {
die('error sending sms');
}
// ... check the response message or whatever
...
Of course you can use the curl extension, but for a simple GET request, file_get_contents() will be the simplest and most portable solution.
I'm trying to save a local copy of an xml file, and then open it with simple xml, but i'm getting some errors.. here's my code:
$feedURL = "https://gdata.youtube.com/feeds/api/users/manitobachildhealth/favorites";
//$xml = file_get_contents("$feedURL");
$xml = file_get_contents($feedURL);
file_put_contents("video.xml", $xml);
// read feed into SimpleXML object
//$sxml = simplexml_load_file($feedURL);
$sxml = simplexml_load_file('video.xml');
The error i'm getting is as follows:
Warning: file_get_contents(https://gdata.youtube.com/feeds/api/users/manitobachildhealth/favorites) [function.file-get-contents]: failed to open stream: Result too large in D:\wamp\www\videos2.php on line 48
I'm not sure why it would be too large of a result, it only returns 6kb of xml. what am i doing wrong?
Update:
This is running on a windows platform using WAMP server - not ideal, but i'm stuck with it.
Update 2:
I've tried using curl and fwrite to achieve a similar result, as suggested below, but it won't write the xml file to the local server. It doesn't give me any errors though.
update 3:
This is obviously a very specific problem with the hosting environment, but I'm not sure where to start looking for the problem. Using curl works great on a linux-based dev server, but is causing problems on this windows-based production server. An extra help in troubleshooting this issue would be most appreciated!
Correct answer for the question:
It is possible you are having the same problem as of this question: CURL and HTTPS, "Cannot resolve host" (DNS-Issue)
Other Details:
You can use SimpleXML to load and save the xml data
$xml = new SimpleXMLElement('https://gdata.youtube.com/feeds/api/users/manitobachildhealth/favorites', NULL, TRUE);
$xml->asXML('video.xml');
I have tested the code above in a WAMP server and it works fine.
Update:
If the above returns error message "[simplexmlelement.--construct]: I/O warning : failed to load external entity ...." It's possible that your server does not allow to include external data or the php file/script does not have the right permission.
Try the following:
1. echo the content of the xml file.
$xml = new SimpleXMLElement('https://gdata.youtube.com/feeds/api/users/manitobachildhealth/favorites', NULL, TRUE);
echo htmlentities($xml->asXML());
If you managed to retrieved the xml content and print it to the browser, then your server is allowing to include external content and most likely the problem with the file permission. Make sure file/script have the right to create xml file.
If the above still does not work try using cURL.
function getPageContent($options)
{
$default = array(
'agent' => $_SERVER['HTTP_USER_AGENT'],
'url' => '',
'referer' => 'http://'.$_SERVER['HTTP_HOST'],
'header' => 0,
'timeout' => 5,
'user' => '',
'proxy' => '',
);
$options = array_merge($default, $options);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $options['url']);
curl_setopt($ch, CURLOPT_HEADER, $options['header']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
if ($options['proxy'] != '') {
curl_setopt($ch, CURLOPT_PROXY, $options['proxy']);
}
curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 0);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $options['timeout']);
curl_setopt($ch, CURLOPT_REFERER, $options['referer']);
curl_setopt($ch, CURLOPT_USERAGENT, $options['agent']);
if ($options['user'] != '') {
curl_setopt($ch, CURLOPT_PROXYUSERPWD, $options['user']);
}
$result = array();
$result['content'] = curl_exec($ch);
$result['info'] = curl_getinfo($ch);
$result['error'] = curl_error($ch);
curl_close($ch);
return $result;
}
$result = getPageContent(array(
'proxy' => '[ip or address]:[port]', // if needed
'user' => '[username]:[password]', // if needed
'url' => 'http://gdata.youtube.com/feeds/api/users/manitobachildhealth/favorites'
));
if (empty($result['error'])) {
// ok
// content of xml file
echo htmlentities($result['content']);
// file
$filename = 'video.xml';
// Open File
if (!$fp = fopen($filename, 'wt')) {
die("Unable to open '$filename'\n\n");
}
// write content to file
fwrite($fp, $result['content']);
// close file
fclose($fp);
} else {
// failed
echo '<pre>';
echo 'Error details;';
print_r ($result['error']);
echo '<hr />Other info:';
print_r ($result['info']);
echo '</pre>';
}
Have you tried using curl and fwrite to get the contents and write them to a local file?
$ch = curl_init("https://gdata.youtube.com/feeds/api/users/manitobachildhealth/favorites");
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
curl_close($ch);
fwrite("video.xml",$output);