Alpha Framework alpha--util
[ class tree: alpha--util ] [ index: alpha--util ] [ all elements ]

Source for file TCPDFFacade.inc

Documentation is available at TCPDFFacade.inc

  1. <?php
  2.  
  3. require_once $config->get('sysRoot').'alpha/lib/tcpdf/config/lang/eng.php';
  4. require_once $config->get('sysRoot').'alpha/util/AlphaTCPDF.inc';
  5.  
  6. /**
  7.  *
  8.  * A facade class for the TCPDF library which is used to convert some HTML content provided by the
  9.  * Markdown library to a PDF file using FPDF
  10.  * 
  11.  * @package alpha::util
  12.  * @since 1.0
  13.  * @author John Collins <dev@alphaframework.org>
  14.  * @version $Id: TCPDFFacade.inc 1454 2011-12-04 15:14:05Z johnc $
  15.  * @license http://www.opensource.org/licenses/bsd-license.php The BSD License
  16.  * @copyright Copyright (c) 2011, John Collins (founder of Alpha Framework).
  17.  *  All rights reserved.
  18.  * 
  19.  *  <pre>
  20.  *  Redistribution and use in source and binary forms, with or
  21.  *  without modification, are permitted provided that the
  22.  *  following conditions are met:
  23.  * 
  24.  *  * Redistributions of source code must retain the above
  25.  *    copyright notice, this list of conditions and the
  26.  *    following disclaimer.
  27.  *  * Redistributions in binary form must reproduce the above
  28.  *    copyright notice, this list of conditions and the
  29.  *    following disclaimer in the documentation and/or other
  30.  *    materials provided with the distribution.
  31.  *  * Neither the name of the Alpha Framework nor the names
  32.  *    of its contributors may be used to endorse or promote
  33.  *    products derived from this software without specific
  34.  *    prior written permission.
  35.  *   
  36.  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
  37.  *  CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  38.  *  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  39.  *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  40.  *  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
  41.  *  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  42.  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  43.  *  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  44.  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  45.  *  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  46.  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
  47.  *  OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  48.  *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  49.  *  </pre>
  50.  *  
  51.  */ 
  52. class TCPDFFacade {
  53.     /**
  54.      * The HTML-format content that we will render as a PDF
  55.      * 
  56.      * @var string 
  57.      * @since 1.0
  58.      */    
  59.     private $content;
  60.     
  61.     /**
  62.      * The PDF object that will be generated from the Markdown HTML content
  63.      * 
  64.      * @var AlphaTCPDF 
  65.      * @since 1.0
  66.      */
  67.     private $pdf;
  68.     
  69.     /**
  70.      * The business object that stores the content will be rendered to Markdown
  71.      * 
  72.      * @var AlphaDAO 
  73.      * @since 1.0
  74.      */
  75.     private $BO null;
  76.     
  77.     /**
  78.      * The auto-generated name of the PDF cache file for the BO
  79.      * 
  80.      * @var string 
  81.      * @since 1.0
  82.      */
  83.     private $PDFFilename;
  84.     
  85.     /**
  86.      * The auto-generated name of the HTML cache file for the BO generated by Markdown
  87.      * 
  88.      * @var string 
  89.      * @since 1.0
  90.      */
  91.     private $HTMLFilename;
  92.     
  93.     /**
  94.      * The constructor
  95.      * 
  96.      * @param object $BO the business object that stores the content will be rendered to Markdown
  97.      * @since 1.0
  98.      */
  99.     public function __construct($BO{
  100.         global $config;
  101.         global $l;
  102.         
  103.         $this->BO $BO;
  104.         $this->PDFFilename $config->get('sysRoot').'cache/pdf/'.get_class($this->BO).'_'.$this->BO->getID().'_'.$this->BO->getVersion().'.pdf';
  105.         $PDFDownloadName str_replace(' ''_'$this->BO->get('title').'.pdf');
  106.         $this->HTMLFilename $config->get('sysRoot').'cache/html/'.get_class($this->BO).'_'.$this->BO->getID().'_'.$this->BO->getVersion().'.html';
  107.         
  108.         // first check the PDF cache, and if its there then re-direct to the file
  109.         if($this->checkPDFCache())
  110.             $this->serveCachedPDF($PDFDownloadName);
  111.         
  112.         if(method_exists($this->BO'getAttachmentsURL'))
  113.             $attachURL $this->BO->getAttachmentsURL();
  114.         else
  115.             $attachURL '';
  116.         
  117.         if ($this->checkHTMLCache()) {
  118.             $this->loadHTMLCache();
  119.         }else{
  120.             $this->content $this->markdown($this->BO->get('content'true)$attachURL);
  121.             $this->HTMLCache();
  122.         }
  123.         
  124.         // Replace all instances of $attachURL in link tags to links to the ViewAttachment controller
  125.         $attachments array();        
  126.         preg_match_all('/href\=\"\$attachURL\/.*\"/'$this->content$attachments);
  127.         
  128.         foreach($attachments[0as $attachmentURL{
  129.             $start strpos($attachmentURL'/');
  130.             $end strrpos($attachmentURL'"');
  131.             $fileName substr($attachmentURL$start+1$end-($start+1));
  132.  
  133.             if(method_exists($this->BO'getAttachmentSecureURL')) {
  134.                 $this->content str_replace($attachmentURL'href='.$this->BO->getAttachmentSecureURL($fileName)$this->content);
  135.             }
  136.         }
  137.         
  138.         // Handle image attachments        
  139.         $attachments array();        
  140.         preg_match_all('/\<img\ src\=\"\$attachURL\/.*\".*\>/'$this->content$attachments);
  141.             
  142.         foreach($attachments[0as $attachmentURL{
  143.             $start strpos($attachmentURL'/');
  144.             $end strrpos($attachmentURL'" alt');
  145.             $fileName substr($attachmentURL$start+1$end-($start+1));
  146.     
  147.             if($config->get('sysCMSImagesWidget')) {
  148.                 // get the details of the source image
  149.                 $path $this->BO->getAttachmentsLocation().'/'.$fileName;
  150.                 $image_details getimagesize($path);
  151.                 $imgType $image_details[2];
  152.                 if($imgType == 1)
  153.                     $type 'gif';
  154.                 elseif($imgType == 2)
  155.                     $type 'jpg';
  156.                 elseif($imgType == 3)
  157.                     $type 'png';
  158.                     
  159.                 $img new Image($path$image_details[0]$image_details[1]$type0.95false(boolean)$config->get('sysCMSImagesWidgetSecure'));
  160.                 $this->content str_replace($attachmentURL$img->renderHTMLLink()$this->content);
  161.             }else{
  162.                 // render a normal image link to the ViewAttachment controller                
  163.                 if(method_exists($this->BO'getAttachmentSecureURL')) {
  164.                     $this->content str_replace($attachmentURL'<img src="'.$this->BO->getAttachmentSecureURL($fileName).'">'$this->content);
  165.                 }
  166.             }
  167.         }
  168.         
  169.         $this->pdf new AlphaTCPDF(PDF_PAGE_ORIENTATIONPDF_UNITPDF_PAGE_FORMATtrue'UTF-8'false);
  170.         $this->pdf->SetCreator(PDF_CREATOR);
  171.         $this->pdf->SetAuthor($this->BO->get('author'));
  172.         $this->pdf->SetTitle($this->BO->get('title'));
  173.         $this->pdf->SetSubject($this->BO->get('description'));
  174.         // TODO inject tags here?
  175.         //$this->pdf->SetKeywords($this->BO->get('keywords'));
  176.         
  177.         //set margins
  178.         $this->pdf->SetMargins(PDF_MARGIN_LEFTPDF_MARGIN_TOPPDF_MARGIN_RIGHT);
  179.         $this->pdf->SetHeaderMargin(PDF_MARGIN_HEADER);
  180.         $this->pdf->SetFooterMargin(PDF_MARGIN_FOOTER);
  181.         
  182.         //set auto page breaks
  183.         $this->pdf->SetAutoPageBreak(TRUEPDF_MARGIN_BOTTOM);
  184.         
  185.         //set image scale factor
  186.         $this->pdf->setImageScale(2.5)
  187.         
  188.         //set some language-dependent strings
  189.         $this->pdf->setLanguageArray($l);
  190.         
  191.         // add a page
  192.         $this->pdf->AddPage();
  193.         
  194.         // add the title
  195.         $title '<h1>'.$this->BO->get('title').'</h1>';
  196.         // add some custom footer info about the article        
  197.         $footer '<br><p>Article URL: <a href="'.$this->BO->get('URL').'">'.$this->BO->get('URL').'</a><br>Title: '.$this->BO->get('title').'<br>Author: '.$this->BO->get('author').'</p>';
  198.         
  199.         // write the title
  200.         $this->pdf->writeHTML($titletrue0true0);
  201.         // output the HTML content
  202.         $this->pdf->writeHTML($this->contenttrue0true0);
  203.         // write the article footer
  204.         $this->pdf->writeHTML($footertrue0true0);        
  205.         
  206.         // save this PDF to the cache
  207.         $this->pdf->Output($this->PDFFilename'F');        
  208.         $this->serveCachedPDF($PDFDownloadName);
  209.     }
  210.     
  211.     /**
  212.      * Facade method which will invoke our custom markdown class rather than the standard one
  213.      * 
  214.      * @since 1.0
  215.      */
  216.      private function markdown($text$attachURL=''{
  217.          global $config;
  218.          
  219.         /*
  220.          * Initialize the parser and return the result of its transform method.
  221.          * 
  222.          */        
  223.         static $parser;
  224.         if (!isset($parser)) {
  225.             $parser_class 'AlphaMarkdown';
  226.             $parser new $parser_class;
  227.         }
  228.         
  229.         /*
  230.          * Replace all instances of $sysURL in the text with the sysURL setting from config
  231.          * 
  232.          */
  233.         $text str_replace('$sysURL'$config->get('sysURL')$text);
  234.         
  235.         // transform text using parser.
  236.         return $parser->transform($text);
  237.     }
  238.     
  239.     /**
  240.      * Fetter for the content
  241.      * 
  242.      * @return string HTML rendered the content
  243.      * @since 1.0
  244.      */
  245.     public function getContent({
  246.         return $this->content;
  247.     }
  248.     
  249.     /**
  250.      * Saves the HTML generated by Markdown to the cache directory
  251.      * 
  252.      * @since 1.0
  253.      */
  254.     private function HTMLCache({
  255.         // check to ensure that the article is not transient before caching it
  256.         if ($this->BO->getID(!= '00000000000'{
  257.             $fp=fopen($this->HTMLFilename,"w");
  258.             if (!$fp{
  259.                 throw new AlphaException('Failed to open the cache file for writing, directory permissions my not be set correctly!');
  260.             }else{
  261.                 flock($fp,2)// locks the file for writting            
  262.                 fwrite($fp,$this->content)
  263.                 flock($fp,3)// unlocks the file
  264.                 fclose($fp)//closes the file
  265.             }
  266.         }
  267.     }
  268.     
  269.     /**
  270.      * Used to check the HTML cache for the BO cache file
  271.      *      
  272.      * @return bool true if the file exists, false otherwise
  273.      * @since 1.0
  274.      */
  275.     private function checkHTMLCache({
  276.         global $config;
  277.         
  278.         return file_exists($this->HTMLFilename);
  279.     }
  280.     
  281.     /**
  282.      * Method to load the content of the cache file to the $content attribute of this object
  283.      * 
  284.      * @since 1.0
  285.      */
  286.     private function loadHTMLCache({        
  287.         $fp fopen($this->HTMLFilename,"r");
  288.         
  289.         if (!$fp{
  290.             throw new AlphaException('Failed to open the cache file for reading, directory permissions my not be set correctly!' ,'loadHTMLCache()');
  291.         }else{                    
  292.             $this->content fread($fpfilesize($this->HTMLFilename));            
  293.             fclose($fp)//closes the file            
  294.         }
  295.     }
  296.     
  297.     /**
  298.      * Used to check the PDF cache for the BO cache file
  299.      *      
  300.      * @return bool true if the file exists, false otherwise
  301.      * @since 1.0
  302.      */
  303.     private function checkPDFCache({
  304.         return file_exists($this->PDFFilename);
  305.     }
  306.     
  307.     /**
  308.      * Used to serve the cached PDF file as a download
  309.      * 
  310.      * @since 1.0
  311.      */
  312.     private function serveCachedPDF($name{
  313.         // first load the file
  314.         $handle fopen ($this->PDFFilename'r')
  315.         $data fread($handlefilesize($this->PDFFilename));
  316.         fclose($handle);
  317.         
  318.         $filesize strlen($data);
  319.         $mimetype 'application/octet-stream';
  320.             
  321.         // Start sending headers
  322.         header("Pragma: public")// required
  323.         header("Expires: 0");
  324.         header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
  325.         header("Cache-Control: private",false)// required for certain browsers
  326.         header("Content-Transfer-Encoding: binary");
  327.         header("Content-Type: " $mimetype);
  328.         header("Content-Length: " $filesize);
  329.         header("Content-Disposition: attachment; filename=\"" $name "\";" );
  330.     
  331.         // Send data
  332.         echo $data;
  333.         die();
  334.     }
  335. }
  336. ?>

Documentation generated on Tue, 13 Dec 2011 20:27:39 +0000 by phpDocumentor 1.4.3