Print module revisited...

April 27, 2011
blog author

Appno Blogger

Appnovation Coop

Recently we did a project which required us to generate a PDF file from a CCK node and send it off to Alfresco. Instantly we thought of using the Print module; however, there's a catch: the PDF file had to be saved remotely under the Drupal site. By default the Print module will allow users to save a PDF file locally on their computer but not on the Drupal site. We explored the module and found that the PDF printing is triggered by the 'print_pdf_controller' function. Under this function it checks if you are using the tcpdf, dompdf or wkhtmltopdf library. The first thing we noticed is that we need to either pass in a 'remote file path' parameter or specify this with a global variable. Since we want to make it flexible we decided to add the extra parameter $remote_path:

function print_pdf_controller($overwriteargs = NULL, $remote_path="") {

Please note that you will have to modify the call to print_pdf_controller function if you need to pass in the new $remote_path parameter. Basically this $remote_path parameter will also be used to determine if the file will be saved remotely in the Drupal site. You can add a radio button in your 'form_alter' call, specify two separate print links or add an admin setting to control which method to use. The next thing you need to do is find the '_print_pdf_tcpdf' and '_print_pdf_dompdf' references and add the same parameter to each function. Please also check write permission for the path you are passing in. You can try using '/sites/default/' or file_directory_path() to define the path since those are usually writable by Drupal by default.

For the '_print_pdf_dompdf' function modification, first go to the end of the function and modify the '$dompdf->stream' line. If the $remote_path is not specified then use the default code to create the file for users to save manually; otherwise, if the $remote_path parameter is provided then it will save the PDF file on the Drupal site. The "$pdfoutput = $dompdf->output();" line allows you to capture the PDF file output. Once you assigned the PDF output in a variable just call the fopen, fwrite and fclose functions to save the content to a file based on the $remote_path parameter.

if ($remote_path == "") {   $dompdf->stream($filename, array('Attachment' => ($print_pdf_content_disposition == 2))); } else {   $pdfoutput = $dompdf->output();   $filename = $output;   $fp = fopen($remote_path, "wb");   if ($fp) {     fwrite($fp, $pdfoutput); }   else {     //error handling   }   fclose($fp); }

Tcpdf modification is very similar. You need to make the similar change to the original line that is located near the end of the '_print_pdf_tcpdf' function. The next thing you need to do is to add new code to re-assign the $output_dest variable to 'S'. You can read the tcpdf library code to find out what 'D', 'I' and 'S' stand for. After that you will need to capture the PDF file content. Tcpdf is a little bit different from dompdf since it will require you to pass two extra parameters. The first one is the filename and the second one is the $output_dest parameter mentioned earlier.

Add the following code changes starting with the "$output_dest = ..." line:

if ($remote_path == "") {   $output_dest = ($print_pdf_content_disposition == 2) ? 'D' : 'I'; } else {   $output_dest = 'S';   $pdfoutput = $pdf->Output($filename, $output_dest);   $f = fopen($abspath, 'wb');   if ($f) {     fwrite($f, $pdfoutput, strlen($pdfoutput));   }   else {     //error handling   }   fclose($f); }

That's it. Now your print PDF function will be able to save the PDF files on the Drupal site as well. We're working on creating a patch for the Print module later to enable this change in a more friendly way and will be submitting it back to the module maintainers.