2003-08-20 16:09:41 +00:00
|
|
|
<?php
|
2003-05-31 10:52:15 +00:00
|
|
|
/*
|
|
|
|
$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
|
2015-01-07 17:16:35 +00:00
|
|
|
2003 - 2015 Roland Gruber
|
2003-05-31 10:52:15 +00:00
|
|
|
|
|
|
|
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,
|
2005-07-27 18:38:17 +00:00
|
|
|
* the createModulePDF() function that may be called by other pages
|
|
|
|
* and furthermore some helper functions.
|
2004-10-30 16:46:06 +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
|
|
|
|
*/
|
|
|
|
|
2005-07-27 18:38:17 +00:00
|
|
|
/** PDF line width */
|
2005-06-17 07:57:55 +00:00
|
|
|
define('LAMPDF_LINEWIDTH',190);
|
2004-10-30 16:46:06 +00:00
|
|
|
|
2005-07-27 18:38:17 +00:00
|
|
|
/** XML functions */
|
2004-05-23 15:23:00 +00:00
|
|
|
include_once('xml_parser.inc');
|
2003-05-31 10:52:15 +00:00
|
|
|
|
2005-07-27 18:38:17 +00:00
|
|
|
/** access to PDF configuration files */
|
|
|
|
include_once('pdfstruct.inc');
|
|
|
|
|
2004-05-23 15:23:00 +00:00
|
|
|
$key = false;
|
|
|
|
$line_width = LAMPDF_LINEWIDTH;
|
|
|
|
|
2004-10-30 16:46:06 +00:00
|
|
|
/**
|
2010-11-06 09:40:32 +00:00
|
|
|
* This function creates the PDF output of one or more accounts.
|
2004-10-30 16:46:06 +00:00
|
|
|
*
|
2005-07-27 18:38:17 +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.
|
2005-07-27 18:38:17 +00:00
|
|
|
* @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
|
2010-11-06 09:40:32 +00:00
|
|
|
* @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) {
|
2004-05-23 15:23:00 +00:00
|
|
|
|
2007-11-14 10:28:39 +00:00
|
|
|
/** PDF generator class */
|
2011-10-14 17:13:05 +00:00
|
|
|
include_once("fpdf.php");
|
2007-11-14 10:28:39 +00:00
|
|
|
/** Unicode support for FPDF */
|
|
|
|
include_once("ufpdf.php");
|
|
|
|
/** LAM PDF generator class */
|
|
|
|
include_once("lamPDF.inc");
|
|
|
|
|
2004-05-23 15:23:00 +00:00
|
|
|
global $key;
|
|
|
|
|
2008-01-08 18:18:53 +00:00
|
|
|
$account_type = $accounts[0]->get_type();
|
2004-06-03 14:26:48 +00:00
|
|
|
// Get PDF structure from xml file
|
2005-07-27 18:38:17 +00:00
|
|
|
$load = loadPDFStructureDefinitions($account_type,$pdf_structure);
|
2004-08-03 19:07:31 +00:00
|
|
|
$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'];
|
|
|
|
// only values with a starting "_" are keys
|
|
|
|
if (strpos($key, '_') === 0) {
|
|
|
|
$pdfKeys[] = substr($key, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ($entry['tag'] == "ENTRY") {
|
|
|
|
$pdfKeys[] = $entry['attributes']['NAME'];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$pdfKeys = array_unique($pdfKeys);
|
2004-06-03 14:26:48 +00:00
|
|
|
|
2004-05-23 15:23:00 +00:00
|
|
|
// The decimal separator must be a dot in order to write pdf-files
|
|
|
|
setlocale(LC_NUMERIC, "C");
|
|
|
|
|
2011-10-14 18:35:42 +00:00
|
|
|
$fontName = "BitstreamVeraSans-Roman";
|
2005-06-17 07:57:55 +00:00
|
|
|
|
2004-05-23 15:23:00 +00:00
|
|
|
// Create a new PDF file acording to the account type
|
2011-10-06 17:42:28 +00:00
|
|
|
$pdf = new lamPDF($load['page_definitions'],$fontName);
|
2004-05-23 15:23:00 +00:00
|
|
|
|
|
|
|
// Loop over each account and add a new page in the PDF file for it
|
|
|
|
foreach($accounts as $account) {
|
2004-05-27 17:42:19 +00:00
|
|
|
|
2004-05-23 15:23:00 +00:00
|
|
|
// Start a new page for each account
|
|
|
|
$pdf->AddPage();
|
|
|
|
|
|
|
|
// Get PDF entries for the current account
|
2015-01-07 17:16:35 +00:00
|
|
|
$entries = $account->get_pdfEntries($pdfKeys);
|
2004-05-23 15:23:00 +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)) {
|
2004-06-03 14:26:48 +00:00
|
|
|
$section_headline = getSectionHeadline($entries[substr($name,1)][0]);
|
2004-05-23 15:23:00 +00:00
|
|
|
}
|
|
|
|
else {
|
2005-06-28 16:33:06 +00:00
|
|
|
$section_headline = $name;
|
2004-05-23 15:23:00 +00:00
|
|
|
}
|
2006-07-29 15:12:20 +00:00
|
|
|
$pdf->setFont($fontName,"B",10);
|
2005-07-18 15:31:51 +00:00
|
|
|
$pdf->Write(0,$section_headline . ":");
|
2004-05-23 15:23:00 +00:00
|
|
|
$pdf->Ln(6);
|
|
|
|
}
|
|
|
|
// We have a section to end
|
|
|
|
elseif($entry['tag'] == "SECTION" && $entry['type'] == "close") {
|
|
|
|
$pdf->Ln(9);
|
|
|
|
}
|
|
|
|
// We have to include a static text.
|
|
|
|
elseif($entry['tag'] == "TEXT") {
|
2004-07-16 06:33:37 +00:00
|
|
|
// Load PDF text from structure array
|
|
|
|
$info_string = $entry['value'];
|
2004-05-23 15:23:00 +00:00
|
|
|
// Set font for text
|
2005-06-17 07:57:55 +00:00
|
|
|
$pdf->setFont($fontName,"",10);
|
2005-07-18 15:31:51 +00:00
|
|
|
$pdf->MultiCell(0,5,$info_string,0,"L",0);
|
2004-05-23 15:23:00 +00:00
|
|
|
// Print linebreak afterwards
|
|
|
|
$pdf->Ln(6);
|
|
|
|
}
|
|
|
|
// We have to include an entry from the account
|
|
|
|
elseif($entry['tag'] == "ENTRY") {
|
2004-05-27 17:42:19 +00:00
|
|
|
// 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
|
|
|
|
$value_entry = $entries[$name];
|
|
|
|
|
|
|
|
// Print entry only when module sumitted values for it
|
|
|
|
if(is_array($value_entry)) {
|
|
|
|
// Loop over all rows of this entry (most of the time this will be just one)
|
|
|
|
foreach($value_entry as $line) {
|
|
|
|
// Substitue XML syntax with valid FPDF methods
|
|
|
|
$methods = processLine($line,true,$fontName);
|
|
|
|
// Call every method
|
|
|
|
foreach($methods as $method) {
|
|
|
|
call_user_func_array(array(&$pdf,$method[0]),$method[1]);
|
|
|
|
}
|
2004-05-27 19:07:50 +00:00
|
|
|
}
|
2004-05-23 15:23:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
$key = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Close PDF
|
2004-05-27 17:42:19 +00:00
|
|
|
$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);
|
2015-06-18 18:16:00 +00:00
|
|
|
chmod($filename, 0640);
|
2012-02-05 10:38:59 +00:00
|
|
|
// return PDF file name
|
|
|
|
return $filename;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return $pdf->Output('', 'S');
|
|
|
|
}
|
2004-05-23 15:23:00 +00:00
|
|
|
}
|
|
|
|
|
2004-10-30 16:46:06 +00:00
|
|
|
/**
|
2005-07-27 18:38:17 +00:00
|
|
|
* Creates a section headline.
|
2004-10-30 16:46:06 +00:00
|
|
|
*
|
2005-07-27 18:38:17 +00:00
|
|
|
* @param string $line section name
|
2004-10-30 16:46:06 +00:00
|
|
|
*
|
2005-07-27 18:38:17 +00:00
|
|
|
* @return string XML code for headline
|
2004-10-30 16:46:06 +00:00
|
|
|
*/
|
2004-06-03 14:26:48 +00:00
|
|
|
function getSectionHeadline($line) {
|
|
|
|
$headline_pattern = '/<block>.*<value>(.*)<\/value><\/block>/';
|
|
|
|
if(preg_match($headline_pattern,$line,$matches)) {
|
|
|
|
$valueStyle = processFormatTags($matches[1],'');
|
|
|
|
return $valueStyle[1];
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return '';
|
2004-05-23 15:23:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-10-30 16:46:06 +00:00
|
|
|
/**
|
2005-07-27 18:38:17 +00:00
|
|
|
* Creates the XML code for an PDF entry.
|
2004-10-30 16:46:06 +00:00
|
|
|
*
|
2005-07-27 18:38:17 +00:00
|
|
|
* @param string $line XML code of PDF entry
|
|
|
|
* @param boolean $first_td True if this is the first column
|
2012-07-15 12:05:47 +00:00
|
|
|
* @param String $fontName font name
|
2004-10-30 16:46:06 +00:00
|
|
|
*
|
2005-07-27 18:38:17 +00:00
|
|
|
* @return array XML codes
|
2004-10-30 16:46:06 +00:00
|
|
|
*/
|
2012-07-15 12:05:47 +00:00
|
|
|
function processLine($line, $first_td = true, $fontName) {
|
2004-05-23 15:23:00 +00:00
|
|
|
global $key, $line_width;
|
|
|
|
|
|
|
|
// PCRE matching <block> tag
|
|
|
|
$block_pattern = '/<block><\/block>/';
|
|
|
|
// PCRE matching a <key> tag
|
|
|
|
$key_pattern = '/(<block>)<key>(.+)<\/key>(.*<\/block>)/';
|
|
|
|
// PCRE matching a <value> tag
|
2004-05-27 17:42:19 +00:00
|
|
|
// !!FIXME!! value must contain at least one character
|
|
|
|
$value_pattern = '/(<block>.*)<value>(.*)<\/value>(<\/block>)/';
|
2004-05-23 15:23:00 +00:00
|
|
|
// PCRE matching a <td> tag
|
|
|
|
$td_pattern = '/(<block>.*?)<td(.*?)>(.+?)<\/td>(.*<\/block>)/';
|
2005-07-28 09:01:41 +00:00
|
|
|
// PCRE matching <tr> tag
|
|
|
|
$tr_pattern = '/<tr><\/tr>/';
|
2004-05-23 15:23:00 +00:00
|
|
|
// PCRE matching a <p> tag
|
|
|
|
$p_pattern = '/(<block>.*)<p>(.+)<\/p>(.*<\/block>)/';
|
|
|
|
// PCRE matching a <br> tag
|
|
|
|
$br_pattern = '/<br \/>/';
|
|
|
|
|
|
|
|
$return = array();
|
|
|
|
if(preg_match($key_pattern,$line,$matches)) {
|
|
|
|
$key = true;
|
|
|
|
$line_width = $line_width - 50;
|
|
|
|
$format = processFormatTags($matches[2],'B');
|
2006-07-29 15:12:20 +00:00
|
|
|
$return[] = array('setFont',array($fontName,$format[0],7));
|
2005-07-28 09:01:41 +00:00
|
|
|
$return[] = array('Cell',array(50,5,$format[1] . ':',0,0,'R',0));
|
2006-07-29 15:12:20 +00:00
|
|
|
$return[] = array('setFont',array($fontName,'',7));
|
2005-06-17 07:57:55 +00:00
|
|
|
return array_merge($return,processLine($matches[1] . $matches[3],false,$fontName));
|
2004-05-23 15:23:00 +00:00
|
|
|
}
|
|
|
|
elseif(preg_match($value_pattern,$line,$matches)) {
|
|
|
|
$format = processFormatTags($matches[2],'');
|
2006-07-29 15:12:20 +00:00
|
|
|
$return[] = array('setFont',array($fontName,$format[0],7));
|
2005-07-28 09:01:41 +00:00
|
|
|
$return[] = array('MultiCell',array(0,5,$format[1],0,'L',0));
|
2006-07-29 15:12:20 +00:00
|
|
|
$return[] = array('setFont',array($fontName,'',7));
|
2005-06-17 07:57:55 +00:00
|
|
|
return array_merge($return,processLine($matches[1] . $matches[3],true,$fontName));
|
2004-05-23 15:23:00 +00:00
|
|
|
}
|
|
|
|
elseif(preg_match($p_pattern,$line,$matches)) {
|
|
|
|
$format = processFormatTags($matches[2],'');
|
2006-07-29 15:12:20 +00:00
|
|
|
$return[] = array('setFont',array($fontName,$format[0],7));
|
2004-05-23 15:23:00 +00:00
|
|
|
$return[] = array('Write',array(5,$format[1]));
|
2006-07-29 15:12:20 +00:00
|
|
|
$return[] = array('setFont',array($fontName,'',7));
|
2005-06-17 07:57:55 +00:00
|
|
|
return array_merge($return,processLine($matches[1] . $matches[3],true,$fontName));
|
2004-05-23 15:23:00 +00:00
|
|
|
}
|
|
|
|
elseif(preg_match($td_pattern,$line,$matches)) {
|
|
|
|
if($first_td && $key) {
|
|
|
|
$first_td = !$first_td;
|
|
|
|
$return[] = array('Cell',array(50,5,'',0,0,'L',0));
|
|
|
|
}
|
|
|
|
$format = processFormatTags($matches[3],'');
|
2005-07-28 09:01:41 +00:00
|
|
|
$attrs = processAttributes($matches[2],array('width' => $line_width,'height' => 5,'align' => 'L'));
|
2006-07-29 15:12:20 +00:00
|
|
|
$return[] = array('setFont',array($fontName,$format[0],7));
|
2004-05-23 15:23:00 +00:00
|
|
|
$return[] = array('Cell',array($attrs['width'],$attrs['height'],$format[1],0,0,$attrs['align'],0));
|
2006-07-29 15:12:20 +00:00
|
|
|
$return[] = array('setFont',array($fontName,'',7));
|
2005-06-17 07:57:55 +00:00
|
|
|
return array_merge($return,processLine($matches[1] . $matches[4],$first_td,$fontName));
|
2004-05-23 15:23:00 +00:00
|
|
|
}
|
|
|
|
elseif(preg_match($br_pattern,$line,$matches)) {
|
|
|
|
return array(array('Ln',array(5)));
|
|
|
|
}
|
|
|
|
elseif(preg_match($block_pattern,$line,$matches)) {
|
2005-07-28 09:01:41 +00:00
|
|
|
$line_width = LAMPDF_LINEWIDTH;
|
|
|
|
return array();
|
|
|
|
}
|
|
|
|
elseif(preg_match($tr_pattern,$line,$matches)) {
|
2004-05-23 15:23:00 +00:00
|
|
|
$line_width = LAMPDF_LINEWIDTH;
|
|
|
|
return array(array('Ln',array(5)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-10-30 16:46:06 +00:00
|
|
|
/**
|
2005-07-27 18:38:17 +00:00
|
|
|
* Formats the XML code.
|
2004-10-30 16:46:06 +00:00
|
|
|
*
|
2005-07-27 18:38:17 +00:00
|
|
|
* @param string $line XML code of PDF entry
|
|
|
|
* @param string $style style commands
|
2004-10-30 16:46:06 +00:00
|
|
|
*
|
2005-07-27 18:38:17 +00:00
|
|
|
* @return array XML code
|
2004-10-30 16:46:06 +00:00
|
|
|
*/
|
2004-05-23 15:23:00 +00:00
|
|
|
function processFormatTags($line,$style) {
|
|
|
|
// PCRE matching a <i> tag
|
|
|
|
$i_pattern = '/(.*)<i>(.+)<\/i>(.*)/';
|
|
|
|
// PCRE matching a <b> tag
|
|
|
|
$b_pattern = '/(.*)<b>(.+)<\/b>(.*)/';
|
|
|
|
// PCRE matching a <u> tag
|
|
|
|
$u_pattern = '/(.*)<u>(.+)<\/u>(.*)/';
|
|
|
|
// Replacement pattern when one of the above pattern matched
|
2004-05-29 19:20:28 +00:00
|
|
|
$replace = "\$1\$2\$3";
|
2004-05-23 15:23:00 +00:00
|
|
|
|
|
|
|
if(preg_match($i_pattern,$line,$matches)) {
|
|
|
|
$style .= "I";
|
|
|
|
$line = preg_replace($i_pattern,$replace,$line);
|
|
|
|
}
|
|
|
|
if(preg_match($b_pattern,$line,$matches)) {
|
|
|
|
$style .= "B";
|
|
|
|
$line = preg_replace($b_pattern,$replace,$line);
|
|
|
|
}
|
|
|
|
if(preg_match($u_pattern,$line,$matches)) {
|
|
|
|
$style .= "U";
|
|
|
|
$line = preg_replace($u_pattern,$replace,$line);
|
|
|
|
}
|
|
|
|
return array($style,$line);
|
|
|
|
}
|
|
|
|
|
2004-10-30 16:46:06 +00:00
|
|
|
/**
|
2005-07-27 18:38:17 +00:00
|
|
|
* Processes width, height and alignment attributes.
|
2004-10-30 16:46:06 +00:00
|
|
|
*
|
2005-07-27 18:38:17 +00:00
|
|
|
* @param string $attrs attributes
|
|
|
|
* @param array $return XML code
|
2004-10-30 16:46:06 +00:00
|
|
|
*
|
2005-07-27 18:38:17 +00:00
|
|
|
* @return array XML code
|
2004-10-30 16:46:06 +00:00
|
|
|
*/
|
2004-05-23 15:23:00 +00:00
|
|
|
function processAttributes($attrs,$return = array()) {
|
|
|
|
global $line_width;
|
|
|
|
|
|
|
|
// PCRE matching width attribute
|
|
|
|
$width_pattern = '/(.*)width\=\"(\\d+)(\%?)\"(.*)/';
|
|
|
|
// PCRE matching height attribute
|
|
|
|
$height_pattern = '/(.*)height\=\"(\\d+)\"(.*)/';
|
|
|
|
// PCRE matching align attribute
|
|
|
|
$align_pattern = '/(.*)align\=\"(L|R|C)\"(.*)/';
|
|
|
|
|
|
|
|
// Remove leading and trailing whitespaces
|
|
|
|
$attrs = trim($attrs);
|
|
|
|
|
|
|
|
if(preg_match($width_pattern,$attrs,$matches)) {
|
|
|
|
if($matches[3] == '%') {
|
|
|
|
$return['width'] = ceil($line_width * $matches[2] / 100);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
$return['width'] = ceil($matches[2]);
|
|
|
|
}
|
|
|
|
return processAttributes($matches[1] . $matches[4],$return);
|
|
|
|
}
|
|
|
|
elseif(preg_match($height_pattern,$attrs,$matches)) {
|
|
|
|
$return['height'] = $matches[2];
|
|
|
|
return processAttributes($matches[1] . $matches[3],$return);
|
|
|
|
}
|
|
|
|
elseif(preg_match($align_pattern,$attrs,$matches)) {
|
|
|
|
$return['align'] = $matches[2];
|
|
|
|
return processAttributes($matches[1] . $matches[3],$return);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return $return;
|
|
|
|
}
|
|
|
|
}
|