2004-05-30 13:43:42 +00:00
< ? php
2017-01-04 19:52:51 +00:00
namespace LAM\PDF ;
use \htmlStatusMessage ;
2017-01-05 20:05:17 +00:00
use \LAMException ;
2018-08-25 17:39:47 +00:00
use \LAM\ImageUtils\ImageManipulationFactory ;
2004-05-30 13:43:42 +00:00
/*
2009-10-27 18:47:12 +00:00
This code is part of LDAP Account Manager ( http :// www . ldap - account - manager . org / )
2011-11-27 14:49:20 +00:00
Copyright ( C ) 2003 - 2006 Michael Duergner
2020-03-03 19:34:06 +00:00
2011 - 2020 Roland Gruber
2004-05-30 13:43:42 +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
/**
2005-07-27 18:27:24 +00:00
* Functions to manage the PDF structures .
2016-12-19 20:32:08 +00:00
*
2011-11-27 14:49:20 +00:00
* @ author Michael Duergner
2004-10-30 16:46:06 +00:00
* @ package PDF
*/
2005-07-27 18:27:24 +00:00
/** LAM configuration */
2018-12-23 16:52:56 +00:00
include_once ( __DIR__ . " /config.inc " );
2004-10-30 16:46:06 +00:00
2020-05-30 10:35:22 +00:00
/**
* Use as server profile name to manage global templates .
*/
const GLOBAL_PROFILE = '__GLOBAL__' ;
2005-07-27 18:27:24 +00:00
/** LDAP object */
2018-12-23 16:52:56 +00:00
include_once ( __DIR__ . " /ldap.inc " );
2004-05-30 13:43:42 +00:00
2004-10-30 16:46:06 +00:00
/**
2005-07-27 18:27:24 +00:00
* This function will return all available PDF structure definitions for the submitted
2017-01-07 18:10:12 +00:00
* account type .
2012-10-28 14:37:54 +00:00
*
2017-01-07 18:10:12 +00:00
* @ param string $typeId the account type
2012-10-28 14:37:54 +00:00
* @ param string $profile server profile name
*
2020-05-03 08:59:35 +00:00
* @ return string [] All available PDF structure definitions for the submitted account
2012-10-28 14:37:54 +00:00
* scope . Each entry is a string being the filename that may be passed to the
2005-07-27 18:27:24 +00:00
* createModulePDF () function as second argument .
2004-10-30 16:46:06 +00:00
*/
2020-05-03 08:59:35 +00:00
function getPDFStructures ( $typeId , $profile ) {
2004-05-30 13:43:42 +00:00
$return = array ();
2017-01-07 18:10:12 +00:00
if ( ! preg_match ( '/[a-zA-Z]+/' , $typeId )) {
return null ;
}
2012-10-28 14:37:54 +00:00
$path = dirname ( __FILE__ ) . '/../config/pdf/' . $profile ;
2004-09-08 14:40:25 +00:00
if ( is_dir ( $path )) {
$dirHandle = opendir ( $path );
while ( $file = readdir ( $dirHandle )) {
2005-07-27 18:27:24 +00:00
$struct_file = explode ( '.' , $file );
2017-01-07 18:10:12 +00:00
if ( ! is_dir ( $path . $file ) && ( $file != '.' ) && ( $file != '..' ) && ( sizeof ( $struct_file ) == 3 ) && ( $struct_file [ 1 ] == $typeId ) && ( $struct_file [ 2 ] == 'xml' )) {
2005-07-27 18:27:24 +00:00
array_push ( $return , $struct_file [ 0 ]);
2004-09-08 14:40:25 +00:00
}
2004-05-30 13:43:42 +00:00
}
2004-09-08 14:40:25 +00:00
sort ( $return );
2004-05-30 13:43:42 +00:00
}
2005-07-27 18:27:24 +00:00
return $return ;
2004-05-30 13:43:42 +00:00
}
2004-10-30 16:46:06 +00:00
/**
2005-07-27 18:27:24 +00:00
* Deletes XML file with PDF structure definitions .
2012-10-28 14:37:54 +00:00
*
2017-01-05 20:05:17 +00:00
* @ param string $typeId account type
* @ param string $name Name of definition to delete
2020-05-03 08:59:35 +00:00
* @ param string $serverProfileName server profile name
2020-03-03 19:34:06 +00:00
* @ return boolean True if file was deleted or false if a problem occurred .
2004-10-30 16:46:06 +00:00
*/
2020-05-03 08:59:35 +00:00
function deletePDFStructure ( $typeId , $name , $serverProfileName ) {
2017-01-05 20:05:17 +00:00
if ( ! isValidPDFStructureName ( $name ) || ! preg_match ( '/[a-zA-Z]+/' , $typeId )) {
return false ;
}
2020-05-03 08:59:35 +00:00
$file = dirname ( __FILE__ ) . '/../config/pdf/' . $serverProfileName . '/' . $name . '.' . $typeId . '.xml' ;
2005-07-27 18:27:24 +00:00
if ( is_file ( $file ) && is_writable ( $file )) {
return unlink ( $file );
}
else {
return false ;
}
2012-10-28 14:37:54 +00:00
2004-07-16 06:33:37 +00:00
}
2004-08-03 19:07:31 +00:00
2004-10-30 16:46:06 +00:00
/**
2005-07-27 18:27:24 +00:00
* This function returns an array with all aviliable logo images .
2012-10-28 14:37:54 +00:00
*
2020-05-03 08:59:35 +00:00
* @ param string $serverProfileName server profile name
2020-05-12 18:58:56 +00:00
* @ return array list of logo files ( array ( 'filename' => PATH , 'infos' => array ( width , height )))
2004-10-30 16:46:06 +00:00
*/
2020-05-03 08:59:35 +00:00
function getAvailableLogos ( $serverProfileName ) {
2004-08-03 19:07:31 +00:00
$return = array ();
2020-05-03 08:59:35 +00:00
$dirPath = dirname ( __FILE__ ) . '/../config/pdf/' . $serverProfileName . '/logos/' ;
2004-08-03 19:07:31 +00:00
$dirHandle = opendir ( $dirPath );
while ( $file = readdir ( $dirHandle )) {
2016-12-19 20:32:08 +00:00
if ( ! is_dir ( $file ) && $file != '.' && $file != '..' && preg_match ( '/\\.(jpg|png)$/i' , $file )) {
2018-08-25 17:39:47 +00:00
include_once dirname ( __FILE__ ) . '/imageutils.inc' ;
$imageManipulator = ImageManipulationFactory :: getImageManipulatorFromFile ( $dirPath . $file );
$infos = array ( $imageManipulator -> getWidth (), $imageManipulator -> getHeight ());
$imageManipulator = null ;
array_push ( $return , array ( 'filename' => $file , 'infos' => $infos ));
2004-08-03 19:07:31 +00:00
}
}
sort ( $return );
return $return ;
}
2012-10-28 14:37:54 +00:00
/**
2017-01-05 20:05:17 +00:00
* Copies a PDF structure from the given source to target .
2012-10-28 14:37:54 +00:00
*
2017-01-05 20:05:17 +00:00
* @ param \LAM\TYPES\ConfiguredType $sourceType source type
* @ param string $sourceStructureName structure name
* @ param \LAM\TYPES\ConfiguredType $targetType target type
2020-05-13 18:47:12 +00:00
* @ throws LAMException error during copy
2012-10-28 14:37:54 +00:00
*/
2017-01-05 20:05:17 +00:00
function copyStructure ( $sourceType , $sourceStructureName , $targetType ) {
if ( ! isValidPDFStructureName ( $sourceStructureName )) {
throw new LAMException ( _ ( 'Failed to copy' ));
2012-10-28 14:37:54 +00:00
}
2017-01-05 20:05:17 +00:00
$sourceConfig = $sourceType -> getTypeManager () -> getConfig () -> getName ();
$sourceTypeId = $sourceType -> getId ();
$targetConfig = $targetType -> getTypeManager () -> getConfig () -> getName ();
$targetTypeId = $targetType -> getId ();
$basePath = dirname ( __FILE__ ) . '/../config/pdf/' ;
2017-01-05 20:40:48 +00:00
$src = $basePath . $sourceConfig . '/' . $sourceStructureName . '.' . $sourceTypeId . '.xml' ;
$dst = $basePath . $targetConfig . '/' . $sourceStructureName . '.' . $targetTypeId . '.xml' ;
2017-01-05 20:05:17 +00:00
if ( !@ copy ( $src , $dst )) {
throw new LAMException ( _ ( 'Failed to copy' ), $sourceConfig . ': ' . $sourceStructureName );
}
}
2012-10-28 14:37:54 +00:00
2017-01-05 20:05:17 +00:00
/**
* Copies a PDF structure from the given source to global templates .
*
* @ param \LAM\TYPES\ConfiguredType $sourceType source type
* @ param string $sourceName structure name
* @ throws Exception
*/
function copyStructureToTemplates ( $sourceType , $sourceName ) {
if ( ! isValidPDFStructureName ( $sourceName )) {
throw new LAMException ( _ ( 'Failed to copy' ));
}
$sourceConfig = $sourceType -> getTypeManager () -> getConfig () -> getName ();
$sourceTypeId = $sourceType -> getId ();
$basePath = dirname ( __FILE__ ) . '/../config/pdf/' ;
$templatePath = dirname ( __FILE__ ) . '/../config/templates/pdf/' ;
2017-01-05 20:40:48 +00:00
$src = $basePath . $sourceConfig . '/' . $sourceName . '.' . $sourceTypeId . '.xml' ;
$dst = $templatePath . $sourceName . '.' . $sourceType -> getScope () . '.xml' ;
2017-01-05 20:05:17 +00:00
if ( !@ copy ( $src , $dst )) {
throw new LAMException ( _ ( 'Failed to copy' ), $sourceConfig . ': ' . $sourceName );
}
2012-10-28 14:37:54 +00:00
}
2013-10-08 19:11:01 +00:00
/**
* Uploads a PDF logo file for the current server profile .
2016-12-19 20:32:08 +00:00
*
2013-10-08 19:11:01 +00:00
* @ param String $file full path of temporary file
* @ param String $name file name
2020-05-03 08:59:35 +00:00
* @ param string $serverProfileName server profile name
2020-05-30 10:35:22 +00:00
* @ return htmlStatusMessage status message to display
2013-10-08 19:11:01 +00:00
*/
2020-05-03 08:59:35 +00:00
function uploadPDFLogo ( $file , $name , $serverProfileName ) {
2016-12-19 20:32:08 +00:00
if ( ! preg_match ( '/[a-zA-Z0-9_-]+\\.(png)|(jpg)/i' , $name )) {
2013-10-08 19:11:01 +00:00
return new htmlStatusMessage ( 'ERROR' , _ ( 'Unable to upload logo file.' ), _ ( 'The file name must end with ".png" or ".jpg".' ));
}
2020-05-30 10:35:22 +00:00
if ( $serverProfileName === GLOBAL_PROFILE ) {
$serverProfileName = '../templates/pdf' ;
}
2020-05-03 08:59:35 +00:00
$dirPath = dirname ( __FILE__ ) . '/../config/pdf/' . $serverProfileName . '/logos/' ;
2018-08-25 17:39:47 +00:00
$success = copy ( $file , $dirPath . '/' . $name );
if ( $success ) {
return new htmlStatusMessage ( 'INFO' , _ ( 'Uploaded logo file.' ), $name );
}
else {
return new htmlStatusMessage ( 'ERROR' , _ ( 'Unable to upload logo file.' ), $name );
2013-10-08 19:11:01 +00:00
}
}
/**
* Deletes a PDF logo file .
2016-12-19 20:32:08 +00:00
*
2013-10-08 19:11:01 +00:00
* @ param String $name file name
2020-05-03 08:59:35 +00:00
* @ param string $serverProfileName server profile name
2013-10-08 19:11:01 +00:00
* @ return StatusMessage status message to display
*/
2020-05-03 08:59:35 +00:00
function deletePDFLogo ( $name , $serverProfileName ) {
2013-10-08 19:11:01 +00:00
// check if valid file
$found = false ;
2020-05-03 08:59:35 +00:00
$logos = getAvailableLogos ( $serverProfileName );
2013-10-08 19:11:01 +00:00
foreach ( $logos as $logo ) {
if ( $logo [ 'filename' ] === $name ) {
$found = true ;
break ;
}
}
if ( ! $found ) {
return new htmlStatusMessage ( 'ERROR' , _ ( 'File does not exist.' ), htmlspecialchars ( $name ));
}
// check if still in use
2017-01-07 18:10:12 +00:00
$typeManager = new \LAM\TYPES\TypeManager ();
$activeTypes = $typeManager -> getConfiguredTypes ();
2020-05-07 18:22:41 +00:00
$reader = new PDFStructureReader ( $serverProfileName );
2013-10-08 19:11:01 +00:00
foreach ( $activeTypes as $type ) {
2020-05-03 08:59:35 +00:00
$structures = getPDFStructures ( $type -> getId (), $serverProfileName );
2013-10-08 19:11:01 +00:00
foreach ( $structures as $structure ) {
2018-05-08 18:11:53 +00:00
try {
$data = $reader -> read ( $type -> getId (), $structure );
if ( $data -> getLogo () == $name ) {
return new htmlStatusMessage ( 'ERROR' , _ ( 'Unable to delete logo file.' ),
sprintf ( _ ( 'Logo is still in use by PDF structure "%s" in account type "%s".' ), $structure , $type -> getAlias ()));
}
}
catch ( LAMException $e ) {
logNewMessage ( LOG_ERR , 'Error reading PDF file ' . $e -> getMessage ());
2013-10-08 19:11:01 +00:00
}
}
}
// delete file
2020-05-03 08:59:35 +00:00
$dirPath = dirname ( __FILE__ ) . '/../config/pdf/' . $serverProfileName . '/logos/' ;
2013-10-08 19:11:01 +00:00
$success = @ unlink ( $dirPath . '/' . $name );
if ( $success ) {
return new htmlStatusMessage ( 'INFO' , _ ( 'Logo file deleted.' ), $name );
}
2018-12-29 14:49:42 +00:00
return new htmlStatusMessage ( 'ERROR' , _ ( 'Unable to delete logo file.' ), $name );
2013-10-08 19:11:01 +00:00
}
2017-01-05 20:05:17 +00:00
/**
* Returns if the give structure name is valid .
*
* @ param string $name structure name
* @ return boolean is valid
*/
function isValidPDFStructureName ( $name ) {
2017-07-02 07:00:14 +00:00
return preg_match ( '/^[a-z0-9\-\_]+$/i' , $name ) === 1 ;
2017-01-05 20:05:17 +00:00
}
2017-01-06 12:56:17 +00:00
/**
* Installs template structures to the current server profile .
*/
function installPDFTemplates () {
2020-05-30 10:35:22 +00:00
$templatePath = __DIR__ . '/../config/templates/pdf' ;
$allTemplates = getPdfTemplateNames ();
2017-01-22 17:00:47 +00:00
$basePath = dirname ( __FILE__ ) . '/../config/pdf/' . $_SESSION [ 'config' ] -> getName ();
if ( ! file_exists ( $basePath )) {
2017-05-15 18:11:00 +00:00
mkdir ( $basePath , 0700 , true );
2017-01-22 17:00:47 +00:00
}
2017-01-06 12:56:17 +00:00
$typeManager = new \LAM\TYPES\TypeManager ();
foreach ( $typeManager -> getConfiguredTypes () as $type ) {
if ( empty ( $allTemplates [ $type -> getScope ()])) {
continue ;
}
foreach ( $allTemplates [ $type -> getScope ()] as $templateName ) {
2017-01-22 17:00:47 +00:00
$path = $basePath . '/' . $templateName . '.' . $type -> getId () . '.xml' ;
2017-01-06 12:56:17 +00:00
if ( ! is_file ( $path )) {
2017-01-11 20:27:28 +00:00
$template = $templatePath . '/' . $templateName . '.' . $type -> getScope () . '.xml' ;
logNewMessage ( LOG_DEBUG , 'Copy template ' . $template . ' to ' . $path );
2017-01-06 12:56:17 +00:00
@ copy ( $template , $path );
}
}
}
2017-01-22 17:00:47 +00:00
if ( ! file_exists ( $basePath . '/logos' )) {
mkdir ( $basePath . '/logos' );
}
2020-05-30 10:35:22 +00:00
$logos = getPdfTemplateLogoNames ();
foreach ( $logos as $logo ) {
$path = $basePath . '/logos/' . $logo ;
$template = $templatePath . '/logos/' . $logo ;
if ( ! is_file ( $path )) {
logNewMessage ( LOG_DEBUG , 'Copy template ' . $template . ' to ' . $path );
@ copy ( $template , $path );
}
}
}
/**
* Returns all PDF template names .
*
* @ return array names ( array ( 'user' => array ( 'default' )))
*/
function getPdfTemplateNames () {
$templatePath = __DIR__ . '/../config/templates/pdf' ;
2017-01-22 17:00:47 +00:00
$templateDir = @ dir ( $templatePath );
2020-05-30 10:35:22 +00:00
$allTemplates = array ();
2017-01-22 17:00:47 +00:00
if ( $templateDir ) {
$entry = $templateDir -> read ();
while ( $entry ){
2020-05-30 10:35:22 +00:00
$parts = explode ( '.' , $entry );
if (( strlen ( $entry ) > 3 ) && ( sizeof ( $parts ) == 3 )) {
$name = $parts [ 0 ];
$scope = $parts [ 1 ];
$allTemplates [ $scope ][] = $name ;
2017-01-22 17:00:47 +00:00
}
$entry = $templateDir -> read ();
}
}
2020-05-30 10:35:22 +00:00
return $allTemplates ;
}
/**
* Returns all PDF template logo names .
*
* @ return array names ( array ( 'user' => array ( 'default.png' )))
*/
function getPdfTemplateLogoNames () {
$templatePath = __DIR__ . '/../config/templates/pdf/logos' ;
$templateDir = @ dir ( $templatePath );
$logos = array ();
if ( $templateDir ) {
$entry = $templateDir -> read ();
while ( $entry ){
if (( strpos ( $entry , '.' ) !== 0 ) && is_file ( $templatePath . '/' . $entry )) {
$logos [] = $entry ;
}
$entry = $templateDir -> read ();
}
}
return $logos ;
}
/**
* Returns the binary data of the PDF template logo .
*
* @ param string $name file name ( without path )
* @ return string binary
*/
function getPdfTemplateLogoBinary ( $name ) {
$templatePath = __DIR__ . '/../config/templates/pdf/logos' ;
$fileName = $templatePath . '/' . $name ;
$handle = fopen ( $fileName , 'r' );
$logoBinary = fread ( $handle , 100000000 );
fclose ( $handle );
return $logoBinary ;
2017-01-06 12:56:17 +00:00
}
2017-06-25 12:23:28 +00:00
/**
* Reads a PDF structure .
*
* @ author Roland Gruber
*/
class PDFStructureReader {
2020-05-07 18:22:41 +00:00
private $serverProfileName ;
/**
* Constructor .
*
* @ param $serverProfileName server profile name
*/
public function __construct ( $serverProfileName ) {
2020-05-30 10:35:22 +00:00
if ( $serverProfileName === GLOBAL_PROFILE ) {
$this -> serverProfileName = '../templates/pdf' ;
}
else {
$this -> serverProfileName = $serverProfileName ;
}
2020-05-07 18:22:41 +00:00
}
2017-06-25 12:23:28 +00:00
/**
* Reads a PDF structure .
*
* @ param string $typeId type id
* @ param string $name structure name
* @ return PDFStructure structure
*/
public function read ( $typeId , $name ) {
if ( ! isValidPDFStructureName ( $name ) || ! preg_match ( '/[a-zA-Z]+/' , $typeId )) {
return null ;
}
$file = $this -> getFileName ( $typeId , $name );
return $this -> readPDFFile ( $file );
}
/**
* Returns the file name for the given structure .
*
* @ param string $typeId type id
* @ param string $name structure name
* @ return string file name
*/
protected function getFileName ( $typeId , $name ) {
2020-05-07 18:22:41 +00:00
return dirname ( __FILE__ ) . '/../config/pdf/' . $this -> serverProfileName . '/' . $name . '.' . $typeId . '.xml' ;
2017-06-25 12:23:28 +00:00
}
/**
* Reads a PDF structure file .
*
* @ param string $file file name
* @ return PDFStructure structure
*/
private function readPDFFile ( $file ) {
2020-05-30 10:35:22 +00:00
logNewMessage ( LOG_DEBUG , $file );
2017-06-25 12:23:28 +00:00
$xml = new \XMLReader ();
$xml -> open ( $file );
$structure = new PDFStructure ();
// open <pdf>
2017-07-02 07:00:14 +00:00
@ $xml -> read ();
2017-06-25 12:23:28 +00:00
if ( ! $xml -> name == 'pdf' ) {
logNewMessage ( LOG_ERR , 'Unknown tag name: ' . $xml -> name );
throw new \LAMException ( _ ( 'Unable to read PDF structure.' ));
}
$structure -> setLogo ( $xml -> getAttribute ( 'filename' ));
$structure -> setTitle ( $xml -> getAttribute ( 'headline' ));
2017-06-25 12:47:33 +00:00
$structure -> setFoldingMarks ( $xml -> getAttribute ( 'foldingmarks' ));
2017-06-25 12:23:28 +00:00
$sections = array ();
while ( $xml -> read ()) {
2018-12-29 14:49:42 +00:00
if (( $xml -> nodeType === \XMLReader :: SIGNIFICANT_WHITESPACE )
|| (( $xml -> name === 'pdf' ) && ( $xml -> nodeType == \XMLReader :: END_ELEMENT ))) {
2017-06-25 12:23:28 +00:00
continue ;
}
elseif ( $xml -> name === 'text' ) {
$xml -> read ();
$sections [] = new PDFTextSection ( $xml -> value );
$xml -> read ();
if ( ! $xml -> name === 'text' ) {
logNewMessage ( LOG_ERR , 'Unexpected tag name: ' . $xml -> name );
throw new \LAMException ( _ ( 'Unable to read PDF structure.' ));
}
}
elseif ( $xml -> name === 'section' ) {
$sections [] = $this -> readSection ( $xml );
}
else {
2018-05-08 18:11:53 +00:00
logNewMessage ( LOG_ERR , 'Unexpected tag name: ' . $xml -> name . ' in ' . $file );
2017-06-25 12:23:28 +00:00
throw new \LAMException ( _ ( 'Unable to read PDF structure.' ));
}
}
$xml -> close ();
$structure -> setSections ( $sections );
return $structure ;
}
/**
* Reads a single section from XML .
*
* @ param \XMLReader $xml reader
*/
private function readSection ( & $xml ) {
$section = new PDFEntrySection ( $xml -> getAttribute ( 'name' ));
$entries = array ();
while ( $xml -> read ()) {
if (( $xml -> name === 'section' ) && ( $xml -> nodeType == \XMLReader :: END_ELEMENT )) {
break ;
}
2018-12-29 14:49:42 +00:00
elseif (( $xml -> nodeType === \XMLReader :: END_ELEMENT )
|| ( $xml -> nodeType === \XMLReader :: SIGNIFICANT_WHITESPACE )) {
2017-06-25 12:23:28 +00:00
continue ;
}
elseif ( $xml -> name === 'entry' ) {
$entries [] = new PDFSectionEntry ( $xml -> getAttribute ( 'name' ));
}
elseif ( ! $xml -> name === 'entry' ) {
logNewMessage ( LOG_ERR , 'Unexpected tag name: ' . $xml -> name );
throw new \LAMException ( _ ( 'Unable to read PDF structure.' ));
}
}
$section -> setEntries ( $entries );
return $section ;
}
}
2017-07-02 07:00:14 +00:00
/**
* Writes PDF structures to files .
*
* @ author Roland Gruber
*/
class PDFStructureWriter {
2020-05-07 18:27:50 +00:00
private $serverProfileName ;
/**
* Constructor .
*
2020-05-13 18:47:12 +00:00
* @ param string $serverProfileName server profile name
2020-05-07 18:27:50 +00:00
*/
public function __construct ( $serverProfileName ) {
2020-05-30 10:35:22 +00:00
if ( $serverProfileName === GLOBAL_PROFILE ) {
$this -> serverProfileName = '../templates/pdf' ;
}
else {
$this -> serverProfileName = $serverProfileName ;
}
2020-05-07 18:27:50 +00:00
}
2017-07-02 07:00:14 +00:00
/**
* Writes the PDF structure to disk .
*
* @ param string $typeId type ID
* @ param string $name structure name
* @ param PDFStructure $structure structure
2020-05-13 18:47:12 +00:00
* @ throws LAMException error during write
2017-07-02 07:00:14 +00:00
*/
public function write ( $typeId , $name , $structure ) {
$fileName = $this -> getFileName ( $typeId , $name );
$xml = $this -> getXML ( $structure );
$this -> writeXML ( $xml , $fileName );
}
/**
* Writes the PDF structure to disk .
*
* @ param string $typeId type ID
* @ param string $name structure name
* @ return string file name
2020-05-13 18:47:12 +00:00
* @ throws LAMException file not valid or not writable
2017-07-02 07:00:14 +00:00
*/
protected function getFileName ( $typeId , $name ) {
if ( ! isValidPDFStructureName ( $name ) || ! preg_match ( '/[a-zA-Z]+/' , $typeId )) {
throw new \LAMException ( _ ( 'PDF structure name not valid' ),
_ ( 'The name for that PDF-structure you submitted is not valid. A valid name must consist of the following characters: \'a-z\',\'A-Z\',\'0-9\',\'_\',\'-\'.' ));
}
2020-05-30 10:35:22 +00:00
$baseDir = __DIR__ . '/../config/pdf/' . $this -> serverProfileName ;
if ( ! is_writable ( $baseDir )) {
2020-08-07 20:07:47 +00:00
throw new \LAMException ( sprintf ( _ ( 'Could not save PDF structure, access denied to %s.' ), $baseDir ));
2017-07-02 07:00:14 +00:00
}
2020-05-30 10:35:22 +00:00
return $baseDir . '/' . $name . '.' . $typeId . '.xml' ;
2017-07-02 07:00:14 +00:00
}
/**
* Returns the generated XML .
*
* @ param PDFStructure $structure structure
* @ return string XML
*/
public function getXML ( $structure ) {
$writer = new \XMLWriter ();
$writer -> openMemory ();
$writer -> setIndent ( true );
$writer -> setIndentString ( " \t " );
$writer -> startElement ( 'pdf' );
$writer -> writeAttribute ( 'filename' , $structure -> getLogo ());
$writer -> writeAttribute ( 'headline' , $structure -> getTitle ());
$writer -> writeAttribute ( 'foldingmarks' , $structure -> getFoldingMarks ());
foreach ( $structure -> getSections () as $section ) {
if ( $section instanceof PDFTextSection ) {
$writer -> startElement ( 'text' );
$writer -> text ( $section -> getText ());
$writer -> endElement ();
}
else {
$writer -> startElement ( 'section' );
if ( $section -> isAttributeTitle ()) {
$writer -> writeAttribute ( 'name' , '_' . $section -> getPdfKey ());
}
else {
$writer -> writeAttribute ( 'name' , $section -> getTitle ());
}
foreach ( $section -> getEntries () as $entry ) {
$writer -> startElement ( 'entry' );
$writer -> writeAttribute ( 'name' , $entry -> getKey ());
$writer -> endElement ();
}
$writer -> endElement ();
}
}
$writer -> endElement ();
return $writer -> outputMemory ();
}
/**
* Writes the XML to the given file .
*
* @ param string $xml XML
* @ param string $file file name
2020-05-13 18:47:12 +00:00
* @ throws LAMException error during write
2017-07-02 07:00:14 +00:00
*/
protected function writeXML ( $xml , $file ) {
$handle = @ fopen ( $file , 'w' );
if ( ! $handle ) {
throw new \LAMException ( _ ( 'Could not save PDF structure, access denied.' ));
}
fwrite ( $handle , $xml );
fclose ( $handle );
}
}
2017-06-25 07:47:32 +00:00
/**
* PDF structure
*
* @ author Roland Gruber
*/
class PDFStructure {
2017-06-25 12:47:33 +00:00
/** no folding marks */
const FOLDING_NONE = 'no' ;
/** standard folding marks */
const FOLDING_STANDARD = 'standard' ;
2017-06-25 07:47:32 +00:00
private $logo = null ;
2017-07-01 07:50:49 +00:00
private $title = 'LDAP Account Manager' ;
2017-06-25 07:47:32 +00:00
2017-06-25 12:47:33 +00:00
private $foldingMarks = 'no' ;
2017-06-25 07:47:32 +00:00
private $sections = array ();
2020-05-07 19:10:47 +00:00
/**
* Returns an array representation of the structure .
*
* @ return array export data
*/
public function export () {
$data = array ();
$data [ 'title' ] = $this -> title ;
$data [ 'foldingMarks' ] = $this -> foldingMarks ;
$data [ 'logo' ] = $this -> logo ;
$data [ 'sections' ] = array ();
foreach ( $this -> sections as $section ) {
$type = ( $section instanceof PDFTextSection ) ? 'text' : 'entry' ;
$sectionData = $section -> export ();
$data [ 'sections' ][] = array (
'type' => $type ,
'data' => $sectionData
);
}
return $data ;
}
2020-05-12 18:58:56 +00:00
/**
* Imports an array representation of the structure .
*
* @ param array $data import data
*/
public function import ( $data ) {
if ( isset ( $data [ 'title' ])) {
$this -> title = $data [ 'title' ];
}
if ( isset ( $data [ 'foldingMarks' ])) {
$this -> foldingMarks = $data [ 'foldingMarks' ];
}
if ( isset ( $data [ 'logo' ])) {
$this -> logo = $data [ 'logo' ];
}
if ( isset ( $data [ 'sections' ])) {
foreach ( $data [ 'sections' ] as $section ) {
if ( $section [ 'type' ] === 'text' ) {
$ this -> sections [] = new PDFTextSection ( $section [ 'data' ]);
}
else {
$entrySection = new PDFEntrySection ( null );
$entrySection -> import ( $section [ 'data' ]);
$this -> sections [] = $entrySection ;
}
}
}
}
2017-06-25 07:47:32 +00:00
/**
* Returns the logo file path .
*
* @ return string logo
*/
public function getLogo () {
return $this -> logo ;
}
/**
* Sets the logo file path .
*
* @ param string $logo logo
*/
public function setLogo ( $logo ) {
$this -> logo = $logo ;
}
/**
* Returns the title .
*
* @ return string title
*/
public function getTitle () {
return $this -> title ;
}
/**
* Sets the title .
*
* @ param string $title title
*/
public function setTitle ( $title ) {
$this -> title = $title ;
}
/**
* Returns if to print folding marks .
*
2017-06-25 12:47:33 +00:00
* @ return string print folding marks
2017-06-25 07:47:32 +00:00
*/
public function getFoldingMarks () {
return $this -> foldingMarks ;
}
/**
* Sets if to print folding marks .
*
2017-06-25 12:47:33 +00:00
* @ param string $foldingMarks print folding marks
2017-06-25 07:47:32 +00:00
*/
public function setFoldingMarks ( $foldingMarks ) {
$this -> foldingMarks = $foldingMarks ;
}
/**
* Returns the sections .
*
* @ return PDFTextSection [] | PDFEntrySection [] $sections
*/
public function getSections () {
return $this -> sections ;
}
/**
* Sets the sections .
*
* @ param PDFTextSection [] | PDFEntrySection [] $sections sections
*/
public function setSections ( $sections ) {
$this -> sections = $sections ;
}
}
/**
* Section for static text .
*
* @ author Roland Gruber
*/
class PDFTextSection {
private $text = '' ;
/**
* Constructor .
*
* @ param string $text text
*/
public function __construct ( $text ) {
$this -> text = $text ;
}
2020-05-07 19:10:47 +00:00
/**
* Exports the section .
*
* @ return string text
*/
public function export () {
return $this -> getText ();
}
2017-06-25 07:47:32 +00:00
/**
* Returns the text .
*
* @ return string text
*/
public function getText () {
return $this -> text ;
}
}
/**
* PDF section that contains LDAP data entries .
*
* @ author Roland Gruber
*/
class PDFEntrySection {
2017-06-25 12:23:28 +00:00
private $title ;
2020-05-13 18:47:12 +00:00
private $entries = array ();
2017-06-25 12:23:28 +00:00
/**
* Constructor
*
* @ param string $title title
*/
public function __construct ( $title ) {
$this -> title = $title ;
}
2020-05-07 19:10:47 +00:00
/**
* Exports the section .
*
* @ return array export data
*/
public function export () {
$data = array ();
$data [ 'title' ] = $this -> title ;
$data [ 'entries' ] = array ();
foreach ( $this -> getEntries () as $entry ) {
$data [ 'entries' ][] = $entry -> getKey ();
}
return $data ;
}
2020-05-12 18:58:56 +00:00
/**
* Imports the section .
*
* @ param array $data import data
*/
public function import ( $data ) {
if ( isset ( $data [ 'title' ])) {
$this -> title = $data [ 'title' ];
}
if ( $data [ 'entries' ]) {
foreach ( $data [ 'entries' ] as $entry ) {
$this -> entries [] = new PDFSectionEntry ( $entry );
}
}
}
2017-06-25 12:23:28 +00:00
/**
* Returns if the title is an attribute value .
*
* @ return boolean is attribute
*/
public function isAttributeTitle () {
2017-08-24 18:29:55 +00:00
return ( bool ) preg_match ( '/^_([a-zA-Z0-9_-])+$/' , $this -> title );
2017-06-25 12:23:28 +00:00
}
/**
* Returns the PDF key name .
*
* @ return string PDF key name
*/
public function getPdfKey () {
return substr ( $this -> title , 1 );
}
/**
* Returns the text title .
*
* @ return string title
*/
public function getTitle () {
return $this -> title ;
}
2017-07-01 07:50:49 +00:00
/**
* Sets the title text .
*
* @ param string $title title
*/
public function setTitle ( $title ) {
$this -> title = $title ;
}
2017-06-25 12:23:28 +00:00
/**
* Returns the entries .
*
* @ return PDFSectionEntry [] entries
*/
public function getEntries () {
return $this -> entries ;
}
/**
* Sets the entries .
*
* @ param PDFSectionEntry [] $entries entries
*/
public function setEntries ( $entries ) {
$this -> entries = $entries ;
}
}
/**
* Single PDF entry .
*
* @ author Roland Gruber
*/
class PDFSectionEntry {
private $key ;
/**
* Constructor
*
* @ param string $key key
*/
public function __construct ( $key ) {
$this -> key = $key ;
}
/**
* Returns the PDF key .
*
* @ return string $key key
*/
public function getKey () {
return $this -> key ;
}
2017-06-25 07:47:32 +00:00
}
2017-10-23 15:58:08 +00:00
/**
* Returns a list of possible fonts .
*
* @ return array list of fonts ( description => font name )
*/
function getPdfFonts () {
return array (
'DejaVu' => 'DejaVuSerif' ,
_ ( 'Chinese Traditional' ) => 'cid0ct' ,
_ ( 'Chinese Simplified' ) => 'cid0cs' ,
2017-11-21 17:17:03 +00:00
_ ( 'Japanese' ) => 'cid0jp' ,
2017-10-23 15:58:08 +00:00
_ ( 'Korean' ) => 'cid0kr' ,
);
}
2012-10-28 14:37:54 +00:00
?>