Trick for FPDI free pdf parser that support PDF version above 1.4
7
up 0 down 0
Already voted for this article!

Trick for FPDI free pdf parser that support PDF version above 1.4

One of our client asked a very interesting question –

Is there any trick for FPDI free Pdf parser to make it compatible with PDF version higher than 1.4 without purchasing the commercial license?

Starting from the introduction of FDPI , it’s a collection of PHP classes allowing developers to read pages from PDF files & use them as templates in FPDF package, which was developed by Olivier Plathey. Apart from a copy of FPDF, FPDI doesn’t require any special PHP extensions. For encrypting PDF files FDPI with FDPF and FDPI-protection package is required.

Directly coming to the point , By default FPDI pdf-parser can “only” handle PDF documents up to PDF version 1.4. With PDF version 1.5 there were new compression features introduced which involve changes in internal structure of a PDF document. Commercial version of FPDI PDF-parser supporting PDF document above 1.4 is available at Setasign but as said its commercial paid version. There are many developers who may want to Encrypt PDF (version above 1.4) from free version of FPDI PDF parser but FPDI free PDF parser doesn’t support it and display one of the following error messages like –

PHP Fatal error: Unable to find xref table - Maybe a Problem with 'auto_detect_line_endings

PHP Fatal error: Uncaught exception 'Exception' with message 'This document (/tmp/document.pdf) probably uses a compression technique which is not supported by the free parser shipped with FPDI. (See https://www.setasign.com/fpdi-pdf-parser for more details)' in /FPDI-1.5.2/pdf_parser.php:329

[... 11:01:06 2015] [error] [client 333.333.333.333] PHP Fatal error:
Uncaught exception 'Exception' with message 'This document (/tmp/label_55a780e22172f.pdf) probably uses a compression technique which is not supported by the free parser shipped with FPDI. (See https://www.setasign.com/fpdi-pdf-parser for more details)' in
...lib/FPDI-1.5.2/pdf_parser.php:329
Stack trace:
#0 ...lib/FPDI-1.5.2/pdf_parser.php(202): pdf_parser->_readXref(Array, 87345)
#1 ...lib/FPDI-1.5.2/fpdi_pdf_parser.php(71): pdf_parser->__construct('/tmp/...')
#2 ...lib/FPDI-1.5.2/fpdi.php(128): fpdi_pdf_parser->__construct('/tmp/..')
#3 ...lib/FPDI-1.5.2/fpdi.php(108): FPDI->_getPdfParser('/tmp/...')
#4 ...php/utils/concatpdf.class.php(37): FPDI->setSourceFile('/tmp/...')
#5 ...php/utils/shipping/provider in ...lib/FPDI-1.5.2/pdf_parser.php on line 329

Indeed getting a code trick and making a free tool compatible for our premium need is much better idea than buying a commercial version of tool. Think like a real smart developer and you will get the code idea of what you want to get done.

Indeed , the simplest way is to convert the PDF file version before it is submitted to FDPI pdf parser. we need to first check the PDF file version with a PHP code.


// pdf version information
$filepdf = fopen("document.pdf","r");
if ($filepdf) {
$line_first = fgets($filepdf);
fclose($filepdf);
} else{
echo "error opening the file.";
}

PDF file version is mostly present in first line of PDF. so we need to read the first line of PDF which will give us something like below response stored in a variable $line_first when using above PHP code –

%PDF-1.5%

Here we get the PDF version but we need to separate version number(1.5) from complete line %PDF-1.5%. so extracting the number from variable $line_first and storing the numeric value in variable $pdfversion using below code.


// extract number such as 1.4 ,1.5 from first read line of pdf file
preg_match_all('!\d+!', $line_first, $matches);	
// save that number in a variable
$pdfversion = implode('.', $matches[0]);

we need to now compare the PDF version of submitted file from 1.4 in such away that if value of variable $pdfversion is greater than 1.4 than proceed with if condition otherwise proceed with else condition.


<?php
if($pdfversion > "1.4"){
// proceed if PDF version greater than 1.4
// convert with ghostscript to version 1.4
// continue with FPDI + FDPF + FDPI PROTECTION
}
else{
// proceed if PDF version upto 1.4
// continue with FPDI + FDPF + FDPI PROTECTION
}
?>

Here we get the PDF version in “only” numeric value stored in a variable/string , as we know very well that free PDF parser only support PDF file upto version 1.4 , so now its time to implement the main logic of converting our PDF file(version above 1.4) into PDF version 1.4 using GHOSTSCRIPT command line. Please make sure that GHOSTSCRIPT is already installed on your server.

use the below command line GHOSTSCRIPT code under PHP exec()


// USE GHOSTSCRIPT IF PDF VERSION ABOVE 1.4 AND SAVE ANY PDF TO VERSION 1.4 , SAVE NEW PDF OF 1.4 VERSION TO NEW LOCATION 
<?php
exec('gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOutputFile="'.$srcfile_new.'" "'.$srcfile.'"'); 
?>

Example Code:


<?php
// Report all errors
error_reporting(E_ALL);
ini_set('display_errors', true);

  // Generate random number and store in $random variable
  $random = rand(1,10000);

  // get pdf file name, send name from ajax on other side and received here 
  $filename = $_POST['filenamepdf'];

  // compete path of pdf file including directory name
  $srcfile = 'pdf-uploaded/'.$filename;
		
  // new path of new pdf file created by ghostscript if file above 1.4 
  $srcfile_new = 'pdf-compatible/'.$filename;
		
  // path of saved encrypted pdf file by fdpi
  $dest_file = 'pdf-encrypted/encrypted-'.$random.'.pdf';
                     
  // read pdf file first line because pdf first line contains pdf version information
  $filepdf = fopen($srcfile,"r");
   if($filepdf) {
     $line_first = fgets($filepdf);
     fclose($filepdf);
   }
   else{
     echo "error opening the file.";
   }
  // extract number such as 1.4,1.5 from first read line of pdf file
  preg_match_all('!\d+!', $line_first, $matches);
					 
  // save that number in a variable
  $pdfversion = implode('.', $matches[0]);

  // compare that number from 1.4(if greater than proceed with ghostscript)
  if($pdfversion > "1.4"){
  // USE GHOSTSCRIPT IF PDF VERSION ABOVE 1.4 AND SAVE ANY PDF TO VERSION 1.4 , SAVE NEW PDF OF 1.4 VERSION TO NEW PATH
    shell_exec('gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOutputFile="'.$srcfile_new.'" "'.$srcfile.'"'); 

    // use now fpdi with pdf parser and fpdi protection
    require_once('fpdi/FPDI_Protection.php');
    $pdf = new \FPDI_Protection();
    $pagecount = $pdf->setSourceFile($srcfile_new);

    for ($loop = 1; $loop <= $pagecount; $loop++) {
      $tplidx = $pdf->importPage($loop);
      $pdf->addPage();
      $pdf->useTemplate($tplidx);
    }

    $pdf->SetProtection(\FPDI_Protection::FULL_PERMISSIONS, "password");
    //$pdf->SetProtection(\FPDI_Protection::FULL_PERMISSIONS, '123456', 'ABCDEF');
    $pdf->Output($dest_file, 'F');
         
  }
  else{						 
    // use FPDI if pdf version upto 1.4 no need for ghostscript 
    require_once('fpdi/FPDI_Protection.php');
    $pdf = new \FPDI_Protection();
    $pagecount = $pdf->setSourceFile($srcfile);

    for ($loop = 1; $loop <= $pagecount; $loop++) {
       $tplidx = $pdf->importPage($loop);
       $pdf->addPage();
       $pdf->useTemplate($tplidx);
     }

    $pdf->SetProtection(\FPDI_Protection::FULL_PERMISSIONS, "password");
    //$pdf->SetProtection(\FPDI_Protection::FULL_PERMISSIONS, '123456', 'ABCDEF');
    $pdf->Output($dest_file, 'F');
  }                
?>

From below You can generate the download link for complete zip for Encrypting any version of PDF files (Includes FPDI + FPDI-protection + FDPF). After generating the link, it will expire in 1 hour. Once expired, you need to re-generate it again in order to download zip.

Generate Download link

Subscribe right now for new blogs notifications and always stay connected with us. please click here

7 thoughts on “Trick for FPDI free pdf parser that support PDF version above 1.4”

  • Jason

    Thanks for sharing, the information came in very useful in a small project I am working on. 🙂

    • webnius_admin

      Jason , thank you too for your positive comment. Myself shoaib and Let me know anytime if I can help you for your any project issue. you can contact me anytime via email / skype.

    • webnius_admin

      muyideen mohammed , it was a server fault and we have fixed it. The download link has started working. you can please try downloading the source code now.

  • jérome

    thank you for sharing your trick !

  • Patrick

    Nice trick! 🙂 but download link doesn’t work 🙁

    • webnius_admin

      we have migrated the hosting & domain recently and the website back-end resources are on maintenance. That’s the reason download link doesn’t work. But its gonna work very soon. Thank you

Leave a Reply to Jason Cancel reply

Your email address will not be published. Required fields are marked *

*