PDF global templates export
This commit is contained in:
		
							parent
							
								
									2e5419b3ac
								
							
						
					
					
						commit
						7bd799bee3
					
				|  | @ -3082,6 +3082,15 @@ class htmlStatusMessage extends htmlElement { | |||
| 		return array(); | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Returns the message type. | ||||
| 	 * | ||||
| 	 * @return String type | ||||
| 	 */ | ||||
| 	public function getType() { | ||||
| 		return $this->type; | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  |  | |||
|  | @ -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'; | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
|  |  | |||
|  | @ -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)); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  |  | |||
|  | @ -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
 | ||||
|  |  | |||
|  | @ -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); | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue