| Current Path : /home/juvelize/saulnois/tmp/install_695d2cf0b4957/src/ |
| Current File : /home/juvelize/saulnois/tmp/install_695d2cf0b4957/src/TPdf.php |
<?php
/*
* @package Tech Fry Library
* @license https://www.gnu.org/licenses/gpl-3.0.en.html
*/
namespace TechFry\Library;
defined('_JEXEC') or die;
use Joomla\CMS\Factory;
use Joomla\CMS\HTML\HTMLHelper;
require(JPATH_LIBRARIES . '/techfry/lib/fpdf/fpdf.php');
// Class for managing FPDF - v1.86 (https://www.fpdf.org/)
class TPdf extends \FPDF
{
// Styles - Text Color, Font Type, Font Size
// Cell (inline), MultiCell (block), Write (without formatting)
public $config;
public $title;
public $main;
public $font;
public $primary_font;
public $secondary_font;
public $font_size;
public $color;
public $page_width;
public $page_height;
public $side_margin;
public $top_margin;
public $y_after_main;
public $primary_color;
public $secondary_color;
public $ignore_write = false;
public $table;
public $column_widths;
public $row_count;
public $col_count;
public $cell_content;
public $href;
public $list_type;
public $list_count;
// align, border, color, bg_color, font, font_size, font_weight
public $styles;
public function __construct($config = [])
{
// $config - left_margin, top_margin, text_color, font, font_size
// title_align, title_font, title_border, title_color, file_name
if (!\is_array($config))
{
$config = (array) $config;
}
$this->config = $config;
$orientation = $this->config['orientation'] ?? 'P';
$unit = $this->config['unit'] ?? 'mm';
$size = $this->config['size'] ?? 'A4';
parent::__construct($orientation, $unit, $size);
$this->add_meta();
// 1. Set Page Margins - Sides and Top
$this->side_margin = $config['left_margin'] ?? 10;
$this->SetLeftMargin($this->side_margin);
$this->SetRightMargin($this->side_margin);
$this->top_margin = $config['top_margin'] ?? 10;
$this->SetTopMargin($this->top_margin);
// 2. Set Text Color
$this->color = $config['text_color'] ?? '#000000';
$this->set_text_color($this->color);
// 3. Set Font
$this->font = $config['font'] ?? 'Arial';
$this->SetFont($this->font); // Mandatory
$this->primary_font = $this->font;
$this->secondary_font = $config['secondary_font'] ?? 'Times';
// 4. Set Font Size
$this->font_size = $config['font_size'] ?? 12;
$this->SetFontSize($this->font_size);
// 5. Colors
$this->primary_color = $config['primary_color'] ?? '#0275d8';
$this->secondary_color = $config['secondary_color'] ?? '#d284ff';
$this->page_width = floor($this->GetPageWidth());
$this->page_height = floor($this->GetPageHeight());
// Defaults
$this->styles['border'] = 0;
$this->styles['align'] = 'L';
$this->styles['fill'] = 0;
}
public function generate_pdf($content = array())
{
// $content - title, main, pages
$this->title = $content['title'] ?? '';
$this->main = $content['main'] ?? '';
$this->AliasNbPages();
$this->AddPage();
// 1. Title
if ($this->title && $this->config['show_title'])
{
$this->add_title();
}
// 2. Main Content
if ($this->main)
{
$this->write_html($this->main);
}
// 3. Pages
if (isset($content['pages']) && !empty($content['pages']))
{
foreach ($content['pages'] as $page)
{
$this->AddPage();
if (isset($page['title']) && $page['title'])
{
$this->title = $page['title'];
$this->add_title();
}
if (isset($page['main']) && $page['main'])
{
$this->write_html($page['main']);
}
}
}
$file_name = $this->config['file_name'] ?? 'file.pdf';
$this->force_download($file_name);
}
// Print text and move to next line
public function add_line($text)
{
$text = iconv('UTF-8', 'ISO-8859-1//IGNORE', $text);
if ($text)
{
// width, height, text, border, align, fill
$height = ceil($this->styles['font_size'] * 0.35);
//$this->MultiCell(0, $height, $text, $this->styles['border'], $this->styles['align'], $this->styles['fill']);
// MutiCell adds space below, so use Cell
$this->Cell(0, $height, $text, $this->styles['border'], 0, $this->styles['align'], $this->styles['fill']);
// width is in mm, font size is in pt
// 48 pt = 0.35 * 48 mm
}
$this->reset_style();
}
// Use Cell()
public function add_text($text)
{
$text = iconv('UTF-8', 'ISO-8859-1//IGNORE', $text);
if ($text)
{
$w = $this->GetStringWidth($text);
$this->Cell($w, 8, $text, $this->styles['border'], 0, $this->styles['align'], $this->styles['fill']);
}
$this->reset_style();
}
public function add_title()
{
$class = $this->config['title_class'] ?? '';
$this->get_styles_from_class($class);
$style = $this->config['title_style'] ?? '';
$this->get_styles_from_style($style);
$this->styles['font_size'] = 36;
$this->apply_styles();
$this->add_line($this->title);
$this->Ln(4);
$this->reset_style();
}
public function Header()
{
if (isset($this->config['header_content']) && $this->config['header_content'])
{
$this->write_html($this->config['header_content']);
}
if (isset($this->config['logo']) && $this->config['logo'])
{
$logo_width = $this->config['logo_width'] ?? 30;
$logo_align = $this->config['logo_align'] ?? 'L';
if ($logo_align == 'L')
{
$x = $this->side_margin;
}
elseif ($logo_align == 'C')
{
$x = floor(($this->page_width - $logo_width)/2);
}
elseif ($logo_align == 'R')
{
$x = $this->page_width - $this->side_margin - $logo_width;
}
$y = $this->top_margin;
$img = HTMLHelper::cleanImageURL($this->config['logo']);
$this->Image($img->url, $x, $y, $logo_width);
}
// Line break
if (isset($this->config['header_gap']) && $this->config['header_gap'])
{
$this->Ln($this->config['header_gap']);
}
}
public function Footer()
{
$this->SetY(-15);
if (isset($this->config['footer_content']) && $this->config['footer_content'])
{
$this->config['footer_content'] = str_replace('{page}', $this->PageNo(), $this->config['footer_content']);
$this->write_html($this->config['footer_content']);
}
}
// HTML Parser
public function write_html($html)
{
// Convert HTML content to PDF
$this->SetY($this->get_y());
// Remove all tags except recognized ones
$html = strip_tags($html, '<strong><b><u><i><a><img><p><br><em><table><tr><td><th><blockquote><ul><ol><li><h1><h2><h3><h4><h5><h6><div><span><hr><a>');
// HTML parser
$a = preg_split('/<(.*)>/U', $html, -1, PREG_SPLIT_DELIM_CAPTURE);
foreach ($a as $i => $e)
{
if ($i % 2 == 0) // Even Index contains Text
{
$this->cell_content = $e;
if (!$this->ignore_write)
{
$this->Write(5, $e);
}
}
else
{
// Closing Tag Tag
if ($e[0] == '/')
{
$this->close_tag(strtoupper(substr($e, 1)));
}
else
{
// Opening Tag - Extract attributes
$a2 = explode(' ', $e);
$tag = strtoupper(array_shift($a2));
$attr = [];
foreach ($a2 as $v)
{
if (preg_match('/([^=]*)=["\']?([^"\']*)/', $v, $a3))
{
$attr[strtoupper($a3[1])] = $a3[2];
}
}
$this->open_tag($tag, $attr);
}
}
}
// Reset Margins
$this->SetLeftMargin($this->side_margin);
$this->SetRightMargin($this->side_margin);
}
public function open_tag($tag, $attr)
{
// CLASS and STYLE attributes are common for all
$class = $attr['CLASS'] ?? '';
$this->get_styles_from_class($class);
$style = $attr['STYLE'] ?? '';
$this->get_styles_from_style($style);
if ($tag == 'STRONG' || $tag == 'B')
{
$this->styles['font_weight'] = 'B';
}
elseif ($tag == 'U')
{
$this->styles['font_weight'] = 'U';
}
elseif ($tag == 'I' || $tag == 'EM')
{
$this->styles['font_weight'] = 'I';
}
elseif ($tag == 'BR')
{
$this->Ln(5);
}
elseif ($tag == 'TABLE')
{
$column_widths = $attr['DATA-COL-WIDTHS'] ?? '';
if ($column_widths)
{
$this->column_widths = explode(',', $column_widths);
}
$this->table = true;
$this->ignore_write = true;
//$this->Ln(5);
}
elseif ($tag == 'TR' && $this->table)
{
$this->Ln(8);
$this->col_count = 0;
}
elseif ($tag == 'UL')
{
$this->list_type = 'ul';
//$this->Ln(4);
}
elseif ($tag == 'OL')
{
$this->list_type = 'ol';
$this->list_count = 1;
//$this->Ln(4);
}
elseif ($tag == 'LI')
{
if ($this->list_type == 'ul')
{
$this->Write(5, chr(149) . ' ');
}
elseif ($this->list_type == 'ol')
{
$this->Write(5, $this->list_count . '. ');
$this->list_count++;
}
//$this->SetX($this->GetX() + $this->listIndent);
}
elseif (preg_match('/H([1-6])/', $tag, $matches))
{
$heading_level = (int) $matches[1];
$font_size = 24 - ($heading_level - 1) * 3;
$this->styles['font_size'] = $font_size;
//$this->Ln(4);
$this->ignore_write = true;
}
elseif ($tag == 'IMG')
{
$src = isset($attr['SRC']) ? $attr['SRC'] : '';
$width = isset($attr['WIDTH']) ? (float)$attr['WIDTH'] : 0;
$height = isset($attr['HEIGHT']) ? (float)$attr['HEIGHT'] : 0;
$img = HTMLHelper::cleanImageURL($src);
if ($width > 0 && $height > 0)
{
$this->Image($img->url, null, null, $width, $height);
}
else
{
$this->Image($img->url, null, null, 50, 50);
}
$this->Ln(5);
}
elseif ($tag == 'HR')
{
if ($class == 'system-pagebreak')
{
$this->AddPage();
}
else
{
$x1 = $this->side_margin;
$y1 = $this->GetY();
$x2 = $this->page_width - $this->side_margin;
$y2 = $y1;
$this->SetDrawColor(200);
$this->Line($x1, $y1, $x2, $y2);
}
}
elseif ($tag == 'A')
{
$this->href = $attr['HREF'] ?? '';
$this->ignore_write = true;
}
$this->apply_styles();
}
// Close Tag
public function close_tag($tag)
{
if ($tag == 'P')
{
// Add space after closing tag
$this->Ln(5);
}
elseif ($tag == 'TABLE')
{
$this->table = false;
$this->ignore_write = false;
$this->column_widths = '';
$this->Ln(5);
}
elseif ($tag == 'TD' || $tag == 'TH')
{
// Column width
if ($this->column_widths)
{
$index = $this->col_count;
$col_width = $this->column_widths[$index];
}
else
{
$col_width = 40;
}
// Make table headings as bold
if ($tag == 'TH')
{
$this->styles['font_weight'] = 'B';
$this->apply_styles();
}
if ($col_width)
{
$this->Cell($col_width, 8, $this->cell_content, 1);
$this->cell_content = '';
}
$this->col_count++;
}
elseif ($tag == 'UL' || $tag == 'OL')
{
$this->list_type = '';
//$this->Ln(4);
}
elseif ($tag == 'LI')
{
$this->Ln(2);
}
elseif (preg_match('/H([1-6])/', $tag, $matches))
{
$this->add_line($this->cell_content);
$this->cell_content = '';
$this->ignore_write = false;
}
elseif ($tag == 'A')
{
$this->SetFont('', 'U');
$this->Write(5, $this->cell_content, $this->href);
$this->href = '';
$this->ignore_write = false;
}
$this->reset_style();
}
// Apply syles for text
public function apply_styles()
{
// $this->styles - color, bg_color, font, font_size, font_weight
// border and align are set in Cell() and MultiCell()
if (isset($this->styles['color']) && $this->styles['color'])
{
$this->set_text_color($this->styles['color']);
}
if (isset($this->styles['bg_color']) && $this->styles['bg_color'])
{
$this->styles['fill'] = true;
$this->set_fill_color($this->styles['bg_color']);
}
else
{
$this->styles['fill'] = false;
}
$font_family = $this->styles['font'] ?? $this->font;
$font_weight = $this->styles['font_weight'] ?? '';
$this->SetFont($font_family, $font_weight);
if (isset($this->styles['font_size']) && $this->styles['font_size'])
{
$this->SetFontSize($this->styles['font_size']);
}
}
// Apply base style
public function reset_style()
{
$this->styles = array(
'align' => 'L',
'border' => 0,
'fill' => false,
'font_size' => $this->font_size,
);
$this->set_text_color($this->color);
$this->SetFont($this->font, '', $this->font_size);
}
// Set Text Color
public function set_text_color($color = '#000000')
{
$colors = $this->hex2dec($color);
$this->SetTextColor($colors['R'], $colors['G'], $colors['B']);
}
// Set Fill or Background Color
public function set_fill_color($color = '#FFFFFF')
{
$colors = $this->hex2dec($color);
$this->SetFillColor($colors['R'], $colors['G'], $colors['B']);
}
// Set Border Color
public function set_draw_color($color = '#CCCCCC')
{
$colors = $this->hex2dec($color);
$this->SetDrawColor($colors['R'], $colors['G'], $colors['B']);
}
public function hex2dec($color = "#000000")
{
$colors = array();
$colors['R'] = hexdec(substr($color, 1, 2));
$colors['G'] = hexdec(substr($color, 3, 2));
$colors['B'] = hexdec(substr($color, 5, 2));
return $colors;
}
public function force_download($name = 'file.pdf')
{
$this->Output('D', $name);
exit;
}
public function open_browser()
{
$this->Output();
exit;
}
public function save_file($path)
{
$this->Output('F', $path);
}
public function get_x()
{
return floor($this->GetX());
}
public function get_y()
{
return floor($this->GetY());
}
public function get_styles_from_class($class)
{
$classes = explode(' ', $class);
// 1. Align
if (\in_array('text-center', $classes))
{
$this->styles['align'] = 'C';
}
elseif (\in_array('text-end', $classes))
{
$this->styles['align'] = 'R';
}
elseif (\in_array('text-start', $classes))
{
$this->styles['align'] = 'L';
}
// 2. Border
if (\in_array('border', $classes))
{
$this->styles['border'] = 1;
}
// 3. Color
if (\in_array('text-primary', $classes))
{
$this->styles['color'] = $this->primary_color;
}
elseif (\in_array('text-secondary', $classes))
{
$this->styles['color'] = $this->secondary_color;
}
elseif (\in_array('text-success', $classes))
{
$this->styles['color'] = '#5bc0de';
}
elseif (\in_array('text-danger', $classes))
{
$this->styles['color'] = '#d9534f';
}
elseif (\in_array('text-light', $classes))
{
$this->styles['color'] = '#dcdcdc';
}
elseif (\in_array('text-white', $classes))
{
$this->styles['color'] = '#FFFFFF';
}
// 4. Background Color
if (\in_array('bg-primary', $classes))
{
$this->styles['bg_color'] = $this->primary_color;
}
elseif (\in_array('bg-secondary', $classes))
{
$this->styles['bg_color'] = $this->secondary_color;
}
elseif (\in_array('bg-light', $classes))
{
$this->styles['bg_color'] = '#dcdcdc';
}
elseif (\in_array('bg-dark', $classes))
{
$this->styles['bg_color'] = '#444444';
}
// 5. Font
if (\in_array('font-primary', $classes))
{
$this->styles['font'] = $this->primary_font;
}
elseif (\in_array('font-secondary', $classes))
{
$this->styles['font'] = $this->secondary_font;
}
// 6. Font Size
if (\in_array('fs-1', $classes))
{
$this->styles['font_size'] = floor($this->font_size * 2);
}
elseif (\in_array('fs-2', $classes))
{
$this->styles['font_size'] = floor($this->font_size * 1.7);
}
elseif (\in_array('fs-3', $classes))
{
$this->styles['font_size'] = floor($this->font_size * 1.4);
}
// 7. Font Weight
if (\in_array('fw-bold', $classes))
{
$this->styles['font_weight'] = 'B';
}
}
// Get Styles from CSS style attribute
public function get_styles_from_style($style)
{
$styles = [];
$declarations = explode(';', $style);
foreach ($declarations as $declaration)
{
$parts = explode(':', $declaration, 2);
if (count($parts) == 2)
{
$property = trim($parts[0]);
$value = trim($parts[1]);
$styles[$property] = $value;
}
}
// 1. Align
if (\array_key_exists('text-align', $styles))
{
if ($styles['text-align'] == 'center')
{
$this->styles['align'] = 'C';
}
elseif ($styles['text-align'] == 'right')
{
$this->styles['align'] = 'R';
}
elseif ($styles['text-align'] == 'left')
{
$this->styles['align'] = 'L';
}
}
// 2. Border
if (\array_key_exists('border', $styles))
{
$this->styles['border'] = 1;
}
// 3. Color
if (\array_key_exists('color', $styles))
{
$this->styles['color'] = $styles['color'];
}
// 4. Background Color
if (\array_key_exists('background-color', $styles))
{
$this->styles['bg_color'] = $styles['background-color'];
}
// 5. Font Size
if (\array_key_exists('font-size', $styles))
{
$this->styles['font_size'] = (int) filter_var($styles['font-size'], FILTER_SANITIZE_NUMBER_INT);
}
// 6. Font Weight
if (\array_key_exists('font-weight', $styles))
{
$this->styles['font_weight'] = 'B';
}
}
public function add_meta()
{
if (isset($this->config['pdf_title']) && $this->config['pdf_title'])
{
$this->SetTitle($this->config['pdf_title']);
}
if (isset($this->config['pdf_author']) && $this->config['pdf_author'])
{
$this->SetAuthor($this->config['pdf_author']);
}
}
}