PMCORE-3540 BE: Generate a output document using the header, footer and pagination defined

This commit is contained in:
Roly Gutierrez
2022-01-17 09:44:48 -04:00
parent a65ea8cd92
commit beacac5a5b
9 changed files with 1788 additions and 3 deletions

View File

@@ -0,0 +1,336 @@
<?php
namespace ProcessMaker\PDF;
/**
* Struct for header and footer configuration.
*/
trait BasicStruct
{
/**
* Path to image file.
* @var string
*/
private $logo = '';
/**
* Width to image file, the height is calculated automatically proportional
* to the original dimensions.
* @var float
*/
private $logoWidth = 0;
/**
* Position of the image with respect to the ordinate X since left margin.
* @var float
*/
private $logoPositionX = 0;
/**
* Position of the image with respect to the ordinate Y since top margin.
* @var float
*/
private $logoPositionY = 0;
/**
* Title of the page.
* @var string
*/
private $title = '';
/**
* Font size of the title.
* @var float
*/
private $titleFontSize = 0;
/**
* Position of the title with respect to the ordinate X since left margin.
* @var float
*/
private $titleFontPositionX = 0;
/**
* Position of the title with respect to the ordinate Y since top margin.
* @var float
*/
private $titleFontPositionY = 0;
/**
* Indicates if the page number is displayed.
* @var bool
*/
private $pageNumber = false;
/**
* Alternative text to indicate the numbered page.
* @var string
*/
private $pageNumberTitle = '';
/**
* Indicates if the pages total is displayed.
* @var bool
*/
private $pageNumberTotal = false;
/**
* Position of the page number with respect to the ordinate X since left margin.
* @var float
*/
private $pageNumberPositionX = 0;
/**
* Position of the page number with respect to the ordinate Y since bottom margin.
* @var float
*/
private $pageNumberPositionY = 0;
/**
* Get logo property.
* @return string
*/
public function getLogo(): string
{
return $this->logo;
}
/**
* Get logoWidth property.
* @return float
*/
public function getLogoWidth(): float
{
return $this->logoWidth;
}
/**
* Get logoPositionX property.
* @return float
*/
public function getLogoPositionX(): float
{
return $this->logoPositionX;
}
/**
* Get logoPositionY property.
* @return float
*/
public function getLogoPositionY(): float
{
return $this->logoPositionY;
}
/**
* Get title property.
* @return string
*/
public function getTitle(): string
{
return $this->title;
}
/**
* Get titleFontSize property.
* @return float
*/
public function getTitleFontSize(): float
{
return $this->titleFontSize;
}
/**
* Get titleFontPositionX property.
* @return float
*/
public function getTitleFontPositionX(): float
{
return $this->titleFontPositionX;
}
/**
* Get titleFontPositionY property.
* @return float
*/
public function getTitleFontPositionY(): float
{
return $this->titleFontPositionY;
}
/**
* Get pageNumber property.
* @return bool
*/
public function getPageNumber(): bool
{
return $this->pageNumber;
}
/**
* Get pageNumberTitle property.
* @return string
*/
public function getPageNumberTitle(): string
{
return $this->pageNumberTitle;
}
/**
* Get pageNumberTotal property.
* @return bool
*/
public function getPageNumberTotal(): bool
{
return $this->pageNumberTotal;
}
/**
* Get pageNumberPositionX property.
* @return float
*/
public function getPageNumberPositionX(): float
{
return $this->pageNumberPositionX;
}
/**
* Get pageNumberPositionY property.
* @return float
*/
public function getPageNumberPositionY(): float
{
return $this->pageNumberPositionY;
}
/**
* Set property title.
* @param string $title
* @return void
*/
public function setTitle(string $title): void
{
$this->title = $title;
}
/**
* Set property titleFontSize.
* @param float $titleFontSize
* @return void
*/
public function setTitleFontSize(float $titleFontSize): void
{
$this->titleFontSize = $titleFontSize;
}
/**
* Set property titleFontPositionX.
* @param float $titleFontPositionX
* @return void
*/
public function setTitleFontPositionX(float $titleFontPositionX): void
{
$this->titleFontPositionX = $titleFontPositionX;
}
/**
* Set property titleFontPositionY.
* @param float $titleFontPositionY
* @return void
*/
public function setTitleFontPositionY(float $titleFontPositionY): void
{
$this->titleFontPositionY = $titleFontPositionY;
}
/**
* Set property logo.
* @param string $logo
* @return void
*/
public function setLogo(string $logo): void
{
$this->logo = $logo;
}
/**
* Set property logoWidth.
* @param float $logoWidth
* @return void
*/
public function setLogoWidth(float $logoWidth): void
{
$this->logoWidth = $logoWidth;
}
/**
* Set property logoPositionX.
* @param float $logoPositionX
* @return void
*/
public function setLogoPositionX(float $logoPositionX): void
{
$this->logoPositionX = $logoPositionX;
}
/**
* Set property logoPositionY.
* @param float $logoPositionY
* @return void
*/
public function setLogoPositionY(float $logoPositionY): void
{
$this->logoPositionY = $logoPositionY;
}
/**
* Set property pageNumber.
* @param bool $pageNumber
* @return void
*/
public function setPageNumber(bool $pageNumber): void
{
$this->pageNumber = $pageNumber;
}
/**
* Set property pageNumberTitle.
* @param string $pageNumberTitle
* @return void
*/
public function setPageNumberTitle(string $pageNumberTitle): void
{
$this->pageNumberTitle = $pageNumberTitle;
}
/**
* Set property pageNumberTotal.
* @param bool $pageNumberTotal
* @return void
*/
public function setPageNumberTotal(bool $pageNumberTotal): void
{
$this->pageNumberTotal = $pageNumberTotal;
}
/**
* Set property pageNumberPositionX.
* @param float $pageNumberPositionX
* @return void
*/
public function setPageNumberPositionX(float $pageNumberPositionX): void
{
$this->pageNumberPositionX = $pageNumberPositionX;
}
/**
* Set property pageNumberPositionY.
* @param float $pageNumberPositionY
* @return void
*/
public function setPageNumberPositionY(float $pageNumberPositionY): void
{
$this->pageNumberPositionY = $pageNumberPositionY;
}
}

View File

@@ -0,0 +1,11 @@
<?php
namespace ProcessMaker\PDF;
class FooterStruct
{
/**
* Using basic struct for footer properties.
*/
use BasicStruct;
}

View File

@@ -0,0 +1,11 @@
<?php
namespace ProcessMaker\PDF;
class HeaderStruct
{
/**
* Using basic struct for header properties.
*/
use BasicStruct;
}

View File

@@ -0,0 +1,242 @@
<?php
namespace ProcessMaker\PDF;
use TCPDF;
class TCPDFHeaderFooter extends TCPDF
{
/**
* Property for configure header element.
* @var HeaderStruct
*/
private $headerStruct;
/**
* Property for configure footer element.
* @var FooterStruct
*/
private $footerStruct;
/**
* Save the original margins configured in the page.
* @var array
*/
private $originalMargins;
/**
* Constructor of the class.
* @param string $orientation
* @param string $unit
* @param string $format
* @param bool $unicode
* @param string $encoding
* @param bool $diskcache
* @param bool $pdfa
*/
public function __construct($orientation = 'P', $unit = 'mm', $format = 'A4', $unicode = true, $encoding = 'UTF-8', $diskcache = false, $pdfa = false)
{
parent::__construct($orientation, $unit, $format, $unicode, $encoding, $diskcache, $pdfa);
$this->headerStruct = new HeaderStruct();
$this->footerStruct = new FooterStruct();
}
/**
* Destructor of the class.
*/
public function __destruct()
{
parent::__destruct();
}
/**
* Gets an object that contains the properties of the header.
* @return HeaderStruct
*/
public function getHeaderStruct(): HeaderStruct
{
return $this->headerStruct;
}
/**
* Gets an object that contains the properties of the footer.
* @return FooterStruct
*/
public function getFooterStruct(): FooterStruct
{
return $this->footerStruct;
}
/**
* This method is used to render the page header.
* This method has been overwritten.
*/
public function Header()
{
$heights = [];
$struct = $this->getHeaderStruct();
if (empty($this->originalMargins)) {
$this->originalMargins = $this->getMargins();
}
$margins = $this->originalMargins;
$this->buildHeaderLogo($struct, $margins, $heights);
$this->buildHeaderTitle($struct, $margins, $heights);
$this->buildHeaderPageNumber($struct, $margins, $heights);
//page adjust
$newHeight = max($heights);
$this->SetTopMargin($newHeight);
}
/**
* Build header logo.
* @param HeaderStruct $struct
* @param array $margins
* @param array $heights
* @return void
*/
private function buildHeaderLogo(HeaderStruct $struct, array $margins, array &$heights): void
{
$path = $struct->getLogo();
if (!file_exists($path)) {
return;
}
$pathinfo = pathinfo($path);
$imageSize = getimagesize($path);
$extension = $pathinfo['extension'];
$x = $struct->getLogoPositionX() + $margins['left'];
$y = $struct->getLogoPositionY() + $margins['top'];
$width = $struct->getLogoWidth();
$this->Image($path, $x, $y, $width, 0, $extension, '', '', false, 300, '', false, false, 0, false, false, false);
$newImageHeight = ($width * $imageSize[0] / $imageSize[1]);
$heights[] = $margins['top'] + $newImageHeight;
}
/**
* Build header title.
* @param HeaderStruct $struct
* @param array $margins
* @param array $heights
* @return void
*/
private function buildHeaderTitle(HeaderStruct $struct, array $margins, array &$heights): void
{
$string = $struct->getTitle();
$x = $struct->getTitleFontPositionX() + $margins['left'];
$y = $struct->getTitleFontPositionY() + $margins['top'];
$fontSize = $struct->getTitleFontSize();
$this->SetXY($x, $y);
$this->SetFont('helvetica', 'B', $fontSize);
$this->MultiCell(0, 0, $string, 0, 'L', false, 1, '', '', true, 0, false, true, 0, 'T', false);
$heights[] = $margins['top'] + ($this->getCellHeight($fontSize, false)) / 2;
}
/**
* Build header page number.
* @param HeaderStruct $struct
* @param array $margins
* @param array $heights
* @return void
*/
private function buildHeaderPageNumber(HeaderStruct $struct, array $margins, array &$heights): void
{
if ($struct->getPageNumber() === true) {
$pageString = empty($struct->getPageNumberTitle()) ? 'Page ' : $struct->getPageNumberTitle() . ' ';
$pageNumberTotal = $struct->getPageNumberTotal() === true ? ' / ' . $this->getAliasNbPages() : '';
$string = $pageString . $this->getAliasNumPage() . $pageNumberTotal;
$x = $struct->getPageNumberPositionX() + $margins['left'];
$y = $struct->getPageNumberPositionY() + $margins['top'];
$fontSize = 8;
$this->SetXY($x, $y);
$this->SetFont('helvetica', 'I', $fontSize);
$this->Cell(0, 0, $string, 0, 0, '', false, '', 0, false, 'T', 'M');
$heights[] = $margins['top'] + ($this->getCellHeight($fontSize, false)) / 2;
}
}
/**
* This method is used to render the page footer.
* This method has been overwritten.
*/
public function Footer()
{
$struct = $this->getFooterStruct();
if (empty($this->originalMargins)) {
$this->originalMargins = $this->getMargins();
}
$margins = $this->originalMargins;
//page adjust
$this->SetY(-1 * ($margins['bottom']));
$currentY = $this->GetY();
$this->buildFooterLogo($margins, $currentY, $struct);
$this->buildFooterTitle($margins, $currentY, $struct);
$this->buildFooterPageNumber($margins, $currentY, $struct);
}
/**
* Build footer logo.
* @param array $margins
* @param float $currentY
* @param HeaderStruct $struct
* @return void
*/
private function buildFooterLogo(array $margins, float $currentY, FooterStruct $struct): void
{
$path = $struct->getLogo();
if (!file_exists($path)) {
return;
}
$pathinfo = pathinfo($path);
$extension = $pathinfo['extension'];
$x = $struct->getLogoPositionX() + $margins['left'];
$y = $struct->getLogoPositionY() + $currentY;
$width = $struct->getLogoWidth();
$this->Image($path, $x, $y, $width, 0, $extension, '', '', false, 300, '', false, false, 0, false, false, false);
}
/**
* Build footer title.
* @param array $margins
* @param float $currentY
* @param HeaderStruct $struct
* @return void
*/
private function buildFooterTitle(array $margins, float $currentY, FooterStruct $struct): void
{
$string = $struct->getTitle();
$x = $struct->getTitleFontPositionX() + $margins['left'];
$y = $struct->getTitleFontPositionY() + $currentY;
$fontSize = $struct->getTitleFontSize();
$this->SetXY($x, $y);
$this->SetFont('helvetica', 'B', $fontSize);
$this->MultiCell(0, 0, $string, 0, 'L', false, 1, '', '', true, 0, false, true, 0, 'T', false);
}
/**
* Build footer page number.
* @param array $margins
* @param float $currentY
* @param HeaderStruct $struct
* @return void
*/
private function buildFooterPageNumber(array $margins, float $currentY, FooterStruct $struct): void
{
if ($struct->getPageNumber() === true) {
$pageString = empty($struct->getPageNumberTitle()) ? 'Page ' : $struct->getPageNumberTitle() . ' ';
$pageNumberTotal = $struct->getPageNumberTotal() === true ? ' / ' . $this->getAliasNbPages() : '';
$string = $pageString . $this->getAliasNumPage() . $pageNumberTotal;
$x = $struct->getPageNumberPositionX() + $margins['left'];
$y = $struct->getPageNumberPositionY() + $currentY;
$fontSize = 8;
$this->SetXY($x, $y);
$this->SetFont('helvetica', 'I', $fontSize);
$this->Cell(0, 0, $string, 0, 0, '', false, '', 0, false, 'T', 'M');
}
}
}