Source for file TCPDFFacade.inc
Documentation is available at TCPDFFacade.inc
require_once $config->get('sysRoot'). 'alpha/lib/tcpdf/config/lang/eng.php';
require_once $config->get('sysRoot'). 'alpha/util/AlphaTCPDF.inc';
* A facade class for the TCPDF library which is used to convert some HTML content provided by the
* Markdown library to a PDF file using FPDF
* @author John Collins <dev@alphaframework.org>
* @version $Id: TCPDFFacade.inc 1454 2011-12-04 15:14:05Z johnc $
* @license http://www.opensource.org/licenses/bsd-license.php The BSD License
* @copyright Copyright (c) 2011, John Collins (founder of Alpha Framework).
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the
* following conditions are met:
* * Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other
* materials provided with the distribution.
* * Neither the name of the Alpha Framework nor the names
* of its contributors may be used to endorse or promote
* products derived from this software without specific
* prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* The HTML-format content that we will render as a PDF
* The PDF object that will be generated from the Markdown HTML content
* The business object that stores the content will be rendered to Markdown
* The auto-generated name of the PDF cache file for the BO
* The auto-generated name of the HTML cache file for the BO generated by Markdown
* @param object $BO the business object that stores the content will be rendered to Markdown
$this->PDFFilename = $config->get('sysRoot'). 'cache/pdf/'. get_class($this->BO). '_'. $this->BO->getID(). '_'. $this->BO->getVersion(). '.pdf';
$PDFDownloadName = str_replace(' ', '_', $this->BO->get('title'). '.pdf');
$this->HTMLFilename = $config->get('sysRoot'). 'cache/html/'. get_class($this->BO). '_'. $this->BO->getID(). '_'. $this->BO->getVersion(). '.html';
// first check the PDF cache, and if its there then re-direct to the file
if($this->checkPDFCache())
$this->serveCachedPDF($PDFDownloadName);
$attachURL = $this->BO->getAttachmentsURL();
if ($this->checkHTMLCache()) {
$this->content = $this->markdown($this->BO->get('content', true), $attachURL);
// Replace all instances of $attachURL in link tags to links to the ViewAttachment controller
preg_match_all('/href\=\"\$attachURL\/.*\"/', $this->content, $attachments);
foreach($attachments[0] as $attachmentURL) {
$start = strpos($attachmentURL, '/');
$end = strrpos($attachmentURL, '"');
$fileName = substr($attachmentURL, $start+ 1, $end- ($start+ 1));
$this->content = str_replace($attachmentURL, 'href='. $this->BO->getAttachmentSecureURL($fileName), $this->content);
// Handle image attachments
preg_match_all('/\<img\ src\=\"\$attachURL\/.*\".*\>/', $this->content, $attachments);
foreach($attachments[0] as $attachmentURL) {
$start = strpos($attachmentURL, '/');
$end = strrpos($attachmentURL, '" alt');
$fileName = substr($attachmentURL, $start+ 1, $end- ($start+ 1));
if($config->get('sysCMSImagesWidget')) {
// get the details of the source image
$path = $this->BO->getAttachmentsLocation(). '/'. $fileName;
$imgType = $image_details[2];
$img = new Image($path, $image_details[0], $image_details[1], $type, 0.95, false, (boolean) $config->get('sysCMSImagesWidgetSecure'));
$this->content = str_replace($attachmentURL, $img->renderHTMLLink(), $this->content);
// render a normal image link to the ViewAttachment controller
$this->content = str_replace($attachmentURL, '<img src="'. $this->BO->getAttachmentSecureURL($fileName). '">', $this->content);
$this->pdf = new AlphaTCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
$this->pdf->SetCreator(PDF_CREATOR);
$this->pdf->SetAuthor($this->BO->get('author'));
$this->pdf->SetTitle($this->BO->get('title'));
$this->pdf->SetSubject($this->BO->get('description'));
// TODO inject tags here?
//$this->pdf->SetKeywords($this->BO->get('keywords'));
$this->pdf->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP, PDF_MARGIN_RIGHT);
$this->pdf->SetHeaderMargin(PDF_MARGIN_HEADER);
$this->pdf->SetFooterMargin(PDF_MARGIN_FOOTER);
$this->pdf->SetAutoPageBreak(TRUE, PDF_MARGIN_BOTTOM);
$this->pdf->setImageScale(2.5);
//set some language-dependent strings
$this->pdf->setLanguageArray($l);
$title = '<h1>'. $this->BO->get('title'). '</h1>';
// add some custom footer info about the article
$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>';
$this->pdf->writeHTML($title, true, 0, true, 0);
// output the HTML content
$this->pdf->writeHTML($this->content, true, 0, true, 0);
// write the article footer
$this->pdf->writeHTML($footer, true, 0, true, 0);
// save this PDF to the cache
$this->pdf->Output($this->PDFFilename, 'F');
$this->serveCachedPDF($PDFDownloadName);
* Facade method which will invoke our custom markdown class rather than the standard one
private function markdown($text, $attachURL= '') {
* Initialize the parser and return the result of its transform method.
$parser_class = 'AlphaMarkdown';
$parser = new $parser_class;
* Replace all instances of $sysURL in the text with the sysURL setting from config
$text = str_replace('$sysURL', $config->get('sysURL'), $text);
// transform text using parser.
return $parser->transform($text);
* @return string HTML rendered the content
* Saves the HTML generated by Markdown to the cache directory
private function HTMLCache() {
// check to ensure that the article is not transient before caching it
if ($this->BO->getID() != '00000000000') {
$fp= fopen($this->HTMLFilename,"w");
throw new AlphaException('Failed to open the cache file for writing, directory permissions my not be set correctly!');
flock($fp,2); // locks the file for writting
flock($fp,3); // unlocks the file
fclose($fp); //closes the file
* Used to check the HTML cache for the BO cache file
* @return bool true if the file exists, false otherwise
private function checkHTMLCache() {
* Method to load the content of the cache file to the $content attribute of this object
private function loadHTMLCache() {
$fp = fopen($this->HTMLFilename,"r");
throw new AlphaException('Failed to open the cache file for reading, directory permissions my not be set correctly!' ,'loadHTMLCache()');
fclose($fp); //closes the file
* Used to check the PDF cache for the BO cache file
* @return bool true if the file exists, false otherwise
private function checkPDFCache() {
* Used to serve the cached PDF file as a download
private function serveCachedPDF($name) {
$handle = fopen ($this->PDFFilename, 'r');
$mimetype = 'application/octet-stream';
header("Pragma: public"); // required
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private",false); // required for certain browsers
header("Content-Transfer-Encoding: binary");
header("Content-Type: " . $mimetype);
header("Content-Length: " . $filesize);
header("Content-Disposition: attachment; filename=\"" . $name . "\";" );
|