Merge pull request #101 from LDAPAccountManager/configImportExport
Config import export
This commit is contained in:
		
						commit
						55ccddbf1e
					
				| 
						 | 
				
			
			@ -4,6 +4,7 @@
 | 
			
		|||
    "squizlabs/php_codesniffer" : "3.4.0"
 | 
			
		||||
  },
 | 
			
		||||
  "require": {
 | 
			
		||||
    "ext-ldap": "*"
 | 
			
		||||
    "ext-ldap": "*",
 | 
			
		||||
    "ext-json": "*"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 2.7 KiB  | 
| 
						 | 
				
			
			@ -1752,6 +1752,16 @@ function getLAMVersionText() {
 | 
			
		|||
	return $text . ' - ' . LAMVersion();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Returns if the given release is a developer version.
 | 
			
		||||
 *
 | 
			
		||||
 * @param string version
 | 
			
		||||
 * @return bool is developer version
 | 
			
		||||
 */
 | 
			
		||||
function isDeveloperVersion($version) {
 | 
			
		||||
	return strpos($version, 'DEV') !== false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * LAM exception with title and message.
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -649,6 +649,78 @@ class LAMConfig {
 | 
			
		|||
		$this->reload();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Returns the server profile data.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @return array data
 | 
			
		||||
	 */
 | 
			
		||||
	public function exportData() {
 | 
			
		||||
		$data = array();
 | 
			
		||||
		$settingsToIgnore = array('modules', 'types', 'tools', 'jobs');
 | 
			
		||||
		foreach ($this->settings as $setting) {
 | 
			
		||||
			if (in_array($setting, $settingsToIgnore)) {
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			$data[$setting] = $this->$setting;
 | 
			
		||||
		}
 | 
			
		||||
		$data['typeSettings'] = $this->typeSettings;
 | 
			
		||||
		$data['moduleSettings'] = $this->moduleSettings;
 | 
			
		||||
		$data['toolSettings'] = $this->toolSettings;
 | 
			
		||||
		$data['jobSettings'] = $this->jobSettings;
 | 
			
		||||
		if ($this->jobsDatabase === 'SQLite') {
 | 
			
		||||
			$dbFileName = __DIR__ . '/../config/' . $this->getName() . '.sqlite';
 | 
			
		||||
			if (is_file($dbFileName) && is_readable($dbFileName)) {
 | 
			
		||||
				$file = @fopen($dbFileName, "r");
 | 
			
		||||
				if ($file) {
 | 
			
		||||
					$dbData = fread($file, 100000000);
 | 
			
		||||
					fclose($file);
 | 
			
		||||
					$data['jobSQLite'] = base64_encode($dbData);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return $data;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Imports server profile data.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param array $data config data
 | 
			
		||||
	 * @throws LAMException import error
 | 
			
		||||
	 */
 | 
			
		||||
	public function importData($data) {
 | 
			
		||||
		$settingsToIgnore = array('modules', 'types', 'tools', 'jobs', 'typeSettings',
 | 
			
		||||
			'moduleSettings', 'toolSettings', 'jobSettings', 'jobSQLite');
 | 
			
		||||
		foreach ($data as $dataKey => $dataValue) {
 | 
			
		||||
			if (in_array($dataKey, $settingsToIgnore)) {
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			if (!in_array($dataKey, $this->settings)) {
 | 
			
		||||
				logNewMessage(LOG_WARNING, 'Ignored setting during import: ' . $dataKey);
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			if (!(($dataValue === null) || is_array($dataValue) || is_string($dataValue) || is_int($dataValue) || is_bool($dataValue))) {
 | 
			
		||||
				throw new LAMException('Invalid import data type for ' . htmlspecialchars($dataKey) . ': ' . gettype($dataValue));
 | 
			
		||||
			}
 | 
			
		||||
			$this->$dataKey = $dataValue;
 | 
			
		||||
		}
 | 
			
		||||
		$typeSettingsData = !empty($data['typeSettings']) && is_array($data['typeSettings']) ? $data['typeSettings'] : array();
 | 
			
		||||
		$this->typeSettings = $typeSettingsData;
 | 
			
		||||
		$moduleSettingsData = !empty($data['moduleSettings']) && is_array($data['moduleSettings']) ? $data['moduleSettings'] : array();
 | 
			
		||||
		$this->moduleSettings = $moduleSettingsData;
 | 
			
		||||
		$toolSettingsData = !empty($data['toolSettings']) && is_array($data['toolSettings']) ? $data['toolSettings'] : array();
 | 
			
		||||
		$this->toolSettings = $toolSettingsData;
 | 
			
		||||
		$jobSettingsData = !empty($data['jobSettings']) && is_array($data['jobSettings']) ? $data['jobSettings'] : array();
 | 
			
		||||
		$this->jobSettings = $jobSettingsData;
 | 
			
		||||
		if (!empty($data['jobSQLite'])) {
 | 
			
		||||
			$dbFileName = __DIR__ . '/../config/' . $this->getName() . '.sqlite';
 | 
			
		||||
			$file = @fopen($dbFileName, "wb");
 | 
			
		||||
			if ($file) {
 | 
			
		||||
				fputs($file, base64_decode($data['jobSQLite']));
 | 
			
		||||
				fclose($file);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	* Reloads preferences from config file
 | 
			
		||||
	*
 | 
			
		||||
| 
						 | 
				
			
			@ -759,6 +831,10 @@ class LAMConfig {
 | 
			
		|||
	/** Saves preferences to config file */
 | 
			
		||||
	public function save() {
 | 
			
		||||
		$conffile = $this->getPath();
 | 
			
		||||
		if (!file_exists($conffile)) {
 | 
			
		||||
			$newFile = fopen($conffile, 'wb');
 | 
			
		||||
			fclose($newFile);
 | 
			
		||||
		}
 | 
			
		||||
		if (is_file($conffile) && is_readable($conffile)) {
 | 
			
		||||
			$file = fopen($conffile, "r");
 | 
			
		||||
			$file_array = array();
 | 
			
		||||
| 
						 | 
				
			
			@ -1775,7 +1851,7 @@ class LAMConfig {
 | 
			
		|||
	/**
 | 
			
		||||
	* Returns a list of active account types.
 | 
			
		||||
	*
 | 
			
		||||
	* @return array list of types
 | 
			
		||||
	* @return string[] list of types
 | 
			
		||||
	*/
 | 
			
		||||
	public function get_ActiveTypes() {
 | 
			
		||||
		if (($this->activeTypes == '') || !isset($this->activeTypes)) {
 | 
			
		||||
| 
						 | 
				
			
			@ -1789,7 +1865,7 @@ class LAMConfig {
 | 
			
		|||
	/**
 | 
			
		||||
	* Sets the list of active types.
 | 
			
		||||
	*
 | 
			
		||||
	* @param array list of types
 | 
			
		||||
	* @param string[] list of types
 | 
			
		||||
	*/
 | 
			
		||||
	public function set_ActiveTypes($types) {
 | 
			
		||||
		$this->activeTypes = implode(",", $types);
 | 
			
		||||
| 
						 | 
				
			
			@ -2681,6 +2757,83 @@ class LAMCfgMain {
 | 
			
		|||
		$this->reload();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Exports the configuration data.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @return array config data
 | 
			
		||||
	 */
 | 
			
		||||
	public function exportData() {
 | 
			
		||||
		$data = array();
 | 
			
		||||
		foreach ($this->settings as $setting) {
 | 
			
		||||
			$data[$setting] = $this->$setting;
 | 
			
		||||
		}
 | 
			
		||||
		return $data;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Imports configuration data.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param array $data config data
 | 
			
		||||
	 * @throws LAMException import error
 | 
			
		||||
	 */
 | 
			
		||||
	public function importData($data) {
 | 
			
		||||
		foreach ($data as $dataKey => $dataValue) {
 | 
			
		||||
			if (!in_array($dataKey, $this->settings)) {
 | 
			
		||||
				logNewMessage(LOG_WARNING, 'Ignored setting during import: ' . $dataKey);
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			if (!(($dataValue === null) || is_array($dataValue) || is_string($dataValue) || is_int($dataValue) || is_bool($dataValue))) {
 | 
			
		||||
				throw new LAMException('Invalid import data type for ' . htmlspecialchars($dataKey) . ': ' . gettype($dataValue));
 | 
			
		||||
			}
 | 
			
		||||
			$this->$dataKey = $dataValue;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Returns the content of the server certificates file
 | 
			
		||||
	 *
 | 
			
		||||
	 * @return null|string certificates
 | 
			
		||||
	 */
 | 
			
		||||
	public function exportCertificates() {
 | 
			
		||||
		$fileName = $this->getSSLCaCertPath();
 | 
			
		||||
		if ($fileName === null) {
 | 
			
		||||
			return null;
 | 
			
		||||
		}
 | 
			
		||||
		$content = null;
 | 
			
		||||
		$handle = @fopen($fileName, "r");
 | 
			
		||||
		if ($handle) {
 | 
			
		||||
			$content = fread($handle, 10000000);
 | 
			
		||||
			fclose($handle);
 | 
			
		||||
		}
 | 
			
		||||
		return $content;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Imports the server certificates.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param null|string $certsContent certificates
 | 
			
		||||
	 * @throws LAMException write to file failed
 | 
			
		||||
	 */
 | 
			
		||||
	public function importCertificates($certsContent) {
 | 
			
		||||
		$fileName = $this->getSSLCaCertPath();
 | 
			
		||||
		if (empty($certsContent)) {
 | 
			
		||||
			if ($fileName !== null) {
 | 
			
		||||
				unlink($fileName);
 | 
			
		||||
			}
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		$fileName = $this->getInternalSSLCaCertFileName();
 | 
			
		||||
		$handle = @fopen($fileName, "wb");
 | 
			
		||||
		if ($handle) {
 | 
			
		||||
			fputs($handle, $certsContent);
 | 
			
		||||
			fclose($handle);
 | 
			
		||||
			@chmod($fileName, 0600);
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			throw new LAMException(printf(_('Unable to write file %s.'), $fileName));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	* Reloads preferences from config file config.cfg
 | 
			
		||||
	*
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3082,6 +3082,15 @@ class htmlStatusMessage extends htmlElement {
 | 
			
		|||
		return array();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Returns the message type.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @return String type
 | 
			
		||||
	 */
 | 
			
		||||
	public function getType() {
 | 
			
		||||
		return $this->type;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			@ -3644,6 +3653,8 @@ class htmlSpan extends htmlElement {
 | 
			
		|||
 | 
			
		||||
	/** htmlElement that generates inner content */
 | 
			
		||||
	private $content = null;
 | 
			
		||||
	/** onclick handler */
 | 
			
		||||
	private $onclick = null;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Constructor.
 | 
			
		||||
| 
						 | 
				
			
			@ -3674,13 +3685,27 @@ class htmlSpan extends htmlElement {
 | 
			
		|||
		if (($this->cssClasses != null) && (sizeof($this->cssClasses) > 0)) {
 | 
			
		||||
			$classesValue = ' class="' . implode(' ', $this->cssClasses) . '"';
 | 
			
		||||
		}
 | 
			
		||||
		echo '<span' . $classesValue . '>';
 | 
			
		||||
		$onclickHandler = '';
 | 
			
		||||
		if (!empty($this->onclick)) {
 | 
			
		||||
			$onclickHandler = ' onclick="' . $this->onclick . '"';
 | 
			
		||||
		}
 | 
			
		||||
		echo '<span' . $classesValue . $onclickHandler . '>';
 | 
			
		||||
		if ($this->content != null) {
 | 
			
		||||
			$return = $this->content->generateHTML($module, $input, $values, $restricted, $tabindex, $scope);
 | 
			
		||||
		}
 | 
			
		||||
		echo '</span>';
 | 
			
		||||
		return $return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Sets the onclick event.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param string $event event handler code
 | 
			
		||||
	 */
 | 
			
		||||
	public function setOnclick($event) {
 | 
			
		||||
		$this->onclick = $event;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			@ -4715,6 +4740,8 @@ class htmlResponsiveInputCheckbox extends htmlInputCheckbox {
 | 
			
		|||
	private $renderParentHtml = false;
 | 
			
		||||
	/** long label */
 | 
			
		||||
	private $longLabel = false;
 | 
			
		||||
	/** label after checkbox */
 | 
			
		||||
	private $labelAfterCheckbox = false;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Constructor.
 | 
			
		||||
| 
						 | 
				
			
			@ -4751,14 +4778,16 @@ class htmlResponsiveInputCheckbox extends htmlInputCheckbox {
 | 
			
		|||
		$row = new htmlResponsiveRow();
 | 
			
		||||
		$tabletColumnsLabel = 6;
 | 
			
		||||
		$tabletColumnsBox = 6;
 | 
			
		||||
		$mobileColumnsLabel = 10;
 | 
			
		||||
		$mobileColumnsBox = 2;
 | 
			
		||||
		if ($this->longLabel) {
 | 
			
		||||
			$tabletColumnsLabel = 10;
 | 
			
		||||
			$tabletColumnsBox = 2;
 | 
			
		||||
		}
 | 
			
		||||
		// label text
 | 
			
		||||
		$labelGroup = new htmlGroup();
 | 
			
		||||
		$labelGroup->addElement(new htmlOutputText($this->label));
 | 
			
		||||
		$row->add($labelGroup, 10, $tabletColumnsLabel, $tabletColumnsLabel, 'responsiveLabel');
 | 
			
		||||
		$text = new htmlSpan(new htmlOutputText($this->label));
 | 
			
		||||
		$text->setCSSClasses($this->cssClasses);
 | 
			
		||||
		$text->setOnclick('jQuery(\'#' . $this->name . '\').prop(\'checked\',!jQuery(\'#' . $this->name . '\').prop(\'checked\')); jQuery(\'#' . $this->name . '\').change();');
 | 
			
		||||
		// input field
 | 
			
		||||
		$fieldGroup = new htmlGroup();
 | 
			
		||||
		$fieldGroup->addElement($this);
 | 
			
		||||
| 
						 | 
				
			
			@ -4767,7 +4796,14 @@ class htmlResponsiveInputCheckbox extends htmlInputCheckbox {
 | 
			
		|||
			$helpLink->setCSSClasses(array('margin-left5 align-unset-img'));
 | 
			
		||||
			$fieldGroup->addElement($helpLink);
 | 
			
		||||
		}
 | 
			
		||||
		$row->add($fieldGroup, 2, $tabletColumnsBox, $tabletColumnsBox, 'responsiveField nowrap');
 | 
			
		||||
		if ($this->labelAfterCheckbox) {
 | 
			
		||||
			$row->add($fieldGroup, $mobileColumnsBox, $tabletColumnsBox, $tabletColumnsBox, 'responsiveLabel nowrap');
 | 
			
		||||
			$row->add($text, $mobileColumnsLabel, $tabletColumnsLabel, $tabletColumnsLabel, 'responsiveField');
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			$row->add($text, $mobileColumnsLabel, $tabletColumnsLabel, $tabletColumnsLabel, 'responsiveLabel');
 | 
			
		||||
			$row->add($fieldGroup, $mobileColumnsBox, $tabletColumnsBox, $tabletColumnsBox, 'responsiveField nowrap');
 | 
			
		||||
		}
 | 
			
		||||
		return $row->generateHTML($module, $input, $values, $restricted, $tabindex, $scope);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -4779,6 +4815,15 @@ class htmlResponsiveInputCheckbox extends htmlInputCheckbox {
 | 
			
		|||
		return '.row';
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Sets if the label should be shown after the checkbox instead before it.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param bool $labelAfterCheckbox show label after box
 | 
			
		||||
	 */
 | 
			
		||||
	public function setLabelAfterCheckbox($labelAfterCheckbox = true) {
 | 
			
		||||
		$this->labelAfterCheckbox = $labelAfterCheckbox;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -759,7 +759,7 @@ class lamList {
 | 
			
		|||
			$selAccounts[] = $id;
 | 
			
		||||
		}
 | 
			
		||||
		// get possible PDF structures
 | 
			
		||||
		$pdf_structures = \LAM\PDF\getPDFStructures($this->type->getId());
 | 
			
		||||
		$pdf_structures = \LAM\PDF\getPDFStructures($this->type->getId(), $_SESSION['config']->getName());
 | 
			
		||||
 | 
			
		||||
		$this->printHeader();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1454,7 +1454,7 @@ class accountContainer {
 | 
			
		|||
	 */
 | 
			
		||||
	private function loadProfileIfRequested() {
 | 
			
		||||
		if (isset($_POST['accountContainerLoadProfile']) && isset($_POST['accountContainerSelectLoadProfile'])) {
 | 
			
		||||
			$profile = \LAM\PROFILES\loadAccountProfile($_POST['accountContainerSelectLoadProfile'], $this->type->getId());
 | 
			
		||||
			$profile = \LAM\PROFILES\loadAccountProfile($_POST['accountContainerSelectLoadProfile'], $this->type->getId(), $_SESSION['config']->getName());
 | 
			
		||||
			$this->lastLoadedProfile = $_POST['accountContainerSelectLoadProfile'];
 | 
			
		||||
			// pass profile to each module
 | 
			
		||||
			$modules = array_keys($this->module);
 | 
			
		||||
| 
						 | 
				
			
			@ -1775,7 +1775,7 @@ class accountContainer {
 | 
			
		|||
				$this->lastLoadedProfile = $cookieProfileName;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		$profile = \LAM\PROFILES\loadAccountProfile($profileName, $this->type->getId());
 | 
			
		||||
		$profile = \LAM\PROFILES\loadAccountProfile($profileName, $this->type->getId(), $_SESSION['config']->getName());
 | 
			
		||||
		// pass profile to each module
 | 
			
		||||
		$modules = array_keys($this->module);
 | 
			
		||||
		foreach ($modules as $module) $this->module[$module]->load_profile($profile);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -61,7 +61,7 @@ include_once('pdfstruct.inc');
 | 
			
		|||
function createModulePDF($accounts, $pdf_structure, $font, $returnAsString = false) {
 | 
			
		||||
	$account_type = $accounts[0]->get_type();
 | 
			
		||||
	// Get PDF structure from xml file
 | 
			
		||||
	$reader = new PDFStructureReader();
 | 
			
		||||
	$reader = new PDFStructureReader($_SESSION['config']->getName());
 | 
			
		||||
	$structure = $reader->read($account_type->getId(), $pdf_structure);
 | 
			
		||||
	// get list of PDF keys
 | 
			
		||||
	$pdfKeys = array();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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");
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -44,18 +49,15 @@ include_once(__DIR__ . "/ldap.inc");
 | 
			
		|||
 * @param string $typeId the account type
 | 
			
		||||
 * @param string $profile server profile name
 | 
			
		||||
 *
 | 
			
		||||
 * @return array All available PDF structure definitions for the submitted account
 | 
			
		||||
 * @return string[] All available PDF structure definitions for the submitted account
 | 
			
		||||
 * scope. Each entry is a string being the filename that may be passed to the
 | 
			
		||||
 * createModulePDF() function as second argument.
 | 
			
		||||
 */
 | 
			
		||||
function getPDFStructures($typeId, $profile = null) {
 | 
			
		||||
function getPDFStructures($typeId, $profile) {
 | 
			
		||||
	$return = array();
 | 
			
		||||
	if (!preg_match('/[a-zA-Z]+/', $typeId)) {
 | 
			
		||||
		return null;
 | 
			
		||||
	}
 | 
			
		||||
	if (!isset($profile)) {
 | 
			
		||||
		$profile = $_SESSION['config']->getName();
 | 
			
		||||
	}
 | 
			
		||||
	$path = dirname(__FILE__) . '/../config/pdf/' . $profile;
 | 
			
		||||
	if(is_dir($path)) {
 | 
			
		||||
		$dirHandle = opendir($path);
 | 
			
		||||
| 
						 | 
				
			
			@ -75,14 +77,14 @@ function getPDFStructures($typeId, $profile = null) {
 | 
			
		|||
 *
 | 
			
		||||
 * @param string $typeId account type
 | 
			
		||||
 * @param string $name Name of definition to delete
 | 
			
		||||
 *
 | 
			
		||||
 * @param string $serverProfileName server profile name
 | 
			
		||||
 * @return boolean True if file was deleted or false if a problem occurred.
 | 
			
		||||
 */
 | 
			
		||||
function deletePDFStructure($typeId, $name) {
 | 
			
		||||
function deletePDFStructure($typeId, $name, $serverProfileName) {
 | 
			
		||||
	if (!isValidPDFStructureName($name) || !preg_match('/[a-zA-Z]+/',$typeId)) {
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
	$file = dirname(__FILE__) . '/../config/pdf/' . $_SESSION['config']->getName() . '/' . $name . '.' . $typeId . '.xml';
 | 
			
		||||
	$file = dirname(__FILE__) . '/../config/pdf/' . $serverProfileName . '/' . $name . '.' . $typeId . '.xml';
 | 
			
		||||
	if(is_file($file) && is_writable($file)) {
 | 
			
		||||
		return unlink($file);
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -95,11 +97,12 @@ function deletePDFStructure($typeId, $name) {
 | 
			
		|||
/**
 | 
			
		||||
 * This function returns an array with all aviliable logo images.
 | 
			
		||||
 *
 | 
			
		||||
 * @return array list of logo files
 | 
			
		||||
 * @param string $serverProfileName server profile name
 | 
			
		||||
 * @return array list of logo files (array('filename' => PATH, 'infos' => array(width, height)))
 | 
			
		||||
 */
 | 
			
		||||
function getAvailableLogos() {
 | 
			
		||||
function getAvailableLogos($serverProfileName) {
 | 
			
		||||
	$return = array();
 | 
			
		||||
	$dirPath = dirname(__FILE__) . '/../config/pdf/' . $_SESSION['config']->getName() . '/logos/';
 | 
			
		||||
	$dirPath = dirname(__FILE__) . '/../config/pdf/' . $serverProfileName . '/logos/';
 | 
			
		||||
	$dirHandle = opendir($dirPath);
 | 
			
		||||
	while($file = readdir($dirHandle)) {
 | 
			
		||||
		if(!is_dir($file) && $file != '.' && $file != '..' && preg_match('/\\.(jpg|png)$/i',$file)) {
 | 
			
		||||
| 
						 | 
				
			
			@ -120,7 +123,7 @@ function getAvailableLogos() {
 | 
			
		|||
 * @param \LAM\TYPES\ConfiguredType $sourceType source type
 | 
			
		||||
 * @param string $sourceStructureName structure name
 | 
			
		||||
 * @param \LAM\TYPES\ConfiguredType $targetType target type
 | 
			
		||||
 * @throws Exception
 | 
			
		||||
 * @throws LAMException error during copy
 | 
			
		||||
 */
 | 
			
		||||
function copyStructure($sourceType, $sourceStructureName, $targetType) {
 | 
			
		||||
	if (!isValidPDFStructureName($sourceStructureName)) {
 | 
			
		||||
| 
						 | 
				
			
			@ -165,13 +168,17 @@ function copyStructureToTemplates($sourceType, $sourceName) {
 | 
			
		|||
 *
 | 
			
		||||
 * @param String $file full path of temporary file
 | 
			
		||||
 * @param String $name file name
 | 
			
		||||
 * @return StatusMessage status message to display
 | 
			
		||||
 * @param string $serverProfileName server profile name
 | 
			
		||||
 * @return htmlStatusMessage status message to display
 | 
			
		||||
 */
 | 
			
		||||
function uploadPDFLogo($file, $name) {
 | 
			
		||||
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".'));
 | 
			
		||||
	}
 | 
			
		||||
	$dirPath = dirname(__FILE__) . '/../config/pdf/' . $_SESSION['config']->getName() . '/logos/';
 | 
			
		||||
	if ($serverProfileName === GLOBAL_PROFILE) {
 | 
			
		||||
		$serverProfileName = '../templates/pdf';
 | 
			
		||||
	}
 | 
			
		||||
	$dirPath = dirname(__FILE__) . '/../config/pdf/' . $serverProfileName . '/logos/';
 | 
			
		||||
	$success = copy($file, $dirPath . '/' . $name);
 | 
			
		||||
	if ($success) {
 | 
			
		||||
		return new htmlStatusMessage('INFO', _('Uploaded logo file.'), $name);
 | 
			
		||||
| 
						 | 
				
			
			@ -185,12 +192,13 @@ function uploadPDFLogo($file, $name) {
 | 
			
		|||
 * Deletes a PDF logo file.
 | 
			
		||||
 *
 | 
			
		||||
 * @param String $name file name
 | 
			
		||||
 * @param string $serverProfileName server profile name
 | 
			
		||||
 * @return StatusMessage status message to display
 | 
			
		||||
 */
 | 
			
		||||
function deletePDFLogo($name) {
 | 
			
		||||
function deletePDFLogo($name, $serverProfileName) {
 | 
			
		||||
	// check if valid file
 | 
			
		||||
	$found = false;
 | 
			
		||||
	$logos = getAvailableLogos();
 | 
			
		||||
	$logos = getAvailableLogos($serverProfileName);
 | 
			
		||||
	foreach ($logos as $logo) {
 | 
			
		||||
		if ($logo['filename'] === $name) {
 | 
			
		||||
			$found = true;
 | 
			
		||||
| 
						 | 
				
			
			@ -203,9 +211,9 @@ function deletePDFLogo($name) {
 | 
			
		|||
	// check if still in use
 | 
			
		||||
	$typeManager = new \LAM\TYPES\TypeManager();
 | 
			
		||||
	$activeTypes = $typeManager->getConfiguredTypes();
 | 
			
		||||
	$reader = new PDFStructureReader();
 | 
			
		||||
	$reader = new PDFStructureReader($serverProfileName);
 | 
			
		||||
	foreach ($activeTypes as $type) {
 | 
			
		||||
		$structures = getPDFStructures($type->getId());
 | 
			
		||||
		$structures = getPDFStructures($type->getId(), $serverProfileName);
 | 
			
		||||
		foreach ($structures as $structure) {
 | 
			
		||||
			try {
 | 
			
		||||
				$data = $reader->read($type->getId(), $structure);
 | 
			
		||||
| 
						 | 
				
			
			@ -220,7 +228,7 @@ function deletePDFLogo($name) {
 | 
			
		|||
		}
 | 
			
		||||
	}
 | 
			
		||||
	// delete file
 | 
			
		||||
	$dirPath = dirname(__FILE__) . '/../config/pdf/' . $_SESSION['config']->getName() . '/logos/';
 | 
			
		||||
	$dirPath = dirname(__FILE__) . '/../config/pdf/' . $serverProfileName . '/logos/';
 | 
			
		||||
	$success = @unlink($dirPath . '/' . $name);
 | 
			
		||||
	if ($success) {
 | 
			
		||||
		return new htmlStatusMessage('INFO', _('Logo file deleted.'), $name);
 | 
			
		||||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			@ -301,6 +351,22 @@ function installPDFTemplates() {
 | 
			
		|||
 */
 | 
			
		||||
class PDFStructureReader {
 | 
			
		||||
 | 
			
		||||
	private $serverProfileName;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Constructor.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param $serverProfileName server profile name
 | 
			
		||||
	 */
 | 
			
		||||
	public function __construct($serverProfileName) {
 | 
			
		||||
		if ($serverProfileName === GLOBAL_PROFILE) {
 | 
			
		||||
			$this->serverProfileName = '../templates/pdf';
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			$this->serverProfileName = $serverProfileName;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Reads a PDF structure.
 | 
			
		||||
	 *
 | 
			
		||||
| 
						 | 
				
			
			@ -324,7 +390,7 @@ class PDFStructureReader {
 | 
			
		|||
	 * @return string file name
 | 
			
		||||
	 */
 | 
			
		||||
	protected function getFileName($typeId, $name) {
 | 
			
		||||
		return dirname(__FILE__) . '/../config/pdf/' . $_SESSION['config']->getName() . '/' . $name . '.' . $typeId . '.xml';
 | 
			
		||||
		return dirname(__FILE__) . '/../config/pdf/' . $this->serverProfileName . '/' . $name . '.' . $typeId . '.xml';
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
| 
						 | 
				
			
			@ -334,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();
 | 
			
		||||
| 
						 | 
				
			
			@ -411,12 +478,29 @@ class PDFStructureReader {
 | 
			
		|||
 */
 | 
			
		||||
class PDFStructureWriter {
 | 
			
		||||
 | 
			
		||||
	private $serverProfileName;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Constructor.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param string $serverProfileName server profile name
 | 
			
		||||
	 */
 | 
			
		||||
	public function __construct($serverProfileName) {
 | 
			
		||||
		if ($serverProfileName === GLOBAL_PROFILE) {
 | 
			
		||||
			$this->serverProfileName = '../templates/pdf';
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			$this->serverProfileName = $serverProfileName;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Writes the PDF structure to disk.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param string $typeId type ID
 | 
			
		||||
	 * @param string $name structure name
 | 
			
		||||
	 * @param PDFStructure $structure structure
 | 
			
		||||
	 * @throws LAMException error during write
 | 
			
		||||
	 */
 | 
			
		||||
	public function write($typeId, $name, $structure) {
 | 
			
		||||
		$fileName = $this->getFileName($typeId, $name);
 | 
			
		||||
| 
						 | 
				
			
			@ -430,16 +514,18 @@ class PDFStructureWriter {
 | 
			
		|||
	 * @param string $typeId type ID
 | 
			
		||||
	 * @param string $name structure name
 | 
			
		||||
	 * @return string file name
 | 
			
		||||
	 * @throws LAMException file not valid or not writable
 | 
			
		||||
	 */
 | 
			
		||||
	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.'));
 | 
			
		||||
		$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/' . $_SESSION['config']->getName() . '/' . $name . '.' . $typeId . '.xml';
 | 
			
		||||
		return $baseDir . '/' . $name . '.' . $typeId . '.xml';
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
| 
						 | 
				
			
			@ -488,6 +574,7 @@ class PDFStructureWriter {
 | 
			
		|||
	 *
 | 
			
		||||
	 * @param string $xml XML
 | 
			
		||||
	 * @param string $file file name
 | 
			
		||||
	 * @throws LAMException error during write
 | 
			
		||||
	 */
 | 
			
		||||
	protected function writeXML($xml, $file) {
 | 
			
		||||
		$handle = @fopen($file,'w');
 | 
			
		||||
| 
						 | 
				
			
			@ -520,6 +607,57 @@ class PDFStructure {
 | 
			
		|||
 | 
			
		||||
	private $sections = array();
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Returns an array representation of the structure.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @return array export data
 | 
			
		||||
	 */
 | 
			
		||||
	public function export() {
 | 
			
		||||
		$data = array();
 | 
			
		||||
		$data['title'] = $this->title;
 | 
			
		||||
		$data['foldingMarks'] = $this->foldingMarks;
 | 
			
		||||
		$data['logo'] = $this->logo;
 | 
			
		||||
		$data['sections'] = array();
 | 
			
		||||
		foreach($this->sections as $section) {
 | 
			
		||||
			$type = ($section instanceof PDFTextSection) ? 'text' : 'entry';
 | 
			
		||||
			$sectionData = $section->export();
 | 
			
		||||
			$data['sections'][] = array(
 | 
			
		||||
				'type' => $type,
 | 
			
		||||
				'data' => $sectionData
 | 
			
		||||
			);
 | 
			
		||||
		}
 | 
			
		||||
		return $data;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Imports an array representation of the structure.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param array $data import data
 | 
			
		||||
	 */
 | 
			
		||||
	public function import($data) {
 | 
			
		||||
		if (isset($data['title'])) {
 | 
			
		||||
			$this->title = $data['title'];
 | 
			
		||||
		}
 | 
			
		||||
		if (isset($data['foldingMarks'])) {
 | 
			
		||||
			$this->foldingMarks = $data['foldingMarks'];
 | 
			
		||||
		}
 | 
			
		||||
		if (isset($data['logo'])) {
 | 
			
		||||
			$this->logo = $data['logo'];
 | 
			
		||||
		}
 | 
			
		||||
		if (isset($data['sections'])) {
 | 
			
		||||
			foreach($data['sections'] as $section) {
 | 
			
		||||
				if ($section['type'] === 'text') {
 | 
			
		||||
					$this->sections[] = new PDFTextSection($section['data']);
 | 
			
		||||
				}
 | 
			
		||||
				else {
 | 
			
		||||
					$entrySection = new PDFEntrySection(null);
 | 
			
		||||
					$entrySection->import($section['data']);
 | 
			
		||||
					$this->sections[] = $entrySection;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Returns the logo file path.
 | 
			
		||||
	 *
 | 
			
		||||
| 
						 | 
				
			
			@ -612,6 +750,15 @@ class PDFTextSection {
 | 
			
		|||
		$this->text = $text;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Exports the section.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @return string text
 | 
			
		||||
	 */
 | 
			
		||||
	public function export() {
 | 
			
		||||
		return $this->getText();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Returns the text.
 | 
			
		||||
	 *
 | 
			
		||||
| 
						 | 
				
			
			@ -631,7 +778,7 @@ class PDFTextSection {
 | 
			
		|||
class PDFEntrySection {
 | 
			
		||||
 | 
			
		||||
	private $title;
 | 
			
		||||
	private $entries;
 | 
			
		||||
	private $entries = array();
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Constructor
 | 
			
		||||
| 
						 | 
				
			
			@ -642,6 +789,37 @@ class PDFEntrySection {
 | 
			
		|||
		$this->title = $title;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Exports the section.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @return array export data
 | 
			
		||||
	 */
 | 
			
		||||
	public function export() {
 | 
			
		||||
		$data = array();
 | 
			
		||||
		$data['title'] = $this->title;
 | 
			
		||||
		$data['entries'] = array();
 | 
			
		||||
		foreach($this->getEntries() as $entry) {
 | 
			
		||||
			$data['entries'][] = $entry->getKey();
 | 
			
		||||
		}
 | 
			
		||||
		return $data;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Imports the section.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param array $data import data
 | 
			
		||||
	 */
 | 
			
		||||
	public function import($data) {
 | 
			
		||||
		if (isset($data['title'])) {
 | 
			
		||||
			$this->title = $data['title'];
 | 
			
		||||
		}
 | 
			
		||||
		if ($data['entries']) {
 | 
			
		||||
			foreach($data['entries'] as $entry) {
 | 
			
		||||
				$this->entries[] = new PDFSectionEntry($entry);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Returns if the title is an attribute value.
 | 
			
		||||
	 *
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,652 @@
 | 
			
		|||
<?php
 | 
			
		||||
namespace LAM\PERSISTENCE;
 | 
			
		||||
use LAM\PDF\PDFStructure;
 | 
			
		||||
use LAM\PDF\PDFStructureReader;
 | 
			
		||||
use LAM\PDF\PDFStructureWriter;
 | 
			
		||||
use LAMCfgMain;
 | 
			
		||||
use LAMConfig;
 | 
			
		||||
use LAMException;
 | 
			
		||||
use selfServiceProfile;
 | 
			
		||||
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;
 | 
			
		||||
use function LAM\PROFILES\installTemplateAccountProfile;
 | 
			
		||||
use function LAM\PROFILES\loadAccountProfile;
 | 
			
		||||
use function LAM\PROFILES\loadTemplateAccountProfile;
 | 
			
		||||
use function LAM\PROFILES\saveAccountProfile;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
  This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
 | 
			
		||||
  Copyright (C) 2020  Roland Gruber
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This file includes functions to manage the persistence of LAM's configuration files.
 | 
			
		||||
 *
 | 
			
		||||
 * @package configuration
 | 
			
		||||
 * @author Roland Gruber
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
include_once __DIR__ . '/config.inc';
 | 
			
		||||
include_once __DIR__ . '/profiles.inc';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Exporter for LAM's configuration data.
 | 
			
		||||
 */
 | 
			
		||||
class ConfigDataExporter {
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Exports LAM's configuration data in JSON format.
 | 
			
		||||
	 * @throws LAMException error during export
 | 
			
		||||
	 */
 | 
			
		||||
	public function exportAsJson() {
 | 
			
		||||
		$mainCfg = $this->_getMainConfiguration();
 | 
			
		||||
		$jsonData = array();
 | 
			
		||||
		$jsonData['mainConfig'] = $this->_getMainConfigData($mainCfg);
 | 
			
		||||
		$jsonData['certificates'] = $this->_getCertificates($mainCfg);
 | 
			
		||||
		$serverProfileNames = getConfigProfiles();
 | 
			
		||||
		$serverProfiles = array();
 | 
			
		||||
		foreach ($serverProfileNames as $serverProfileName) {
 | 
			
		||||
			$serverProfiles[$serverProfileName] = new \LAMConfig($serverProfileName);
 | 
			
		||||
		}
 | 
			
		||||
		$jsonData['serverProfiles'] = $this->_getServerProfiles($serverProfiles);
 | 
			
		||||
		$jsonData['accountProfiles'] = $this->_getAccountProfiles($serverProfiles);
 | 
			
		||||
		$jsonData['accountProfileTemplates'] = $this->_getAccountProfileTemplates();
 | 
			
		||||
		$jsonData['pdfProfiles'] = $this->_getPdfProfiles($serverProfiles);
 | 
			
		||||
		$jsonData['pdfProfileTemplates'] = $this->_getPdfProfileTemplates();
 | 
			
		||||
		$jsonData['selfServiceProfiles'] = $this->_getSelfServiceProfiles();
 | 
			
		||||
		/**
 | 
			
		||||
		 * TODO
 | 
			
		||||
		 *
 | 
			
		||||
		 * webauthn
 | 
			
		||||
		 */
 | 
			
		||||
		return json_encode($jsonData);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Returns the main configuration.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @return LAMCfgMain main config
 | 
			
		||||
	 */
 | 
			
		||||
	public function _getMainConfiguration() {
 | 
			
		||||
		return new LAMCfgMain();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Internal function to read master configuration.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param LAMCfgMain $mainCfg main config
 | 
			
		||||
	 * @return array data
 | 
			
		||||
	 */
 | 
			
		||||
	public function _getMainConfigData($mainCfg) {
 | 
			
		||||
		return $mainCfg->exportData();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Returns the certificate file content.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param LAMCfgMain $mainCfg main config
 | 
			
		||||
	 * @return array data
 | 
			
		||||
	 */
 | 
			
		||||
	public function _getCertificates($mainCfg) {
 | 
			
		||||
		return $mainCfg->exportCertificates();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Returns the content of the server profiles.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param array $serverProfiles list of server profiles (name => object)
 | 
			
		||||
	 * @return array $data
 | 
			
		||||
	 */
 | 
			
		||||
	public function _getServerProfiles($serverProfiles) {
 | 
			
		||||
		$data = array();
 | 
			
		||||
		foreach ($serverProfiles as $profileName => $serverProfile) {
 | 
			
		||||
			$data[$profileName] = $serverProfile->exportData();
 | 
			
		||||
		}
 | 
			
		||||
		return $data;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Returns the content of the account profiles.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param array $serverProfiles list of server profiles (name => object)
 | 
			
		||||
	 * @return array $data
 | 
			
		||||
	 */
 | 
			
		||||
	public function _getAccountProfiles($serverProfiles) {
 | 
			
		||||
		$data = array();
 | 
			
		||||
		foreach ($serverProfiles as $profileName => $serverProfile) {
 | 
			
		||||
			foreach ($serverProfile->get_ActiveTypes() as $typeId) {
 | 
			
		||||
				$accountProfileNames = getAccountProfiles($typeId, $profileName);
 | 
			
		||||
				foreach ($accountProfileNames as $accountProfileName) {
 | 
			
		||||
					$accountProfile = loadAccountProfile($accountProfileName, $typeId, $profileName);
 | 
			
		||||
					$data[$profileName][$typeId][$accountProfileName] = $accountProfile;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return $data;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Returns the content of the account profile templates.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @return array $data
 | 
			
		||||
	 * @throws LAMException error reading template
 | 
			
		||||
	 */
 | 
			
		||||
	public function _getAccountProfileTemplates() {
 | 
			
		||||
		$data = array();
 | 
			
		||||
		$accountProfileTemplateNames = getProfileTemplateNames();
 | 
			
		||||
		foreach ($accountProfileTemplateNames as $scope => $templateNames) {
 | 
			
		||||
			foreach ($templateNames as $templateName) {
 | 
			
		||||
				$accountProfileTemplate = loadTemplateAccountProfile($templateName, $scope);
 | 
			
		||||
				$data[$scope][$templateName] = $accountProfileTemplate;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return $data;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Returns the content of the PDF profiles.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param array $serverProfiles list of server profiles (name => object)
 | 
			
		||||
	 * @return array $data
 | 
			
		||||
	 */
 | 
			
		||||
	public function _getPdfProfiles($serverProfiles) {
 | 
			
		||||
		$data = array();
 | 
			
		||||
		foreach ($serverProfiles as $profileName => $serverProfile) {
 | 
			
		||||
			foreach ($serverProfile->get_ActiveTypes() as $typeId) {
 | 
			
		||||
				$pdfProfileNames = getPDFStructures($typeId, $profileName);
 | 
			
		||||
				$reader = new PDFStructureReader($profileName);
 | 
			
		||||
				foreach ($pdfProfileNames as $pdfProfileName) {
 | 
			
		||||
					$pdfStructure = $reader->read($typeId, $pdfProfileName);
 | 
			
		||||
					$data[$profileName]['structures'][$typeId][$pdfProfileName] = $pdfStructure->export();
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			$logoData = getAvailableLogos($profileName);
 | 
			
		||||
			foreach ($logoData as $logo) {
 | 
			
		||||
				$logoFileName = $logo['filename'];
 | 
			
		||||
				$logoPath = __DIR__ . '/../config/pdf/' . $profileName . '/logos/' . $logoFileName;
 | 
			
		||||
				$handle = fopen($logoPath, 'r');
 | 
			
		||||
				$logoBinary = fread($handle, 100000000);
 | 
			
		||||
				fclose($handle);
 | 
			
		||||
				$data[$profileName]['logos'][$logoFileName] = base64_encode($logoBinary);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		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;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Returns the content of the self service profiles.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @return array data
 | 
			
		||||
	 */
 | 
			
		||||
	public function _getSelfServiceProfiles() {
 | 
			
		||||
		$data = array();
 | 
			
		||||
		$profileTypes = getSelfServiceProfiles();
 | 
			
		||||
		foreach ($profileTypes as $profileType => $profileNames) {
 | 
			
		||||
			foreach ($profileNames as $profileName) {
 | 
			
		||||
				$profile = loadSelfServiceProfile($profileName, $profileType);
 | 
			
		||||
				if ($profile === false) {
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
				$data[$profileType][$profileName] = $profile->export();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return $data;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Importer for LAM's configuration data.
 | 
			
		||||
 */
 | 
			
		||||
class ConfigDataImporter {
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Returns a list of possible import objects.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param string $json JSON data
 | 
			
		||||
	 * @return ImporterStep[] steps
 | 
			
		||||
	 * @throws LAMException if invalid format
 | 
			
		||||
	 */
 | 
			
		||||
	public function getPossibleImportSteps($json) {
 | 
			
		||||
		$data = json_decode($json, true);
 | 
			
		||||
		if ($data === null) {
 | 
			
		||||
			throw new LAMException(_('Unable to read import file.'));
 | 
			
		||||
		}
 | 
			
		||||
		$steps = array();
 | 
			
		||||
		foreach ($data as $key => $value) {
 | 
			
		||||
			switch ($key) {
 | 
			
		||||
				case 'mainConfig':
 | 
			
		||||
					$steps[] = new ImporterStep(_('General settings'), 'mainConfig', $value);
 | 
			
		||||
					break;
 | 
			
		||||
				case 'certificates':
 | 
			
		||||
					$steps[] = new ImporterStep(_('SSL certificates'), 'certificates', $value);
 | 
			
		||||
					break;
 | 
			
		||||
				case 'serverProfiles':
 | 
			
		||||
					$mainStep = new ImporterStep(_('Server profiles'), 'serverProfiles', $value);
 | 
			
		||||
					foreach ($value as $profileName => $profileData) {
 | 
			
		||||
						$mainStep->addSubStep(new ImporterStep($profileName, 'serverProfile_' . $profileName, $profileData));
 | 
			
		||||
					}
 | 
			
		||||
					$steps[] = $mainStep;
 | 
			
		||||
					break;
 | 
			
		||||
				case 'accountProfiles':
 | 
			
		||||
					$mainStep = new ImporterStep(_('Account profiles'), 'accountProfiles', $value);
 | 
			
		||||
					foreach ($value as $profileName => $profileData) {
 | 
			
		||||
						$mainStep->addSubStep(new ImporterStep($profileName, 'accountProfile_' . $profileName, $profileData));
 | 
			
		||||
					}
 | 
			
		||||
					$steps[] = $mainStep;
 | 
			
		||||
					break;
 | 
			
		||||
				case 'accountProfileTemplates':
 | 
			
		||||
					$steps[] = new ImporterStep(_('Account profiles') . ' - ' . _('Global templates'), 'accountProfileTemplates', $value);
 | 
			
		||||
					break;
 | 
			
		||||
				case 'pdfProfiles':
 | 
			
		||||
					$mainStep = new ImporterStep(_('PDF structures'), 'pdfProfiles', $value);
 | 
			
		||||
					foreach ($value as $profileName => $profileData) {
 | 
			
		||||
						$mainStep->addSubStep(new ImporterStep($profileName, 'pdfProfile_' . $profileName, $profileData));
 | 
			
		||||
					}
 | 
			
		||||
					$steps[] = $mainStep;
 | 
			
		||||
					break;
 | 
			
		||||
				case 'pdfProfileTemplates':
 | 
			
		||||
					$steps[] = new ImporterStep(_('PDF structures') . ' - ' . _('Global templates'), 'pdfProfileTemplates', $value);
 | 
			
		||||
					break;
 | 
			
		||||
				case 'selfServiceProfiles':
 | 
			
		||||
					$steps[] = new ImporterStep(_('Self service profiles'), 'selfServiceProfiles', $value);
 | 
			
		||||
					break;
 | 
			
		||||
				default:
 | 
			
		||||
					logNewMessage(LOG_WARNING, 'Unknown import type: ' . $key);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (empty($steps)) {
 | 
			
		||||
			throw new LAMException(_('Unable to read import file.'));
 | 
			
		||||
		}
 | 
			
		||||
		return $steps;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Runs the actual import.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param ImporterStep[] $steps import steps
 | 
			
		||||
	 * @throws LAMException if error occurred
 | 
			
		||||
	 */
 | 
			
		||||
	public function runImport($steps) {
 | 
			
		||||
		foreach ($steps as $step) {
 | 
			
		||||
			if (!$step->isActive()) {
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			$key = $step->getKey();
 | 
			
		||||
			switch ($key) {
 | 
			
		||||
				case 'mainConfig':
 | 
			
		||||
					$this->importMainConfig($step->getValue());
 | 
			
		||||
					break;
 | 
			
		||||
				case 'certificates':
 | 
			
		||||
					$this->importCertificates($step->getValue());
 | 
			
		||||
					break;
 | 
			
		||||
				case 'serverProfiles':
 | 
			
		||||
					$this->importServerProfiles($step);
 | 
			
		||||
					break;
 | 
			
		||||
				case 'accountProfiles':
 | 
			
		||||
					$this->importAccountProfiles($step);
 | 
			
		||||
					break;
 | 
			
		||||
				case 'accountProfileTemplates':
 | 
			
		||||
					$this->importAccountProfileTemplates($step);
 | 
			
		||||
					break;
 | 
			
		||||
				case 'pdfProfiles':
 | 
			
		||||
					$this->importPdfProfiles($step);
 | 
			
		||||
					break;
 | 
			
		||||
				case 'pdfProfileTemplates':
 | 
			
		||||
					$this->importPdfProfileTemplates($step);
 | 
			
		||||
					break;
 | 
			
		||||
				case 'selfServiceProfiles':
 | 
			
		||||
					$this->importSelfServiceProfiles($step);
 | 
			
		||||
					break;
 | 
			
		||||
				default:
 | 
			
		||||
					logNewMessage(LOG_WARNING, 'Unknown import type: ' . $key);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Imports the main configuration.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param array $data main config data
 | 
			
		||||
	 * @throws LAMException error during import
 | 
			
		||||
	 */
 | 
			
		||||
	private function importMainConfig($data) {
 | 
			
		||||
		$cfgMain = new LAMCfgMain();
 | 
			
		||||
		$cfgMain->importData($data);
 | 
			
		||||
		$cfgMain->save();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Imports the SSL certificates.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param null|string $data file content
 | 
			
		||||
	 * @throws LAMException error during import
 | 
			
		||||
	 */
 | 
			
		||||
	private function importCertificates($data) {
 | 
			
		||||
		$cfgMain = new LAMCfgMain();
 | 
			
		||||
		$cfgMain->importCertificates($data);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Imports the server profiles.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param ImporterStep $step step
 | 
			
		||||
	 * @throws LAMException error during import
 | 
			
		||||
	 */
 | 
			
		||||
	private function importServerProfiles($step) {
 | 
			
		||||
		$failedProfiles = array();
 | 
			
		||||
		foreach ($step->getSubSteps() as $profileStep) {
 | 
			
		||||
			if (!$profileStep->isActive()) {
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			$data = $profileStep->getValue();
 | 
			
		||||
			$profileName = str_replace('serverProfile_', '', $profileStep->getKey());
 | 
			
		||||
			$serverProfile = new LAMConfig($profileName);
 | 
			
		||||
			$serverProfile->importData($data);
 | 
			
		||||
			$result = $serverProfile->save();
 | 
			
		||||
			if ($result === LAMConfig::SAVE_FAIL) {
 | 
			
		||||
				$failedProfiles[] = $profileName;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (!empty($failedProfiles)) {
 | 
			
		||||
			throw new LAMException(_('Unable to save server profile.'), implode(', ', $failedProfiles));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Imports the account profiles.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param ImporterStep $step step
 | 
			
		||||
	 * @throws LAMException error during import
 | 
			
		||||
	 */
 | 
			
		||||
	private function importAccountProfiles($step) {
 | 
			
		||||
		$failedProfiles = array();
 | 
			
		||||
		foreach ($step->getSubSteps() as $profileStep) {
 | 
			
		||||
			if (!$profileStep->isActive()) {
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			$data = $profileStep->getValue();
 | 
			
		||||
			$serverProfileName = str_replace('accountProfile_', '', $profileStep->getKey());
 | 
			
		||||
			$serverProfile = new LAMConfig($serverProfileName);
 | 
			
		||||
			foreach ($data as $typeId => $accountProfiles) {
 | 
			
		||||
				foreach ($accountProfiles as $accountProfileName => $accountProfileData) {
 | 
			
		||||
					$result = saveAccountProfile($accountProfileData, $accountProfileName, $typeId, $serverProfile);
 | 
			
		||||
					if (!$result) {
 | 
			
		||||
						$failedProfiles[] = $serverProfileName . ':' . $typeId . ':' . $accountProfileName;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (!empty($failedProfiles)) {
 | 
			
		||||
			throw new LAMException(_('Unable to save account profile.'), implode(', ', $failedProfiles));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Imports the account profile templates.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param ImporterStep $step step
 | 
			
		||||
	 * @throws LAMException error during import
 | 
			
		||||
	 */
 | 
			
		||||
	private function importAccountProfileTemplates($step) {
 | 
			
		||||
		$data = $step->getValue();
 | 
			
		||||
		foreach ($data as $typeId => $accountProfileTemplates) {
 | 
			
		||||
			foreach ($accountProfileTemplates as $accountProfileTemplateName => $accountProfileData) {
 | 
			
		||||
				installTemplateAccountProfile($typeId, $accountProfileTemplateName, $accountProfileData);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Imports the PDF profiles.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param ImporterStep $step step
 | 
			
		||||
	 * @throws LAMException error during import
 | 
			
		||||
	 */
 | 
			
		||||
	private function importPdfProfiles($step) {
 | 
			
		||||
		$failedProfiles = array();
 | 
			
		||||
		foreach ($step->getSubSteps() as $profileStep) {
 | 
			
		||||
			if (!$profileStep->isActive()) {
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			$data = $profileStep->getValue();
 | 
			
		||||
			$serverProfileName = str_replace('pdfProfile_', '', $profileStep->getKey());
 | 
			
		||||
			if (isset($data['structures'])) {
 | 
			
		||||
				$writer = new PDFStructureWriter($serverProfileName);
 | 
			
		||||
				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) {
 | 
			
		||||
							logNewMessage(LOG_ERR, $e->getTitle() . ' ' . $e->getMessage());
 | 
			
		||||
							$failedProfiles[] = $serverProfileName . ':' . $typeId . ':' . $pdfProfileName;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			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);
 | 
			
		||||
					uploadPDFLogo($tempFilePath, $logoFileName, $serverProfileName);
 | 
			
		||||
					unlink($tempFilePath);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (!empty($failedProfiles)) {
 | 
			
		||||
			throw new LAMException(_('Could not save PDF structure, access denied.'), implode(', ', $failedProfiles));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * 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));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Imports the self service profiles.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param ImporterStep $step importer step
 | 
			
		||||
	 * @throws LAMException error saving profiles
 | 
			
		||||
	 */
 | 
			
		||||
	private function importSelfServiceProfiles($step) {
 | 
			
		||||
		$failedNames = array();
 | 
			
		||||
		$data = $step->getValue();
 | 
			
		||||
		foreach ($data as $typeId => $profileData) {
 | 
			
		||||
			foreach ($profileData as $profileName => $currentProfileData) {
 | 
			
		||||
				$profile = selfServiceProfile::import($currentProfileData);
 | 
			
		||||
				$result = saveSelfServiceProfile($profileName, $typeId, $profile);
 | 
			
		||||
				if (!$result) {
 | 
			
		||||
					$failedNames[] = $profileName;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if (!empty($failedNames)) {
 | 
			
		||||
			throw new LAMException(_('Unable to save profile!'), implode(', ', $failedNames));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Step of the import process.
 | 
			
		||||
 */
 | 
			
		||||
class ImporterStep {
 | 
			
		||||
 | 
			
		||||
	private $label;
 | 
			
		||||
	private $key;
 | 
			
		||||
	private $value;
 | 
			
		||||
	private $active = false;
 | 
			
		||||
	private $subSteps = array();
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Constructor.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param string $label label
 | 
			
		||||
	 * @param string $key key
 | 
			
		||||
	 * @param array $value value
 | 
			
		||||
	 */
 | 
			
		||||
	public function __construct($label, $key, $value) {
 | 
			
		||||
		$this->label = $label;
 | 
			
		||||
		$this->key = $key;
 | 
			
		||||
		$this->value = $value;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Returns the label.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @return string label
 | 
			
		||||
	 */
 | 
			
		||||
	public function getLabel() {
 | 
			
		||||
		return $this->label;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Returns the key.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @return string key
 | 
			
		||||
	 */
 | 
			
		||||
	public function getKey() {
 | 
			
		||||
		return $this->key;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Returns if this step should be executed.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @return bool active
 | 
			
		||||
	 */
 | 
			
		||||
	public function isActive(): bool {
 | 
			
		||||
		return $this->active;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Sets if this step should be executed.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param bool $active active
 | 
			
		||||
	 */
 | 
			
		||||
	public function setActive(bool $active) {
 | 
			
		||||
		$this->active = $active;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Returns the value.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @return string value
 | 
			
		||||
	 */
 | 
			
		||||
	public function getValue() {
 | 
			
		||||
		return $this->value;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Adds a sub-step.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param ImporterStep $subStep sub-step
 | 
			
		||||
	 */
 | 
			
		||||
	public function addSubStep($subStep) {
 | 
			
		||||
		$this->subSteps[] = $subStep;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Returns the sub-steps.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @return ImporterStep[] sub-steps
 | 
			
		||||
	 */
 | 
			
		||||
	public function getSubSteps() {
 | 
			
		||||
		return $this->subSteps;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,5 +1,6 @@
 | 
			
		|||
<?php
 | 
			
		||||
namespace LAM\PROFILES;
 | 
			
		||||
use LAM\TYPES\TypeManager;
 | 
			
		||||
use \LAMException;
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -45,7 +46,6 @@ function getAccountProfiles($typeId, $profile = null) {
 | 
			
		|||
	$dir = @dir(dirname(__FILE__) . "/../config/profiles/" . $profile);
 | 
			
		||||
 | 
			
		||||
	$ret = array();
 | 
			
		||||
	$pos = 0;
 | 
			
		||||
	if ($dir) {
 | 
			
		||||
		$entry = $dir->read();
 | 
			
		||||
		while ($entry){
 | 
			
		||||
| 
						 | 
				
			
			@ -79,30 +79,45 @@ function profileExists($name, $typeId) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
* Loads an profile of the given account type
 | 
			
		||||
*
 | 
			
		||||
* @param string $profile name of the profile (without .<scope> extension)
 | 
			
		||||
* @param string $typeId account type
 | 
			
		||||
* @return array hash array (attribute => value)
 | 
			
		||||
*/
 | 
			
		||||
function loadAccountProfile($profile, $typeId) {
 | 
			
		||||
	$typeManager = new \LAM\TYPES\TypeManager();
 | 
			
		||||
	$type = $typeManager->getConfiguredType($typeId);
 | 
			
		||||
	if (!isValidProfileName($profile) || !preg_match("/^[a-z0-9_]+$/i", $typeId) || ($type == null)) {
 | 
			
		||||
		return false;
 | 
			
		||||
 * Loads an profile of the given account type
 | 
			
		||||
 *
 | 
			
		||||
 * @param string $profile name of the profile (without .<scope> extension)
 | 
			
		||||
 * @param string $typeId account type
 | 
			
		||||
 * @param string $serverProfileName server profile name
 | 
			
		||||
 * @return array hash array (attribute => value)
 | 
			
		||||
 */
 | 
			
		||||
function loadAccountProfile($profile, $typeId, $serverProfileName) {
 | 
			
		||||
	if (!isValidProfileName($profile) || !preg_match("/^[a-z0-9_]+$/i", $typeId)) {
 | 
			
		||||
		logNewMessage(LOG_NOTICE, "Invalid account profile name: $serverProfileName:$profile:$typeId");
 | 
			
		||||
		return array();
 | 
			
		||||
	}
 | 
			
		||||
	$file = substr(__FILE__, 0, strlen(__FILE__) - 17) . "/config/profiles/"  . $serverProfileName . '/' . $profile . "." . $typeId;
 | 
			
		||||
	try {
 | 
			
		||||
		return readAccountProfileFile($file);
 | 
			
		||||
	} catch (LAMException $e) {
 | 
			
		||||
		StatusMessage('ERROR', $e->getTitle(), $e->getMessage());
 | 
			
		||||
	}
 | 
			
		||||
	return array();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Reads an account profile from the given file name.
 | 
			
		||||
 *
 | 
			
		||||
 * @param string $fileName file name
 | 
			
		||||
 * @return array hash array (attribute => value)
 | 
			
		||||
 * @throws LAMException error reading file
 | 
			
		||||
 */
 | 
			
		||||
function readAccountProfileFile($fileName) {
 | 
			
		||||
	$settings = array();
 | 
			
		||||
	$file = substr(__FILE__, 0, strlen(__FILE__) - 17) . "/config/profiles/"  . $_SESSION['config']->getName() . '/' . $profile . "." . $typeId;
 | 
			
		||||
	if (is_file($file)) {
 | 
			
		||||
		$file = @fopen($file, "r");
 | 
			
		||||
	if (is_file($fileName)) {
 | 
			
		||||
		$file = @fopen($fileName, "r");
 | 
			
		||||
		if ($file) {
 | 
			
		||||
			while (!feof($file)) {
 | 
			
		||||
				$line = fgets($file, 1024);
 | 
			
		||||
				if (($line === false) || ($line == "\n") || ($line[0] == "#")) {
 | 
			
		||||
				if (($line === false) || ($line == '') || ($line == "\n") || ($line[0] == "#")) {
 | 
			
		||||
					continue; // ignore comments
 | 
			
		||||
				}
 | 
			
		||||
				// search keywords
 | 
			
		||||
				$parts = array();
 | 
			
		||||
				$parts = explode(": ", $line);
 | 
			
		||||
				if (sizeof($parts) == 2) {
 | 
			
		||||
					$option = $parts[0];
 | 
			
		||||
| 
						 | 
				
			
			@ -113,15 +128,15 @@ function loadAccountProfile($profile, $typeId) {
 | 
			
		|||
				}
 | 
			
		||||
			}
 | 
			
		||||
			fclose($file);
 | 
			
		||||
			return $settings;
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			StatusMessage("ERROR", "", _("Unable to load profile!") . " " . $file);
 | 
			
		||||
			throw new LAMException(_("Unable to load profile!"), $fileName);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		StatusMessage("ERROR", "", _("Unable to load profile!") . " " . $file);
 | 
			
		||||
		throw new LAMException(_("Unable to load profile!"), $fileName);
 | 
			
		||||
	}
 | 
			
		||||
	return $settings;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			@ -132,27 +147,40 @@ function loadAccountProfile($profile, $typeId) {
 | 
			
		|||
* @param array $attributes hash array (attribute => value)
 | 
			
		||||
* @param string $profile name of the account profile (without .<scope> extension)
 | 
			
		||||
* @param string $typeId account type
 | 
			
		||||
 * @param \LAMConfig $serverProfile server profile
 | 
			
		||||
* @return boolean true, if saving succeeded
 | 
			
		||||
*/
 | 
			
		||||
function saveAccountProfile($attributes, $profile, $typeId) {
 | 
			
		||||
	if (!isLoggedIn()) return false;
 | 
			
		||||
function saveAccountProfile($attributes, $profile, $typeId, $serverProfile) {
 | 
			
		||||
	// check profile name and type id
 | 
			
		||||
	$typeManager = new \LAM\TYPES\TypeManager();
 | 
			
		||||
	$typeManager = new TypeManager($serverProfile);
 | 
			
		||||
	$type = $typeManager->getConfiguredType($typeId);
 | 
			
		||||
	if (!isValidProfileName($profile) || !preg_match("/^[a-z0-9_]+$/i", $typeId) || ($type == null)) {
 | 
			
		||||
		logNewMessage(LOG_NOTICE, 'Invalid account profile name: ' . $profile . ':' . $typeId);
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
	if (!is_array($attributes)) {
 | 
			
		||||
		logNewMessage(LOG_NOTICE, 'Invalid account profile data');
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
	$path = substr(__FILE__, 0, strlen(__FILE__) - 17) . "/config/profiles/" . $_SESSION['config']->getName() . '/' . $profile . "." . $typeId;
 | 
			
		||||
	$file = @fopen($path, "w");
 | 
			
		||||
	$path = substr(__FILE__, 0, strlen(__FILE__) - 17) . "/config/profiles/" . $serverProfile->getName() . '/' . $profile . "." . $typeId;
 | 
			
		||||
	return writeProfileDataToFile($path, $attributes);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Writes the profile data to the given file.
 | 
			
		||||
 *
 | 
			
		||||
 * @param string $fileName file name
 | 
			
		||||
 * @param array $data profile data
 | 
			
		||||
 * @return bool writing was ok
 | 
			
		||||
 */
 | 
			
		||||
function writeProfileDataToFile($fileName, $data) {
 | 
			
		||||
	$file = @fopen($fileName, "w");
 | 
			
		||||
	if ($file) {
 | 
			
		||||
  	// write attributes
 | 
			
		||||
		$keys = array_keys($attributes);
 | 
			
		||||
		// write attributes
 | 
			
		||||
		$keys = array_keys($data);
 | 
			
		||||
		for ($i = 0; $i < sizeof($keys); $i++) {
 | 
			
		||||
			if (isset($attributes[$keys[$i]])) {
 | 
			
		||||
				$line = $keys[$i] . ": " . implode("+::+", $attributes[$keys[$i]]) . "\n";
 | 
			
		||||
			if (isset($data[$keys[$i]])) {
 | 
			
		||||
				$line = $keys[$i] . ": " . implode("+::+", $data[$keys[$i]]) . "\n";
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				$line = $keys[$i] . ": \n";
 | 
			
		||||
| 
						 | 
				
			
			@ -163,6 +191,7 @@ function saveAccountProfile($attributes, $profile, $typeId) {
 | 
			
		|||
		fclose($file);
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		logNewMessage(LOG_NOTICE, 'Unable to open account profile file: ' . $fileName);
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
	return true;
 | 
			
		||||
| 
						 | 
				
			
			@ -179,7 +208,7 @@ function delAccountProfile($file, $typeId) {
 | 
			
		|||
	if (!isLoggedIn()) {
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
	$typeManager = new \LAM\TYPES\TypeManager();
 | 
			
		||||
	$typeManager = new TypeManager();
 | 
			
		||||
	$type = $typeManager->getConfiguredType($typeId);
 | 
			
		||||
	if (!isValidProfileName($file) || !preg_match("/^[a-z0-9_]+$/i", $typeId) || ($type == null)) {
 | 
			
		||||
		return false;
 | 
			
		||||
| 
						 | 
				
			
			@ -206,7 +235,7 @@ function isValidProfileName($name) {
 | 
			
		|||
 * @param \LAM\TYPES\ConfiguredType $sourceType source type
 | 
			
		||||
 * @param string $sourceProfileName profile name
 | 
			
		||||
 * @param \LAM\TYPES\ConfiguredType $targetType target type
 | 
			
		||||
 * @throws Exception
 | 
			
		||||
 * @throws LAMException error during copy
 | 
			
		||||
 */
 | 
			
		||||
function copyAccountProfile($sourceType, $sourceProfileName, $targetType) {
 | 
			
		||||
	if (!isValidProfileName($sourceProfileName)) {
 | 
			
		||||
| 
						 | 
				
			
			@ -229,7 +258,7 @@ function copyAccountProfile($sourceType, $sourceProfileName, $targetType) {
 | 
			
		|||
 *
 | 
			
		||||
 * @param \LAM\TYPES\ConfiguredType $sourceType source type
 | 
			
		||||
 * @param string $sourceProfileName profile name
 | 
			
		||||
 * @throws Exception
 | 
			
		||||
 * @throws LAMException error during copy
 | 
			
		||||
 */
 | 
			
		||||
function copyAccountProfileToTemplates($sourceType, $sourceProfileName) {
 | 
			
		||||
	if (!isValidProfileName($sourceProfileName)) {
 | 
			
		||||
| 
						 | 
				
			
			@ -250,7 +279,34 @@ function copyAccountProfileToTemplates($sourceType, $sourceProfileName) {
 | 
			
		|||
 * Installs template profiles to the current server profile.
 | 
			
		||||
 */
 | 
			
		||||
function installProfileTemplates() {
 | 
			
		||||
	$templatePath = dirname(__FILE__) . '/../config/templates/profiles';
 | 
			
		||||
	$allTemplates = getProfileTemplateNames();
 | 
			
		||||
	$basePath = dirname(__FILE__) . '/../config/profiles/' . $_SESSION['config']->getName();
 | 
			
		||||
	if (!file_exists($basePath)) {
 | 
			
		||||
		mkdir($basePath, 0700, true);
 | 
			
		||||
	}
 | 
			
		||||
	$typeManager = new TypeManager();
 | 
			
		||||
	foreach ($typeManager->getConfiguredTypes() as $type) {
 | 
			
		||||
		if (empty($allTemplates[$type->getScope()])) {
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
		foreach ($allTemplates[$type->getScope()] as $templateName) {
 | 
			
		||||
			$path = $basePath . '/' . $templateName . '.' . $type->getId();
 | 
			
		||||
			if (!is_file($path)) {
 | 
			
		||||
				$template = getProfileTemplateFileName($type->getScope(), $templateName);
 | 
			
		||||
				logNewMessage(LOG_DEBUG, 'Copy template ' . $template . ' to ' . $path);
 | 
			
		||||
				@copy($template, $path);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Returns a list of all global profile templates.
 | 
			
		||||
 *
 | 
			
		||||
 * @return array names (array('user' => array('default', 'extra')))
 | 
			
		||||
 */
 | 
			
		||||
function getProfileTemplateNames() {
 | 
			
		||||
	$templatePath = __DIR__ . '/../config/templates/profiles';
 | 
			
		||||
	$templateDir = @dir($templatePath);
 | 
			
		||||
	$allTemplates = array();
 | 
			
		||||
	if ($templateDir) {
 | 
			
		||||
| 
						 | 
				
			
			@ -265,24 +321,54 @@ function installProfileTemplates() {
 | 
			
		|||
			$entry = $templateDir->read();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	$basePath = dirname(__FILE__) . '/../config/profiles/' . $_SESSION['config']->getName();
 | 
			
		||||
	if (!file_exists($basePath)) {
 | 
			
		||||
		mkdir($basePath, 0700, true);
 | 
			
		||||
	return $allTemplates;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Returns the file name of a global template.
 | 
			
		||||
 *
 | 
			
		||||
 * @param string $scope e.g. user
 | 
			
		||||
 * @param string $name profile name
 | 
			
		||||
 * @return string file name
 | 
			
		||||
 */
 | 
			
		||||
function getProfileTemplateFileName($scope, $name) {
 | 
			
		||||
	return __DIR__ . '/../config/templates/profiles' . '/' . $name . '.' . $scope;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Loads a template profile of the given account scope.
 | 
			
		||||
 *
 | 
			
		||||
 * @param string $profile name of the profile (without .<scope> extension)
 | 
			
		||||
 * @param string $scope account type
 | 
			
		||||
 * @return array hash array (attribute => value)
 | 
			
		||||
 * @throws LAMException error reading profile template
 | 
			
		||||
 */
 | 
			
		||||
function loadTemplateAccountProfile($profile, $scope) {
 | 
			
		||||
	if (!isValidProfileName($profile) || !preg_match("/^[a-z0-9_]+$/i", $scope)) {
 | 
			
		||||
		logNewMessage(LOG_NOTICE, "Invalid account profile name: $profile:$scope");
 | 
			
		||||
		return array();
 | 
			
		||||
	}
 | 
			
		||||
	$typeManager = new \LAM\TYPES\TypeManager();
 | 
			
		||||
	foreach ($typeManager->getConfiguredTypes() as $type) {
 | 
			
		||||
		if (empty($allTemplates[$type->getScope()])) {
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
		foreach ($allTemplates[$type->getScope()] as $templateName) {
 | 
			
		||||
			$path = $basePath . '/' . $templateName . '.' . $type->getId();
 | 
			
		||||
			if (!is_file($path)) {
 | 
			
		||||
				$template = $templatePath . '/' . $templateName . '.' . $type->getScope();
 | 
			
		||||
				logNewMessage(LOG_DEBUG, 'Copy template ' . $template . ' to ' . $path);
 | 
			
		||||
				@copy($template, $path);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	$fileName = getProfileTemplateFileName($scope, $profile);
 | 
			
		||||
	return readAccountProfileFile($fileName);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Installs a single template from the given data.
 | 
			
		||||
 *
 | 
			
		||||
 * @param string $scope account type (e.g. user)
 | 
			
		||||
 * @param string $name template name
 | 
			
		||||
 * @param array $data profile data
 | 
			
		||||
 * @throws LAMException error saving file
 | 
			
		||||
 */
 | 
			
		||||
function installTemplateAccountProfile($scope, $name, $data) {
 | 
			
		||||
	if (!isValidProfileName($name) || !preg_match("/^[a-z0-9_]+$/i", $scope)) {
 | 
			
		||||
		logNewMessage(LOG_NOTICE, "Invalid account profile name: $name:$scope");
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	$fileName = getProfileTemplateFileName($scope, $name);
 | 
			
		||||
	$success = writeProfileDataToFile($fileName, $data);
 | 
			
		||||
	if (!$success) {
 | 
			
		||||
		throw new LAMException('Unable to write account profile template: ' . $fileName);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
?>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -170,7 +170,7 @@ function checkSelfServiceOptions($scope, $fields, $attributes, $passwordChangeOn
 | 
			
		|||
/**
 | 
			
		||||
* Returns a list of all available self service profiles (without .conf)
 | 
			
		||||
*
 | 
			
		||||
* @return array profile names (array(<account type> => array(<profile1>, <profile2>, ...)))
 | 
			
		||||
* @return array profile names (array('account type' => array('profile1', 'profile2')))
 | 
			
		||||
*/
 | 
			
		||||
function getSelfServiceProfiles() {
 | 
			
		||||
	$types = LAM\TYPES\getTypes();
 | 
			
		||||
| 
						 | 
				
			
			@ -201,7 +201,7 @@ function getSelfServiceProfiles() {
 | 
			
		|||
*
 | 
			
		||||
* @param string $name profile name
 | 
			
		||||
* @param string $scope account type
 | 
			
		||||
* @return selfServiceProfile|false profile if file was readable, false otherwise
 | 
			
		||||
* @return false|selfServiceProfile profile or false if file was not readable
 | 
			
		||||
*/
 | 
			
		||||
function loadSelfServiceProfile($name, $scope) {
 | 
			
		||||
	if (!preg_match("/^[0-9a-z _-]+$/i", $name) || !preg_match("/^[0-9a-z _-]+$/i", $scope)) {
 | 
			
		||||
| 
						 | 
				
			
			@ -213,7 +213,13 @@ function loadSelfServiceProfile($name, $scope) {
 | 
			
		|||
		$file = @fopen($file, "r");
 | 
			
		||||
		if ($file) {
 | 
			
		||||
			$data = fread($file, 10000000);
 | 
			
		||||
			$profile = unserialize($data);
 | 
			
		||||
			$profileData = @json_decode($data, true);
 | 
			
		||||
			if ($profileData === null) {
 | 
			
		||||
				$profile = unserialize($data);
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				$profile = selfServiceProfile::import($profileData);
 | 
			
		||||
			}
 | 
			
		||||
			fclose($file);
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
| 
						 | 
				
			
			@ -249,7 +255,7 @@ function saveSelfServiceProfile($name, $scope, $profile) {
 | 
			
		|||
	$file = @fopen($path, "w");
 | 
			
		||||
	if ($file) {
 | 
			
		||||
	  	// write settings to file
 | 
			
		||||
		fputs($file, serialize($profile));
 | 
			
		||||
		fputs($file, json_encode($profile->export()));
 | 
			
		||||
		// close file
 | 
			
		||||
		fclose($file);
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -521,6 +527,32 @@ class selfServiceProfile {
 | 
			
		|||
		$this->baseUrl = '';
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Converts the export data back to a self service profile.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @param array $data export data
 | 
			
		||||
	 * @return selfServiceProfile profile
 | 
			
		||||
	 */
 | 
			
		||||
	public static function import($data) {
 | 
			
		||||
		$profile = new selfServiceProfile();
 | 
			
		||||
		$vars = get_class_vars(selfServiceProfile::class);
 | 
			
		||||
		foreach ($data as $key => $value) {
 | 
			
		||||
			if (in_array($key, $vars)) {
 | 
			
		||||
				$profile->$key = $value;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return $profile;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Returns a representation of the self service profile.
 | 
			
		||||
	 *
 | 
			
		||||
	 * @return array self service profile data
 | 
			
		||||
	 */
 | 
			
		||||
	public function export() {
 | 
			
		||||
		return json_decode(json_encode($this), true);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Returns the server's base URL (e.g. https://www.example.com).
 | 
			
		||||
	 *
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -86,6 +86,10 @@ a img {
 | 
			
		|||
	border: 0px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
a.img-padding1 img {
 | 
			
		||||
	padding: 1rem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
a.classicBold {
 | 
			
		||||
	color: blue;
 | 
			
		||||
	text-decoration: none;
 | 
			
		||||
| 
						 | 
				
			
			@ -462,6 +466,10 @@ table.collapse {
 | 
			
		|||
	display: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.display-as-block {
 | 
			
		||||
	display: block;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.nowrap {
 | 
			
		||||
	white-space: nowrap;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -489,7 +497,7 @@ div.smallScroll {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
.fullwidth {
 | 
			
		||||
	width: 100%;
 | 
			
		||||
	width: 100%!important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.halfwidth {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,277 @@
 | 
			
		|||
<?php
 | 
			
		||||
namespace LAM\CONFIG;
 | 
			
		||||
use htmlButton;
 | 
			
		||||
use htmlGroup;
 | 
			
		||||
use htmlInputFileUpload;
 | 
			
		||||
use htmlLink;
 | 
			
		||||
use htmlOutputText;
 | 
			
		||||
use htmlResponsiveInputCheckbox;
 | 
			
		||||
use htmlResponsiveInputField;
 | 
			
		||||
use htmlResponsiveRow;
 | 
			
		||||
use htmlStatusMessage;
 | 
			
		||||
use htmlSubTitle;
 | 
			
		||||
use LAM\PERSISTENCE\ConfigDataExporter;
 | 
			
		||||
use LAM\PERSISTENCE\ConfigDataImporter;
 | 
			
		||||
use LAMCfgMain;
 | 
			
		||||
use LAMException;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
  This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
 | 
			
		||||
  Copyright (C) 2020  Roland Gruber
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
  the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
  (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
  This program is distributed in the hope that it will be useful,
 | 
			
		||||
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
  GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
  You should have received a copy of the GNU General Public License
 | 
			
		||||
  along with this program; if not, write to the Free Software
 | 
			
		||||
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
* Import and export functions for LAM configuration.
 | 
			
		||||
*
 | 
			
		||||
* @package configuration
 | 
			
		||||
* @author Roland Gruber
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/** Access to persistence functions */
 | 
			
		||||
include_once('../../lib/persistence.inc');
 | 
			
		||||
 | 
			
		||||
// start session
 | 
			
		||||
if (strtolower(session_module_name()) == 'files') {
 | 
			
		||||
	session_save_path("../../sess");
 | 
			
		||||
}
 | 
			
		||||
lam_start_session();
 | 
			
		||||
 | 
			
		||||
setlanguage();
 | 
			
		||||
 | 
			
		||||
if (!isset($_SESSION['cfgMain'])) {
 | 
			
		||||
	$cfg = new LAMCfgMain();
 | 
			
		||||
	$_SESSION['cfgMain'] = $cfg;
 | 
			
		||||
}
 | 
			
		||||
$cfg = &$_SESSION['cfgMain'];
 | 
			
		||||
 | 
			
		||||
// export
 | 
			
		||||
if (isset($_POST['exportConfig']) && $cfg->checkPassword($_SESSION["mainconf_password"])) {
 | 
			
		||||
	$exporter = new ConfigDataExporter();
 | 
			
		||||
	if (!headers_sent()) {
 | 
			
		||||
		header('Content-Type: application/json; charset=utf-8');
 | 
			
		||||
		header('Content-disposition: attachment; filename=lam-config.json');
 | 
			
		||||
	}
 | 
			
		||||
	try {
 | 
			
		||||
		echo $exporter->exportAsJson();
 | 
			
		||||
    }
 | 
			
		||||
	catch (LAMException $e) {
 | 
			
		||||
	    logNewMessage('ERROR', $e->getTitle() . ' ' . $e->getMessage());
 | 
			
		||||
    }
 | 
			
		||||
	exit;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
echo $_SESSION['header'];
 | 
			
		||||
printHeaderContents(_("Import and export configuration"), '../..');
 | 
			
		||||
 | 
			
		||||
?>
 | 
			
		||||
	</head>
 | 
			
		||||
	<body class="admin">
 | 
			
		||||
    <?php
 | 
			
		||||
        // include all JavaScript files
 | 
			
		||||
        printJsIncludes('../..');
 | 
			
		||||
    ?>
 | 
			
		||||
    <table class="lamTop ui-corner-all">
 | 
			
		||||
        <tr>
 | 
			
		||||
            <td align="left">
 | 
			
		||||
                <a class="lamLogo" href="http://www.ldap-account-manager.org/" target="new_window">
 | 
			
		||||
				    <?php echo getLAMVersionText(); ?>
 | 
			
		||||
                </a>
 | 
			
		||||
            </td>
 | 
			
		||||
        </tr>
 | 
			
		||||
    </table>
 | 
			
		||||
    <form action="confImportExport.php" method="post" autocomplete="off" enctype="multipart/form-data">
 | 
			
		||||
    <br><br>
 | 
			
		||||
    <?php
 | 
			
		||||
 | 
			
		||||
    // check if user is logged in
 | 
			
		||||
    if (!isset($_POST['submitLogin']) && !isset($_SESSION["mainconf_password"])) {
 | 
			
		||||
        showLoginDialog();
 | 
			
		||||
        exit();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // check login
 | 
			
		||||
    if (isset($_POST['submitLogin']) && !checkLogin($cfg)) {
 | 
			
		||||
	    exit();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    displayImportExport();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Shows the login dialog for the configuration master password.
 | 
			
		||||
     *
 | 
			
		||||
     * @param htmlStatusMessage $message message to show if any error occured
 | 
			
		||||
     */
 | 
			
		||||
	function showLoginDialog($message = null) {
 | 
			
		||||
    	$tabindex = 0;
 | 
			
		||||
		$content = new htmlResponsiveRow();
 | 
			
		||||
		$loginContent = new htmlResponsiveRow();
 | 
			
		||||
		$loginContent->setCSSClasses(array('maxrow fullwidth roundedShadowBox spacing5'));
 | 
			
		||||
		if ($message !== null) {
 | 
			
		||||
		    $loginContent->add($message, 12);
 | 
			
		||||
        }
 | 
			
		||||
		$pwdInput = new htmlResponsiveInputField(_("Master password"), 'password', '', '236');
 | 
			
		||||
		$pwdInput->setIsPassword(true);
 | 
			
		||||
		$pwdInput->setCSSClasses(array('lam-initial-focus'));
 | 
			
		||||
		$loginContent->add($pwdInput, 12);
 | 
			
		||||
		$loginContent->addLabel(new htmlOutputText(' ', false));
 | 
			
		||||
		$loginContent->addField(new htmlButton('submitLogin', _("Ok")));
 | 
			
		||||
 | 
			
		||||
		$content->add($loginContent, 12);
 | 
			
		||||
 | 
			
		||||
		parseHtml(null, $content, array(), false, $tabindex, null);
 | 
			
		||||
		renderBackLink();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Renders the link back to login page.
 | 
			
		||||
     */
 | 
			
		||||
	function renderBackLink() {
 | 
			
		||||
		$tabindex = 0;
 | 
			
		||||
		$content = new htmlResponsiveRow();
 | 
			
		||||
        $content->addVerticalSpacer('2rem');
 | 
			
		||||
        $content->add(new htmlLink(_('Back to login'), '../login.php', '../../graphics/undo.png'), 12);
 | 
			
		||||
		$content->addVerticalSpacer('1rem');
 | 
			
		||||
		parseHtml(null, $content, array(), false, $tabindex, null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Checks the login password.
 | 
			
		||||
     *
 | 
			
		||||
     * @param LAMCfgMain $cfg main config
 | 
			
		||||
     * @return bool login ok
 | 
			
		||||
     */
 | 
			
		||||
	function checkLogin($cfg) {
 | 
			
		||||
        $password = $_POST['password'];
 | 
			
		||||
        if ($cfg->checkPassword($password)) {
 | 
			
		||||
	        $_SESSION["mainconf_password"] = $password;
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        showLoginDialog(new htmlStatusMessage('ERROR', _('The password is invalid! Please try again.')));
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Displays the import/export functions.
 | 
			
		||||
     */
 | 
			
		||||
    function displayImportExport() {
 | 
			
		||||
	    $tabindex = 0;
 | 
			
		||||
	    $content = new htmlResponsiveRow();
 | 
			
		||||
 | 
			
		||||
	    $content->add(new htmlSubTitle(_('Export')), 12);
 | 
			
		||||
	    $content->add(new htmlButton('exportConfig', _('Export')), 12);
 | 
			
		||||
 | 
			
		||||
	    $content->add(new htmlSubTitle(_('Import')), 12);
 | 
			
		||||
	    renderImportPart($content);
 | 
			
		||||
 | 
			
		||||
	    parseHtml(null, $content, array(), false, $tabindex, null);
 | 
			
		||||
	    renderBackLink();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Renders the import area.
 | 
			
		||||
     *
 | 
			
		||||
     * @param htmlResponsiveRow $content content where to add import part
 | 
			
		||||
     */
 | 
			
		||||
    function renderImportPart($content) {
 | 
			
		||||
        $validUpload = false;
 | 
			
		||||
        $importSteps = array();
 | 
			
		||||
        if (isset($_POST['importConfig'])) {
 | 
			
		||||
	        try {
 | 
			
		||||
	            if (empty($_FILES['import-file']['tmp_name'])) {
 | 
			
		||||
	                throw new LAMException('The file you uploaded is too large. Please check php.ini, upload_max_size setting');
 | 
			
		||||
                }
 | 
			
		||||
		        $handle = fopen($_FILES['import-file']['tmp_name'], "r");
 | 
			
		||||
		        $data = fread($handle, 100000000);
 | 
			
		||||
		        fclose($handle);
 | 
			
		||||
	            $importer = new ConfigDataImporter();
 | 
			
		||||
		        $importSteps = $importer->getPossibleImportSteps($data);
 | 
			
		||||
		        $tmpFile = __DIR__ . '/../../tmp/internal/import_' . getRandomNumber() . '.tmp';
 | 
			
		||||
		        $file = @fopen($tmpFile, "w");
 | 
			
		||||
		        if ($file) {
 | 
			
		||||
			        fputs($file, $data);
 | 
			
		||||
			        fclose($file);
 | 
			
		||||
			        chmod($tmpFile, 0600);
 | 
			
		||||
		        }
 | 
			
		||||
		        $_SESSION['configImportFile'] = $tmpFile;
 | 
			
		||||
	            $validUpload = true;
 | 
			
		||||
            }
 | 
			
		||||
            catch (LAMException $e) {
 | 
			
		||||
                $content->add(new htmlStatusMessage('ERROR', htmlspecialchars($e->getTitle()), htmlspecialchars($e->getMessage())), 12);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (!isset($_POST['importConfigConfirm']) && !$validUpload) {
 | 
			
		||||
	        $content->add(new htmlInputFileUpload('import-file'), 12);
 | 
			
		||||
	        $content->add(new htmlButton('importConfig', _('Submit')), 12);
 | 
			
		||||
        }
 | 
			
		||||
        elseif (isset($_POST['importConfig'])) {
 | 
			
		||||
            $content->add(new htmlOutputText(_('Import steps')), 12);
 | 
			
		||||
            foreach ($importSteps as $importStep) {
 | 
			
		||||
                $stepKey = 'step_' . $importStep->getKey();
 | 
			
		||||
                $stepCheckbox = new htmlResponsiveInputCheckbox($stepKey, true, $importStep->getLabel());
 | 
			
		||||
                $stepCheckbox->setLabelAfterCheckbox();
 | 
			
		||||
                $stepCheckbox->setCSSClasses(array('bold'));
 | 
			
		||||
                $subStepIds = array();
 | 
			
		||||
                $content->add($stepCheckbox, 12);
 | 
			
		||||
	            $content->addVerticalSpacer('0.3rem');
 | 
			
		||||
                foreach ($importStep->getSubSteps() as $subStep) {
 | 
			
		||||
                    $subStepKey = 'step_' . $subStep->getKey();
 | 
			
		||||
                    $subStepIds[] = $subStepKey;
 | 
			
		||||
	                $subStepCheckbox = new htmlResponsiveInputCheckbox($subStepKey, true, $subStep->getLabel());
 | 
			
		||||
	                $subStepCheckbox->setLabelAfterCheckbox();
 | 
			
		||||
	                $content->add($subStepCheckbox, 12);
 | 
			
		||||
                }
 | 
			
		||||
                $stepCheckbox->setTableRowsToShow($subStepIds);
 | 
			
		||||
                $content->addVerticalSpacer('1rem');
 | 
			
		||||
            }
 | 
			
		||||
            $buttonGroup = new htmlGroup();
 | 
			
		||||
	        $buttonGroup->addElement(new htmlButton('importConfigConfirm', _('Import')));
 | 
			
		||||
	        $buttonGroup->addElement(new htmlButton('importCancel', _('Cancel')));
 | 
			
		||||
	        $content->add($buttonGroup, 12);
 | 
			
		||||
        }
 | 
			
		||||
        elseif (isset($_POST['importConfigConfirm'])) {
 | 
			
		||||
			$handle = fopen($_SESSION['configImportFile'], "r");
 | 
			
		||||
	        $data = fread($handle, 100000000);
 | 
			
		||||
	        fclose($handle);
 | 
			
		||||
	        try {
 | 
			
		||||
		        $importer = new ConfigDataImporter();
 | 
			
		||||
		        $importSteps = $importer->getPossibleImportSteps($data);
 | 
			
		||||
		        foreach ($importSteps as $importStep) {
 | 
			
		||||
			        $importStep->setActive(isset($_POST['step_' . $importStep->getKey()]));
 | 
			
		||||
			        foreach ($importStep->getSubSteps() as $subStep) {
 | 
			
		||||
				        $subStep->setActive(isset($_POST['step_' . $subStep->getKey()]));
 | 
			
		||||
                    }
 | 
			
		||||
		        }
 | 
			
		||||
		        $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);
 | 
			
		||||
		        $content->add(new htmlButton('importCancel', _('Back')), 12);
 | 
			
		||||
	        }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
	?>
 | 
			
		||||
    </form>
 | 
			
		||||
	</body>
 | 
			
		||||
</html>
 | 
			
		||||
| 
						 | 
				
			
			@ -1,8 +1,11 @@
 | 
			
		|||
<?php
 | 
			
		||||
namespace LAM\CONFIG;
 | 
			
		||||
use htmlLink;
 | 
			
		||||
use htmlResponsiveRow;
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
  This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
 | 
			
		||||
  Copyright (C) 2003 - 2019  Roland Gruber
 | 
			
		||||
  Copyright (C) 2003 - 2020  Roland Gruber
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
| 
						 | 
				
			
			@ -42,6 +45,9 @@ setlanguage();
 | 
			
		|||
 | 
			
		||||
echo $_SESSION['header'];
 | 
			
		||||
printHeaderContents(_("Configuration overview"), '../..');
 | 
			
		||||
$tabindex = 0;
 | 
			
		||||
$content = new htmlResponsiveRow();
 | 
			
		||||
 | 
			
		||||
?>
 | 
			
		||||
	</head>
 | 
			
		||||
	<body class="admin">
 | 
			
		||||
| 
						 | 
				
			
			@ -59,69 +65,45 @@ printHeaderContents(_("Configuration overview"), '../..');
 | 
			
		|||
			</tr>
 | 
			
		||||
		</table>
 | 
			
		||||
		<br><br>
 | 
			
		||||
		<TABLE border="0" width="100%" class="ui-corner-all roundedShadowBox">
 | 
			
		||||
		<?php
 | 
			
		||||
			if (isLAMProVersion()) {
 | 
			
		||||
				echo "<tr><td rowspan=4 width=20> </td><td></td><td></td></tr>\n";
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				echo "<tr><td rowspan=3 width=20> </td><td></td><td></td></tr>\n";
 | 
			
		||||
			}
 | 
			
		||||
		?>
 | 
			
		||||
		<TR>
 | 
			
		||||
			<TD width="60" height="70">
 | 
			
		||||
			<a href="mainlogin.php">
 | 
			
		||||
				<IMG height="32" width="32" alt="general settings" src="../../graphics/bigTools.png">
 | 
			
		||||
			</a>
 | 
			
		||||
			</TD>
 | 
			
		||||
			<TD>
 | 
			
		||||
			<a href="mainlogin.php">
 | 
			
		||||
				<?php echo _("Edit general settings") ?>
 | 
			
		||||
			</a>
 | 
			
		||||
			</TD>
 | 
			
		||||
		</TR>
 | 
			
		||||
		<TR>
 | 
			
		||||
			<TD height="70">
 | 
			
		||||
			<a href="conflogin.php" target="_self">
 | 
			
		||||
				<IMG height="32" width="32" alt="server settings" src="../../graphics/profiles.png">
 | 
			
		||||
			</a>
 | 
			
		||||
			</TD>
 | 
			
		||||
			<TD>
 | 
			
		||||
			<a href="conflogin.php" target="_self">
 | 
			
		||||
				<?php echo _("Edit server profiles"); ?>
 | 
			
		||||
			</a>
 | 
			
		||||
			</TD>
 | 
			
		||||
		</TR>
 | 
			
		||||
		<?php
 | 
			
		||||
		if (isLAMProVersion()) {
 | 
			
		||||
			echo "<TR>\n";
 | 
			
		||||
				echo "<TD height=\"70\">\n";
 | 
			
		||||
				echo "<a href=\"../selfService/adminLogin.php\" target=\"_self\">\n";
 | 
			
		||||
					echo "<IMG height=\"32\" width=\"32\" alt=\"self service\" src=\"../../graphics/bigPeople.png\">\n";
 | 
			
		||||
				echo "</a>\n";
 | 
			
		||||
				echo "</TD>\n";
 | 
			
		||||
				echo "<TD>\n";
 | 
			
		||||
				echo "<a href=\"../selfService/adminLogin.php\" target=\"_self\">\n";
 | 
			
		||||
					echo _("Edit self service");
 | 
			
		||||
				echo "</a>\n";
 | 
			
		||||
				echo "</TD>\n";
 | 
			
		||||
			echo "</TR>\n";
 | 
			
		||||
		}
 | 
			
		||||
		?>
 | 
			
		||||
		</TABLE>
 | 
			
		||||
		<p><br></p>
 | 
			
		||||
 | 
			
		||||
        <?php
 | 
			
		||||
        $topContent = new htmlResponsiveRow();
 | 
			
		||||
        $topContent->setCSSClasses(array('maxrow fullwidth roundedShadowBox spacing5'));
 | 
			
		||||
        $mainCfgLink = new htmlLink(_("Edit general settings"), 'mainlogin.php', '../../graphics/bigTools.png');
 | 
			
		||||
        $mainCfgLink->setCSSClasses(array('img-padding1 display-as-block'));
 | 
			
		||||
        $topContent->add($mainCfgLink, 12);
 | 
			
		||||
        $cfgLink = new htmlLink(_("Edit server profiles"), 'conflogin.php', '../../graphics/profiles.png');
 | 
			
		||||
        $cfgLink->setCSSClasses(array('img-padding1 display-as-block'));
 | 
			
		||||
        $topContent->add($cfgLink, 12);
 | 
			
		||||
        if (isLAMProVersion()) {
 | 
			
		||||
        	$selfServiceLink = new htmlLink(_("Edit self service"), '../selfService/adminLogin.php', '../../graphics/bigPeople.png');
 | 
			
		||||
        	$selfServiceLink->setCSSClasses(array('img-padding1 display-as-block'));
 | 
			
		||||
	        $topContent->add($selfServiceLink, 12);
 | 
			
		||||
        }
 | 
			
		||||
        if (isDeveloperVersion(LAMVersion())) {
 | 
			
		||||
	        $topContent->addVerticalSpacer('1rem');
 | 
			
		||||
	        $importExportLink = new htmlLink(_("Import and export configuration"), 'confImportExport.php', '../../graphics/confImportExport.png');
 | 
			
		||||
	        $importExportLink->setCSSClasses(array('img-padding1 display-as-block'));
 | 
			
		||||
	        $topContent->add($importExportLink, 12);
 | 
			
		||||
        }
 | 
			
		||||
        $content->add($topContent, 12);
 | 
			
		||||
        $content->addVerticalSpacer('4rem');
 | 
			
		||||
        ?>
 | 
			
		||||
 | 
			
		||||
		<?php
 | 
			
		||||
		if (isLAMProVersion()) {
 | 
			
		||||
			include_once(__DIR__ . "/../../lib/env.inc");
 | 
			
		||||
			$printer = new \LAM\ENV\LAMLicenseInfoPrinter();
 | 
			
		||||
			$printer->printLicenseInfo();
 | 
			
		||||
			echo "<br><br>";
 | 
			
		||||
			$content->add($printer->getLicenseInfo(), 12);
 | 
			
		||||
			$content->addVerticalSpacer('2rem');
 | 
			
		||||
		}
 | 
			
		||||
		?>
 | 
			
		||||
 | 
			
		||||
		<p> <a href="../login.php"><IMG alt="back" src="../../graphics/undo.png"> <?php echo _("Back to login") ?></a></p>
 | 
			
		||||
		<p><br><br></p>
 | 
			
		||||
		$content->add(new htmlLink(_("Back to login"), '../login.php', '../../graphics/undo.png'), 12);
 | 
			
		||||
		$content->addVerticalSpacer('2rem');
 | 
			
		||||
 | 
			
		||||
		parseHtml('none', $content, array(), true, $tabindex, 'none');
 | 
			
		||||
 | 
			
		||||
		?>
 | 
			
		||||
 | 
			
		||||
	</body>
 | 
			
		||||
</html>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,7 +21,7 @@ use \LAM\TYPES\TypeManager;
 | 
			
		|||
 | 
			
		||||
  This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
 | 
			
		||||
  Copyright (C) 2003 - 2006  Michael Duergner
 | 
			
		||||
                2005 - 2018  Roland Gruber
 | 
			
		||||
                2005 - 2020  Roland Gruber
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
| 
						 | 
				
			
			@ -107,7 +107,7 @@ $container->add(new htmlTitle(_('PDF editor')), 12);
 | 
			
		|||
if (isset($_POST['deleteProfile']) && ($_POST['deleteProfile'] == 'true')) {
 | 
			
		||||
	$typeToDelete = $typeManager->getConfiguredType($_POST['profileDeleteType']);
 | 
			
		||||
	// delete structure
 | 
			
		||||
	if (\LAM\PDF\deletePDFStructure($_POST['profileDeleteType'], $_POST['profileDeleteName'])) {
 | 
			
		||||
	if (\LAM\PDF\deletePDFStructure($_POST['profileDeleteType'], $_POST['profileDeleteName'], $_SESSION['config']->getName())) {
 | 
			
		||||
		$message = new htmlStatusMessage('INFO', _('Deleted PDF structure.'), $typeToDelete->getAlias() . ': ' . htmlspecialchars($_POST['profileDeleteName']));
 | 
			
		||||
		$container->add($message, 12);
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -173,13 +173,13 @@ if (!empty($_POST['export'])) {
 | 
			
		|||
if (isset($_POST['uploadLogo']) && !empty($_FILES['logoUpload']) && !empty($_FILES['logoUpload']['size'])) {
 | 
			
		||||
	$file = $_FILES['logoUpload']['tmp_name'];
 | 
			
		||||
	$filename = $_FILES['logoUpload']['name'];
 | 
			
		||||
	$container->add(\LAM\PDF\uploadPDFLogo($file, $filename), 12);
 | 
			
		||||
	$container->add(\LAM\PDF\uploadPDFLogo($file, $filename, $_SESSION['config']->getName()), 12);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// delete logo file
 | 
			
		||||
if (isset($_POST['delLogo'])) {
 | 
			
		||||
	$toDel = $_POST['logo'];
 | 
			
		||||
	$container->add(\LAM\PDF\deletePDFLogo($toDel), 12);
 | 
			
		||||
	$container->add(\LAM\PDF\deletePDFLogo($toDel, $_SESSION['config']->getName()), 12);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// get list of account types
 | 
			
		||||
| 
						 | 
				
			
			@ -192,7 +192,7 @@ foreach ($sortedTypes as $typeId => $title) {
 | 
			
		|||
		'scope' => $type->getScope(),
 | 
			
		||||
		'title' => $title,
 | 
			
		||||
		'icon' => $type->getIcon(),
 | 
			
		||||
		'templates' => \LAM\PDF\getPDFStructures($type->getId()));
 | 
			
		||||
		'templates' => \LAM\PDF\getPDFStructures($type->getId(), $_SESSION['config']->getName()));
 | 
			
		||||
	$availableTypes[$title] = $type->getId();
 | 
			
		||||
}
 | 
			
		||||
// check if a template should be edited
 | 
			
		||||
| 
						 | 
				
			
			@ -275,7 +275,7 @@ include __DIR__ . '/../../lib/adminHeader.inc';
 | 
			
		|||
		// manage logos
 | 
			
		||||
		$container->addVerticalSpacer('4rem');
 | 
			
		||||
		$container->add(new htmlSubTitle(_('Manage logos')), 12);
 | 
			
		||||
		$logos = \LAM\PDF\getAvailableLogos();
 | 
			
		||||
		$logos = \LAM\PDF\getAvailableLogos($_SESSION['config']->getName());
 | 
			
		||||
		$logoOptions = array();
 | 
			
		||||
		foreach ($logos as $logo) {
 | 
			
		||||
			$file = $logo['filename'];
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,7 +22,7 @@ use LAM\PDF\PDFStructureWriter;
 | 
			
		|||
/*
 | 
			
		||||
  This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
 | 
			
		||||
  Copyright (C) 2003 - 2006  Michael Duergner
 | 
			
		||||
                2007 - 2019  Roland Gruber
 | 
			
		||||
                2007 - 2020  Roland Gruber
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
| 
						 | 
				
			
			@ -105,7 +105,7 @@ if(isset($_GET['abort'])) {
 | 
			
		|||
// 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();
 | 
			
		||||
	$reader = new PDFStructureReader($_SESSION['config']->getName());
 | 
			
		||||
	try {
 | 
			
		||||
		if(isset($_GET['edit'])) {
 | 
			
		||||
			$_SESSION['currentPDFStructure'] = $reader->read($type->getId(), $_GET['edit']);
 | 
			
		||||
| 
						 | 
				
			
			@ -135,7 +135,7 @@ if (!empty($_POST['form_submit'])) {
 | 
			
		|||
// main pdf structure page
 | 
			
		||||
$saveErrors = array();
 | 
			
		||||
if(isset($_GET['submit'])) {
 | 
			
		||||
	$writer = new PDFStructureWriter();
 | 
			
		||||
	$writer = new PDFStructureWriter($_SESSION['config']->getName());
 | 
			
		||||
	try {
 | 
			
		||||
		$writer->write($type->getId(), $_POST['pdfname'], $_SESSION['currentPDFStructure']);
 | 
			
		||||
		unset($_SESSION['currentPDFStructure']);
 | 
			
		||||
| 
						 | 
				
			
			@ -218,7 +218,7 @@ else if (isset($_POST['pdfname'])) {
 | 
			
		|||
// headline
 | 
			
		||||
$headline = $_SESSION['currentPDFStructure']->getTitle();
 | 
			
		||||
// logo
 | 
			
		||||
$logoFiles = \LAM\PDF\getAvailableLogos();
 | 
			
		||||
$logoFiles = \LAM\PDF\getAvailableLogos($_SESSION['config']->getName());
 | 
			
		||||
$logos = array(_('No logo') => 'none');
 | 
			
		||||
foreach($logoFiles as $logoFile) {
 | 
			
		||||
	$logos[$logoFile['filename'] . ' (' . $logoFile['infos'][0] . ' x ' . $logoFile['infos'][1] . ")"] = $logoFile['filename'];
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,7 +10,7 @@ use \htmlSubTitle;
 | 
			
		|||
/*
 | 
			
		||||
 | 
			
		||||
  This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
 | 
			
		||||
  Copyright (C) 2003 - 2019  Roland Gruber
 | 
			
		||||
  Copyright (C) 2003 - 2020  Roland Gruber
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
| 
						 | 
				
			
			@ -127,7 +127,7 @@ if (isset($_POST['save'])) {
 | 
			
		|||
	$errors = checkProfileOptions($_POST['accounttype'], $options);
 | 
			
		||||
	if (sizeof($errors) == 0) {  // input data is valid, save profile
 | 
			
		||||
		// save profile
 | 
			
		||||
		if (\LAM\PROFILES\saveAccountProfile($options, $_POST['profname'], $_POST['accounttype'])) {
 | 
			
		||||
		if (\LAM\PROFILES\saveAccountProfile($options, $_POST['profname'], $_POST['accounttype'], $_SESSION['config'])) {
 | 
			
		||||
			metaRefresh('profilemain.php?savedSuccessfully=' . $_POST['profname']);
 | 
			
		||||
			exit();
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -168,7 +168,7 @@ if (isset($_POST['save'])) {
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
elseif (isset($_GET['edit'])) {
 | 
			
		||||
	$old_options = \LAM\PROFILES\loadAccountProfile($_GET['edit'], $type->getId());
 | 
			
		||||
	$old_options = \LAM\PROFILES\loadAccountProfile($_GET['edit'], $type->getId(), $_SESSION['config']->getName());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// display formular
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -294,7 +294,7 @@ function showMainPage(\LAM\TYPES\ConfiguredType $type, $selectedModules) {
 | 
			
		|||
	$pdfCheckbox = new htmlResponsiveInputCheckbox('createPDF', $createPDF, _('Create PDF files'));
 | 
			
		||||
	$pdfCheckbox->setTableRowsToShow(array('pdfStructure', 'pdf_font'));
 | 
			
		||||
	$row->add($pdfCheckbox, 12);
 | 
			
		||||
	$pdfStructures = \LAM\PDF\getPDFStructures($type->getId());
 | 
			
		||||
	$pdfStructures = \LAM\PDF\getPDFStructures($type->getId(), $_SESSION['config']->getName());
 | 
			
		||||
	$pdfSelected = array();
 | 
			
		||||
	if (isset($_POST['pdfStructure'])) {
 | 
			
		||||
		$pdfSelected = array($_POST['pdfStructure']);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -120,4 +120,56 @@ class LAMCfgMainTest extends TestCase {
 | 
			
		|||
		$this->assertFalse($this->conf->showLicenseWarningOnScreen());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Tests the export.
 | 
			
		||||
	 */
 | 
			
		||||
	public function testExportData() {
 | 
			
		||||
		$this->conf->passwordMinLower = 3;
 | 
			
		||||
		$this->conf->sessionTimeout = 240;
 | 
			
		||||
		$this->conf->logLevel = LOG_ERR;
 | 
			
		||||
		$this->conf->mailServer = 'mailserver';
 | 
			
		||||
 | 
			
		||||
		$data = $this->conf->exportData();
 | 
			
		||||
 | 
			
		||||
		$this->assertEquals(3, $data['passwordMinLower']);
 | 
			
		||||
		$this->assertEquals(240, $data['sessionTimeout']);
 | 
			
		||||
		$this->assertEquals(LOG_ERR, $data['logLevel']);
 | 
			
		||||
		$this->assertEquals('mailserver', $data['mailServer']);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Tests the import.
 | 
			
		||||
	 */
 | 
			
		||||
	public function testImportData() {
 | 
			
		||||
		$importData = array();
 | 
			
		||||
		$importData['passwordMinLower'] = 3;
 | 
			
		||||
		$importData['sessionTimeout'] = 240;
 | 
			
		||||
		$importData['logLevel'] = LOG_ERR;
 | 
			
		||||
		$importData['mailServer'] = 'mailserver';
 | 
			
		||||
		$importData['allowedHosts'] = null;
 | 
			
		||||
		$importData['IGNORE_ME'] = 'ignore';
 | 
			
		||||
 | 
			
		||||
		$this->conf->importData($importData);
 | 
			
		||||
 | 
			
		||||
		$this->assertEquals(3, $this->conf->passwordMinLower);
 | 
			
		||||
		$this->assertEquals(240, $this->conf->sessionTimeout);
 | 
			
		||||
		$this->assertEquals(LOG_ERR, $this->conf->logLevel);
 | 
			
		||||
		$this->assertEquals('mailserver', $this->conf->mailServer);
 | 
			
		||||
		$this->assertNull($this->conf->allowedHosts);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Tests the import with invalid data.
 | 
			
		||||
	 */
 | 
			
		||||
	public function testImportData_invalid() {
 | 
			
		||||
		$importData = array();
 | 
			
		||||
		$importData['passwordMinLower'] = 3;
 | 
			
		||||
		$importData['sessionTimeout'] = 240;
 | 
			
		||||
		$importData['logLevel'] = LOG_ERR;
 | 
			
		||||
		$importData['mailServer'] = new LAMLanguage('de_de', 'UTF-8', 'DE');
 | 
			
		||||
 | 
			
		||||
		$this->expectException(LAMException::class);
 | 
			
		||||
		$this->conf->importData($importData);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -3,7 +3,7 @@ use PHPUnit\Framework\TestCase;
 | 
			
		|||
/*
 | 
			
		||||
 | 
			
		||||
 This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
 | 
			
		||||
 Copyright (C) 2016 - 2019  Roland Gruber
 | 
			
		||||
 Copyright (C) 2016 - 2020  Roland Gruber
 | 
			
		||||
 | 
			
		||||
 This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 it under the terms of the GNU General Public License as published by
 | 
			
		||||
| 
						 | 
				
			
			@ -21,7 +21,7 @@ use PHPUnit\Framework\TestCase;
 | 
			
		|||
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
include_once 'lam/tests/utils/configuration.inc';
 | 
			
		||||
include_once __DIR__ . '/../utils/configuration.inc';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * LAMConfig test case.
 | 
			
		||||
| 
						 | 
				
			
			@ -858,6 +858,63 @@ class LAMConfigTest extends TestCase {
 | 
			
		|||
		$this->assertEquals($sizeTypeSettings, sizeof($this->lAMConfig->get_typeSettings()));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Tests the export.
 | 
			
		||||
	 */
 | 
			
		||||
	public function testExportData() {
 | 
			
		||||
		$this->lAMConfig->set_defaultLanguage('lang');
 | 
			
		||||
		$this->lAMConfig->set_ServerURL('myserver');
 | 
			
		||||
		$this->lAMConfig->set_typeSettings(array('typetest' => '1'));
 | 
			
		||||
		$this->lAMConfig->set_moduleSettings(array('modtest' => '1'));
 | 
			
		||||
		$this->lAMConfig->setToolSettings(array('tooltest' => '1'));
 | 
			
		||||
		$this->lAMConfig->setJobSettings(array('jobtest' => '1'));
 | 
			
		||||
 | 
			
		||||
		$data = $this->lAMConfig->exportData();
 | 
			
		||||
 | 
			
		||||
		$this->assertEquals('lang', $data['defaultLanguage']);
 | 
			
		||||
		$this->assertEquals('myserver', $data['ServerURL']);
 | 
			
		||||
		$this->assertEquals(array('typetest' => '1'), $data['typeSettings']);
 | 
			
		||||
		$this->assertEquals(array('modtest' => '1'), $data['moduleSettings']);
 | 
			
		||||
		$this->assertEquals(array('tooltest' => '1'), $data['toolSettings']);
 | 
			
		||||
		$this->assertEquals(array('jobtest' => '1'), $data['jobSettings']);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Tests the import.
 | 
			
		||||
	 */
 | 
			
		||||
	public function testImportData() {
 | 
			
		||||
		$importData = array();
 | 
			
		||||
		$importData['ServerURL'] = 'testserver';
 | 
			
		||||
		$importData['defaultLanguage'] = 'de_DE.utf8';
 | 
			
		||||
		$importData['typeSettings'] = array('typetest' => 'value');
 | 
			
		||||
		$importData['toolSettings'] = array('tooltest' => 'value');
 | 
			
		||||
		$importData['moduleSettings'] = array('modtest' => 'value');
 | 
			
		||||
		$importData['jobSettings'] = array('jobtest' => 'value');
 | 
			
		||||
		$importData['IGNORE_ME'] = 'ignore';
 | 
			
		||||
 | 
			
		||||
		$this->lAMConfig->importData($importData);
 | 
			
		||||
 | 
			
		||||
		$this->assertEquals('testserver', $this->lAMConfig->get_ServerURL());
 | 
			
		||||
		$this->assertEquals('de_DE.utf8', $this->lAMConfig->get_defaultLanguage());
 | 
			
		||||
		$this->assertEquals(array('typetest' => 'value'), $this->lAMConfig->get_typeSettings());
 | 
			
		||||
		$this->assertEquals(array('tooltest' => 'value'), $this->lAMConfig->getToolSettings());
 | 
			
		||||
		$this->assertEquals(array('modtest' => 'value'), $this->lAMConfig->get_moduleSettings());
 | 
			
		||||
		$this->assertEquals(array('jobtest' => 'value'), $this->lAMConfig->getJobSettings());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Tests the import with invalid data.
 | 
			
		||||
	 */
 | 
			
		||||
	public function testImportData_invalid() {
 | 
			
		||||
		$importData = array();
 | 
			
		||||
		$importData['ServerURL'] = 'testserver';
 | 
			
		||||
		$importData['typeSettings'] = array('typetest' => 'value');
 | 
			
		||||
		$importData['defaultLanguage'] = new LAMLanguage('de_de', 'UTF-8', 'DE');
 | 
			
		||||
 | 
			
		||||
		$this->expectException(LAMException::class);
 | 
			
		||||
		$this->lAMConfig->importData($importData);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Saves the config
 | 
			
		||||
	 */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,7 +24,7 @@ include_once __DIR__ . '/../../lib/account.inc';
 | 
			
		|||
include_once __DIR__ . '/../../lib/security.inc';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * LAMConfig test case.
 | 
			
		||||
 * account.inc test cases.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Roland Gruber
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			@ -155,4 +155,13 @@ class AccountTest extends TestCase {
 | 
			
		|||
		$this->assertFalse(isCommandlineSafeEmailAddress('test+abc@example.com'));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Tests isDeveloperVersion()
 | 
			
		||||
	 */
 | 
			
		||||
	function testIsDeveloperVersion() {
 | 
			
		||||
		$this->assertFalse(isDeveloperVersion('0.4.1'));
 | 
			
		||||
		$this->assertFalse(isDeveloperVersion('3.2.RC1'));
 | 
			
		||||
		$this->assertTrue(isDeveloperVersion('4.5.DEV'));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,6 @@
 | 
			
		|||
<?php
 | 
			
		||||
 | 
			
		||||
use LAM\PDF\PDFSectionEntry;
 | 
			
		||||
use LAM\PDF\PDFTextSection;
 | 
			
		||||
use LAM\PDF\PDFEntrySection;
 | 
			
		||||
use LAM\PDF\PDFStructureReader;
 | 
			
		||||
| 
						 | 
				
			
			@ -26,21 +28,22 @@ use PHPUnit\Framework\TestCase;
 | 
			
		|||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
include_once 'lam/lib/pdfstruct.inc';
 | 
			
		||||
include_once __DIR__ . '/../../lib/pdfstruct.inc';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Reads a sample PDF structure.
 | 
			
		||||
 * Tests classes in pdfstruct.inc.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Roland Gruber
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
class ReadStructureTest extends TestCase {
 | 
			
		||||
class PdfStructTest extends TestCase {
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Reads the sample structure.
 | 
			
		||||
	 */
 | 
			
		||||
	public function testRead() {
 | 
			
		||||
		$reader = $this->getMockBuilder('\LAM\PDF\PDFStructureReader')
 | 
			
		||||
			->setConstructorArgs(array('test'))
 | 
			
		||||
			->setMethods(array('getFileName'))
 | 
			
		||||
			->getMock();
 | 
			
		||||
		$reader->method('getFileName')->willReturn($this->getTestFileName('test.xml'));
 | 
			
		||||
| 
						 | 
				
			
			@ -99,17 +102,144 @@ class ReadStructureTest extends TestCase {
 | 
			
		|||
		fclose($fileHandle);
 | 
			
		||||
		// read structure
 | 
			
		||||
		$reader = $this->getMockBuilder('\LAM\PDF\PDFStructureReader')
 | 
			
		||||
		->setConstructorArgs(array('test'))
 | 
			
		||||
		->setMethods(array('getFileName'))
 | 
			
		||||
		->getMock();
 | 
			
		||||
		$reader->method('getFileName')->willReturn($file);
 | 
			
		||||
		$structure = $reader->read('type', 'name');
 | 
			
		||||
		// create writer and get output XML
 | 
			
		||||
		$writer = new PDFStructureWriter();
 | 
			
		||||
		$writer = new PDFStructureWriter('test');
 | 
			
		||||
		$xml = $writer->getXML($structure);
 | 
			
		||||
		// compare
 | 
			
		||||
		$this->assertEquals($originalXML, $xml);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Tests PDFTextSection
 | 
			
		||||
	 */
 | 
			
		||||
	public function testExportPDFTextSection() {
 | 
			
		||||
		$section = new PDFTextSection('sometext');
 | 
			
		||||
 | 
			
		||||
		$data = $section->export();
 | 
			
		||||
 | 
			
		||||
		$this->assertEquals('sometext', $data);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Tests PDFEntrySection
 | 
			
		||||
	 */
 | 
			
		||||
	public function testExportPDFEntrySection() {
 | 
			
		||||
		$section = new PDFEntrySection('mytitle');
 | 
			
		||||
		$section->setEntries(array(new PDFSectionEntry('key1'), new PDFSectionEntry('key2')));
 | 
			
		||||
 | 
			
		||||
		$data = $section->export();
 | 
			
		||||
 | 
			
		||||
		$expected = array(
 | 
			
		||||
			'title' => 'mytitle',
 | 
			
		||||
			'entries' => array('key1', 'key2')
 | 
			
		||||
		);
 | 
			
		||||
 | 
			
		||||
		$this->assertEquals($expected, $data);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Tests PDFStructure
 | 
			
		||||
	 */
 | 
			
		||||
	public function testExportPDFStructure() {
 | 
			
		||||
		$structure = new PDFStructure();
 | 
			
		||||
		$structure->setFoldingMarks(PDFStructure::FOLDING_STANDARD);
 | 
			
		||||
		$structure->setLogo('somelogo');
 | 
			
		||||
		$structure->setTitle('mytitle');
 | 
			
		||||
		$entrySection = new PDFEntrySection('sometitle');
 | 
			
		||||
		$entrySection->setEntries(array(new PDFSectionEntry('key1')));
 | 
			
		||||
		$structure->setSections(array(
 | 
			
		||||
			new PDFTextSection('sometext'),
 | 
			
		||||
			$entrySection
 | 
			
		||||
		));
 | 
			
		||||
 | 
			
		||||
		$data = $structure->export();
 | 
			
		||||
 | 
			
		||||
		$expected = array(
 | 
			
		||||
			'title' => 'mytitle',
 | 
			
		||||
			'foldingMarks' => PDFStructure::FOLDING_STANDARD,
 | 
			
		||||
			'logo' => 'somelogo',
 | 
			
		||||
			'sections' => array(
 | 
			
		||||
				array(
 | 
			
		||||
					'type' => 'text',
 | 
			
		||||
					'data' => 'sometext'
 | 
			
		||||
				),
 | 
			
		||||
				array(
 | 
			
		||||
					'type' => 'entry',
 | 
			
		||||
					'data' => array(
 | 
			
		||||
						'title' => 'sometitle',
 | 
			
		||||
						'entries' => array('key1')
 | 
			
		||||
					)
 | 
			
		||||
				)
 | 
			
		||||
			)
 | 
			
		||||
		);
 | 
			
		||||
 | 
			
		||||
		$this->assertEquals($expected, $data);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Tests import in PDFEntrySection.
 | 
			
		||||
	 */
 | 
			
		||||
	public function testImportPDFEntrySection() {
 | 
			
		||||
		$data = array(
 | 
			
		||||
			'title' => 'mytitle',
 | 
			
		||||
			'entries' => array('e1', 'e2')
 | 
			
		||||
		);
 | 
			
		||||
 | 
			
		||||
		$section = new PDFEntrySection(null);
 | 
			
		||||
		$section->import($data);
 | 
			
		||||
 | 
			
		||||
		$this->assertEquals('mytitle', $section->getTitle());
 | 
			
		||||
		$entries = $section->getEntries();
 | 
			
		||||
		$this->assertEquals(2, sizeof($entries));
 | 
			
		||||
		$this->assertEquals('e1', ($entries[0]->getKey()));
 | 
			
		||||
		$this->assertEquals('e2', ($entries[1]->getKey()));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Tests the import in PDFStructure.
 | 
			
		||||
	 */
 | 
			
		||||
	public function testImportPDFStructure() {
 | 
			
		||||
		$data = array(
 | 
			
		||||
			'title' => 'mytitle',
 | 
			
		||||
			'foldingMarks' => PDFStructure::FOLDING_STANDARD,
 | 
			
		||||
			'logo' => 'logo',
 | 
			
		||||
			'sections' => array(
 | 
			
		||||
				array(
 | 
			
		||||
					'type' => 'text',
 | 
			
		||||
					'data' => 'textvalue'
 | 
			
		||||
				),
 | 
			
		||||
				array(
 | 
			
		||||
					'type' => 'entry',
 | 
			
		||||
					'data' => array(
 | 
			
		||||
						'title' => 'etitle',
 | 
			
		||||
						'entries' => array('e1', 'e2')
 | 
			
		||||
					)
 | 
			
		||||
				),
 | 
			
		||||
			)
 | 
			
		||||
		);
 | 
			
		||||
 | 
			
		||||
		$structure = new PDFStructure();
 | 
			
		||||
		$structure->import($data);
 | 
			
		||||
 | 
			
		||||
		$this->assertEquals('mytitle', $structure->getTitle());
 | 
			
		||||
		$this->assertEquals(PDFStructure::FOLDING_STANDARD, $structure->getFoldingMarks());
 | 
			
		||||
		$this->assertEquals('logo', $structure->getLogo());
 | 
			
		||||
		$sections = $structure->getSections();
 | 
			
		||||
		$this->assertEquals(2, sizeof($sections));
 | 
			
		||||
		$this->assertTrue($sections[0] instanceof PDFTextSection);
 | 
			
		||||
		$this->assertEquals('textvalue', $sections[0]->getText());
 | 
			
		||||
		$this->assertTrue($sections[1] instanceof PDFEntrySection);
 | 
			
		||||
		$entries = $sections[1]->getEntries();
 | 
			
		||||
		$this->assertEquals(2, sizeof($entries));
 | 
			
		||||
		$this->assertEquals('e1', $entries[0]->getKey());
 | 
			
		||||
		$this->assertEquals('e2', $entries[1]->getKey());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
?>
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,104 @@
 | 
			
		|||
<?php
 | 
			
		||||
namespace LAM\PERSISTENCE;
 | 
			
		||||
use PHPUnit\Framework\TestCase;
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
 This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
 | 
			
		||||
 Copyright (C) 2020  Roland Gruber
 | 
			
		||||
 | 
			
		||||
 This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 it under the terms of the GNU General Public License as published by
 | 
			
		||||
 the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 (at your option) any later version.
 | 
			
		||||
 | 
			
		||||
 This program is distributed in the hope that it will be useful,
 | 
			
		||||
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 GNU General Public License for more details.
 | 
			
		||||
 | 
			
		||||
 You should have received a copy of the GNU General Public License
 | 
			
		||||
 along with this program; if not, write to the Free Software
 | 
			
		||||
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
include_once __DIR__ . '/../../lib/persistence.inc';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * ConfigDataExporter test case.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Roland Gruber
 | 
			
		||||
 */
 | 
			
		||||
class ConfigDataExporterTest extends TestCase {
 | 
			
		||||
 | 
			
		||||
	public function testExportAsJson() {
 | 
			
		||||
		$mainData = array(
 | 
			
		||||
			'confMainKey1' => 'val',
 | 
			
		||||
			'confMainKey2' => 4,
 | 
			
		||||
			'confMainKey3' => '',
 | 
			
		||||
		);
 | 
			
		||||
		$profileData = array(
 | 
			
		||||
			'profile1' => array('ServerURL' => 'myserver'),
 | 
			
		||||
			'profile2' => array('ServerURL' => 'myserver2'),
 | 
			
		||||
		);
 | 
			
		||||
		$accountProfileData = array(
 | 
			
		||||
			'profile1' => array('user' => array('default' => array('key' => 'value'))),
 | 
			
		||||
			'profile1' => array(
 | 
			
		||||
				'user' => array('default' => array('key' => 'value')),
 | 
			
		||||
				'group' => array('default' => array('key' => 'value')),
 | 
			
		||||
			),
 | 
			
		||||
		);
 | 
			
		||||
		$accountProfileTemplateData = array(
 | 
			
		||||
			'user' => array('default' => array('key' => 'value')),
 | 
			
		||||
			'group' => array('default' => array('key' => 'value')),
 | 
			
		||||
		);
 | 
			
		||||
		$pdfData = array(
 | 
			
		||||
			'profile1' => array('structures' => array(
 | 
			
		||||
				'user' => array(
 | 
			
		||||
					'default' => array('key' => 'value'))
 | 
			
		||||
			)),
 | 
			
		||||
			'profile1' => array('structures' => array(
 | 
			
		||||
				'user' => array('default' => array('key' => 'value')),
 | 
			
		||||
				'group' => array('default' => array('key' => 'value')),
 | 
			
		||||
			)),
 | 
			
		||||
		);
 | 
			
		||||
		$pdfTemplateData = array(
 | 
			
		||||
			'user' => array('default' => array('key' => 'value')),
 | 
			
		||||
			'group' => array('default' => array('key' => 'value')),
 | 
			
		||||
		);
 | 
			
		||||
		$selfServiceData = array(
 | 
			
		||||
			'profile1' => array('key' => 'value'),
 | 
			
		||||
			'profile2' => array('key' => 'value'),
 | 
			
		||||
		);
 | 
			
		||||
		$expectedJson = json_encode(array(
 | 
			
		||||
			'mainConfig' => $mainData,
 | 
			
		||||
			'certificates' => 'certs',
 | 
			
		||||
			'serverProfiles' => $profileData,
 | 
			
		||||
			'accountProfiles' => $accountProfileData,
 | 
			
		||||
			'accountProfileTemplates' => $accountProfileTemplateData,
 | 
			
		||||
			'pdfProfiles' => $pdfData,
 | 
			
		||||
			'pdfProfileTemplates' => $pdfTemplateData,
 | 
			
		||||
			'selfServiceProfiles' => $selfServiceData,
 | 
			
		||||
		));
 | 
			
		||||
 | 
			
		||||
		$exporter = $this->getMockBuilder('\LAM\PERSISTENCE\ConfigDataExporter')
 | 
			
		||||
			->setMethods(array('_getMainConfigData', '_getCertificates', '_getServerProfiles',
 | 
			
		||||
				'_getAccountProfiles', '_getAccountProfileTemplates', '_getPdfProfiles',
 | 
			
		||||
				'_getPdfProfileTemplates', '_getSelfServiceProfiles'))
 | 
			
		||||
			->getMock();
 | 
			
		||||
		$exporter->method('_getMainConfigData')->willReturn($mainData);
 | 
			
		||||
		$exporter->method('_getCertificates')->willReturn('certs');
 | 
			
		||||
		$exporter->method('_getServerProfiles')->willReturn($profileData);
 | 
			
		||||
		$exporter->method('_getAccountProfiles')->willReturn($accountProfileData);
 | 
			
		||||
		$exporter->method('_getAccountProfileTemplates')->willReturn($accountProfileTemplateData);
 | 
			
		||||
		$exporter->method('_getPdfProfiles')->willReturn($pdfData);
 | 
			
		||||
		$exporter->method('_getPdfProfileTemplates')->willReturn($pdfTemplateData);
 | 
			
		||||
		$exporter->method('_getSelfServiceProfiles')->willReturn($selfServiceData);
 | 
			
		||||
 | 
			
		||||
		$json = $exporter->exportAsJson();
 | 
			
		||||
 | 
			
		||||
		$this->assertEquals($expectedJson, $json);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -3,7 +3,7 @@ use PHPUnit\Framework\TestCase;
 | 
			
		|||
/*
 | 
			
		||||
 | 
			
		||||
  This code is part of LDAP Account Manager (http://www.ldap-account-manager.org/)
 | 
			
		||||
  Copyright (C) 2019  Roland Gruber
 | 
			
		||||
  Copyright (C) 2019 - 2020  Roland Gruber
 | 
			
		||||
 | 
			
		||||
  This program is free software; you can redistribute it and/or modify
 | 
			
		||||
  it under the terms of the GNU General Public License as published by
 | 
			
		||||
| 
						 | 
				
			
			@ -21,7 +21,7 @@ use PHPUnit\Framework\TestCase;
 | 
			
		|||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
require_once 'lam/lib/selfService.inc';
 | 
			
		||||
require_once __DIR__ . '/../../lib/selfService.inc';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Checks selfServiceProfile.
 | 
			
		||||
| 
						 | 
				
			
			@ -43,6 +43,23 @@ class selfServiceProfileTest extends TestCase {
 | 
			
		|||
		$this->assertEquals('https://test.com', $profile->getBaseUrl());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public function testImportExport() {
 | 
			
		||||
		$profile = new selfServiceProfile();
 | 
			
		||||
		$moduleSettings = array('x1' => 'y1', 'x2' => 'y2');
 | 
			
		||||
		$profile->moduleSettings = $moduleSettings;
 | 
			
		||||
		$profile->baseColor = 'green';
 | 
			
		||||
		$profile->language = 'de_DE@UTF8';
 | 
			
		||||
		$profile->pageHeader = 'header';
 | 
			
		||||
 | 
			
		||||
		$export = $profile->export();
 | 
			
		||||
		$importedProfile = selfServiceProfile::import($export);
 | 
			
		||||
 | 
			
		||||
		$this->assertEquals($moduleSettings, $importedProfile->moduleSettings);
 | 
			
		||||
		$this->assertEquals('green', $importedProfile->baseColor);
 | 
			
		||||
		$this->assertEquals('de_DE@UTF8', $importedProfile->language);
 | 
			
		||||
		$this->assertEquals('header', $importedProfile->pageHeader);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
?>
 | 
			
		||||
		Loading…
	
		Reference in New Issue