diff --git a/lam/lib/html.inc b/lam/lib/html.inc
index bf6c515e..21fb7b7d 100644
--- a/lam/lib/html.inc
+++ b/lam/lib/html.inc
@@ -3082,6 +3082,15 @@ class htmlStatusMessage extends htmlElement {
return array();
}
+ /**
+ * Returns the message type.
+ *
+ * @return String type
+ */
+ public function getType() {
+ return $this->type;
+ }
+
}
/**
diff --git a/lam/lib/pdfstruct.inc b/lam/lib/pdfstruct.inc
index e80591de..ef73e703 100644
--- a/lam/lib/pdfstruct.inc
+++ b/lam/lib/pdfstruct.inc
@@ -34,6 +34,11 @@ use \LAM\ImageUtils\ImageManipulationFactory;
/** LAM configuration */
include_once(__DIR__ . "/config.inc");
+/**
+ * Use as server profile name to manage global templates.
+ */
+const GLOBAL_PROFILE = '__GLOBAL__';
+
/** LDAP object */
include_once(__DIR__ . "/ldap.inc");
@@ -164,12 +169,15 @@ function copyStructureToTemplates($sourceType, $sourceName) {
* @param String $file full path of temporary file
* @param String $name file name
* @param string $serverProfileName server profile name
- * @return StatusMessage status message to display
+ * @return htmlStatusMessage status message to display
*/
function uploadPDFLogo($file, $name, $serverProfileName) {
if (!preg_match('/[a-zA-Z0-9_-]+\\.(png)|(jpg)/i', $name)) {
return new htmlStatusMessage('ERROR', _('Unable to upload logo file.'), _('The file name must end with ".png" or ".jpg".'));
}
+ if ($serverProfileName === GLOBAL_PROFILE) {
+ $serverProfileName = '../templates/pdf';
+ }
$dirPath = dirname(__FILE__) . '/../config/pdf/' . $serverProfileName . '/logos/';
$success = copy($file, $dirPath . '/' . $name);
if ($success) {
@@ -242,21 +250,8 @@ function isValidPDFStructureName($name) {
* Installs template structures to the current server profile.
*/
function installPDFTemplates() {
- $templatePath = dirname(__FILE__) . '/../config/templates/pdf';
- $templateDir = @dir($templatePath);
- $allTemplates = array();
- if ($templateDir) {
- $entry = $templateDir->read();
- while ($entry){
- $parts = explode('.', $entry);
- if ((strlen($entry) > 3) && (sizeof($parts) == 3)) {
- $name = $parts[0];
- $scope = $parts[1];
- $allTemplates[$scope][] = $name;
- }
- $entry = $templateDir->read();
- }
- }
+ $templatePath = __DIR__ . '/../config/templates/pdf';
+ $allTemplates = getPdfTemplateNames();
$basePath = dirname(__FILE__) . '/../config/pdf/' . $_SESSION['config']->getName();
if (!file_exists($basePath)) {
mkdir($basePath, 0700, true);
@@ -278,20 +273,75 @@ function installPDFTemplates() {
if (!file_exists($basePath . '/logos')) {
mkdir($basePath . '/logos');
}
- $templatePath = dirname(__FILE__) . '/../config/templates/pdf/logos';
+ $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';
$templateDir = @dir($templatePath);
+ $allTemplates = array();
if ($templateDir) {
$entry = $templateDir->read();
while ($entry){
- $path = $basePath . '/logos/' . $entry;
- if ((strpos($entry, '.') !== 0) && !is_file($path)) {
- $template = $templatePath . '/' . $entry;
- logNewMessage(LOG_DEBUG, 'Copy template ' . $template . ' to ' . $path);
- @copy($template, $path);
+ $parts = explode('.', $entry);
+ if ((strlen($entry) > 3) && (sizeof($parts) == 3)) {
+ $name = $parts[0];
+ $scope = $parts[1];
+ $allTemplates[$scope][] = $name;
}
$entry = $templateDir->read();
}
}
+ 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;
}
/**
@@ -309,7 +359,12 @@ class PDFStructureReader {
* @param $serverProfileName server profile name
*/
public function __construct($serverProfileName) {
- $this->serverProfileName = $serverProfileName;
+ if ($serverProfileName === GLOBAL_PROFILE) {
+ $this->serverProfileName = '../templates/pdf';
+ }
+ else {
+ $this->serverProfileName = $serverProfileName;
+ }
}
/**
@@ -345,6 +400,7 @@ class PDFStructureReader {
* @return PDFStructure structure
*/
private function readPDFFile($file) {
+ logNewMessage(LOG_DEBUG, $file);
$xml = new \XMLReader();
$xml->open($file);
$structure = new PDFStructure();
@@ -430,7 +486,12 @@ class PDFStructureWriter {
* @param string $serverProfileName server profile name
*/
public function __construct($serverProfileName) {
- $this->serverProfileName = $serverProfileName;
+ if ($serverProfileName === GLOBAL_PROFILE) {
+ $this->serverProfileName = '../templates/pdf';
+ }
+ else {
+ $this->serverProfileName = $serverProfileName;
+ }
}
/**
@@ -460,10 +521,11 @@ class PDFStructureWriter {
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/' . $this->serverProfileName)) {
- throw new \LAMException(_('Could not save PDF structure, access denied.'));
+ $baseDir = __DIR__ . '/../config/pdf/' . $this->serverProfileName;
+ if(!is_writable($baseDir)) {
+ throw new \LAMException(_('Could not save PDF structure, access denied to ' . $baseDir . '.'));
}
- return dirname(__FILE__) . '/../config/pdf/' . $this->serverProfileName . '/' . $name . '.' . $typeId . '.xml';
+ return $baseDir . '/' . $name . '.' . $typeId . '.xml';
}
/**
diff --git a/lam/lib/persistence.inc b/lam/lib/persistence.inc
index 59274f7f..5ad8b67d 100644
--- a/lam/lib/persistence.inc
+++ b/lam/lib/persistence.inc
@@ -8,6 +8,9 @@ use LAMConfig;
use LAMException;
use function LAM\PDF\getAvailableLogos;
use function LAM\PDF\getPDFStructures;
+use function LAM\PDF\getPdfTemplateLogoBinary;
+use function LAM\PDF\getPdfTemplateLogoNames;
+use function LAM\PDF\getPdfTemplateNames;
use function LAM\PDF\uploadPDFLogo;
use function LAM\PROFILES\getAccountProfiles;
use function LAM\PROFILES\getProfileTemplateNames;
@@ -68,8 +71,9 @@ class ConfigDataExporter {
}
$jsonData['serverProfiles'] = $this->_getServerProfiles($serverProfiles);
$jsonData['accountProfiles'] = $this->_getAccountProfiles($serverProfiles);
- $jsonData['accountProfileTemplates'] = $this->_getAccountProfileTemplates($serverProfiles);
+ $jsonData['accountProfileTemplates'] = $this->_getAccountProfileTemplates();
$jsonData['pdfProfiles'] = $this->_getPdfProfiles($serverProfiles);
+ $jsonData['pdfProfileTemplates'] = $this->_getPdfProfileTemplates();
/**
* TODO
*
@@ -147,11 +151,10 @@ class ConfigDataExporter {
/**
* Returns the content of the account profile templates.
*
- * @param array $serverProfiles list of server profiles (name => object)
* @return array $data
* @throws LAMException error reading template
*/
- public function _getAccountProfileTemplates($serverProfiles) {
+ public function _getAccountProfileTemplates() {
$data = array();
$accountProfileTemplateNames = getProfileTemplateNames();
foreach ($accountProfileTemplateNames as $scope => $templateNames) {
@@ -193,6 +196,29 @@ class ConfigDataExporter {
return $data;
}
+ /**
+ * Returns the content of the account profile templates.
+ *
+ * @return array $data
+ * @throws LAMException error reading template
+ */
+ public function _getPdfProfileTemplates() {
+ $data = array();
+ $pdfTemplateNames = getPdfTemplateNames();
+ $reader = new PDFStructureReader(\LAM\PDF\GLOBAL_PROFILE);
+ foreach ($pdfTemplateNames as $scope => $templateNames) {
+ foreach ($templateNames as $templateName) {
+ $pdfStructure = $reader->read($scope, $templateName);
+ $data['structures'][$scope][$templateName] = $pdfStructure->export();
+ }
+ }
+ $logoNames = getPdfTemplateLogoNames();
+ foreach ($logoNames as $logoName) {
+ $data['logos'][$logoName] = base64_encode(getPdfTemplateLogoBinary($logoName));
+ }
+ return $data;
+ }
+
}
/**
@@ -245,6 +271,9 @@ class ConfigDataImporter {
}
$steps[] = $mainStep;
break;
+ case 'pdfProfileTemplates':
+ $steps[] = new ImporterStep(_('PDF structures') . ' - ' . _('Global templates'), 'pdfProfileTemplates', $value);
+ break;
default:
logNewMessage(LOG_WARNING, 'Unknown import type: ' . $key);
}
@@ -286,6 +315,9 @@ class ConfigDataImporter {
case 'pdfProfiles':
$this->importPdfProfiles($step);
break;
+ case 'pdfProfileTemplates':
+ $this->importPdfProfileTemplates($step);
+ break;
default:
logNewMessage(LOG_WARNING, 'Unknown import type: ' . $key);
}
@@ -409,7 +441,7 @@ class ConfigDataImporter {
$writer->write($typeId, $pdfProfileName, $structure);
}
catch (LAMException $e) {
- logNewMessage('ERROR', $e->getMessage());
+ logNewMessage(LOG_ERR, $e->getTitle() . ' ' . $e->getMessage());
$failedProfiles[] = $serverProfileName . ':' . $typeId . ':' . $pdfProfileName;
}
}
@@ -432,6 +464,54 @@ class ConfigDataImporter {
}
}
+ /**
+ * Imports the PDF profile templates.
+ *
+ * @param ImporterStep $step step
+ * @throws LAMException error during import
+ */
+ private function importPdfProfileTemplates($step) {
+ $failedNames = array();
+ $data = $step->getValue();
+ if (isset($data['structures'])) {
+ $writer = new PDFStructureWriter(\LAM\PDF\GLOBAL_PROFILE);
+ foreach ($data['structures'] as $typeId => $pdfProfiles) {
+ foreach ($pdfProfiles as $pdfProfileName => $pdfProfileData) {
+ $structure = new PDFStructure();
+ $structure->import($pdfProfileData);
+ try {
+ $writer->write($typeId, $pdfProfileName, $structure);
+ }
+ catch (LAMException $e) {
+ $failedNames[] = $typeId . ':' . $pdfProfileName;
+ logNewMessage(LOG_ERR, $e->getTitle() . ' ' . $e->getMessage());
+ }
+ }
+ }
+ }
+ $failedLogos = array();
+ if (isset($data['logos'])) {
+ foreach ($data['logos'] as $logoFileName => $logoData) {
+ $tempFilePath = tempnam("/tmp", "lam");
+ $tempFile = fopen($tempFilePath, "w");
+ $logoBinary = base64_decode($logoData);
+ fwrite($tempFile, $logoBinary);
+ fclose($tempFile);
+ $message = uploadPDFLogo($tempFilePath, $logoFileName, \LAM\PDF\GLOBAL_PROFILE);
+ unlink($tempFilePath);
+ if ($message->getType() === 'ERROR') {
+ $failedLogos[] = $logoFileName;
+ }
+ }
+ }
+ if (!empty($failedNames)) {
+ throw new LAMException(_('Could not save PDF structure, access denied.'), implode(', ', $failedNames));
+ }
+ if (!empty($failedLogos)) {
+ throw new LAMException(_('Unable to upload logo file.'), implode(', ', $failedLogos));
+ }
+ }
+
}
/**
diff --git a/lam/lib/profiles.inc b/lam/lib/profiles.inc
index a45fe0f1..3a9711b1 100644
--- a/lam/lib/profiles.inc
+++ b/lam/lib/profiles.inc
@@ -114,7 +114,7 @@ function readAccountProfileFile($fileName) {
if ($file) {
while (!feof($file)) {
$line = fgets($file, 1024);
- if (($line == "\n")||($line[0] == "#")) {
+ if (($line == '') || ($line == "\n") || ($line[0] == "#")) {
continue; // ignore comments
}
// search keywords
diff --git a/lam/templates/config/confImportExport.php b/lam/templates/config/confImportExport.php
index 182ae2a3..ea2e6677 100644
--- a/lam/templates/config/confImportExport.php
+++ b/lam/templates/config/confImportExport.php
@@ -262,6 +262,7 @@ printHeaderContents(_("Import and export configuration"), '../..');
$importer->runImport($importSteps);
unlink($_SESSION['configImportFile']);
$content->add(new htmlStatusMessage('INFO', _('Configuration import ended successful.')), 12);
+ $content->add(new htmlButton('importNew', _('New import')), 12);
}
catch (LAMException $e) {
$content->add(new htmlStatusMessage('ERROR', htmlspecialchars($e->getTitle()), htmlspecialchars($e->getMessage())), 12);