diff --git a/lam/lib/html.inc b/lam/lib/html.inc index f96ddaf5..3ccf5a34 100644 --- a/lam/lib/html.inc +++ b/lam/lib/html.inc @@ -1704,6 +1704,8 @@ class htmlOutputText extends htmlElement { private $markAsRequired = false; /** no wrap */ private $noWrap = false; + /** preformatted */ + private $isPreformatted = false; /** * Constructor. @@ -1736,6 +1738,9 @@ class htmlOutputText extends htmlElement { if ($this->isBold) { echo ""; } + if ($this->isPreformatted) { + echo "
";
+		}
 		if ($this->escapeHTML) {
 			echo htmlspecialchars($this->string);
 		}
@@ -1747,6 +1752,9 @@ class htmlOutputText extends htmlElement {
 			if (is_dir("../graphics")) $graphicsPath = "../graphics";
 			echo 'required';
 		}
+		if ($this->isPreformatted) {
+			echo "
"; + } if ($this->isBold) { echo "
"; } @@ -1783,6 +1791,15 @@ class htmlOutputText extends htmlElement { $this->noWrap = $noWrap; } + /** + * Sets if the text is preformatted. + * + * @param boolean $preformatted is preformatted (default true) + */ + public function setPreformatted($preformatted = true) { + $this->isPreformatted = $preformatted; + } + } /** diff --git a/lam/lib/lamPDF.inc b/lam/lib/lamPDF.inc index cabd0f3f..bcd50665 100644 --- a/lam/lib/lamPDF.inc +++ b/lam/lib/lamPDF.inc @@ -1,4 +1,6 @@ fontName = $fontName; if (!defined('FPDF_FONTPATH')) { define('FPDF_FONTPATH', dirname(__FILE__) . '/font/'); @@ -72,7 +74,7 @@ class lamPDF extends UFPDF { // Call constructor of superclass parent::__construct('P','mm','A4'); - $this->page_definitions = $page_definitions; + $this->structure = $structure; // Open PDF file and write some basic information $this->Open(); @@ -81,7 +83,7 @@ class lamPDF extends UFPDF { $this->AddFont($this->fontName, 'I', $this->fontList[$this->fontName][2]); $this->AddFont($this->fontName, 'BI', $this->fontList[$this->fontName][3]); $this->setFont($this->fontName,"",12); - $this->setTitle($this->page_definitions['headline']); + $this->setTitle($structure->getTitle()); $this->setCreator("LDAP Account Manager"); $this->setMargins('10.0','10.0','10.0'); $this->setAutoPageBreak(true,'20.0'); @@ -91,21 +93,21 @@ class lamPDF extends UFPDF { * Creates the PDF page header. */ function header() { - if($this->page_definitions['filename'] != 'none') { - $imageFile = substr(__FILE__,0,strlen(__FILE__)- 14) . "config/pdf/" . $_SESSION['config']->getName() . "/logos/" . $this->page_definitions['filename']; + if($this->structure->getLogo() != 'none') { + $imageFile = substr(__FILE__,0,strlen(__FILE__)- 14) . "config/pdf/" . $_SESSION['config']->getName() . "/logos/" . $this->structure->getLogo(); $imgProperties = getimagesize($imageFile); $this->Image($imageFile,10,15,($imgProperties[0] / $this->k) / 5, ($imgProperties[1] / $this->k) / 5,0,"JPG"); } $this->SetY(23); $this->SetFont($this->fontName,"B",18); - $this->Cell(170,5,$this->page_definitions['headline'],0,1,"R",0); + $this->Cell(170,5,$this->structure->getTitle(), 0, 1, "R", 0); $this->Ln(3); $this->SetLineWidth(0.4); $this->Line(10,38,200,38); $this->Line(10,40,200,40); $this->SetY(50); //set folding marks - if (isset($this->page_definitions['foldingmarks']) && ($this->page_definitions['foldingmarks'] == 'standard')) { + if ($this->structure->getFoldingMarks() == PDFStructure::FOLDING_STANDARD) { $this->SetLineWidth(0.2); $foldingMarks = array(97, 202); foreach ($foldingMarks as $mark) { diff --git a/lam/lib/pdf.inc b/lam/lib/pdf.inc index 966a1a92..1ef4a0d8 100644 --- a/lam/lib/pdf.inc +++ b/lam/lib/pdf.inc @@ -1,8 +1,6 @@ get_type(); // Get PDF structure from xml file - $load = \LAM\PDF\loadPDFStructure($account_type->getId(), $pdf_structure); - $structure = $load['structure']; + $reader = new PDFStructureReader(); + $structure = $reader->read($account_type->getId(), $pdf_structure); // 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); - } + foreach($structure->getSections() as $section) { + if (!$section instanceof PDFEntrySection) { + continue; } - if ($entry['tag'] == "ENTRY") { - $pdfKeys[] = $entry['attributes']['NAME']; + if ($section->isAttributeTitle()) { + $pdfKeys[] = $section->getPdfKey(); + } + foreach ($section->getEntries() as $entry) { + $pdfKeys[] = $entry->getKey(); } } $pdfKeys = array_unique($pdfKeys); @@ -95,7 +89,7 @@ function createModulePDF($accounts, $pdf_structure="default", $returnAsString = $fontName = "Dejavu"; // Create a new PDF file acording to the account type - $pdf = new \lamPDF($load['page_definitions'],$fontName); + $pdf = new \lamPDF($structure, $fontName); // Loop over each account and add a new page in the PDF file for it foreach($accounts as $account) { @@ -107,28 +101,10 @@ function createModulePDF($accounts, $pdf_structure="default", $returnAsString = $entries = $account->get_pdfEntries($pdfKeys, $account_type->getId()); // 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']; - if(preg_match("/^_[a-zA-Z_]+/",$name)) { - $section_headline = getSectionHeadline($entries[substr($name,1)][0]); - } - else { - $section_headline = $name; - } - $pdf->setFont($fontName, "B", LAMPDF_FONT_SIZE_BIG); - $pdf->Write(0,$section_headline . ":"); - $pdf->Ln(LAMPDF_LINEHEIGHT); - } - // We have a section to end - elseif($entry['tag'] == "SECTION" && $entry['type'] == "close") { - $pdf->Ln(LAMPDF_LINEHEIGHT * 2); - } - // We have to include a static text. - elseif($entry['tag'] == "TEXT") { + foreach ($structure->getSections() as $section) { + if ($section instanceof PDFTextSection) { $pdf->setFont($fontName, "", LAMPDF_FONT_SIZE); - $info_string = str_replace("\r", "", $entry['value']); + $info_string = str_replace("\r", "", $section->getText()); $info_string = explode("\n", $info_string); foreach ($info_string as $text) { $pdf->MultiCell(0, LAMPDF_LINEHEIGHT, trim($text), 0, "L", 0); @@ -136,32 +112,42 @@ function createModulePDF($accounts, $pdf_structure="default", $returnAsString = } $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']; - // skip non-existent entries - if (isset($entries[$name])) { - // Get current entry - $valueEntries = $entries[$name]; - - // Print entry only when module sumitted values for it - if(is_array($valueEntries)) { - // Loop over all rows of this entry (most of the time this will be just one) - foreach($valueEntries as $valueEntry) { - if ($valueEntry instanceof PDFLabelValue) { - printLabelValue($pdf, $valueEntry, $fontName); - } - else if ($valueEntry instanceof PDFTable) { - printTable($pdf, $valueEntry, $fontName); + elseif ($section instanceof PDFEntrySection) { + // section headline + if($section->isAttributeTitle()) { + $section_headline = getSectionHeadline($entries[$section->getPdfKey()][0]); + } + else { + $section_headline = $section->getTitle(); + } + $pdf->setFont($fontName, "B", LAMPDF_FONT_SIZE_BIG); + $pdf->Write(0,$section_headline . ":"); + $pdf->Ln(LAMPDF_LINEHEIGHT); + // entries + foreach ($section->getEntries() as $entry) { + // skip non-existent entries + if (isset($entries[$entry->getKey()])) { + // Get current entry + $valueEntries = $entries[$entry->getKey()]; + // Print entry only when module sumitted values for it + if(is_array($valueEntries)) { + // Loop over all rows of this entry (most of the time this will be just one) + foreach($valueEntries as $valueEntry) { + if ($valueEntry instanceof PDFLabelValue) { + printLabelValue($pdf, $valueEntry, $fontName); + } + else if ($valueEntry instanceof PDFTable) { + printTable($pdf, $valueEntry, $fontName); + } } } } } + // section end + $pdf->Ln(LAMPDF_LINEHEIGHT * 2); } } } - // Close PDF $pdf->Close(); if (!$returnAsString) { diff --git a/lam/lib/pdfstruct.inc b/lam/lib/pdfstruct.inc index f1e8fde6..5cedd21b 100644 --- a/lam/lib/pdfstruct.inc +++ b/lam/lib/pdfstruct.inc @@ -71,94 +71,6 @@ function getPDFStructures($typeId, $profile = null) { return $return; } -/** - * This function is used to get the PDF structure from XML file. - * - * @param string $typeId the account type - * @param string $name structure name - * - * @return array PDF structure - */ -function loadPDFStructure($typeId, $name='default') { - if (!isValidPDFStructureName($name) || !preg_match('/[a-zA-Z]+/', $typeId)) { - return null; - } - $parser = new xmlParser(); - $file = dirname(__FILE__) . '/../config/pdf/' . $_SESSION['config']->getName() . '/' . $name . '.' . $typeId . '.xml'; - $xml = $parser->parse($file); - $border = array(); - $structure = array(); - $complete_page_definitions = array('filename' => 'printLogo.jpg', 'headline' => 'LDAP Account Manager'); - if (!empty($xml)) { - $border['start'] = $xml[1]['PDF'][0]; - $page_definitions = $xml[0][$xml[1]['PDF'][0]]['attributes']; - foreach($page_definitions as $key => $value) { - $complete_page_definitions[strtolower($key)] = $value; - unset($page_definitions[$key]); - } - $border['end'] = $xml[1]['PDF'][1]; - $structure = array_slice($xml[0],$border['start'] + 1,$border['end'] - ($border['start'] + 1)); - } - return array('structure' => $structure, 'page_definitions' => $complete_page_definitions); -} - - -/** - * Saves PDF structure to XML file in format: ..xml - * - * @param string $typeId account type - * @param string $name name of structure - * @return string "no perms" if access denied or "ok". - */ -function savePDFStructure($typeId, $name) { - if (!isValidPDFStructureName($name) || !preg_match('/[a-zA-Z]+/', $typeId)) { - return 'no perms'; - } - $struct_file = dirname(__FILE__) . '/../config/pdf/' . $_SESSION['config']->getName() . '/' . $name . '.' . $typeId . '.xml'; - if(!is_writable(dirname(__FILE__) . '/../config/pdf/' . $_SESSION['config']->getName())) { - return 'no perms'; - } - else { - $handle = @fopen($struct_file,'w'); - if (!$handle) return 'no perms'; - $pdf_attributes = ''; - foreach($_SESSION['currentPageDefinitions'] as $key => $value) { - $pdf_attributes .= ' ' . $key . '="' . $value . '"'; - } - $file = '\n"; - foreach($_SESSION['currentPDFStructure'] as $entry) { - $ident = ''; - for($i=0;$i<$entry['level'] -1;$i++) { - $ident .= "\t"; - } - $attributes = ''; - if(isset($entry['attributes']) && is_array($entry['attributes'])) { - foreach($entry['attributes'] as $key => $value) { - $attributes .= ' ' . strtolower($key) . '="' . $value . '"'; - } - } - if($entry['type'] == 'open') { - $file .= $ident . '<' . strtolower($entry['tag']) . $attributes . ">\n"; - } - elseif($entry['type'] == 'close') { - $file .= $ident . '\n"; - } - elseif($entry['type'] == 'complete') { - if(isset($entry['value'])) { - $file .= $ident . '<' . strtolower($entry['tag']) . $attributes . '>' . $entry['value'] . '\n"; - } - else { - $file .= $ident . '<' . strtolower($entry['tag']) . $attributes . " />\n"; - } - } - } - $file .= ""; - fwrite($handle,$file); - fclose($handle); - return 'ok'; - } -} - /** * Deletes XML file with PDF structure definitions. * @@ -323,7 +235,7 @@ function deletePDFLogo($name) { * @return boolean is valid */ function isValidPDFStructureName($name) { - return preg_match('/[a-zA-Z0-9\-\_]+/',$name) === 1; + return preg_match('/^[a-z0-9\-\_]+$/i',$name) === 1; } /** @@ -382,4 +294,441 @@ function installPDFTemplates() { } } +/** + * Reads a PDF structure. + * + * @author Roland Gruber + */ +class PDFStructureReader { + + /** + * 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) { + return dirname(__FILE__) . '/../config/pdf/' . $_SESSION['config']->getName() . '/' . $name . '.' . $typeId . '.xml'; + } + + /** + * Reads a PDF structure file. + * + * @param string $file file name + * @return PDFStructure structure + */ + private function readPDFFile($file) { + $xml = new \XMLReader(); + $xml->open($file); + $structure = new PDFStructure(); + // open + @$xml->read(); + 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')); + $structure->setFoldingMarks($xml->getAttribute('foldingmarks')); + $sections = array(); + while ($xml->read()) { + if ($xml->nodeType === \XMLReader::SIGNIFICANT_WHITESPACE) { + continue; + } + elseif (($xml->name === 'pdf') && ($xml->nodeType == \XMLReader::END_ELEMENT)) { + 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 { + logNewMessage(LOG_ERR, 'Unexpected tag name: ' . $xml->name); + 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; + } + elseif ($xml->nodeType === \XMLReader::END_ELEMENT) { + continue; + } + elseif ($xml->nodeType === \XMLReader::SIGNIFICANT_WHITESPACE) { + 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; + } + +} + +/** + * Writes PDF structures to files. + * + * @author Roland Gruber + */ +class PDFStructureWriter { + + /** + * Writes the PDF structure to disk. + * + * @param string $typeId type ID + * @param string $name structure name + * @param PDFStructure $structure structure + */ + 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 + */ + 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\',\'_\',\'-\'.')); + } + if(!is_writable(dirname(__FILE__) . '/../config/pdf/' . $_SESSION['config']->getName())) { + throw new \LAMException(_('Could not save PDF structure, access denied.')); + } + return dirname(__FILE__) . '/../config/pdf/' . $_SESSION['config']->getName() . '/' . $name . '.' . $typeId . '.xml'; + } + + /** + * 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 + */ + 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); + } + +} + +/** + * PDF structure + * + * @author Roland Gruber + */ +class PDFStructure { + + /** no folding marks */ + const FOLDING_NONE = 'no'; + /** standard folding marks */ + const FOLDING_STANDARD = 'standard'; + + private $logo = null; + + private $title = 'LDAP Account Manager'; + + private $foldingMarks = 'no'; + + private $sections = array(); + + /** + * 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. + * + * @return string print folding marks + */ + public function getFoldingMarks() { + return $this->foldingMarks; + } + + /** + * Sets if to print folding marks. + * + * @param string $foldingMarks print folding marks + */ + 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; + } + + /** + * Returns the text. + * + * @return string text + */ + public function getText() { + return $this->text; + } + +} + +/** + * PDF section that contains LDAP data entries. + * + * @author Roland Gruber + */ +class PDFEntrySection { + + private $title; + private $entries; + + /** + * Constructor + * + * @param string $title title + */ + public function __construct($title) { + $this->title = $title; + } + + /** + * Returns if the title is an attribute value. + * + * @return boolean is attribute + */ + public function isAttributeTitle() { + return boolval(preg_match('/^_([a-zA-Z0-9_-])+$/', $this->title)); + } + + /** + * 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; + } + + /** + * Sets the title text. + * + * @param string $title title + */ + public function setTitle($title) { + $this->title = $title; + } + + /** + * 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; + } + +} + ?> diff --git a/lam/lib/xml_parser.inc b/lam/lib/xml_parser.inc deleted file mode 100644 index fb425911..00000000 --- a/lam/lib/xml_parser.inc +++ /dev/null @@ -1,70 +0,0 @@ -xmlParser = xml_parser_create(); - xml_set_object($this->xmlParser, $this); - xml_parser_set_option($this->xmlParser, XML_OPTION_CASE_FOLDING, 1); - xml_parser_set_option($this->xmlParser, XML_OPTION_SKIP_WHITE, 1); - } - - /** - * Starts the parsing. - * - * @param String $filename file name - * @return array XML structure - */ - function parse($filename) { - if(file_exists($filename)) { - $xmlStructure = array(); - $xmlIndex = array(); - $xmlContent = - xml_parse_into_struct($this->xmlParser, implode("", file($filename)), $xmlStructure, $xmlIndex); - return array($xmlStructure, $xmlIndex); - } - return array(); - } -} -?> \ No newline at end of file diff --git a/lam/templates/pdfedit/pdfmain.php b/lam/templates/pdfedit/pdfmain.php index 18e2e7a3..70cbdc45 100644 --- a/lam/templates/pdfedit/pdfmain.php +++ b/lam/templates/pdfedit/pdfmain.php @@ -75,7 +75,6 @@ setlanguage(); // Unset PDF structure definitions in session if set if(isset($_SESSION['currentPDFStructure'])) { unset($_SESSION['currentPDFStructure']); - unset($_SESSION['currentPageDefinitions']); } // check if user is logged in, if not go to login @@ -223,6 +222,12 @@ include '../main_header.php'; $container->addElement($message, true); } + if (isset($_GET['loadFailed'])) { + $message = new htmlStatusMessage("ERROR", _("Unable to read PDF structure."), htmlspecialchars($_GET['name'])); + $message->colspan = 10; + $container->addElement($message, true); + } + // new template if (!empty($availableTypes)) { $container->addElement(new htmlSubTitle(_('Create a new PDF structure')), true); diff --git a/lam/templates/pdfedit/pdfpage.php b/lam/templates/pdfedit/pdfpage.php index e31b46f1..b6e77381 100644 --- a/lam/templates/pdfedit/pdfpage.php +++ b/lam/templates/pdfedit/pdfpage.php @@ -14,6 +14,12 @@ use \htmlSubTitle; use \htmlFieldset; use \htmlInputTextarea; use \htmlHiddenInput; +use LAM\PDF\PDFStructureReader; +use LAM\PDF\PDFTextSection; +use LAM\PDF\PDFEntrySection; +use LAM\PDF\PDFStructure; +use LAM\PDF\PDFSectionEntry; +use LAM\PDF\PDFStructureWriter; /* $Id$ @@ -57,8 +63,6 @@ include_once('../../lib/ldap.inc'); include_once('../../lib/config.inc'); /** module functions */ include_once('../../lib/modules.inc'); -/** XML functions */ -include_once('../../lib/xml_parser.inc'); // start session startSecureSession(); @@ -84,9 +88,6 @@ if (!$_SESSION['ldap'] || !$_SESSION['ldap']->server()) { // Write $_POST variables to $_GET when form was submitted via post if (isset($_POST['type'])) { $_GET = $_POST; - if ($_POST['pdfname'] == '') { - unset($_GET['pdfname']); - } } $typeManager = new \LAM\TYPES\TypeManager(); @@ -103,270 +104,48 @@ if(isset($_GET['abort'])) { exit; } -// set new logo and headline -if ((isset($_GET['headline'])) && ($_GET['logoFile'] != $_SESSION['currentPageDefinitions']['filename'])) { - $_SESSION['currentPageDefinitions']['filename'] = $_GET['logoFile']; -} -if ((isset($_GET['headline'])) && ($_GET['headline'] != $_SESSION['currentPageDefinitions']['headline'])) { - $_SESSION['currentPageDefinitions']['headline'] = str_replace('<','',str_replace('>','',$_GET['headline'])); -} -if ((isset($_GET['foldingmarks'])) && (!isset($_SESSION['currentPageDefinitions']['foldingmarks']) || ($_GET['foldingmarks'] != $_SESSION['currentPageDefinitions']['foldingmarks']))) { - $_SESSION['currentPageDefinitions']['foldingmarks'] = $_GET['foldingmarks']; +// Load PDF structure from file if it is not defined in session +if(!isset($_SESSION['currentPDFStructure'])) { + // Load structure file to be edit + $reader = new PDFStructureReader(); + try { + if(isset($_GET['edit'])) { + $_SESSION['currentPDFStructure'] = $reader->read($type->getId(), $_GET['edit']); + } + // Load default structure file when creating a new one + else { + $_SESSION['currentPDFStructure'] = $reader->read($type->getId(), 'default'); + } + } + catch (\LAMException $e) { + metaRefresh('pdfmain.php?loadFailed=1&name=' . $_GET['edit']); + exit; + } } -// Change section headline -foreach ($_GET as $key => $value) { - if (strpos($key, 'section_') === 0) { - $pos = substr($key, strlen('section_')); - $_SESSION['currentPDFStructure'][$pos]['attributes']['NAME'] = $value; - } +if (!empty($_POST['form_submit'])) { + updateBasicSettings($_SESSION['currentPDFStructure']); + updateSectionTitles($_SESSION['currentPDFStructure']); + addSection($_SESSION['currentPDFStructure']); + addSectionEntry($_SESSION['currentPDFStructure']); + removeItem($_SESSION['currentPDFStructure']); + moveUp($_SESSION['currentPDFStructure']); + moveDown($_SESSION['currentPDFStructure']); } // Check if pdfname is valid, then save current structure to file and go to // main pdf structure page $saveErrors = array(); if(isset($_GET['submit'])) { - if(!isset($_GET['pdfname']) || !preg_match('/[a-zA-Z0-9\-\_]+/',$_GET['pdfname'])) { - $saveErrors[] = array('ERROR', _('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\',\'_\',\'-\'.')); + $writer = new PDFStructureWriter(); + try { + $writer->write($type->getId(), $_POST['pdfname'], $_SESSION['currentPDFStructure']); + unset($_SESSION['currentPDFStructure']); + metaRefresh('pdfmain.php?savedSuccessfully=' . $_POST['pdfname']); + exit; } - else { - $return = \LAM\PDF\savePDFStructure($type->getId(), $_GET['pdfname']); - if($return == 'ok') { - metaRefresh('pdfmain.php?savedSuccessfully=' . $_GET['pdfname']); - exit; - } - elseif($return == 'no perms'){ - $saveErrors[] = array('ERROR', _("Could not save PDF structure, access denied."), $_GET['pdfname']); - } - } -} -// add a new text field -elseif(isset($_GET['add_text'])) { - // Check if text for static text field is specified - if(empty($_GET['text_text'])) { - StatusMessage('ERROR',_('No static text specified'),_('The static text must contain at least one character.')); - } - else { - $entry = array(array('tag' => 'TEXT','type' => 'complete','level' => '2','value' => str_replace("\r", "\n", $_GET['text_text']))); - // Insert new field in structure - array_splice($_SESSION['currentPDFStructure'],$_GET['add_text_position'],0,$entry); - } -} -// add a new section with text headline -elseif(isset($_GET['add_sectionText'])) { - // Check if name for new section is specified when needed - if(!isset($_GET['new_section_text']) || ($_GET['new_section_text'] == '')) { - StatusMessage('ERROR',_('No section text specified'),_('The headline for a new section must contain at least one character.')); - } - else { - $attributes = array(); - $attributes['NAME'] = $_GET['new_section_text']; - $entry = array(array('tag' => 'SECTION','type' => 'open','level' => '2','attributes' => $attributes),array('tag' => 'SECTION','type' => 'close','level' => '2')); - // Insert new field in structure - array_splice($_SESSION['currentPDFStructure'],$_GET['add_sectionText_position'],0,$entry); - } -} -// Add a new section with item as headline -elseif(isset($_GET['add_section'])) { - $attributes = array(); - $attributes['NAME'] = '_' . $_GET['new_section_item']; - $entry = array(array('tag' => 'SECTION','type' => 'open','level' => '2','attributes' => $attributes),array('tag' => 'SECTION','type' => 'close','level' => '2')); - // Insert new field in structure - array_splice($_SESSION['currentPDFStructure'],$_GET['add_section_position'],0,$entry); -} -// Add a new value field -elseif(isset($_GET['add_new_field'])) { - $field = array('tag' => 'ENTRY','type' => 'complete','level' => '3','attributes' => array('NAME' => $_GET['new_field'])); - $pos = 0; - // Find begin section to insert into - while($pos < $_GET['add_field_position']) { - next($_SESSION['currentPDFStructure']); - $pos++; - } - $current = next($_SESSION['currentPDFStructure']); - $pos++; - // End of section to insert into - while($current && $current['tag'] != 'SECTION' && $current['type'] != 'close') { - $current = next($_SESSION['currentPDFStructure']); - $pos++; - } - // Insert new entry before closing section tag - array_splice($_SESSION['currentPDFStructure'],$pos,0,array($field)); -} - -foreach ($_GET as $key => $value) { - // remove entry or section - if (strpos($key, 'remove_') === 0) { - $pos = substr($key, strlen('remove_')); - $remove = $_SESSION['currentPDFStructure'][$pos]; - // We have a section to remove - if($remove['tag'] == "SECTION") { - $end = $pos + 1; - // Find end of section to remove - while (isset($_SESSION['currentPDFStructure'][$end]) && ($_SESSION['currentPDFStructure'][$end]['tag'] != 'SECTION') - && ($_SESSION['currentPDFStructure'][$end]['type'] != 'close')) { - $end++; - } - // Remove complete section with all value entries in it from structure - array_splice($_SESSION['currentPDFStructure'], $pos, $end - $pos + 1); - } - // We have a value entry to remove - elseif($remove['tag'] == "ENTRY") { - array_splice($_SESSION['currentPDFStructure'], $pos, 1); - } - // We hava a static text to remove - elseif($remove['tag'] == "TEXT") { - array_splice($_SESSION['currentPDFStructure'], $pos, 1); - } - } - // Move a section, static text field or value entry downwards - elseif (strpos($key, 'down_') === 0) { - $index = substr($key, strlen('down_')); - $tmp = $_SESSION['currentPDFStructure'][$index]; - $next = $_SESSION['currentPDFStructure'][$index + 1]; - // We have a section or static text to move - if($tmp['tag'] == 'SECTION' || $tmp['tag'] == 'TEXT') { - $pos = 0; - $current = current($_SESSION['currentPDFStructure']); - // Find section or static text entry to move - while($pos < $index) { - $current = next($_SESSION['currentPDFStructure']); - $pos++; - } - $borders = array(); - // We have a section to move - if($current['tag'] == 'SECTION'){ - $borders[$current['type']][] = $pos; - $current = next($_SESSION['currentPDFStructure']); - $pos++; - // Find end of section to move - while($current && $current['tag'] != 'SECTION' && $current['type'] != 'close') { - $current = next($_SESSION['currentPDFStructure']); - $pos++; - } - $borders['close'][] = $pos; - } - // We have a static text entry to move - elseif($current['tag'] == 'TEXT') { - $borders['open'][] = $pos; - $borders['close'][] = $pos; - } - $current = next($_SESSION['currentPDFStructure']); - $pos++; - // Find next section or static text entry in structure - if($current) { - // Next is a section - if($current['tag'] == 'SECTION') { - $borders[$current['type']][] = $pos; - $current = next($_SESSION['currentPDFStructure']); - $pos++; - // Find end of this section - while($current && $current['tag'] != 'SECTION' && $current['type'] != 'close') { - if($current['tag'] == 'SECTION') { - $borders[$current['type']][] = $pos; - } - $current = next($_SESSION['currentPDFStructure']); - $pos++; - } - } - // Next is static text entry - elseif($current['tag'] == 'TEXT') { - $borders['open'][] = $pos; - } - $borders['close'][] = $pos; - } - // Move only downwars if not bottenmost element of this structure - if(count($borders['open']) > 1) { - // Calculate entries to move and move them - $cut_start = $borders['open'][count($borders['open']) - 1]; - $cut_count = $borders['close'][count($borders['close']) - 1] - $borders['open'][count($borders['open']) - 1] + 1; - $insert_pos = $borders['open'][count($borders['open']) - 2]; - $tomove = array_splice($_SESSION['currentPDFStructure'],$cut_start,$cut_count); - array_splice($_SESSION['currentPDFStructure'],$insert_pos,0,$tomove); - } - } - // We have a value entry to move; move it only if it is not the bottmmost - // element of this section. - elseif($tmp['tag'] == 'ENTRY' && $next['tag'] == 'ENTRY') { - $_SESSION['currentPDFStructure'][$index] = $_SESSION['currentPDFStructure'][$index + 1]; - $_SESSION['currentPDFStructure'][$index + 1] = $tmp; - } - } - // Move a section, static text or value entry upwards - elseif (strpos($key, 'up_') === 0) { - $index = substr($key, strlen('up_')); - $tmp = $_SESSION['currentPDFStructure'][$index]; - $prev = $_SESSION['currentPDFStructure'][$index - 1]; - // We have a section or static text to move - if($tmp['tag'] == 'SECTION' || $tmp['tag'] == 'TEXT') { - $pos = 0; - $borders = array(); - $current = current($_SESSION['currentPDFStructure']); - // Add borders of sections and static text entry to array - if($current['tag'] == 'SECTION') { - $borders[$current['type']][] = $pos; - } - elseif($current['tag'] == 'TEXT') { - $borders['open'][] = $pos; - $borders['close'][] = $pos; - } - // Find all sections and statci text fields before the section or static - // text entry to move upwards - while($pos < $index) { - $current = next($_SESSION['currentPDFStructure']); - $pos++; - if($current['tag'] == 'SECTION') { - $borders[$current['type']][] = $pos; - } - elseif($current['tag'] == 'TEXT') { - $borders['open'][] = $pos; - $borders['close'][] = $pos; - } - } - // Move only when not topmost element - if(count($borders['close']) > 0) { - // We have a section to move up - if($current['tag'] == 'SECTION') { - $current = next($_SESSION['currentPDFStructure']); - $pos++; - // Find end of section to move - while($current && $current['tag'] != 'SECTION' && $current['type'] != 'close') { - $current = next($_SESSION['currentPDFStructure']); - $pos++; - } - $borders['close'][] = $pos; - } - // Calculate the entries to move and move them - $cut_start = $borders['open'][count($borders['open']) - 1]; - $cut_count = $borders['close'][count($borders['close']) - 1] - $borders['open'][count($borders['open']) - 1] + 1; - $insert_pos = $borders['open'][count($borders['open']) - 2]; - $tomove = array_splice($_SESSION['currentPDFStructure'],$cut_start,$cut_count); - array_splice($_SESSION['currentPDFStructure'],$insert_pos,0,$tomove); - } - } - // We have a value entry to move; move it only if its not the topmost - // entry in this section - elseif($tmp['tag'] == 'ENTRY' && $prev['tag'] == 'ENTRY') { - $_SESSION['currentPDFStructure'][$index] = $prev; - $_SESSION['currentPDFStructure'][$index - 1] = $tmp; - } - } -} - -// Load PDF structure from file if it is not defined in session -if(!isset($_SESSION['currentPDFStructure'])) { - // Load structure file to be edit - if(isset($_GET['edit'])) { - $load = \LAM\PDF\loadPDFStructure($type->getId(), $_GET['edit']); - $_SESSION['currentPDFStructure'] = $load['structure']; - $_SESSION['currentPageDefinitions'] = $load['page_definitions']; - $_GET['pdfname'] = $_GET['edit']; - } - // Load default structure file when creating a new one - else { - $load = \LAM\PDF\loadPDFStructure($type->getId()); - $_SESSION['currentPDFStructure'] = $load['structure']; - $_SESSION['currentPageDefinitions'] = $load['page_definitions']; + catch (\LAMException $e) { + $saveErrors[] = array('ERROR', $e->getTitle(), $e->getMessage()); } } @@ -432,17 +211,11 @@ $structureName = ''; if (isset($_GET['edit'])) { $structureName = $_GET['edit']; } -elseif (isset($_GET['pdfname'])) { - $structureName = $_GET['pdfname']; -} else if (isset($_POST['pdfname'])) { $structureName = $_POST['pdfname']; } // headline -$headline = 'LDAP Account Manager'; -if (isset($_SESSION['currentPageDefinitions']['headline'])) { - $headline = $_SESSION['currentPageDefinitions']['headline']; -} +$headline = $_SESSION['currentPDFStructure']->getTitle(); // logo $logoFiles = \LAM\PDF\getAvailableLogos(); $logos = array(_('No logo') => 'none'); @@ -450,8 +223,8 @@ foreach($logoFiles as $logoFile) { $logos[$logoFile['filename'] . ' (' . $logoFile['infos'][0] . ' x ' . $logoFile['infos'][1] . ")"] = $logoFile['filename']; } $selectedLogo = array('printLogo.jpg'); -if (isset($_SESSION['currentPageDefinitions']['filename'])) { - $selectedLogo = array($_SESSION['currentPageDefinitions']['filename']); +if (isset($_SESSION['currentPDFStructure'])) { + $selectedLogo = array($_SESSION['currentPDFStructure']->getLogo()); } ?> @@ -473,8 +246,8 @@ $logoSelect = new htmlTableExtendedSelect('logoFile', $logos, $selectedLogo, _(' $logoSelect->setHasDescriptiveElements(true); $mainContent->addElement($logoSelect, true); $foldingMarks = 'no'; -if (isset($_SESSION['currentPageDefinitions']['foldingmarks'])) { - $foldingMarks = $_SESSION['currentPageDefinitions']['foldingmarks']; +if (isset($_SESSION['currentPDFStructure'])) { + $foldingMarks = $_SESSION['currentPDFStructure']->getFoldingMarks(); } $possibleFoldingMarks = array(_('No') => 'no', _('Yes') => 'standard'); $foldingMarksSelect = new htmlTableExtendedSelect('foldingmarks', $possibleFoldingMarks, array($foldingMarks), _('Folding marks')); @@ -482,38 +255,38 @@ $foldingMarksSelect->setHasDescriptiveElements(true); $mainContent->addElement($foldingMarksSelect, true); $mainContent->addElement(new htmlSpacer(null, '30px'), true); // PDF structure +$structure = $_SESSION['currentPDFStructure']; // print every entry in the current structure $structureContent = new htmlTable(); -for ($key = 0; $key < sizeof($_SESSION['currentPDFStructure']); $key++) { - $entry = $_SESSION['currentPDFStructure'][$key]; +$sections = $structure->getSections(); +for ($key = 0; $key < sizeof($sections); $key++) { + $section = $sections[$key]; // create the up/down/remove links - $linkBase = 'pdfpage.php?type=' . $type->getId() . '&pdfname=' . $structureName . '&headline=' . $headline . '&logoFile=' . $selectedLogo[0] . '&foldingmarks=' . $foldingMarks; - $linkUp = new htmlButton('up_' . $key, 'up.gif', true); + $linkUp = new htmlButton('up_section_' . $key, 'up.gif', true); $linkUp->setTitle(_("Up")); - $linkDown = new htmlButton('down_' . $key, 'down.gif', true); + $linkDown = new htmlButton('down_section_' . $key, 'down.gif', true); $linkDown->setTitle(_("Down")); - $linkRemove = new htmlButton('remove_' . $key, 'delete.gif', true); + $linkRemove = new htmlButton('remove_section_' . $key, 'delete.gif', true); $linkRemove->setTitle(_("Remove")); $emptyBox = new htmlOutputText(''); // We have a new section to start - if(($entry['tag'] == "SECTION") && ($entry['type'] == 'open')) { - $name = $entry['attributes']['NAME']; - if(preg_match("/^_[a-zA-Z0-9_]+_[a-zA-Z0-9_]+/",$name)) { - $section_headline = translateFieldIDToName(substr($name,1), $type->getScope(), $availablePDFFields); + if($section instanceof PDFEntrySection) { + if($section->isAttributeTitle()) { + $section_headline = translateFieldIDToName($section->getPdfKey(), $type->getScope(), $availablePDFFields); } else { - $section_headline = $name; + $section_headline = $section->getTitle(); } $nonTextSectionElements[$section_headline] = $key; $sectionElements[$section_headline] = $key; $structureContent->addElement(new htmlSpacer(null, '15px'), true); // Section headline is a value entry - if(preg_match("/^_[a-zA-Z0-9_]+_[a-zA-Z0-9_]+/",$name)) { + if($section->isAttributeTitle()) { $headlineElements = array(); foreach($section_items_array as $item) { $headlineElements[translateFieldIDToName($item, $type->getScope(), $availablePDFFields)] = '_' . $item; } - $sectionHeadlineSelect = new htmlSelect('section_' . $key, $headlineElements, array($name)); + $sectionHeadlineSelect = new htmlSelect('section_' . $key, $headlineElements, array('_' . $section->getPdfKey())); $sectionHeadlineSelect->setHasDescriptiveElements(true); $sectionHeadlineGroup = new htmlGroup(); $sectionHeadlineGroup->addElement($sectionHeadlineSelect); @@ -534,14 +307,7 @@ for ($key = 0; $key < sizeof($_SESSION['currentPDFStructure']); $key++) { else { $structureContent->addElement($emptyBox); } - $hasAdditionalSections = false; - for ($a = $key + 1; $a < sizeof($_SESSION['currentPDFStructure']); $a++) { - if ((($_SESSION['currentPDFStructure'][$a]['tag'] == "SECTION") && ($_SESSION['currentPDFStructure'][$a]['type'] == "open")) - || ($_SESSION['currentPDFStructure'][$a]['tag'] == "TEXT")) { - $hasAdditionalSections = true; - break; - } - } + $hasAdditionalSections = $key < (sizeof($sections) - 1); if ($hasAdditionalSections) { $structureContent->addElement($linkDown); } @@ -549,12 +315,46 @@ for ($key = 0; $key < sizeof($_SESSION['currentPDFStructure']); $key++) { $structureContent->addElement($emptyBox); } $structureContent->addElement($linkRemove, true); + // add section entries + $sectionEntries = $section->getEntries(); + for ($e = 0; $e < sizeof($sectionEntries); $e++) { + $sectionEntry = $sectionEntries[$e]; + $structureContent->addElement(new htmlSpacer('10px', null)); + $fieldOutput = new htmlOutputText(translateFieldIDToName($sectionEntry->getKey(), $type->getScope(), $availablePDFFields)); + $structureContent->addElement($fieldOutput); + if ($e != 0) { + $entryLinkUp = new htmlButton('up_entry_' . $key . '_' . $e, 'up.gif', true); + $entryLinkUp->setTitle(_("Up")); + $structureContent->addElement($entryLinkUp); + } + else { + $structureContent->addElement($emptyBox); + } + if ($e < (sizeof($sectionEntries) - 1)) { + $linkDown = new htmlButton('down_entry_' . $key . '_' . $e, 'down.gif', true); + $linkDown->setTitle(_("Down")); + $structureContent->addElement($linkDown); + } + else { + $structureContent->addElement($emptyBox); + } + $entryLinkRemove = new htmlButton('remove_entry_' . $key . '_' . $e, 'delete.gif', true); + $entryLinkRemove->setTitle(_("Remove")); + $structureContent->addElement($entryLinkRemove, true); + } } // We have to include a static text. - elseif($entry['tag'] == "TEXT") { + elseif($section instanceof PDFTextSection) { // Add current satic text for dropdown box needed for the position when inserting a new // section or static text entry - $sectionElements[_('Static text')] = $key + 1; + $textSnippet = $section->getText(); + $textSnippet = str_replace(array("\n", "\r"), array(" ", " "), $textSnippet); + $textSnippet = trim($textSnippet); + if (strlen($textSnippet) > 15) { + $textSnippet = substr($textSnippet, 0, 15) . '...'; + } + $textSnippet = htmlspecialchars($textSnippet); + $sectionElements[_('Static text') . ': ' . $textSnippet] = $key; $structureContent->addElement(new htmlSpacer(null, '15px'), true); $sectionHeadlineOutput = new htmlOutputText(_('Static text')); $sectionHeadlineOutput->colspan = 2; @@ -565,7 +365,7 @@ for ($key = 0; $key < sizeof($_SESSION['currentPDFStructure']); $key++) { else { $structureContent->addElement($emptyBox); } - if ($key != sizeof($_SESSION['currentPDFStructure']) - 1) { + if ($key != sizeof($sections) - 1) { $structureContent->addElement($linkDown); } else { @@ -573,32 +373,12 @@ for ($key = 0; $key < sizeof($_SESSION['currentPDFStructure']); $key++) { } $structureContent->addElement($linkRemove, true); $structureContent->addElement(new htmlSpacer('10px', null)); - $staticTextOutput = new htmlOutputText($entry['value']); + $staticTextOutput = new htmlOutputText($section->getText()); + $staticTextOutput->setPreformatted(); $structureContent->addElement($staticTextOutput, true); } - // We have to include an entry from the account - elseif($entry['tag'] == "ENTRY") { - // Get name of current entry - $name = $entry['attributes']['NAME']; - $structureContent->addElement(new htmlSpacer('10px', null)); - $fieldOutput = new htmlOutputText(translateFieldIDToName($name, $type->getScope(), $availablePDFFields)); - $structureContent->addElement($fieldOutput); - if ($_SESSION['currentPDFStructure'][$key - 1]['tag'] != 'SECTION') { - $structureContent->addElement($linkUp); - } - else { - $structureContent->addElement($emptyBox); - } - if ($_SESSION['currentPDFStructure'][$key + 1]['tag'] != 'SECTION') { - $structureContent->addElement($linkDown); - } - else { - $structureContent->addElement($emptyBox); - } - $structureContent->addElement($linkRemove, true); - } } -$sectionElements[_('End')] = sizeof($_SESSION['currentPDFStructure']); +$sectionElements[_('End')] = sizeof($structure->getSections()); $structureContent->colspan = 3; $mainContent->addElement($structureContent); $container->addElement(new htmlFieldset($mainContent), true); @@ -663,6 +443,7 @@ $buttonContainer->addElement($saveButton); $buttonContainer->addElement($cancelButton); $buttonContainer->addElement(new htmlHiddenInput('modules', $modules)); $buttonContainer->addElement(new htmlHiddenInput('type', $type->getId())); +$buttonContainer->addElement(new htmlHiddenInput('form_submit', 'true')); $container->addElement($buttonContainer, true); addSecurityTokenToMetaHTML($container); @@ -710,4 +491,190 @@ function translateFieldIDToName($id, $scope, $availablePDFFields) { return $id; } +/** + * Updates basic settings such as logo and head line. + * + * @param PDFStructure $structure + */ +function updateBasicSettings(&$structure) { + // set headline + if (isset($_POST['headline'])) { + $structure->setTitle(str_replace('<', '', str_replace('>', '', $_POST['headline']))); + } + // set logo + if (isset($_POST['logoFile'])) { + $structure->setLogo($_POST['logoFile']); + } + // set folding marks + if (isset($_POST['foldingmarks'])) { + $structure->setFoldingMarks($_POST['foldingmarks']); + } +} + +/** + * Updates section titles. + * + * @param PDFStructure $structure + */ +function updateSectionTitles(&$structure) { + $sections = $structure->getSections(); + foreach ($_POST as $key => $value) { + if (strpos($key, 'section_') === 0) { + $pos = substr($key, strlen('section_')); + $sections[$pos]->setTitle($value); + } + } +} + +/** + * Adds a new section if requested. + * + * @param PDFStructure $structure + */ +function addSection(&$structure) { + $sections = $structure->getSections(); + // add a new text field + if(isset($_POST['add_text'])) { + // Check if text for static text field is specified + if(empty($_POST['text_text'])) { + StatusMessage('ERROR',_('No static text specified'),_('The static text must contain at least one character.')); + } + else { + $section = new PDFTextSection(str_replace("\r", "", $_POST['text_text'])); + array_splice($sections, $_POST['add_text_position'], 0, array($section)); + $structure->setSections($sections); + } + } + // add a new section with text headline + elseif(isset($_POST['add_sectionText'])) { + // Check if name for new section is specified when needed + if(empty($_POST['new_section_text'])) { + StatusMessage('ERROR',_('No section text specified'),_('The headline for a new section must contain at least one character.')); + } + else { + $section = new PDFEntrySection($_POST['new_section_text']); + array_splice($sections, $_POST['add_text_position'], 0, array($section)); + $structure->setSections($sections); + } + } + // Add a new section with item as headline + elseif(isset($_POST['add_section'])) { + $section = new PDFEntrySection('_' . $_POST['new_section_item']); + array_splice($sections, $_POST['add_text_position'], 0, array($section)); + $structure->setSections($sections); + } +} + +/** + * Adds a new entry to a section if requested. + * + * @param PDFStructure $structure + */ +function addSectionEntry(&$structure) { + if(isset($_POST['add_new_field'])) { + $field = new PDFSectionEntry($_POST['new_field']); + $sections = $structure->getSections(); + $pos = $_POST['add_field_position']; + $entries = $sections[$pos]->getEntries(); + $entries[] = $field; + $sections[$pos]->setEntries($entries); + $structure->setSections($sections); + } +} + +/** + * Removes a section or entry if requested. + * + * @param PDFStructure $structure + */ +function removeItem(&$structure) { + $sections = $structure->getSections(); + foreach ($_POST as $key => $value) { + // remove section + if (strpos($key, 'remove_section_') === 0) { + $pos = substr($key, strlen('remove_section_')); + unset($sections[$pos]); + $sections = array_values($sections); + $structure->setSections($sections); + } + // remove section entry + if (strpos($key, 'remove_entry_') === 0) { + $parts = substr($key, strlen('remove_entry_')); + $parts = explode('_', $parts); + $sectionPos = $parts[0]; + $entryPos = $parts[1]; + $entries = $sections[$sectionPos]->getEntries(); + unset($entries[$entryPos]); + $entries = array_values($entries); + $sections[$sectionPos]->setEntries($entries); + $structure->setSections($sections); + } + } +} + +/** + * Moves up a section or entry if requested. + * + * @param PDFStructure $structure + */ +function moveUp(&$structure) { + $sections = $structure->getSections(); + foreach ($_POST as $key => $value) { + // move section + if (strpos($key, 'up_section_') === 0) { + $pos = substr($key, strlen('up_section_')); + $sectionTmp = $sections[$pos - 1]; + $sections[$pos - 1] = $sections[$pos]; + $sections[$pos] = $sectionTmp; + $structure->setSections($sections); + } + // move section entry + if (strpos($key, 'up_entry_') === 0) { + $parts = substr($key, strlen('up_entry_')); + $parts = explode('_', $parts); + $sectionPos = $parts[0]; + $entryPos = $parts[1]; + $entries = $sections[$sectionPos]->getEntries(); + $entryTmp = $entries[$entryPos - 1]; + $entries[$entryPos - 1] = $entries[$entryPos]; + $entries[$entryPos] = $entryTmp; + $sections[$sectionPos]->setEntries($entries); + $structure->setSections($sections); + } + } +} + +/** + * Moves down a section or entry if requested. + * + * @param PDFStructure $structure + */ +function moveDown(&$structure) { + $sections = $structure->getSections(); + foreach ($_POST as $key => $value) { + // move section + if (strpos($key, 'down_section_') === 0) { + $pos = substr($key, strlen('down_section_')); + $sectionTmp = $sections[$pos + 1]; + $sections[$pos + 1] = $sections[$pos]; + $sections[$pos] = $sectionTmp; + $structure->setSections($sections); + } + // move section entry + if (strpos($key, 'down_entry_') === 0) { + $parts = substr($key, strlen('down_entry_')); + $parts = explode('_', $parts); + $sectionPos = $parts[0]; + $entryPos = $parts[1]; + $entries = $sections[$sectionPos]->getEntries(); + $entries = $sections[$sectionPos]->getEntries(); + $entryTmp = $entries[$entryPos + 1]; + $entries[$entryPos + 1] = $entries[$entryPos]; + $entries[$entryPos] = $entryTmp; + $sections[$sectionPos]->setEntries($entries); + $structure->setSections($sections); + } + } +} + ?> diff --git a/lam/tests/lib/pdfstructTest.php b/lam/tests/lib/pdfstructTest.php new file mode 100644 index 00000000..7e206065 --- /dev/null +++ b/lam/tests/lib/pdfstructTest.php @@ -0,0 +1,114 @@ +getMockBuilder('\LAM\PDF\PDFStructureReader') + ->setMethods(array('getFileName')) + ->getMock(); + $reader->method('getFileName')->willReturn($this->getTestFileName('test.xml')); + + $structure = $reader->read('type', 'name'); + $this->assertEquals('printLogo.jpg', $structure->getLogo()); + $this->assertEquals('User information', $structure->getTitle()); + $this->assertEquals(PDFStructure::FOLDING_STANDARD, $structure->getFoldingMarks()); + $sections = $structure->getSections(); + $this->assertEquals(4, sizeof($sections)); + // check first section + $this->assertInstanceOf(PDFEntrySection::class, $sections[0]); + $this->assertFalse($sections[0]->isAttributeTitle()); + $this->assertEquals('Personal user information', $sections[0]->getTitle()); + $entries = $sections[0]->getEntries(); + $this->assertEquals(3, sizeof($entries)); + $this->assertEquals('inetOrgPerson_givenName', $entries[0]->getKey()); + $this->assertEquals('inetOrgPerson_sn', $entries[1]->getKey()); + $this->assertEquals('inetOrgPerson_street', $entries[2]->getKey()); + // check text section + $this->assertInstanceOf(PDFTextSection::class, $sections[1]); + $this->assertEquals('test text', $sections[1]->getText()); + // check third section + $this->assertInstanceOf(PDFEntrySection::class, $sections[2]); + $this->assertTrue($sections[2]->isAttributeTitle()); + $this->assertEquals('posixAccount_uid', $sections[2]->getPdfKey()); + $entries = $sections[2]->getEntries(); + $this->assertEquals(2, sizeof($entries)); + $this->assertEquals('posixAccount_homeDirectory', $entries[0]->getKey()); + $this->assertEquals('posixAccount_loginShell', $entries[1]->getKey()); + // check fourth section + $this->assertInstanceOf(PDFEntrySection::class, $sections[3]); + $this->assertFalse($sections[3]->isAttributeTitle()); + $this->assertEquals('No entries', $sections[3]->getTitle()); + $entries = $sections[3]->getEntries(); + $this->assertEquals(0, sizeof($entries)); + } + + /** + * Returns the full path to the given file name. + * + * @param string $file file name + */ + private function getTestFileName($file) { + return dirname(dirname(__FILE__)) . '/resources/pdf/' . $file; + } + + /** + * Tests if the output is the same as the original PDF. + */ + public function testWrite() { + $file = $this->getTestFileName('writer.xml'); + // read input XML + $fileHandle = fopen($file, "r"); + $originalXML = fread($fileHandle, 1000000); + fclose($fileHandle); + // read structure + $reader = $this->getMockBuilder('\LAM\PDF\PDFStructureReader') + ->setMethods(array('getFileName')) + ->getMock(); + $reader->method('getFileName')->willReturn($file); + $structure = $reader->read('type', 'name'); + // create writer and get output XML + $writer = new PDFStructureWriter(); + $xml = $writer->getXML($structure); + // compare + $this->assertEquals($originalXML, $xml); + } + +} + +?> \ No newline at end of file diff --git a/lam/tests/resources/pdf/test.xml b/lam/tests/resources/pdf/test.xml new file mode 100644 index 00000000..fec76e9c --- /dev/null +++ b/lam/tests/resources/pdf/test.xml @@ -0,0 +1,14 @@ + +
+ + + + +
+ test text +
+ + +
+
+ \ No newline at end of file diff --git a/lam/tests/resources/pdf/writer.xml b/lam/tests/resources/pdf/writer.xml new file mode 100644 index 00000000..7469e546 --- /dev/null +++ b/lam/tests/resources/pdf/writer.xml @@ -0,0 +1,12 @@ + +
+ + + +
+ test text +
+ + +
+