1<?php 2namespace LAM\TOOLS\PDF_EDITOR; 3use \htmlTitle; 4use \htmlStatusMessage; 5use \LAMCfgMain; 6use \htmlSubTitle; 7use \htmlSelect; 8use \htmlImage; 9use \htmlSpacer; 10use \htmlButton; 11use \htmlLink; 12use \htmlOutputText; 13use \htmlInputFileUpload; 14use \htmlHelpLink; 15use \htmlInputField; 16use \htmlHiddenInput; 17use \htmlResponsiveRow; 18use \htmlGroup; 19use \LAM\TYPES\TypeManager; 20/* 21 22 This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/) 23 Copyright (C) 2003 - 2006 Michael Duergner 24 2005 - 2020 Roland Gruber 25 26 This program is free software; you can redistribute it and/or modify 27 it under the terms of the GNU General Public License as published by 28 the Free Software Foundation; either version 2 of the License, or 29 (at your option) any later version. 30 31 This program is distributed in the hope that it will be useful, 32 but WITHOUT ANY WARRANTY; without even the implied warranty of 33 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 34 GNU General Public License for more details. 35 36 You should have received a copy of the GNU General Public License 37 along with this program; if not, write to the Free Software 38 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 39 40*/ 41 42/** 43* This is the main window of the PDF structure editor. 44* 45* @author Michael Duergner 46* @author Roland Gruber 47* @package PDF 48*/ 49 50/** security functions */ 51include_once(__DIR__ . "/../../lib/security.inc"); 52/** access to PDF configuration files */ 53include_once(__DIR__ . "/../../lib/pdfstruct.inc"); 54/** LDAP object */ 55include_once(__DIR__ . "/../../lib/ldap.inc"); 56/** for language settings */ 57include_once(__DIR__ . "/../../lib/config.inc"); 58/** module functions */ 59include_once(__DIR__ . "/../../lib/modules.inc"); 60 61// start session 62startSecureSession(); 63enforceUserIsLoggedIn(); 64 65// die if no write access 66if (!checkIfWriteAccessIsAllowed()) die(); 67 68checkIfToolIsActive('toolPDFEditor'); 69 70if (!empty($_POST)) { 71 validateSecurityToken(); 72} 73 74setlanguage(); 75 76// Unset PDF structure definitions in session if set 77if(isset($_SESSION['currentPDFStructure'])) { 78 unset($_SESSION['currentPDFStructure']); 79} 80 81// check if user is logged in, if not go to login 82if (!$_SESSION['ldap'] || !$_SESSION['ldap']->server()) { 83 metaRefresh("../login.php"); 84 exit; 85} 86 87// check if new template should be created 88if(isset($_POST['createNewTemplate'])) { 89 metaRefresh('pdfpage.php?type=' . htmlspecialchars($_POST['typeId'])); 90 exit(); 91} 92 93$typeManager = new TypeManager(); 94$types = $typeManager->getConfiguredTypes(); 95$sortedTypes = array(); 96foreach ($types as $type) { 97 if ($type->isHidden() || !checkIfWriteAccessIsAllowed($type->getId())) { 98 continue; 99 } 100 $sortedTypes[$type->getId()] = $type->getAlias(); 101} 102natcasesort($sortedTypes); 103 104$container = new htmlResponsiveRow(); 105$container->add(new htmlTitle(_('PDF editor')), 12); 106 107if (isset($_POST['deleteProfile']) && ($_POST['deleteProfile'] == 'true')) { 108 $typeToDelete = $typeManager->getConfiguredType($_POST['profileDeleteType']); 109 // delete structure 110 if (\LAM\PDF\deletePDFStructure($_POST['profileDeleteType'], $_POST['profileDeleteName'], $_SESSION['config']->getName())) { 111 $message = new htmlStatusMessage('INFO', _('Deleted PDF structure.'), $typeToDelete->getAlias() . ': ' . htmlspecialchars($_POST['profileDeleteName'])); 112 $container->add($message, 12); 113 } 114 else { 115 $message = new htmlStatusMessage('ERROR', _('Unable to delete PDF structure!'), $typeToDelete->getAlias() . ': ' . htmlspecialchars($_POST['profileDeleteName'])); 116 $container->add($message, 12); 117 } 118} 119 120$configProfiles = getConfigProfiles(); 121$serverProfiles = array(); 122foreach ($configProfiles as $profileName) { 123 $serverProfiles[$profileName] = new \LAMConfig($profileName); 124} 125 126// import structures 127if (!empty($_POST['import'])) { 128 $cfg = new LAMCfgMain(); 129 $typeId = $_POST['typeId']; 130 // check master password 131 $errMessage = null; 132 if (!$cfg->checkPassword($_POST['passwd_i_' . $_POST['typeId']])) { 133 $errMessage = new htmlStatusMessage('ERROR', _('Master password is wrong!')); 134 } 135 elseif (!empty($_POST['importProfiles_' . $typeId])) { 136 $options = array(); 137 foreach ($_POST['importProfiles_' . $typeId] as $importProfiles) { 138 $parts = explode('##', $importProfiles); 139 $options[] = array('conf' => $parts[0], 'typeId' => $parts[1], 'name' => $parts[2]); 140 } 141 $errMessage = importStructures($_POST['typeId'], $options, $serverProfiles, $typeManager); 142 } 143 if ($errMessage !== null) { 144 $container->add($errMessage, 12); 145 } 146} 147 148// export structures 149if (!empty($_POST['export'])) { 150 $cfg = new LAMCfgMain(); 151 $typeId = $_POST['typeId']; 152 // check master password 153 $errMessage = null; 154 if (!$cfg->checkPassword($_POST['passwd_e_' . $_POST['typeId']])) { 155 $errMessage = new htmlStatusMessage('ERROR', _('Master password is wrong!')); 156 } 157 elseif (!empty($_POST['exportProfiles_' . $typeId])) { 158 $options = array(); 159 foreach ($_POST['exportProfiles_' . $typeId] as $importProfiles) { 160 $parts = explode('##', $importProfiles); 161 $options[] = array('conf' => $parts[0], 'typeId' => $parts[1]); 162 } 163 $typeId = $_POST['typeId']; 164 $name = $_POST['name_' . $typeId]; 165 $errMessage = exportStructures($typeId, $name, $options, $serverProfiles, $typeManager); 166 } 167 if ($errMessage !== null) { 168 $container->add($errMessage, 12); 169 } 170} 171 172// upload logo file 173if (isset($_POST['uploadLogo']) && !empty($_FILES['logoUpload']) && !empty($_FILES['logoUpload']['size'])) { 174 $file = $_FILES['logoUpload']['tmp_name']; 175 $filename = $_FILES['logoUpload']['name']; 176 $container->add(\LAM\PDF\uploadPDFLogo($file, $filename, $_SESSION['config']->getName()), 12); 177} 178 179// delete logo file 180if (isset($_POST['delLogo'])) { 181 $toDel = $_POST['logo']; 182 $container->add(\LAM\PDF\deletePDFLogo($toDel, $_SESSION['config']->getName()), 12); 183} 184 185// get list of account types 186$availableTypes = array(); 187$templateClasses = array(); 188foreach ($sortedTypes as $typeId => $title) { 189 $type = $typeManager->getConfiguredType($typeId); 190 $templateClasses[] = array( 191 'typeId' => $type->getId(), 192 'scope' => $type->getScope(), 193 'title' => $title, 194 'icon' => $type->getIcon(), 195 'templates' => \LAM\PDF\getPDFStructures($type->getId(), $_SESSION['config']->getName())); 196 $availableTypes[$title] = $type->getId(); 197} 198// check if a template should be edited 199foreach ($templateClasses as $templateClass) { 200 if (isset($_POST['editTemplate_' . $templateClass['typeId']]) || isset($_POST['editTemplate_' . $templateClass['typeId'] . '_x'])) { 201 metaRefresh('pdfpage.php?type=' . htmlspecialchars($templateClass['typeId']) . '&edit=' . htmlspecialchars($_POST['template_' . $templateClass['typeId']])); 202 exit; 203 } 204} 205include __DIR__ . '/../../lib/adminHeader.inc'; 206 207?> 208<div class="user-bright smallPaddingContent"> 209<form enctype="multipart/form-data" action="pdfmain.php" method="post" name="pdfmainForm" > 210<input type="hidden" name="<?php echo getSecurityTokenName(); ?>" value="<?php echo getSecurityTokenValue(); ?>"> 211 <?php 212 if (isset($_GET['savedSuccessfully'])) { 213 $message = new htmlStatusMessage("INFO", _("PDF structure was successfully saved."), htmlspecialchars($_GET['savedSuccessfully'])); 214 $container->add($message, 12); 215 } 216 217 if (isset($_GET['loadFailed'])) { 218 $message = new htmlStatusMessage("ERROR", _("Unable to read PDF structure."), htmlspecialchars($_GET['name'])); 219 $container->add($message, 12); 220 } 221 222 // new template 223 if (!empty($availableTypes)) { 224 $container->add(new htmlSubTitle(_('Create a new PDF structure')), 12); 225 $newProfileSelect = new htmlSelect('typeId', $availableTypes); 226 $newProfileSelect->setHasDescriptiveElements(true); 227 $container->addLabel($newProfileSelect); 228 $container->addField(new htmlButton('createNewTemplate', _('Create'))); 229 $container->addVerticalSpacer('2rem'); 230 } 231 232 // existing templates 233 $container->add(new htmlSubTitle(_("Manage existing PDF structures")), 12); 234 foreach ($templateClasses as $templateClass) { 235 $labelGroup = new htmlGroup(); 236 $labelGroup->addElement(new htmlImage('../../graphics/' . $templateClass['icon'])); 237 $labelGroup->addElement(new htmlSpacer('3px', null)); 238 $labelGroup->addElement(new htmlOutputText($templateClass['title'])); 239 $container->add($labelGroup, 12, 4); 240 $select = new htmlSelect('template_' . $templateClass['typeId'], $templateClass['templates']); 241 $container->add($select, 12, 4); 242 $buttonGroup = new htmlGroup(); 243 $exEditButton = new htmlButton('editTemplate_' . $templateClass['typeId'], 'edit.png', true); 244 $exEditButton->setTitle(_('Edit')); 245 $buttonGroup->addElement($exEditButton); 246 $deleteLink = new htmlLink(null, '#', '../../graphics/delete.png'); 247 $deleteLink->setTitle(_('Delete')); 248 $deleteLink->setOnClick("profileShowDeleteDialog('" . _('Delete') . "', '" . _('Ok') . "', '" . 249 _('Cancel') . "', '" . $templateClass['typeId'] . "', '" . 'template_' . 250 $templateClass['typeId'] . "'); return false;"); 251 $deleteLink->setCSSClasses(array('margin3')); 252 $buttonGroup->addElement($deleteLink); 253 254 if (count($configProfiles) > 1) { 255 $importLink = new htmlLink(null, '#', '../../graphics/import.png'); 256 $importLink->setTitle(_('Import PDF structures')); 257 $importLink->setOnClick("showDistributionDialog('" . _("Import PDF structures") . "', '" . 258 _('Ok') . "', '" . _('Cancel') . "', '" . $templateClass['typeId'] . 259 "', 'import'); return false;"); 260 $importLink->setCSSClasses(array('margin3')); 261 $buttonGroup->addElement($importLink); 262 } 263 $exportLink = new htmlLink(null, '#', '../../graphics/export.png'); 264 $exportLink->setTitle(_('Export PDF structure')); 265 $exportLink->setOnClick("showDistributionDialog('" . _("Export PDF structure") . "', '" . 266 _('Ok') . "', '" . _('Cancel') . "', '" . $templateClass['typeId'] . 267 "', 'export', '" . 'template_' . $templateClass['typeId'] . "', '" . 268 $_SESSION['config']->getName() . "'); return false;"); 269 $exportLink->setCSSClasses(array('margin3')); 270 $buttonGroup->addElement($exportLink); 271 $container->add($buttonGroup, 12, 4); 272 $container->addVerticalSpacer('1rem'); 273 } 274 275 // manage logos 276 $container->addVerticalSpacer('4rem'); 277 $container->add(new htmlSubTitle(_('Manage logos')), 12); 278 $logos = \LAM\PDF\getAvailableLogos($_SESSION['config']->getName()); 279 $logoOptions = array(); 280 foreach ($logos as $logo) { 281 $file = $logo['filename']; 282 $label = $file . ' (' . $logo['infos'][0] . ' x ' . $logo['infos'][1] . ")"; 283 $logoOptions[$label] = $file; 284 } 285 $logoSelect = new htmlSelect('logo', $logoOptions, null); 286 $logoSelect->setHasDescriptiveElements(true); 287 $container->addLabel($logoSelect); 288 $delLogo = new htmlButton('delLogo', _('Delete')); 289 $delLogo->setIconClass('deleteButton'); 290 $container->addField($delLogo); 291 $container->addVerticalSpacer('2rem'); 292 $container->addLabel(new htmlInputFileUpload('logoUpload')); 293 $logoUpload = new htmlButton('uploadLogo', _('Upload')); 294 $logoUpload->setIconClass('upButton'); 295 $container->addField($logoUpload); 296 297 $container->addVerticalSpacer('2rem'); 298 // generate content 299 $tabindex = 1; 300 parseHtml(null, $container, array(), false, $tabindex, 'user'); 301 302 echo "</form>\n"; 303 echo "</div>\n"; 304 305 foreach ($templateClasses as $templateClass) { 306 $typeId = $templateClass['typeId']; 307 $scope = $templateClass['scope']; 308 $importOptions = array(); 309 foreach ($configProfiles as $profile) { 310 $typeManagerImport = new TypeManager($serverProfiles[$profile]); 311 $typesImport = $typeManagerImport->getConfiguredTypesForScope($scope); 312 foreach ($typesImport as $typeImport) { 313 if (($profile != $_SESSION['config']->getName()) || ($typeImport->getId() != $typeId)) { 314 $accountProfiles = \LAM\PDF\getPDFStructures($typeImport->getId(), $profile); 315 if (!empty($accountProfiles)) { 316 foreach ($accountProfiles as $accountProfile) { 317 $importOptions[$profile][$typeImport->getAlias() . ': ' . $accountProfile] = $profile . '##' . $typeImport->getId() . '##' . $accountProfile; 318 } 319 } 320 } 321 } 322 } 323 324 //import dialog 325 echo "<div id=\"importDialog_$typeId\" class=\"hidden\">\n"; 326 echo "<form id=\"importDialogForm_$typeId\" method=\"post\" action=\"pdfmain.php\">\n"; 327 328 $containerStructures = new htmlResponsiveRow(); 329 $containerStructures->add(new htmlOutputText(_('PDF structures')), 12); 330 331 $select = new htmlSelect('importProfiles_' . $typeId, $importOptions, array(), count($importOptions, 1) < 15 ? count($importOptions, 1) : 15); 332 $select->setMultiSelect(true); 333 $select->setHasDescriptiveElements(true); 334 $select->setContainsOptgroups(true); 335 336 $containerStructures->add($select, 11); 337 $containerStructures->add(new htmlHelpLink('408'), 1); 338 339 $containerStructures->addVerticalSpacer('2rem'); 340 341 $containerStructures->add(new htmlOutputText(_("Master password")), 12); 342 $exportPasswd = new htmlInputField('passwd_i_' . $typeId); 343 $exportPasswd->setIsPassword(true); 344 $containerStructures->add($exportPasswd, 11); 345 $containerStructures->add(new htmlHelpLink('236'), 1); 346 $containerStructures->add(new htmlHiddenInput('import', '1'), 12); 347 $containerStructures->add(new htmlHiddenInput('typeId', $typeId), 12); 348 addSecurityTokenToMetaHTML($containerStructures); 349 350 parseHtml(null, $containerStructures, array(), false, $tabindex, 'user'); 351 352 echo '</form>'; 353 echo "</div>\n"; 354 355 //export dialog 356 echo "<div id=\"exportDialog_$typeId\" class=\"hidden\">\n"; 357 echo "<form id=\"exportDialogForm_$typeId\" method=\"post\" action=\"pdfmain.php\">\n"; 358 359 $containerTarget = new htmlResponsiveRow(); 360 361 $containerTarget->add(new htmlOutputText(_("Target server profile")), 12); 362 $exportOptions = array(); 363 foreach ($configProfiles as $profile) { 364 $typeManagerExport = new TypeManager($serverProfiles[$profile]); 365 $typesExport = $typeManagerExport->getConfiguredTypesForScope($scope); 366 foreach ($typesExport as $typeExport) { 367 if (($profile != $_SESSION['config']->getName()) || ($typeExport->getId() != $typeId)) { 368 $exportOptions[$typeManagerExport->getConfig()->getName()][$typeExport->getAlias()] = $profile . '##' . $typeExport->getId(); 369 } 370 } 371 } 372 $exportOptions['*' . _('Global templates')][_('Global templates')] = 'templates*##'; 373 374 $exportSize = count($exportOptions) < 10 ? count($exportOptions, 1) : 10; 375 $select = new htmlSelect('exportProfiles_' . $typeId, $exportOptions, array(), $exportSize); 376 $select->setHasDescriptiveElements(true); 377 $select->setContainsOptgroups(true); 378 $select->setMultiSelect(true); 379 380 $containerTarget->add($select, 11); 381 $containerTarget->add(new htmlHelpLink('363'), 1); 382 383 $containerTarget->addVerticalSpacer('2rem'); 384 385 $containerTarget->add(new htmlOutputText(_("Master password")), 12); 386 $exportPasswd = new htmlInputField('passwd_e_' . $typeId); 387 $exportPasswd->setIsPassword(true); 388 $containerTarget->add($exportPasswd, 11); 389 $containerTarget->add(new htmlHelpLink('236'), 1); 390 $containerTarget->add(new htmlHiddenInput('export', '1'), 12); 391 $containerTarget->add(new htmlHiddenInput('typeId', $typeId), 12); 392 $containerTarget->add(new htmlHiddenInput('name_' . $typeId, '_'), 12); 393 addSecurityTokenToMetaHTML($containerTarget); 394 395 parseHtml(null, $containerTarget, array(), false, $tabindex, 'user'); 396 397 echo '</form>'; 398 echo "</div>\n"; 399 } 400 401// form for delete action 402echo '<div id="deleteProfileDialog" class="hidden"><form id="deleteProfileForm" action="pdfmain.php" method="post">'; 403 echo _("Do you really want to delete this PDF structure?"); 404 echo '<br><br><div class="nowrap">'; 405 echo _("Structure name") . ': <div id="deleteText" style="display: inline;"></div></div>'; 406 echo '<input id="profileDeleteType" type="hidden" name="profileDeleteType" value="">'; 407 echo '<input id="profileDeleteName" type="hidden" name="profileDeleteName" value="">'; 408 echo '<input type="hidden" name="deleteProfile" value="true">'; 409 echo '<input type="hidden" name="' . getSecurityTokenName() . '" value="' . getSecurityTokenValue() . '">'; 410echo '</form></div>'; 411 412include __DIR__ . '/../../lib/adminFooter.inc'; 413 414 415/** 416 * Imports the selected PDF structures. 417 * 418 * @param string $typeId type id 419 * @param array $options options 420 * @param \LAMConfig[] $serverProfiles server profiles (name => profile object) 421 * @param TypeManager $typeManager type manager 422 * @return \htmlStatusMessage message or null 423 */ 424function importStructures($typeId, $options, &$serverProfiles, TypeManager &$typeManager) { 425 foreach ($options as $option) { 426 $sourceConfName = $option['conf']; 427 $sourceTypeId = $option['typeId']; 428 $sourceName = $option['name']; 429 $sourceTypeManager = new TypeManager($serverProfiles[$sourceConfName]); 430 $sourceType = $sourceTypeManager->getConfiguredType($sourceTypeId); 431 $targetType = $typeManager->getConfiguredType($typeId); 432 if (($sourceType !== null) && ($targetType !== null)) { 433 try { 434 \LAM\PDF\copyStructure($sourceType, $sourceName, $targetType); 435 } 436 catch (\LAMException $e) { 437 return new \htmlStatusMessage('ERROR', $e->getTitle(), $e->getMessage()); 438 } 439 } 440 } 441 return new \htmlStatusMessage('INFO', _('Import successful')); 442} 443 444/** 445 * Exports the selected account profile. 446 * 447 * @param string $typeId source type id 448 * @param string $name profile name 449 * @param array $options options 450 * @param \LAMConfig[] $serverProfiles server profiles (name => profile object) 451 * @param TypeManager $typeManager type manager 452 * @return \htmlStatusMessage message or null 453 */ 454function exportStructures($typeId, $name, $options, &$serverProfiles, TypeManager &$typeManager) { 455 $sourceType = $typeManager->getConfiguredType($typeId); 456 if ($sourceType === null) { 457 return null; 458 } 459 foreach ($options as $option) { 460 $targetConfName = $option['conf']; 461 if ($targetConfName == 'templates*') { 462 try { 463 \LAM\PDF\copyStructureToTemplates($sourceType, $name); 464 } 465 catch (\LAMException $e) { 466 return new \htmlStatusMessage('ERROR', $e->getTitle(), $e->getMessage()); 467 } 468 } 469 else { 470 $targetTypeId = $option['typeId']; 471 $targetTypeManager = new TypeManager($serverProfiles[$targetConfName]); 472 $targetType = $targetTypeManager->getConfiguredType($targetTypeId); 473 if ($targetType !== null) { 474 try { 475 \LAM\PDF\copyStructure($sourceType, $name, $targetType); 476 } 477 catch (\LAMException $e) { 478 return new \htmlStatusMessage('ERROR', $e->getTitle(), $e->getMessage()); 479 } 480 } 481 } 482 } 483 return new \htmlStatusMessage('INFO', _('Export successful')); 484} 485 486?> 487