LDAPAccountManager/lam/lib/pdf.inc

390 lines
9.8 KiB
PHP
Raw Normal View History

<?php
2017-02-18 09:13:08 +00:00
namespace LAM\PDF;
/*
$Id$
2009-10-27 18:47:12 +00:00
This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
2012-02-05 10:38:59 +00:00
Copyright (C) 2003 - 2004 Michael Duergner
2017-02-18 09:13:08 +00:00
2003 - 2017 Roland Gruber
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
2004-10-30 16:46:06 +00:00
/**
* LDAP Account Manager PDF printing library. It consists of lamPDF class,
* the createModulePDF() function that may be called by other pages
* and furthermore some helper functions.
2016-05-10 16:37:01 +00:00
*
2006-07-29 15:12:20 +00:00
* @author Michael Duergner
2012-02-05 10:38:59 +00:00
* @author Roland Gruber
2004-10-30 16:46:06 +00:00
* @package PDF
*/
2017-02-18 20:10:06 +00:00
/** line width */
define('LAMPDF_LINEWIDTH', 190);
/** line height */
define('LAMPDF_LINEHEIGHT', 5);
/** width of a label */
define('LAMPDF_LABELWIDTH', 50);
/** font size */
2017-02-15 20:45:26 +00:00
define('LAMPDF_FONT_SIZE', 7);
2017-02-18 20:10:06 +00:00
/** font size for bigger text */
define('LAMPDF_FONT_SIZE_BIG', 10);
2004-10-30 16:46:06 +00:00
/** XML functions */
include_once('xml_parser.inc');
/** access to PDF configuration files */
include_once('pdfstruct.inc');
2004-10-30 16:46:06 +00:00
/**
* This function creates the PDF output of one or more accounts.
2016-05-10 16:37:01 +00:00
*
* @param array $accounts A numbered array containing all accounts the PDF page should
2004-10-30 16:46:06 +00:00
* be created for. The entries of the array must be AccountContainer objects.
* @param string $pdf_structure The filename of the structure definition that should be used
* to create the PDF page. If not submitted the 'default.user' structure definition
2004-10-30 16:46:06 +00:00
* for the appropriate account type.
2012-02-05 10:38:59 +00:00
* @param $returnAsString returns the PDF output as String value instead of writing it to a file
* @return String PDF file name
2004-10-30 16:46:06 +00:00
*/
2012-02-05 10:38:59 +00:00
function createModulePDF($accounts, $pdf_structure="default", $returnAsString = false) {
2016-05-10 16:37:01 +00:00
2007-11-14 10:28:39 +00:00
/** PDF generator class */
2016-05-10 16:37:01 +00:00
include_once("fpdf-lam.inc");
2007-11-14 10:28:39 +00:00
/** Unicode support for FPDF */
include_once("ufpdf.php");
/** LAM PDF generator class */
include_once("lamPDF.inc");
2008-01-08 18:18:53 +00:00
$account_type = $accounts[0]->get_type();
// Get PDF structure from xml file
2017-01-05 20:05:17 +00:00
$load = \LAM\PDF\loadPDFStructure($account_type->getId(), $pdf_structure);
$structure = $load['structure'];
2015-01-07 17:16:35 +00:00
// get list of PDF keys
$pdfKeys = array();
foreach($structure as $entry) {
if ($entry['tag'] == "SECTION" && $entry['type'] == "open") {
$key = $entry['attributes']['NAME'];
2016-05-10 16:37:01 +00:00
// only values with a starting "_" are keys
2015-01-07 17:16:35 +00:00
if (strpos($key, '_') === 0) {
$pdfKeys[] = substr($key, 1);
}
}
if ($entry['tag'] == "ENTRY") {
$pdfKeys[] = $entry['attributes']['NAME'];
}
}
$pdfKeys = array_unique($pdfKeys);
2016-05-10 16:37:01 +00:00
// The decimal separator must be a dot in order to write pdf-files
setlocale(LC_NUMERIC, "C");
2016-05-10 16:37:01 +00:00
2017-02-19 10:14:16 +00:00
$fontName = "Dejavu";
2016-05-10 16:37:01 +00:00
// Create a new PDF file acording to the account type
2017-02-18 09:13:08 +00:00
$pdf = new \lamPDF($load['page_definitions'],$fontName);
2016-05-10 16:37:01 +00:00
// Loop over each account and add a new page in the PDF file for it
foreach($accounts as $account) {
2016-05-10 16:37:01 +00:00
// Start a new page for each account
$pdf->AddPage();
2016-05-10 16:37:01 +00:00
// Get PDF entries for the current account
2017-04-01 07:57:03 +00:00
$entries = $account->get_pdfEntries($pdfKeys, $account_type->getId());
2016-05-10 16:37:01 +00:00
// Now create the PDF file acording to the structure with the submitted values
foreach($structure as $entry) {
// We have a new section to start
if($entry['tag'] == "SECTION" && $entry['type'] == "open") {
$name = $entry['attributes']['NAME'];
2007-12-28 15:57:43 +00:00
if(preg_match("/^_[a-zA-Z_]+/",$name)) {
$section_headline = getSectionHeadline($entries[substr($name,1)][0]);
}
else {
$section_headline = $name;
}
2017-02-18 20:10:06 +00:00
$pdf->setFont($fontName, "B", LAMPDF_FONT_SIZE_BIG);
2005-07-18 15:31:51 +00:00
$pdf->Write(0,$section_headline . ":");
2017-02-18 20:10:06 +00:00
$pdf->Ln(LAMPDF_LINEHEIGHT);
}
// We have a section to end
elseif($entry['tag'] == "SECTION" && $entry['type'] == "close") {
2017-02-18 20:10:06 +00:00
$pdf->Ln(LAMPDF_LINEHEIGHT * 2);
}
// We have to include a static text.
elseif($entry['tag'] == "TEXT") {
2017-02-18 20:10:06 +00:00
$pdf->setFont($fontName, "", LAMPDF_FONT_SIZE);
$info_string = str_replace("\r", "", $entry['value']);
$info_string = explode("\n", $info_string);
foreach ($info_string as $text) {
$pdf->MultiCell(0, LAMPDF_LINEHEIGHT, trim($text), 0, "L", 0);
$pdf->Ln(0);
}
$pdf->Ln(LAMPDF_LINEHEIGHT * 2);
}
// We have to include an entry from the account
elseif($entry['tag'] == "ENTRY") {
// Get name of current entry
$name = $entry['attributes']['NAME'];
2011-01-09 16:39:11 +00:00
// skip non-existent entries
if (isset($entries[$name])) {
// Get current entry
2017-02-15 20:45:26 +00:00
$valueEntries = $entries[$name];
2016-05-10 16:37:01 +00:00
2011-01-09 16:39:11 +00:00
// Print entry only when module sumitted values for it
2017-02-15 20:45:26 +00:00
if(is_array($valueEntries)) {
2011-01-09 16:39:11 +00:00
// Loop over all rows of this entry (most of the time this will be just one)
2017-02-15 20:45:26 +00:00
foreach($valueEntries as $valueEntry) {
if ($valueEntry instanceof PDFLabelValue) {
printLabelValue($pdf, $valueEntry, $fontName);
}
2017-02-18 09:13:08 +00:00
else if ($valueEntry instanceof PDFTable) {
printTable($pdf, $valueEntry, $fontName);
}
}
}
}
}
}
}
2016-05-10 16:37:01 +00:00
// Close PDF
$pdf->Close();
2012-02-05 10:38:59 +00:00
if (!$returnAsString) {
// use timestamp and random number from ldap.inc as filename so it should be unique.
2013-07-21 11:34:31 +00:00
$filename = '../../tmp/' . getRandomNumber() . time() .'.pdf';
2012-02-05 10:38:59 +00:00
// Save PDF
$pdf->Output($filename);
chmod($filename, 0640);
2012-02-05 10:38:59 +00:00
// return PDF file name
return $filename;
}
else {
return $pdf->Output('', 'S');
}
}
2004-10-30 16:46:06 +00:00
/**
* Creates a section headline.
2016-05-10 16:37:01 +00:00
*
2017-02-15 20:45:26 +00:00
* @param PDFEntry $entry content entry
2016-05-10 16:37:01 +00:00
*
2017-02-15 20:45:26 +00:00
* @return string headline
2004-10-30 16:46:06 +00:00
*/
2017-02-15 20:45:26 +00:00
function getSectionHeadline($entry) {
2017-02-18 08:59:57 +00:00
return $entry->getHeadline();
2017-02-15 20:45:26 +00:00
}
/**
* Prints a PDFLabelValue entry.
*
* @param lamPDF $pdf PDF
* @param PDFLabelValue $valueEntry entry
* @param string $fontName font name
*/
function printLabelValue(&$pdf, $valueEntry, $fontName) {
$pdf->SetFont($fontName, 'B', LAMPDF_FONT_SIZE);
2017-02-18 20:10:06 +00:00
$pdf->Cell(LAMPDF_LABELWIDTH, LAMPDF_LINEHEIGHT, $valueEntry->getLabel() . ':', 0, 0, 'R', 0);
2017-02-15 20:45:26 +00:00
$pdf->SetFont($fontName, '', LAMPDF_FONT_SIZE);
2017-02-18 20:10:06 +00:00
$pdf->MultiCell(0, LAMPDF_LINEHEIGHT, $valueEntry->getValue(), 0, 'L', 0);
$pdf->Ln(0);
}
2017-02-18 09:13:08 +00:00
/**
* Prints a PDFTable entry.
*
* @param lamPDF $pdf PDF
2017-02-18 20:10:06 +00:00
* @param PDFTable $table entry
2017-02-18 09:13:08 +00:00
* @param string $fontName font name
*/
2017-02-18 20:10:06 +00:00
function printTable(&$pdf, $table, $fontName) {
2017-03-08 16:19:44 +00:00
$headline = $table->getHeadline();
if (!empty($headline)) {
2017-02-18 20:10:06 +00:00
$pdf->SetFont($fontName, 'B', LAMPDF_FONT_SIZE);
2017-03-08 16:19:44 +00:00
$pdf->Cell(LAMPDF_LABELWIDTH, LAMPDF_LINEHEIGHT, $headline . ':', 0 , 0, 'L', 0);
2017-02-18 20:10:06 +00:00
$pdf->Ln(LAMPDF_LINEHEIGHT);
}
2017-02-18 20:10:06 +00:00
foreach ($table->rows as $row) {
foreach ($row->cells as $cell) {
$width = $cell->width;
if (!empty($width) && (strpos($width, '%') !== false)) {
$width = ceil(LAMPDF_LINEWIDTH * substr($width, 0, -1) / 100);
}
if ($cell->bold) {
$pdf->SetFont($fontName, 'B', LAMPDF_FONT_SIZE);
}
$pdf->Cell($width, LAMPDF_LINEHEIGHT, $cell->content, 0, 0, $cell->align, 0);
if ($cell->bold) {
$pdf->SetFont($fontName, '', LAMPDF_FONT_SIZE);
}
}
2017-02-18 20:10:06 +00:00
$pdf->Ln(LAMPDF_LINEHEIGHT);
}
2017-02-18 20:10:06 +00:00
$pdf->Ln(LAMPDF_LINEHEIGHT);
}
2017-02-15 20:45:26 +00:00
2017-02-18 08:59:57 +00:00
/**
* Common interface for all PDF entries.
*
* @package PDF
* @author Roland Gruber
*/
2017-02-15 20:45:26 +00:00
interface PDFEntry {
/**
2017-02-18 08:59:57 +00:00
* Returns the head line of the entry.
2017-02-15 20:45:26 +00:00
*
* @return string label
*/
2017-02-18 08:59:57 +00:00
public function getHeadline();
2017-02-15 20:45:26 +00:00
}
/**
* Represents a table for PDF export.
*
* @package PDF
* @author Roland Gruber
*/
class PDFTable implements PDFEntry {
/** optional label of table */
private $label = '';
/** list of PDFTableRow elements */
public $rows = array();
/**
* Constructor
*
* @param String $label label
*/
public function __construct($label = null) {
$this->label = $label;
}
2017-02-18 08:59:57 +00:00
/**
* {@inheritDoc}
* @see PDFEntry::getHeadline()
*/
public function getHeadline() {
return $this->label;
}
2017-02-15 20:45:26 +00:00
}
/**
* Represents a table row for PDF export.
*
* @package PDF
* @author Roland Gruber
*/
class PDFTableRow {
/** list of PDFTableCell */
public $cells = array();
}
/**
* Represents a table cell for PDF export.
*
* @package PDF
* @author Roland Gruber
*/
class PDFTableCell {
const ALIGN_LEFT = 'L';
const ALIGN_RIGHT = 'R';
const ALIGN_CENTER = 'C';
/** content text of cell */
public $content = '';
/** text alignment */
public $align = self::ALIGN_LEFT;
/** cell width (e.g. "20%") */
public $width = null;
/** bold text */
public $bold = false;
/**
* Constructor.
*
* @param String $content cell content
* @param String $width width (e.g. "20%")
* @param String $align cell alignment (default: left)
* @param boolean $bold print in bold
*/
public function __construct($content, $width = null, $align = null, $bold = false) {
$this->content = empty($content) ? ' ' : $content;
$this->align = ($align == null) ? self::ALIGN_LEFT : $align;
$this->width = $width;
$this->bold = $bold;
}
}
/**
* Simple PDF object to print label value entries.
*
* @package PDF
* @author Roland Gruber
*/
class PDFLabelValue implements PDFEntry {
private $label = '';
private $value = '';
/**
* Constructor
*
* @param string $label label
* @param string $value value
*/
public function __construct($label, $value) {
$this->label = $label;
$this->value = $value;
}
/**
* Returns the label.
*
* @return string $label label
*/
public function getLabel() {
return $this->label;
}
/**
* Returns the value.
*
* @return string $value value
*/
public function getValue() {
return $this->value;
}
2017-02-18 08:59:57 +00:00
/**
* {@inheritDoc}
* @see PDFEntry::getHeadline()
*/
public function getHeadline() {
return $this->value;
}
2017-02-15 20:45:26 +00:00
}