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

Source for file AlphaTCPDF.inc

Documentation is available at AlphaTCPDF.inc

  1. <?php
  2.  
  3. require_once $config->get('sysRoot').'alpha/lib/tcpdf/tcpdf.php';
  4. require_once $config->get('sysRoot').'alpha/controller/front/FrontController.inc';
  5. require_once $config->get('sysRoot').'alpha/util/helpers/AlphaValidator.inc';
  6. require_once $config->get('sysRoot').'alpha/view/widgets/Image.inc';
  7.  
  8. /**
  9.  * Custom version of the TCPDF library class, allowing for any required overrides.
  10.  * 
  11.  * @package alpha::util
  12.  * @since 1.0
  13.  * @author John Collins <dev@alphaframework.org>
  14.  * @version $Id: AlphaTCPDF.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 AlphaTCPDF extends TCPDF {
  53.     /**
  54.      * Trace logger
  55.      * 
  56.      * @var Logger 
  57.      * @since 1.0
  58.      */
  59.     private static $logger = null;
  60.     
  61.     /**
  62.      * Overrides the TCPDF::Image method to decrypt encrypted $file paths from the Image widget, then pass
  63.      * them to the normal TCPDF::Image along with all of the other (unmodified) parameters.
  64.      * 
  65.      * @param string $file Name of the file containing the image.
  66.      * @param float $x Abscissa of the upper-left corner.
  67.      * @param float $y Ordinate of the upper-left corner.
  68.      * @param float $w Width of the image in the page. If not specified or equal to zero, it is automatically calculated.
  69.      * @param float $h Height of the image in the page. If not specified or equal to zero, it is automatically calculated.
  70.      * @param string $type Image format. Possible values are (case insensitive): JPEG and PNG (whitout GD library) and all images supported by GD: GD, GD2, GD2PART, GIF, JPEG, PNG, BMP, XBM, XPM;. If not specified, the type is inferred from the file extension.
  71.      * @param mixed $link URL or identifier returned by AddLink().
  72.      * @param string $align Indicates the alignment of the pointer next to image insertion relative to image height. The value can be:<ul><li>T: top-right for LTR or top-left for RTL</li><li>M: middle-right for LTR or middle-left for RTL</li><li>B: bottom-right for LTR or bottom-left for RTL</li><li>N: next line</li></ul>
  73.      * @param boolean $resize If true resize (reduce) the image to fit $w and $h (requires GD library).
  74.      * @param int $dpi dot-per-inch resolution used on resize
  75.      * @param string $palign Allows to center or align the image on the current line. Possible values are:<ul><li>L : left align</li><li>C : center</li><li>R : right align</li><li>'' : empty string : left for LTR or right for RTL</li></ul>
  76.      * @param boolean $ismask true if this image is a mask, false otherwise
  77.      * @param mixed $imgmask image object returned by this function or false
  78.      * @param mixed $border Indicates if borders must be drawn around the image. The value can be either a number:<ul><li>0: no border (default)</li><li>1: frame</li></ul>or a string containing some or all of the following characters (in any order):<ul><li>L: left</li><li>T: top</li><li>R: right</li><li>B: bottom</li></ul>
  79.      * @since 1.0
  80.      */
  81.     public function Image($file, $x='', $y='', $w=0, $h=0, $type='', $link='', $align='', $resize=false, $dpi=300, $palign='', $ismask=false, $imgmask=false, $border=0) {
  82.         if(self::$logger == null)
  83.             self::$logger = new Logger('AlphaTCPDF');
  84.         
  85.         global $config;
  86.             
  87.         self::$logger->debug('Processing image file URL ['.$file.']');
  88.         
  89.         try {
  90.             if(strpos($file, '/tk/') !== false) {
  91.                 $start = strpos($file, '/tk/')+3;
  92.                 $end = strlen($file);
  93.                 $tk = substr($file, $start+1, $end-($start+1));
  94.                 $decoded = FrontController::getDecodeQueryParams($tk);
  95.                 
  96.                 parent::Image($decoded['s'], $x, $y, $w, $h, $type, $link, $align, $resize, $dpi, $palign, $ismask, $imgmask, $border);
  97.             }else {
  98.                 // it has no query string, so threat as a regular image URL
  99.                 if(AlphaValidator::isURL($file))
  100.                     parent::Image($config->get('sysRoot').'/'.Image::convertImageURLToPath($file), $x, $y, $w, $h, $type, $link, $align, $resize, $dpi, $palign, $ismask, $imgmask, $border);
  101.                 else
  102.                     parent::Image($file, $x, $y, $w, $h, $type, $link, $align, $resize, $dpi, $palign, $ismask, $imgmask, $border);
  103.             }
  104.         }catch(Exception $e) {
  105.             self::$logger->error('Error processing image file URL ['.$file.'], error ['.$e->getMessage().']');
  106.             throw $e;
  107.         }
  108.     }
  109.     
  110.     /**
  111.      * Process opening tags.  Overridden here to fix a bug when the image type can't be determined from the URL.
  112.      * 
  113.      * @param array $dom html dom array
  114.      * @param int $key current element id
  115.      * @param boolean $cell if true add the default cMargin space to each new line (default false).
  116.      * @access protected
  117.      */
  118.     protected function openHTMLTagHandler(&$dom, $key, $cell=false) {
  119.         $tag = $dom[$key];
  120.         $parent = $dom[($dom[$key]['parent'])];
  121.         $firstorlast = ($key == 1);
  122.         // check for text direction attribute
  123.         if (isset($tag['attribute']['dir'])) {
  124.             $this->tmprtl = $tag['attribute']['dir'] == 'rtl' ? 'R' : 'L';
  125.         } else {
  126.             $this->tmprtl = false;
  127.         }
  128.         //Opening tag
  129.         switch($tag['value']) {
  130.             case 'table': {
  131.                 $cp = 0;
  132.                 $cs = 0;
  133.                 $dom[$key]['rowspans'] = array();
  134.                 if (!$this->empty_string($dom[$key]['thead'])) {
  135.                     // set table header
  136.                     $this->thead = $dom[$key]['thead'];
  137.                 }
  138.                 if (isset($tag['attribute']['cellpadding'])) {
  139.                     $cp = $this->getHTMLUnitToUnits($tag['attribute']['cellpadding'], 1, 'px');
  140.                     $this->oldcMargin = $this->cMargin;
  141.                     $this->cMargin = $cp;
  142.                 }
  143.                 if (isset($tag['attribute']['cellspacing'])) {
  144.                     $cs = $this->getHTMLUnitToUnits($tag['attribute']['cellspacing'], 1, 'px');
  145.                 }
  146.                 $this->checkPageBreak((2 * $cp) + (2 * $cs) + $this->lasth);
  147.                 break;
  148.             }
  149.             case 'tr': {
  150.                 // array of columns positions
  151.                 $dom[$key]['cellpos'] = array();
  152.                 break;
  153.             }
  154.             case 'hr': {
  155.                 $this->addHTMLVertSpace(1, $cell, '', $firstorlast, $tag['value'], false);
  156.                 $this->htmlvspace = 0;
  157.                 $wtmp = $this->w - $this->lMargin - $this->rMargin;
  158.                 if ((isset($tag['attribute']['width'])) AND ($tag['attribute']['width'] != '')) {
  159.                     $hrWidth = $this->getHTMLUnitToUnits($tag['attribute']['width'], $wtmp, 'px');
  160.                 } else {
  161.                     $hrWidth = $wtmp;
  162.                 }
  163.                 $x = $this->GetX();
  164.                 $y = $this->GetY();
  165.                 $prevlinewidth = $this->GetLineWidth();
  166.                 $this->Line($x, $y, $x + $hrWidth, $y);
  167.                 $this->SetLineWidth($prevlinewidth);
  168.                 $this->addHTMLVertSpace(1, $cell, '', !isset($dom[($key + 1)]), $tag['value'], false);
  169.                 break;
  170.             }
  171.             case 'a': {
  172.                 if (array_key_exists('href', $tag['attribute'])) {
  173.                     $this->HREF['url'] = $tag['attribute']['href'];
  174.                 }
  175.                 $this->HREF['color'] = $this->htmlLinkColorArray;
  176.                 $this->HREF['style'] = $this->htmlLinkFontStyle;
  177.                 if (array_key_exists('style', $tag['attribute'])) {
  178.                     // get style attributes
  179.                     preg_match_all('/([^;:\s]*):([^;]*)/', $tag['attribute']['style'], $style_array, PREG_PATTERN_ORDER);
  180.                     $astyle = array();
  181.                     while (list($id, $name) = each($style_array[1])) {
  182.                         $name = strtolower($name);
  183.                         $astyle[$name] = trim($style_array[2][$id]);
  184.                     }
  185.                     if (isset($astyle['color'])) {
  186.                         $this->HREF['color'] = $this->convertHTMLColorToDec($astyle['color']);
  187.                     }
  188.                     if (isset($astyle['text-decoration'])) {
  189.                         $this->HREF['style'] = '';
  190.                         $decors = explode(' ', strtolower($astyle['text-decoration']));
  191.                         foreach ($decors as $dec) {
  192.                             $dec = trim($dec);
  193.                             if (!$this->empty_string($dec)) {
  194.                                 if ($dec{0} == 'u') {
  195.                                     $this->HREF['style'] .= 'U';
  196.                                 } elseif ($dec{0} == 'l') {
  197.                                     $this->HREF['style'] .= 'D';
  198.                                 }
  199.                             }
  200.                         }
  201.                     }
  202.                 }        
  203.                 break;
  204.             }
  205.             case 'img': {
  206.                 if (isset($tag['attribute']['src'])) {
  207.                     // replace relative path with real server path
  208.                     if ($tag['attribute']['src'][0] == '/') {
  209.                         $tag['attribute']['src'] = $_SERVER['DOCUMENT_ROOT'].$tag['attribute']['src'];
  210.                     }
  211.                     
  212.                     $tag['attribute']['src'] = urldecode($tag['attribute']['src']);
  213.                     
  214.                     if (!isset($tag['attribute']['width'])) {
  215.                         $tag['attribute']['width'] = 0;
  216.                     }
  217.                     if (!isset($tag['attribute']['height'])) {
  218.                         $tag['attribute']['height'] = 0;
  219.                     }
  220.                     
  221.                     $tag['attribute']['align'] = 'bottom';
  222.                     
  223.                     switch($tag['attribute']['align']) {
  224.                         case 'top': {
  225.                         $align = 'T';
  226.                             break;
  227.                         }
  228.                         case 'middle': {
  229.                             $align = 'M';
  230.                             break;
  231.                         }
  232.                         case 'bottom': {
  233.                             $align = 'B';
  234.                             break;
  235.                         }
  236.                         default: {
  237.                             $align = 'B';
  238.                             break;
  239.                         }
  240.                     }
  241.                     $fileinfo = pathinfo($tag['attribute']['src']);
  242.                     if (isset($fileinfo['extension']) AND (!$this->empty_string($fileinfo['extension']))) {
  243.                         $type = strtolower($fileinfo['extension']);
  244.                     }else{
  245.                         $type = '';
  246.                     }
  247.                     $prevy = $this->y;
  248.                     $xpos = $this->GetX();
  249.                     if (isset($dom[($key - 1)]) AND ($dom[($key - 1)]['value'] == ' ')) {
  250.                         if ($this->rtl) {
  251.                             $xpos += $this->GetStringWidth(' ');
  252.                         } else {
  253.                             $xpos -= $this->GetStringWidth(' ');
  254.                         }
  255.                     }
  256.                     $imglink = '';
  257.                     if (isset($this->HREF['url']) AND !$this->empty_string($this->HREF['url'])) {
  258.                         $imglink = $this->HREF['url'];
  259.                         if ($imglink{0} == '#') {
  260.                             // convert url to internal link
  261.                             $page = intval(substr($imglink, 1));
  262.                             $imglink = $this->AddLink();
  263.                             $this->SetLink($imglink, 0, $page);
  264.                         }
  265.                     }
  266.                     $border = 0;
  267.                     if (isset($tag['attribute']['border']) AND !empty($tag['attribute']['border'])) {
  268.                         // currently only support 1 (frame) or a combination of 'LTRB'
  269.                         $border = $tag['attribute']['border'];
  270.                     }
  271.                     if (isset($tag['attribute']['width'])) {
  272.                         $iw = $this->getHTMLUnitToUnits($tag['attribute']['width'], 1, 'px', false);
  273.                     }
  274.                     if (isset($tag['attribute']['height'])) {
  275.                         $ih = $this->getHTMLUnitToUnits($tag['attribute']['height'], 1, 'px', false);
  276.                     }
  277.                     if (($type == 'eps') OR ($type == 'ai')) {
  278.                         $this->ImageEps($tag['attribute']['src'], $xpos, $this->GetY(), $iw, $ih, $imglink, true, $align, '', $border);
  279.                     } else {
  280.                         $this->Image($tag['attribute']['src'], $xpos, $this->GetY(), $iw, $ih, '', $imglink, $align, false, 300, '', false, false, $border);
  281.                     }
  282.                     switch($align) {
  283.                         case 'T': {
  284.                             $this->y = $prevy;
  285.                             break;
  286.                         }
  287.                         case 'M': {
  288.                             $this->y = (($this->img_rb_y + $prevy - ($tag['fontsize'] / $this->k)) / 2) ;
  289.                             break;
  290.                         }
  291.                         case 'B': {
  292.                             $this->y = $this->img_rb_y - ($tag['fontsize'] / $this->k);
  293.                             break;
  294.                         }
  295.                     }
  296.                 }
  297.                 break;
  298.             }
  299.             case 'dl': {
  300.                 ++$this->listnum;
  301.                 $this->addHTMLVertSpace(0, $cell, '', $firstorlast, $tag['value'], false);
  302.                 break;
  303.             }
  304.             case 'dt': {
  305.                 $this->addHTMLVertSpace(1, $cell, '', $firstorlast, $tag['value'], false);
  306.                 break;
  307.             }
  308.             case 'dd': {
  309.                 if ($this->rtl) {
  310.                     $this->rMargin += $this->listindent;
  311.                 } else {
  312.                     $this->lMargin += $this->listindent;
  313.                 }
  314.                 $this->addHTMLVertSpace(1, $cell, '', $firstorlast, $tag['value'], false);
  315.                 break;
  316.             }
  317.             case 'ul':
  318.             case 'ol': {
  319.                 $this->addHTMLVertSpace(0, $cell, '', $firstorlast, $tag['value'], false);
  320.                 $this->htmlvspace = 0;
  321.                 ++$this->listnum;
  322.                 if ($tag['value'] == 'ol') {
  323.                     $this->listordered[$this->listnum] = true;
  324.                 } else {
  325.                     $this->listordered[$this->listnum] = false;
  326.                 }
  327.                 if (isset($tag['attribute']['start'])) {
  328.                     $this->listcount[$this->listnum] = intval($tag['attribute']['start']) - 1;
  329.                 } else {
  330.                     $this->listcount[$this->listnum] = 0;
  331.                 }
  332.                 if ($this->rtl) {
  333.                     $this->rMargin += $this->listindent;
  334.                 } else {
  335.                     $this->lMargin += $this->listindent;
  336.                 }
  337.                 $this->addHTMLVertSpace(0, $cell, '', $firstorlast, $tag['value'], false);
  338.                 $this->htmlvspace = 0;
  339.                 break;
  340.             }
  341.             case 'li': {
  342.                 $this->addHTMLVertSpace(1, $cell, '', $firstorlast, $tag['value'], false);
  343.                 if ($this->listordered[$this->listnum]) {
  344.                     // ordered item
  345.                     if (isset($parent['attribute']['type']) AND !$this->empty_string($parent['attribute']['type'])) {
  346.                         $this->lispacer = $parent['attribute']['type'];
  347.                     } elseif (isset($parent['listtype']) AND !$this->empty_string($parent['listtype'])) {
  348.                         $this->lispacer = $parent['listtype'];
  349.                     } elseif (isset($this->lisymbol) AND !$this->empty_string($this->lisymbol)) {
  350.                         $this->lispacer = $this->lisymbol;
  351.                     } else {
  352.                         $this->lispacer = '#';
  353.                     }
  354.                     ++$this->listcount[$this->listnum];
  355.                     if (isset($tag['attribute']['value'])) {
  356.                         $this->listcount[$this->listnum] = intval($tag['attribute']['value']);
  357.                     }
  358.                 } else {
  359.                     // unordered item
  360.                     if (isset($parent['attribute']['type']) AND !$this->empty_string($parent['attribute']['type'])) {
  361.                         $this->lispacer = $parent['attribute']['type'];
  362.                     } elseif (isset($parent['listtype']) AND !$this->empty_string($parent['listtype'])) {
  363.                         $this->lispacer = $parent['listtype'];
  364.                     } elseif (isset($this->lisymbol) AND !$this->empty_string($this->lisymbol)) {
  365.                         $this->lispacer = $this->lisymbol;
  366.                     } else {
  367.                         $this->lispacer = '!';
  368.                     }
  369.                 }
  370.                 break;
  371.             }
  372.             case 'blockquote': {
  373.                 if ($this->rtl) {
  374.                     $this->rMargin += $this->listindent;
  375.                 } else {
  376.                     $this->lMargin += $this->listindent;
  377.                 }
  378.                 $this->addHTMLVertSpace(2, $cell, '', $firstorlast, $tag['value'], false);
  379.                 break;
  380.             }
  381.             case 'br': {
  382.                 $this->Ln('', $cell);
  383.                 break;
  384.             }
  385.             case 'div': {
  386.                 $this->addHTMLVertSpace(1, $cell, '', $firstorlast, $tag['value'], false);
  387.                 break;
  388.             }
  389.             case 'p': {
  390.                 $this->addHTMLVertSpace(2, $cell, '', $firstorlast, $tag['value'], false);
  391.                 break;
  392.             }
  393.             case 'pre': {
  394.                 $this->addHTMLVertSpace(1, $cell, '', $firstorlast, $tag['value'], false);
  395.                 $this->premode = true;
  396.                 break;
  397.             }
  398.             case 'sup': {
  399.                 $this->SetXY($this->GetX(), $this->GetY() - ((0.7 * $this->FontSizePt) / $this->k));
  400.                 break;
  401.             }
  402.             case 'sub': {
  403.                 $this->SetXY($this->GetX(), $this->GetY() + ((0.3 * $this->FontSizePt) / $this->k));
  404.                 break;
  405.             }
  406.             case 'h1': 
  407.             case 'h2': 
  408.             case 'h3': 
  409.             case 'h4': 
  410.             case 'h5': 
  411.             case 'h6': {
  412.                 $this->addHTMLVertSpace(1, $cell, ($tag['fontsize'] * 1.5) / $this->k, $firstorlast, $tag['value'], false);
  413.             break;
  414.             }
  415.             case 'tcpdf': {
  416.                 // NOT HTML: used to call TCPDF methods
  417.                 if (isset($tag['attribute']['method'])) {
  418.                     $tcpdf_method = $tag['attribute']['method'];
  419.                     if (method_exists($this, $tcpdf_method)) {
  420.                         if (isset($tag['attribute']['params']) AND (!empty($tag['attribute']['params']))) {
  421.                             eval('$params = array('.$tag['attribute']['params'].');');
  422.                             call_user_func_array(array($this, $tcpdf_method), $params);
  423.                         } else {
  424.                             $this->$tcpdf_method();
  425.                         }
  426.                         $this->newline = true;
  427.                     }
  428.                 }
  429.             }
  430.             default: {
  431.                 break;
  432.             }
  433.         }
  434.     }
  435. }
  436.  
  437. ?>

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