Saturday, June 30, 2012

Google Cloud Print with the Zend Framework

This is a quick tutorial on how to use Google Cloud Print from PHP under the Zend Framework. Parts of this are based on other online tutorials (including Mimeo's tutorial). See also https://developers.google.com/cloud-print/docs/overview

First, we need to get a cloud printer set up. Follow the directions here: http://support.google.com/cloudprint/bin/answer.py?&answer=1686197

Now, we need to determine the GUID of the cloud printer you set up. The following code will query the cloudprint service and dump the results of the "search" command:

<?

require_once 'Zend/Loader/Autoloader.php';

$autoloader = Zend_Loader_Autoloader::getInstance();

$username = 'username@gmail.com';
$password = 'password';

$client = Zend_Gdata_ClientLogin::getHttpClient($username, $password, 'cloudprint');

// Get token, add headers, set uri
$Client_Login_Token = $client->getClientLoginToken();
$client->setHeaders('Authorization','GoogleLogin auth='.$Client_Login_Token);
$client->setUri('http://www.google.com/cloudprint/interface/search');

$response = $client->request(Zend_Http_Client::POST);

$PrinterResponse = json_decode($response->getBody());

if (isset($PrinterResponse->printers)) {
    foreach ($PrinterResponse->printers as $printer) {
        echo ("{$printer->id}\t{$printer->name}\r\n");
    }
} else {
    echo "Something went wrong!\r\n";
    print_r($PrinterResponse);
}


?>

The output (from command line) will look something like this:

4d267d11-4135-0710-d0b2-18aacfeff12d Microsoft XPS Document Writer
__google__docs Save to Google Docs
1c2ea9f6-2b17-0cc4-507f-b59cf1592763 Fax
390272cc-fe27-b4fe-c60f-eba7db8c6b63 Send To OneNote 2007

The printer that I'll be using for this tutorial is the first one, "Microsoft XPS Document Writer". Locate your printer in the output, and make a note of the GUID (e.g. 4d267d11-4135-0710-d0b2-18aacfeff12d

For my purposes, I did not need to print PDFs to cloud print, I needed to print some existing html-based reports. To get HTML in to a format that cloud print would accept, I used the DOMPDF library.

DOMPDF comes with its own autoloader, but it can easily be made to work with Zend's autoloader:


require_once('path/to/dompdf/dompdf_config.inc.php');


$autoloader = Zend_Loader_Autoloader::getInstance();
$autoloader->pushAutoloader('DOMPDF_autoload','');


Once DOMPDF is set up, we can create a PDF from some HTML:


$dompdf = new DOMPDF();
$dompdf->load_html('<html><body><b>Hello, Google Cloud Print!</b></body></html>');
$dompdf->render();
$data = $dompdf->output();


Cloud Print current supports content types of url, application/pdf, image/jpeg, and image/png. For the URL type, the resource you reference must be a pdf, jpeg, or png. If you already have your data in one of these three formats, you don't need to bother with DOMPDF.

Here is the complete example, which renders some HTML to a PDF and sends it to Google Cloud Print:


<?

// Configuration

$username = 'username@gmail.com';
$password = 'password';
$printerid = '4d267d11-4135-0710-d0b2-18aacfeff12d';
$jobtitle = 'Description of the print job';


// Autoloader
require_once 'Zend/Loader/Autoloader.php';
require_once('/path/to/dompdf/dompdf_config.inc.php');

$autoloader = Zend_Loader_Autoloader::getInstance();
$autoloader->pushAutoloader('DOMPDF_autoload','');

// HTML to PDF
$dompdf = new DOMPDF();
$dompdf->load_html('<html><body><b>Hello, Google Cloud Print!</b></body></html>');
$dompdf->render();
$data = $dompdf->output();

// Set up Gdata client and log in
$client = \Zend_Gdata_ClientLogin::getHttpClient($username, $password, 'cloudprint');
$Client_Login_Token = $client->getClientLoginToken();
$client->setHeaders('Authorization','GoogleLogin auth='.$Client_Login_Token);
$client->setUri('http://www.google.com/cloudprint/interface/submit');

// Set parameters
$client->setParameterPost('printerid',$printerid);
$client->setParameterPost('title', $jobtitle);
$client->setParameterPost('contentTransferEncoding','base64');
$client->setParameterPost('content',base64_encode($data));
$client->setParameterPost('contentType','application/pdf');

// Submit and get response
$response = $client->request(\Zend_Http_Client::POST);

// Check response
$PrinterResponse = json_decode($response->getBody());

if (isset($PrinterResponse->success) && $PrinterResponse->success==1) {
    echo "Success! The document should print shortly.\r\n";
} else {
    echo "Failure!\r\n";
    print_r($PrinterResponse);
}


?>

On my setup, when I execute this, after a few seconds a "Save the file as" dialog appears on the Windows computer that I configured the XPS Document Writer on. Saving the file and opening it, I see the following: