1
0
mirror of https://github.com/e107inc/e107.git synced 2025-01-18 05:09:05 +01:00
php-e107/e107_plugins/pdf/e107pdf.php
2010-02-10 18:18:01 +00:00

329 lines
11 KiB
PHP

<?php
/*
* e107 website system
*
* Copyright (C) 2008-2009 e107 Inc (e107.org)
* Released under the terms and conditions of the
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt)
*
* Plugin - PDF generator
*
* $Source: /cvs_backup/e107_0.8/e107_plugins/pdf/e107pdf.php,v $
* $Revision$
* $Date$
* $Author$
*/
if (!defined('e107_INIT')) { exit; }
/*
TODO:
1. Look at using disc cache
2. More detailed check on image paths
*/
// Debug option - adds entries to rolling log (only works in 0.8)
//define ('PDF_DEBUG', TRUE);
define ('PDF_DEBUG', FALSE);
define('K_PATH_MAIN', '');
define('K_PATH_URL', SITEURL); // Used with forms (TODO: check validity)
/*
The full tcpdf distribution includes a utility to generate new fonts, as well as lots of other fonts.
It can be downloaded from: http://sourceforge.net/projects/tcpdf/
*/
require_once(e_PLUGIN.'pdf/tcpdf.php'); //require the ufpdf class
include_lan(e_PLUGIN.'pdf/languages/'.e_LANGUAGE.'_admin_pdf.php');
//extend tcpdf class from package with custom functions
class e107PDF extends TCPDF
{
protected $pdfPrefs = array(); // Prefs - loaded before creating a pdf
/**
* Constructor
* @param string $orientation page orientation. Possible values are (case insensitive):<ul><li>P or Portrait (default)</li><li>L or Landscape</li></ul>
* @param string $unit User measure unit. Possible values are:<ul><li>pt: point</li><li>mm: millimeter (default)</li><li>cm: centimeter</li><li>in: inch</li></ul><br />A point equals 1/72 of inch, that is to say about 0.35 mm (an inch being 2.54 cm). This is a very common unit in typography; font sizes are expressed in that unit.
* @param mixed $format The format used for pages. It can be either one of the following values (case insensitive) or a custom format in the form of a two-element array containing the width and the height (expressed in the unit given by unit).<ul><li>4A0</li><li>2A0</li><li>A0</li><li>A1</li><li>A2</li><li>A3</li><li>A4 (default)</li><li>A5</li><li>A6</li><li>A7</li><li>A8</li><li>A9</li><li>A10</li><li>B0</li><li>B1</li><li>B2</li><li>B3</li><li>B4</li><li>B5</li><li>B6</li><li>B7</li><li>B8</li><li>B9</li><li>B10</li><li>C0</li><li>C1</li><li>C2</li><li>C3</li><li>C4</li><li>C5</li><li>C6</li><li>C7</li><li>C8</li><li>C9</li><li>C10</li><li>RA0</li><li>RA1</li><li>RA2</li><li>RA3</li><li>RA4</li><li>SRA0</li><li>SRA1</li><li>SRA2</li><li>SRA3</li><li>SRA4</li><li>LETTER</li><li>LEGAL</li><li>EXECUTIVE</li><li>FOLIO</li></ul>
* @param boolean $unicode TRUE means that the input text is unicode (default = true)
* @param boolean $diskcache if TRUE reduce the RAM memory usage by caching temporary data on filesystem (slower).
* @param String $encoding charset encoding; default is UTF-8
*/
public function __construct($orientation='P',$unit='mm',$format='A4', $unicode = true, $encoding = 'UTF-8', $diskcache = false)
{
global $pdfpref;
//Call parent constructor
parent::__construct($orientation,$unit,$format, $unicode, $encoding, $diskcache);
//Initialization
$this->setCellHeightRatio(1.25); // Should already be the default
}
//default preferences if none present
function getDefaultPDFPrefs()
{
$pdfpref['pdf_margin_left'] = '25';
$pdfpref['pdf_margin_right'] = '15';
$pdfpref['pdf_margin_top'] = '15';
$pdfpref['pdf_font_family'] = 'helvetica';
$pdfpref['pdf_font_size'] = '8';
$pdfpref['pdf_font_size_sitename'] = '14';
$pdfpref['pdf_font_size_page_url'] = '8';
$pdfpref['pdf_font_size_page_number'] = '8';
$pdfpref['pdf_show_logo'] = true;
$pdfpref['pdf_show_sitename'] = false;
$pdfpref['pdf_show_page_url'] = true;
$pdfpref['pdf_show_page_number'] = true;
$pdfpref['pdf_error_reporting'] = true;
return $pdfpref;
}
/**
* Set up the e107 PDF prefs - if can't be loaded from the DB, force some sensible defaults
*/
//get preferences from db
function getPDFPrefs()
{
global $sql, $eArrayStorage;
if(!is_object($eArrayStorage))
{
e107_require_once(e_HANDLER.'arraystorage_class.php');
$eArrayStorage = new ArrayData();
}
if(!is_object($sql)){ $sql = new db; }
$num_rows = $sql -> db_Select('core', '*', "e107_name='pdf' ");
if($num_rows == 0)
{
$tmp = $this->getDefaultPDFPrefs();
$tmp2 = $eArrayStorage->WriteArray($tmp);
$sql -> db_Insert('core', "'pdf', '".$tmp2."' ");
$sql -> db_Select('core', '*', "e107_name='pdf' ");
}
$row = $sql -> db_Fetch();
$pdfPref = $eArrayStorage->ReadArray($row['e107_value']);
return $pdfPref;
}
/**
* Convert e107-encoded text to body text
* @param string $text
* @return string with various entities replaced with their equivalent characters
*/
function toPDF($text)
{
$search = array('&#39;', '&#039;', '&#036;', '&quot;');
$replace = array("'", "'", '$', '"');
$text = str_replace($search, $replace, $text);
return $text;
}
/**
* Convert e107-encoded text to title text
* @param string $text
* @return string with various characters replaced with '-' TODO: Why?
*/
function toPDFTitle($text)
{
$search = array(":", "*", "?", '"', '<', '>', '|');
$replace = array('-', '-', '-', '-', '-', '-', '-');
$text = str_replace($search, $replace, $text);
return $text;
}
/**
* The makePDF function does all the real parsing and composing
* @param array $text needs to be an array containing the following:
* $text = array($text, $creator, $author, $title, $subject, $keywords, $url[, $orientation]);
* @return - none (the PDF file is output, all being well)
*/
function makePDF($text)
{
$tp = e107::getParser();
//call get preferences
$this->pdfPref = $this->getPDFPrefs();
//define logo and source pageurl (before the parser!)
if(is_readable(THEME.'images/logopdf.png'))
{
$logo = THEME.'images/logopdf.png';
}
else
{
$logo = e_IMAGE.'logo.png';
}
define('PDFLOGO', $logo); //define logo to add in header
define('PDFPAGEURL', $text[6]); //define page url to add in header
//parse the data
$text[3] = $this->toPDF($text[3]); //replace some in the title
$text[3] = $this->toPDFTitle($text[3]); //replace some in the title
foreach($text as $k=>$v)
{
$text[$k] = $tp->toHTML($v, TRUE, 'BODY');
}
//set some variables
$this->SetMargins($this->pdfPref['pdf_margin_left'],$this->pdfPref['pdf_margin_top'],$this->pdfPref['pdf_margin_right']);
$this->SetAutoPageBreak(true,25); // Force new page break at 25mm from bottom
$this->SetPrintHeader(TRUE);
//start creating the pdf and adding the data
$this->DefOrientation=(varset($text[7], 'P') == 'L' ? 'L' : 'P'); // Page orientation - P=portrait, L=landscape
$this->AliasNbPages(); //calculate current page + number of pages
$this->AddPage(); //start page
$this->SetFont($this->pdfPref['pdf_font_family'],'',$this->pdfPref['pdf_font_size']); //set font
$this->SetHeaderFont(array($this->pdfPref['pdf_font_family'],'',$this->pdfPref['pdf_font_size']));
$this->SetFooterFont(array($this->pdfPref['pdf_font_family'],'',$this->pdfPref['pdf_font_size']));
$this->WriteHTML($text[0], true); //write text TODO: possibly other parameters
$this->SetCreator($text[1]); //name of creator
$this->SetAuthor($text[2]); //name of author
$this->SetTitle($text[3]); //title
$this->SetSubject($text[4]); //subject
$this->SetKeywords($text[5]); //space/comma separated
$file = $text[3].'.pdf'; //name of the file
$this->Output($file, 'D'); //Save PDF to file (D = output to download window)
return;
}
/**
* Add e107-specific header to each page.
* Uses various prefs set in the admin page.
* Overrides the tcpdf default header function
*/
function Header()
{
$pageWidth = $this->getPageWidth(); // Will be 210 for A4 portrait
$ormargins = $this->getOriginalMargins();
$headerfont = $this->getHeaderFont();
$headerdata = $this->getHeaderData();
$topMargin = $this->pdfPref['pdf_margin_top'];
if($this->pdfPref['pdf_show_logo'])
{
$this->SetFont($this->pdfPref['pdf_font_family'],'',$this->pdfPref['pdf_font_size']);
$this->Image(PDFLOGO, $this->GetX(), $topMargin);
$imgx = $this->getImageRBX();
$imgy = $this->getImageRBY(); // Coordinates of bottom right of logo
$a=$this->GetStringWidth(SITENAME);
$b=$this->GetStringWidth(PDFPAGEURL);
$c = max($a, $b) + $this->rMargin;
if(($imgx + $c) > $pageWidth) // See if room for other text to right of logo
{ // No room - move to underneath
$this->SetX($this->lMargin);
$this->SetY($imgy+2);
}
else
{
$m = 0;
if($this->pdfPref['pdf_show_sitename'])
{
$m = 5;
}
if($this->pdfPref['pdf_show_page_url'])
{
$m += 5;
}
if($this->pdfPref['pdf_show_page_number'])
{
$m += 5;
}
$this->SetX($imgx); // May not be needed
$newY = max($topMargin, $imgy - $m);
$this->SetY($newY); //Room to right of logo - calculate space to line up bottom of text with bottom of logo
}
}
else
{
$this->SetY($topMargin);
}
// Now print text - 'cursor' positioned in correct start position
$cellwidth = $pageWidth - $this->GetX()-$this->rMargin;
$align = 'R';
// echo "imgx: {$imgx} imgy: {$imgy} cellwidth: {$cellwidth} m: {$m} <br />";
if($this->pdfPref['pdf_show_sitename'])
{
$this->SetFont($this->pdfPref['pdf_font_family'],'B',$this->pdfPref['pdf_font_size_sitename']);
$this->Cell($cellwidth,5,SITENAME,0,1,$align);
}
if($this->pdfPref['pdf_show_page_url'])
{
$this->SetFont($this->pdfPref['pdf_font_family'],'I',$this->pdfPref['pdf_font_size_page_url']);
$this->Cell($cellwidth,5,PDFPAGEURL,0,1,$align,'',PDFPAGEURL);
}
if($this->pdfPref['pdf_show_page_number'])
{
$this->SetFont($this->pdfPref['pdf_font_family'],'I',$this->pdfPref['pdf_font_size_page_number']);
$this->Cell($cellwidth,5,PDF_LAN_19.' '.$this->PageNo().'/{nb}',0,1,$align); // {nb} is an alias for the total number of pages
}
$this->SetFont($this->pdfPref['pdf_font_family'],'',$this->pdfPref['pdf_font_size']);
// Following cloned from tcpdf header function
$this->SetY((2.835 / $this->getScaleFactor()) + max($imgy, $this->GetY())); // 2.835 is number of pixels per mm
if ($this->getRTL())
{
$this->SetX($ormargins['right']);
}
else
{
$this->SetX($ormargins['left']);
}
$this->Cell(0, 0, '', 'T', 0, 'C'); // This puts a line between header and text
$this->SetTopMargin($this->GetY()+2); // FIXME: Bodge to force main body text to start below header
}
/**
* Override standard function to use our own font directory
*/
protected function _getfontpath()
{
return str_replace(e_HTTP, e_ROOT, e_PLUGIN_ABS.'pdf/font/');
}
/**
* Called by tcpdf when it encounters a file reference - e.g. source file name in 'img' tag - so we can tweak the source path
* (tcpdf modified to check for a class extension which adds this method)
* @param string $fileName - name of file as it appears in the 'src' parameter
* @param string $source - name of tag which provoked call (might be useful to affect encoding)
* @return string - file name adjusted to suit tcpdf
*/
function filePathModify($fileName, $source = '')
{
if (substr($fileName,0,1) == '/')
{ // Its an absolute file reference
return str_replace(e_HTTP,e_ROOT,$fileName);
}
else
{ // Its a relative link
return realpath($fileName);
}
}
}
?>