PDF convertor
* distributed under the LGPL License
*
* @package Html2pdf
* @author Laurent MINGUET
* @copyright 2016 Laurent MINGUET
*/
require_once(dirname(__FILE__).'/_class/tcpdfConfig.php');
class HTML2PDF
{
/**
* HTML2PDF_myPdf object, extends from TCPDF
* @var HTML2PDF_myPdf
*/
public $pdf = null;
/**
* CSS parsing
* @var HTML2PDF_parsingCss
*/
public $parsingCss = null;
/**
* HTML parsing
* @var HTML2PDF_parsingHtml
*/
public $parsingHtml = null;
protected $_langue = 'fr'; // locale of the messages
protected $_orientation = 'P'; // page orientation : Portrait ou Landscape
protected $_format = 'A4'; // page format : A4, A3, ...
protected $_encoding = ''; // charset encoding
protected $_unicode = true; // means that the input text is unicode (default = true)
protected $_testTdInOnepage = true; // test of TD that can not take more than one page
protected $_testIsImage = true; // test if the images exist or not
protected $_testIsDeprecated = false; // test the deprecated functions
protected $_fallbackImage = null; // fallback image to use in img tags
protected $_parsePos = 0; // position in the parsing
protected $_tempPos = 0; // temporary position for complex table
protected $_page = 0; // current page number
protected $_subHtml = null; // sub html
protected $_subPart = false; // sub HTML2PDF
protected $_subHEADER = array(); // sub action to make the header
protected $_subFOOTER = array(); // sub action to make the footer
protected $_subSTATES = array(); // array to save some parameters
protected $_isSubPart = false; // flag : in a sub html2pdf
protected $_isInThead = false; // flag : in a thead
protected $_isInTfoot = false; // flag : in a tfoot
protected $_isInOverflow = false; // flag : in a overflow
protected $_isInFooter = false; // flag : in a footer
protected $_isInDraw = null; // flag : in a draw (svg)
protected $_isAfterFloat = false; // flag : is just after a float
protected $_isInForm = false; // flag : is in a float. false / action of the form
protected $_isInLink = ''; // flag : is in a link. empty / href of the link
protected $_isInParagraph = false; // flag : is in a paragraph
protected $_isForOneLine = false; // flag : in a specific sub html2pdf to have the height of the next line
protected $_maxX = 0; // maximum X of the current zone
protected $_maxY = 0; // maximum Y of the current zone
protected $_maxE = 0; // number of elements in the current zone
protected $_maxH = 0; // maximum height of the line in the current zone
protected $_maxSave = array(); // save the maximums of the current zone
protected $_currentH = 0; // height of the current line
protected $_defaultLeft = 0; // default marges of the page
protected $_defaultTop = 0;
protected $_defaultRight = 0;
protected $_defaultBottom = 0;
protected $_defaultFont = null; // default font to use, is the asked font does not exist
protected $_margeLeft = 0; // current marges of the page
protected $_margeTop = 0;
protected $_margeRight = 0;
protected $_margeBottom = 0;
protected $_marges = array(); // save the different marges of the current page
protected $_pageMarges = array(); // float marges of the current page
protected $_background = array(); // background informations
protected $_hideHeader = array(); // array : list of pages which the header gonna be hidden
protected $_firstPage = true; // flag : first page
protected $_defList = array(); // table to save the stats of the tags UL and OL
protected $_lstAnchor = array(); // list of the anchors
protected $_lstField = array(); // list of the fields
protected $_lstSelect = array(); // list of the options of the current select
protected $_previousCall = null; // last action called
protected $_debugActif = false; // flag : mode debug is active
protected $_debugOkUsage = false; // flag : the function memory_get_usage exist
protected $_debugOkPeak = false; // flag : the function memory_get_peak_usage exist
protected $_debugLevel = 0; // level in the debug
protected $_debugStartTime = 0; // debug start time
protected $_debugLastTime = 0; // debug stop time
static protected $_subobj = null; // object html2pdf prepared in order to accelerate the creation of sub html2pdf
static protected $_tables = array(); // static table to prepare the nested html tables
/**
* class constructor
*
* @access public
* @param string $orientation page orientation, same as TCPDF
* @param mixed $format The format used for pages, same as TCPDF
* @param $tring $langue Lang : fr, en, it...
* @param boolean $unicode TRUE means that the input text is unicode (default = true)
* @param String $encoding charset encoding; default is UTF-8
* @param array $marges Default margins (left, top, right, bottom)
* @return HTML2PDF $this
*/
public function __construct($orientation = 'P', $format = 'A4', $langue='fr', $unicode=true, $encoding='UTF-8', $marges = array(5, 5, 5, 8))
{
// init the page number
$this->_page = 0;
$this->_firstPage = true;
// save the parameters
$this->_orientation = $orientation;
$this->_format = $format;
$this->_langue = strtolower($langue);
$this->_unicode = $unicode;
$this->_encoding = $encoding;
// load the Local
HTML2PDF_locale::load($this->_langue);
// create the HTML2PDF_myPdf object
$this->pdf = new HTML2PDF_myPdf($orientation, 'mm', $format, $unicode, $encoding);
// init the CSS parsing object
$this->parsingCss = new HTML2PDF_parsingCss($this->pdf);
$this->parsingCss->fontSet();
$this->_defList = array();
// init some tests
$this->setTestTdInOnePage(true);
$this->setTestIsImage(true);
$this->setTestIsDeprecated(true);
// init the default font
$this->setDefaultFont(null);
// init the HTML parsing object
$this->parsingHtml = new HTML2PDF_parsingHtml($this->_encoding);
$this->_subHtml = null;
$this->_subPart = false;
// init the marges of the page
if (!is_array($marges)) $marges = array($marges, $marges, $marges, $marges);
$this->_setDefaultMargins($marges[0], $marges[1], $marges[2], $marges[3]);
$this->_setMargins();
$this->_marges = array();
// init the form's fields
$this->_lstField = array();
return $this;
}
/**
* Destructor
*
* @access public
* @return null
*/
public function __destruct()
{
}
/**
* Gets the detailed version as array
*
* @return array
*/
public function getVersionAsArray()
{
return array(
'major' => 4,
'minor' => 6,
'revision' => 1,
);
}
/**
* Gets the current version as string
*
* @return string
*/
public function getVersion()
{
$v = $this->getVersionAsArray();
return $v['major'].'.'.$v['minor'].'.'.$v['revision'];
}
/**
* Clone to create a sub HTML2PDF from HTML2PDF::$_subobj
*
* @access public
*/
public function __clone()
{
$this->pdf = clone $this->pdf;
$this->parsingHtml = clone $this->parsingHtml;
$this->parsingCss = clone $this->parsingCss;
$this->parsingCss->setPdfParent($this->pdf);
}
/**
* set the debug mode to On
*
* @access public
* @return HTML2PDF $this
*/
public function setModeDebug()
{
$time = microtime(true);
$this->_debugActif = true;
$this->_debugOkUsage = function_exists('memory_get_usage');
$this->_debugOkPeak = function_exists('memory_get_peak_usage');
$this->_debugStartTime = $time;
$this->_debugLastTime = $time;
$this->_DEBUG_stepline('step', 'time', 'delta', 'memory', 'peak');
$this->_DEBUG_add('Init debug');
return $this;
}
/**
* Set the test of TD that can not take more than one page
*
* @access public
* @param boolean $mode
* @return HTML2PDF $this
*/
public function setTestTdInOnePage($mode = true)
{
$this->_testTdInOnepage = $mode ? true : false;
return $this;
}
/**
* Set the test if the images exist or not
*
* @access public
* @param boolean $mode
* @return HTML2PDF $this
*/
public function setTestIsImage($mode = true)
{
$this->_testIsImage = $mode ? true : false;
return $this;
}
/**
* @param string $fallback Path or URL to the fallback image
*
* @return $this
*/
public function setFallbackImage($fallback)
{
$this->_fallbackImage = $fallback;
return $this;
}
/**
* Set the test on deprecated functions
*
* @access public
* @param boolean $mode
* @return HTML2PDF $this
*/
public function setTestIsDeprecated($mode = true)
{
$this->_testIsDeprecated = $mode ? true : false;
return $this;
}
/**
* Set the default font to use, if no font is specified, or if the asked font does not exist
*
* @access public
* @param string $default name of the default font to use. If null : Arial if no font is specified, and error if the asked font does not exist
* @return HTML2PDF $this
*/
public function setDefaultFont($default = null)
{
$this->_defaultFont = $default;
$this->parsingCss->setDefaultFont($default);
return $this;
}
/**
* add a font, see TCPDF function addFont
*
* @access public
* @param string $family Font family. The name can be chosen arbitrarily. If it is a standard family name, it will override the corresponding font.
* @param string $style Font style. Possible values are (case insensitive):
empty string: regular (default)
B: bold
I: italic
BI or IB: bold italic
* @param string $file The font definition file. By default, the name is built from the family and style, in lower case with no spaces.
* @return HTML2PDF $this
* @see TCPDF::addFont
*/
public function addFont($family, $style='', $file='')
{
$this->pdf->AddFont($family, $style, $file);
return $this;
}
/**
* display a automatic index, from the bookmarks
*
* @access public
* @param string $titre index title
* @param int $sizeTitle font size of the index title, in mm
* @param int $sizeBookmark font size of the index, in mm
* @param boolean $bookmarkTitle add a bookmark for the index, at his beginning
* @param boolean $displayPage display the page numbers
* @param int $onPage if null : at the end of the document on a new page, else on the $onPage page
* @param string $fontName font name to use
* @return null
*/
public function createIndex($titre = 'Index', $sizeTitle = 20, $sizeBookmark = 15, $bookmarkTitle = true, $displayPage = true, $onPage = null, $fontName = 'helvetica')
{
$oldPage = $this->_INDEX_NewPage($onPage);
$this->pdf->createIndex($this, $titre, $sizeTitle, $sizeBookmark, $bookmarkTitle, $displayPage, $onPage, $fontName);
if ($oldPage) $this->pdf->setPage($oldPage);
}
/**
* clean up the objects
*
* @access protected
*/
protected function _cleanUp()
{
HTML2PDF::$_subobj = null;
HTML2PDF::$_tables = array();
}
/**
* Send the document to a given destination: string, local file or browser.
* Dest can be :
* I : send the file inline to the browser (default). The plug-in is used if available. The name given by name is used when one selects the "Save as" option on the link generating the PDF.
* D : send to the browser and force a file download with the name given by name.
* F : save to a local server file with the name given by name.
* S : return the document as a string. name is ignored.
* FI: equivalent to F + I option
* FD: equivalent to F + D option
* true => I
* false => S
*
* @param string $name The name of the file when saved.
* @param string $dest Destination where to send the document.
* @return string content of the PDF, if $dest=S
* @throws HTML2PDF_exception
* @see TCPDF::close
* @access public
*/
public function Output($name = '', $dest = false)
{
// close the pdf and clean up
$this->_cleanUp();
// if on debug mode
if ($this->_debugActif) {
$this->_DEBUG_add('Before output');
$this->pdf->Close();
exit;
}
// complete parameters
if ($dest===false) $dest = 'I';
if ($dest===true) $dest = 'S';
if ($dest==='') $dest = 'I';
if ($name=='') $name='document.pdf';
// clean up the destination
$dest = strtoupper($dest);
if (!in_array($dest, array('I', 'D', 'F', 'S', 'FI','FD'))) $dest = 'I';
// the name must be a PDF name
if (strtolower(substr($name, -4))!='.pdf') {
throw new HTML2PDF_exception(0, 'The output document name "'.$name.'" is not a PDF name');
}
// call the output of TCPDF
return $this->pdf->Output($name, $dest);
}
/**
* convert HTML to PDF
*
* @access public
* @param string $html
* @param boolean $debugVue enable the HTML debug vue
* @return null
*/
public function writeHTML($html, $debugVue = false)
{
// if it is a real html page, we have to convert it
if (preg_match('/getHtmlFromPage($html);
$html = str_replace('[[date_y]]', date('Y'), $html);
$html = str_replace('[[date_m]]', date('m'), $html);
$html = str_replace('[[date_d]]', date('d'), $html);
$html = str_replace('[[date_h]]', date('H'), $html);
$html = str_replace('[[date_i]]', date('i'), $html);
$html = str_replace('[[date_s]]', date('s'), $html);
// If we are in HTML debug vue : display the HTML
if ($debugVue) {
return $this->_vueHTML($html);
}
// convert HTMl to PDF
$this->parsingCss->readStyle($html);
$this->parsingHtml->setHTML($html);
$this->parsingHtml->parse();
$this->_makeHTMLcode();
}
/**
* convert the HTML of a real page, to a code adapted to HTML2PDF
*
* @access public
* @param string $html HTML code of a real page
* @return string HTML adapted to HTML2PDF
*/
public function getHtmlFromPage($html)
{
$html = str_replace('';
// extract the link tags
preg_match_all('/]*)>/isU', $html, $match);
foreach ($match[0] as $src)
$content = $src.''.$content;
// extract the css style tags
preg_match_all('/