<?php

/**
 * This file contains the definition for the html2pdf class.
 *
 * @package CGHTML2PDF
 * @category Utilities
 * @author  calguy1000 <calguy1000@cmsmadesimple.org>
 * @copyright Copyright 2014 by Robert Campbell
 */

namespace CGHTML2PDF;
require_once(dirname(__DIR__).'/vendor/autoload.php');

/**
 * This class provides a convenient mechanism for generating PDF from HTML content.
 *
 * This class will read the modules preferences for page size, orientation, and headers and footers.
 * Though the parameters allow overriding them.
 *
 * This class directly uses <a href="http://www.mpdf1.com">mPdf</a> for generating PDF from HTML.  The HTML
 * provided must be compatible with that understood by mPdf.  Please see the documentation on that website
 * for more information about supported and unsupportd HTML and CSS.
 *
 * Trivial Example:<br/>
 * <code>
 * $obj = new \CGHTML2PDF\html2pdf();<br/>
 * $obj->writeHTML('&lt;p&gt;This is a test&lt;/p&gt;');<br/>
 * $obj->Output();
 * </code>
 */
class html2pdf
{
    /**
     * @ignore
     */
    private $_mpdf;

    /**
     * Constructor.
     *
     * @param array $parms An array of parameters to override the preferences.<br/>
     *  The parms associative array can have the following values:<br/>
     *    string 'orientation' The page orientation.  portrait, or landscape.<br/>
     *    string 'pagesize' The page slze.  Accepted values are letter,legal,A4,A5, etc.<br/>
     *    int 'margin_left' Left margin (in milimiters).<br/>
     *    int 'margin_top' Top margin (in milimiters).  This value must account for the height of any page header.<br/>
     *    int 'margin_bottom' Bottom margin (in milimiters).  This value must account for the height of any page footer.<br/>
     *    int 'margin_right' Right margin (in milimiters).<br/>
     */
    public function __construct($parms)
    {
        $mod = \cms_utils::get_module(MOD_CGHTML2PDF);
        $prefs = $mod->GetPreferences();
        $prefs = array_merge($prefs,$parms);

        $orientation = (strtolower($prefs['orientation']) == 'portrait')?'P':'L';
        $fmt = $prefs['pagesize'];
        if( $orientation == 'L') $fmt .= '-L';

        $lang = substr(strtolower(\CmsNlsOperations::get_current_language()),0,2);
        $encoding = 'UTF-8';
        $margins = array($prefs['margin_left'],$prefs['margin_top'], $prefs['margin_right'],$prefs['margin_bottom']);

        $this->_mpdf = new \mPDF($lang,$fmt,'','',
                                 (int) $prefs['margin_left'], (int) $prefs['margin_right'],
                                 (int) $prefs['margin_top'], (int) $prefs['margin_bottom']);
        $config = cmsms()->GetConfig();
        $this->_mpdf->SetBasePath($config['root_path']);
    }

    /**
     * Generate the PDF code from the HTML.
     * This method does not generate a PDF file, however it builds the in-memory structure so that PDF can be generated.
     * This can be a very memory intensive operation depending upon the size of the document provided.
     *
     * @param string $html The HTML document.
     */
    public function writeHTML($html)
    {
        // if we do not have a htmlpagefooter tag
        $mod = \cms_utils::get_module(MOD_CGHTML2PDF);
        $prefs = $mod->GetPreferences();
        $smarty = \cmsms()->GetSmarty();
        $smarty->assign('cmsms_user',\cge_userops::get_uid_email());

        // fix some macro variables.
        if( $prefs['page_footer'] && !preg_match('/<htmlpagefooter/isU', $html) ) {
            // for each </page> tag, insert the header
            $prefs['page_footer'] = trim($smarty->fetch('string:'.$prefs['page_footer']));
            $footer_html = '<htmlpagefooter name="__'.__CLASS__.'__">'.$prefs['page_footer'].'</htmlpagefooter>';
            $footer_html .= '<sethtmlpagefooter name="__'.__CLASS__.'__"/>';
            $html = preg_replace_callback(
                '#<body(?!_)(.*?)>#i',
                function($matches) use ($footer_html) {
                    return $matches[0].$footer_html;
                },
                $html);
        }

        // if we do not have a htmlpageheader tag
        if( $prefs['page_header'] && !preg_match('/<htmlpageheader/isU', $html) ) {
            // for each <page> tag, insert the header
            $prefs['page_header'] = trim($smarty->fetch('string:'.$prefs['page_header']));
            $header_html = '<htmlpageheader name="__'.__CLASS__.'__">'.$prefs['page_header'].'</htmlpageheader>';
            $header_html .= '<sethtmlpageheader name="__'.__CLASS__.'__"  page="ALL" value="ON" show-this-page="1"/>';
            $html = preg_replace_callback(
                '/<body(?!_)(.*?)>/i',
                function($matches) use ($header_html,$prefs) {
                    return $matches[0].$header_html;
                },
                $html);
        }

        $replacements = array('[PAGE]'=>'{PAGENO}','[NUMPAGES]'=>'{nb}','[NPAGES]'=>'{nb}','[NBPG]'=>'{nbpg}');
        $html = str_replace(array_keys($replacements),array_values($replacements),$html);

        return $this->_mpdf->WriteHTML($html);
    }

    /**
     * Generate PDF output.
     *
     * @param string $filename The destination filename.
     * @param string $dest The output destination.  Possible values are:<br/>
     *   D: Send the file to the browser and force a file download with the name provided.<br/>
     *   F: Save the PDF file to a local file with the name provided.<br/>
     *   I: Send the file inline to the browser (default)<br/>
     *   S: Return the document as a string.  The filename is ignored.
     */
    public function Output($filename = null, $dest = null)
    {
        return $this->_mpdf->Output($filename,$dest);
    }


    /**
     * @ignore
     */
    public function __call($name, $arguments)
    {
        if( method_exists($this->_mpdf,$name) ) {
            return call_user_func_array(array($this->_mpdf,$name),$arguments);
        }
    }
} // end of class

?>
