openrat-cms

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

commit 2ef5807288ad0b440514573cdd45afc187f85000
parent fcd742dbafac5c8321da1516d94a2c07fcbbd750
Author: Jan Dankert <devnull@localhost>
Date:   Thu, 23 Aug 2018 00:27:01 +0200

Funktion config() in das Modul 'configuration' verschoben sowie Fluent Interface eingebaut. ElementAction um Flags und Format ergänzt.

Diffstat:
modules/cms-core/Dispatcher.class.php | 8++++----
modules/cms-core/action/ConfigurationAction.class.php | 2+-
modules/cms-core/action/ElementAction.class.php | 126++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
modules/cms-core/action/TemplateAction.class.php | 5+++--
modules/cms-core/functions/common.inc.php | 26--------------------------
modules/cms-core/model/Element.class.php | 65++++++++++++++++++++++++++++++++++++++++++++++++++---------------
modules/configuration/Configuration.class.php | 188+++++++++++++++++++++++++++----------------------------------------------------
modules/configuration/ConfigurationLoader.class.php | 153+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
modules/configuration/require.php | 3++-
9 files changed, 348 insertions(+), 228 deletions(-)

diff --git a/modules/cms-core/Dispatcher.class.php b/modules/cms-core/Dispatcher.class.php @@ -7,7 +7,7 @@ namespace cms; use BadMethodCallException; use cms\action\Action; -use Configuration; +use ConfigurationLoader; use DomainException; use Http; use http\Exception; @@ -41,7 +41,7 @@ class Dispatcher */ public function doAction() { - define('PRODUCTION', config('production')); + define('PRODUCTION', config()->is('production')); define('DEVELOPMENT', !PRODUCTION); @@ -207,7 +207,7 @@ class Dispatcher // Konfiguration lesen. // Wenn Konfiguration noch nicht in Session vorhanden oder die Konfiguration geändert wurde (erkennbar anhand des Datei-Datums) // dann die Konfiguration neu einlesen. - if (!is_array($conf) || $conf['config']['auto_reload'] && Configuration::lastModificationTime() > $conf['config']['last_modification_time']) { + if (!is_array($conf) || $conf['config']['auto_reload'] && ConfigurationLoader::lastModificationTime() > $conf['config']['last_modification_time']) { // Da die Konfiguration neu eingelesen wird, sollten wir auch die Sitzung komplett leeren. if (is_array($conf) && $conf['config']['session_destroy_on_config_reload']) @@ -217,7 +217,7 @@ class Dispatcher require(OR_MODULES_DIR . 'util/config-default.php'); $conf = createDefaultConfig(); - $customConfig = Configuration::load(); + $customConfig = ConfigurationLoader::load(); $conf = array_replace_recursive($conf, $customConfig); diff --git a/modules/cms-core/action/ConfigurationAction.class.php b/modules/cms-core/action/ConfigurationAction.class.php @@ -137,7 +137,7 @@ class ConfigurationAction extends Action $conf['interpreter']['environment'] = $_ENV; $conf['interpreter']['temp_dir'] = sys_get_temp_dir(); - $conf['interpreter']['configuration'] = ini_get_all(); + $conf['interpreter']['ConfigurationLoader'] = ini_get_all(); $conf['resources'] = getrusage(); $extensions = get_loaded_extensions(); diff --git a/modules/cms-core/action/ElementAction.class.php b/modules/cms-core/action/ElementAction.class.php @@ -181,7 +181,7 @@ class ElementAction extends Action function propView() { global $conf; - $this->setTemplateVar('type',$this->element->type ); + $this->setTemplateVar('type',$this->element->getTypeName() ); // Abhaengig vom aktuellen Element-Typ die Eigenschaften anzeigen $properties = $this->element->getRelatedProperties(); @@ -202,12 +202,20 @@ class ElementAction extends Action $this->setTemplateVar('writable' ,$this->element->writable ); break; + case 'inherit': + $this->setTemplateVar('inherit' ,$this->element->inherit ); + break; + + case 'html': + $this->setTemplateVar('html' ,$this->element->html ); + break; + case 'subtype': $convertToLang = false; - switch( $this->element->type ) + switch( $this->element->typeid ) { - case 'info': + case ELEMENT_TYPE_INFO: $subtypes = Array('db_id', 'db_name', 'project_id', @@ -241,15 +249,15 @@ class ElementAction extends Action $convertToLang = true; break; - case 'infodate': - case 'linkdate': + case ELEMENT_TYPE_INFODATE: + case ELEMENT_TYPE_LINKDATE: $subtypes = Array('date_published', 'date_saved', 'date_created' ); $convertToLang = true; break; - case 'link': + case ELEMENT_TYPE_LINK: $subtypes = Array( 'file', 'image', @@ -260,7 +268,7 @@ class ElementAction extends Action $convertToLang = true; break; - case 'linkinfo': + case ELEMENT_TYPE_LINKINFO: $subtypes = Array('width', 'height', 'id', @@ -282,13 +290,13 @@ class ElementAction extends Action $convertToLang = true; break; - case 'insert': + case ELEMENT_TYPE_INSERT: $subtypes = Array('inline', 'ssi' ); $convertToLang = true; break; - case 'dynamic': + case ELEMENT_TYPE_DYNAMIC: $files = Array(); $handle = opendir ('./macro'); @@ -313,7 +321,7 @@ class ElementAction extends Action foreach( $subtypes as $t=>$v ) { unset($subtypes[$t]); - $subtypes[$v] = lang('EL_'.$this->element->type.'_'.$v); + $subtypes[$v] = lang('EL_'.$this->element->getTypeName().'_'.$v); } } @@ -329,7 +337,8 @@ class ElementAction extends Action case 'dateformat': - $ini_date_format = $conf['date']['format']; + //$ini_date_format = config('date','format'); + $ini_date_format = config()->subset('date')->get('format'); $dateformat = array(); $this->setTemplateVar('dateformat',''); @@ -352,22 +361,22 @@ class ElementAction extends Action // Eigenschaften Text und Text-Absatz case 'defaultText': - switch( $this->element->type ) + switch( $this->element->typeid ) { - case 'longtext': + case ELEMENT_TYPE_LONGTEXT: $this->setTemplateVar('default_longtext',$this->element->defaultText ); break; - case 'select': - case 'text': + case ELEMENT_TYPE_SELECT: + case ELEMENT_TYPE_TEXT: $this->setTemplateVar('default_text' ,$this->element->defaultText ); break; } break; - case 'htmlwiki': - if ( !$this->element->wiki && !$this->element->html ) + case 'format': + if ( !$this->element->format ) $format = 'none'; elseif ( $this->element->wiki && !$this->element->html ) $format = 'wiki'; @@ -377,19 +386,17 @@ class ElementAction extends Action $format = 'wiki,html'; $this->setTemplateVar('format', $format ); - - $formatlist = array(); - $formatlist['none' ] = 'raw'; // Nur Text, ohne Auszeichnungen - // Für einfache Textelemente gibt es keinen HTML-Editor - if ( $this->element->type == 'longtext' ) - $formatlist['html' ] = 'html'; // Text mit HTML-Editor - $formatlist['wiki' ] = 'wiki'; // Text mit Markup, HTML nicht erlaubt - $formatlist['wiki,html'] = 'wikihtml'; // Text mit Markup, HTML erlaubt - - foreach( $formatlist as $t=>$v ) - $formatlist[$t] = array('lang'=>'EL_PROP_'.$v); - - $this->setTemplateVar('formatlist', $formatlist ); + + $formats = Element::getAvailableFormats(); + + // Für einfache Textelemente gibt es keinen HTML-Editor + if ( $this->element->typeid == ELEMENT_TYPE_LONGTEXT ) + unset( $formats[ ELEMENT_FORMAT_HTML ] ); + + foreach( $formats as $t=>$v ) + $formats[$t] = array('lang'=>'EL_PROP_'.$v); + + $this->setTemplateVar('formatlist', $formats); break; case 'linktype': @@ -446,14 +453,14 @@ class ElementAction extends Action // Eigenschaften PHP-Code case 'code': - switch( $this->element->type ) + switch( $this->element->typeid ) { - case 'select': + case ELEMENT_TYPE_SELECT: $this->setTemplateVar('select_items',$this->element->code ); break; - case 'dynamic': + case ELEMENT_TYPE_DYNAMIC: $className = $this->element->subtype; $fileName = OR_DYNAMICCLASSES_DIR.'/'.$className.'.class.'.PHP_EXT; @@ -503,7 +510,7 @@ class ElementAction extends Action break; - case 'code': + case ELEMENT_TYPE_CODE: if ( $conf['security']['disable_dynamic_code'] ) $this->addNotice('element',$this->element->name,'CODE_DISABLED',OR_NOTICE_WARN); @@ -541,19 +548,19 @@ class ElementAction extends Action $o = new BaseObject( $id ); $o->load(); - switch( $this->element->type ) + switch( $this->element->typeid ) { - case 'list': + case ELEMENT_TYPE_INSERT: if ( !$o->isFolder ) continue 2; break; - case 'link': + case ELEMENT_TYPE_LINK: if ( !$o->isPage && !$o->isFile && !$o->isLink ) continue 2; break; //Change tobias - case 'insert': + case ELEMENT_TYPE_INSERT: if ( !$o->isFolder && !$o->isPage && !$o->isFile && !$o->isLink ) continue 2; break; @@ -623,7 +630,7 @@ class ElementAction extends Action break; default: - throw new \LogicException('not an element property: '.$propertyName ); + throw new \LogicException('Unknown element property: '.$propertyName ); } } } @@ -631,31 +638,41 @@ class ElementAction extends Action /** - * Speichern der Element-Eigenschaften + * Speichern der Element-Eigenschaften. */ function propPost() { global $conf; - $ini_date_format = $conf['date']['format']; - - if ( $this->hasRequestVar('dateformat')) + $ini_date_format = config('date','format'); + + + if ( $this->hasRequestVar('format')) + $this->element->format = $this->getRequestId('format'); + + + if ( $this->hasRequestVar('dateformat')) $this->element->dateformat = $ini_date_format[$this->getRequestVar('dateformat')]; - $this->element->subtype = $this->getRequestVar('subtype'); - - if ( $this->hasRequestVar('default_longtext')) - $this->element->defaultText = $this->getRequestVar('default_longtext',OR_FILTER_RAW); - else - $this->element->defaultText = $this->getRequestVar('default_text',OR_FILTER_ALPHANUM); - $this->element->wiki = in_array('wiki',explode(',',$this->getRequestVar('format'))); - $this->element->html = in_array('html',explode(',',$this->getRequestVar('format'))); - $this->element->withIcon = $this->getRequestVar('with_icon') != ''; - $this->element->allLanguages = $this->getRequestVar('all_languages') != ''; - $this->element->writable = $this->getRequestVar('writable') != ''; + + + if ( $this->hasRequestVar('default_longtext')) + $this->element->defaultText = $this->getRequestVar('default_longtext',OR_FILTER_RAW); + else + $this->element->defaultText = $this->getRequestVar('default_text',OR_FILTER_ALPHANUM); + + $this->element->subtype = $this->getRequestVar('subtype'); + + $this->element->html = $this->hasRequestVar('html'); + $this->element->withIcon = $this->hasRequestVar('with_icon'); + $this->element->allLanguages = $this->hasRequestVar('all_languages'); + $this->element->writable = $this->hasRequestVar('writable'); + $this->element->inherit = $this->hasRequestVar('inherit'); + $this->element->decimals = $this->getRequestVar('decimals'); $this->element->decPoint = $this->getRequestVar('dec_point'); $this->element->thousandSep = $this->getRequestVar('thousand_sep'); $this->element->folderObjectId = $this->getRequestVar('folderobjectid' ); $this->element->defaultObjectId = $this->getRequestVar('default_objectid'); + if ( $this->hasRequestVar('select_items')) $this->element->code = $this->getRequestVar('select_items'); else @@ -670,7 +687,6 @@ class ElementAction extends Action if ( $this->hasRequestVar('parameters')) $this->element->code = $this->getRequestVar('parameters',OR_FILTER_RAW); -// Html::debug($this->element); $this->element->save(); $this->addNotice('element',$this->element->name,'SAVED'); diff --git a/modules/cms-core/action/TemplateAction.class.php b/modules/cms-core/action/TemplateAction.class.php @@ -371,8 +371,9 @@ class TemplateAction extends Action $list[$elid]['id' ] = $elid; $list[$elid]['name' ] = $element->name; $list[$elid]['description'] = $element->desc; - $list[$elid]['type' ] = $element->type; - + $list[$elid]['type' ] = $element->getTypeName(); + $list[$elid]['typeid' ] = $element->typeid; + unset( $element ); } $this->setTemplateVar('elements',$list); diff --git a/modules/cms-core/functions/common.inc.php b/modules/cms-core/functions/common.inc.php @@ -69,32 +69,6 @@ function readonly() -/* - * Liest einen Schluessel aus der Konfiguration - * - * @return String, leer falls Schluessel nicht vorhanden - */ -function config( $part1,$part2=null,$part3=null ) -{ - global $conf; - - if ( $part2 == null) - if ( isset($conf[$part1])) - return $conf[$part1]; - else - return ''; - - if ( $part3 == null) - if ( isset($conf[$part1][$part2])) - return $conf[$part1][$part2]; - else - return ''; - - if ( isset($conf[$part1][$part2][$part3])) - return $conf[$part1][$part2][$part3]; - else - return ''; -} /** diff --git a/modules/cms-core/model/Element.class.php b/modules/cms-core/model/Element.class.php @@ -114,6 +114,12 @@ class Element */ var $writable; + /** + * values are inherited from parent nodes. + * @var bool + */ + public $inherit; + /** * Schalter, ob dieses Element in allen Sprachen den gleichen Inhalt haben soll * @type Boolean @@ -234,6 +240,7 @@ SQL $this->html = $prop['flags'] & ELEMENT_FLAG_HTML_ALLOWED; $this->allLanguages = $prop['flags'] & ELEMENT_FLAG_ALL_LANGUAGES; $this->writable = $prop['flags'] & ELEMENT_FLAG_WRITABLE; + $this->inherit = $prop['flags'] & ELEMENT_FLAG_INHERIT; if ( !$this->writable) $this->withIcon = false; @@ -279,6 +286,7 @@ SQL $flags += ELEMENT_FLAG_HTML_ALLOWED * intval($this->html ); $flags += ELEMENT_FLAG_ALL_LANGUAGES * intval($this->allLanguages); $flags += ELEMENT_FLAG_WRITABLE * intval($this->writable ); + $flags += ELEMENT_FLAG_INHERIT * intval($this->inherit ); $sql->setInt ( 'elementid' ,$this->elementid ); $sql->setInt ( 'templateid' ,$this->templateid ); @@ -387,22 +395,22 @@ SQL */ function getRelatedProperties() { - $prp = array('text' =>array('withIcon','allLanguages','writable','htmlwiki','defaultText'), - 'longtext'=>array('withIcon','allLanguages','writable','htmlwiki','defaultText'), - 'select' =>array('withIcon','allLanguages','writable','defaultText','code'), - 'number' =>array('withIcon','allLanguages','writable','decPoint','decimals','thousandSep'), - 'link' =>array('subtype','withIcon','allLanguages','writable','linktype','folderObjectId','defaultObjectId'), - 'date' =>array('withIcon','allLanguages','writable','dateformat','defaultText'), - 'list' =>array('subtype','withIcon','allLanguages','writable','folderObjectId','defaultObjectId'), - 'insert' =>array('subtype','withIcon','allLanguages','writable','folderObjectId','defaultObjectId'), - 'copy' =>array('prefix','name','defaultText'), + $prp = array('text' =>array('inherit','withIcon','allLanguages','writable','html','defaultText'), + 'longtext'=>array('inherit','withIcon','allLanguages','writable','html','defaultText','format'), + 'select' =>array('inherit','withIcon','allLanguages','writable','defaultText','code'), + 'number' =>array('inherit','withIcon','allLanguages','writable','decPoint','decimals','thousandSep'), + 'link' =>array('inherit','subtype','withIcon','allLanguages','writable','linktype','folderObjectId','defaultObjectId'), + 'date' =>array('inherit','withIcon','allLanguages','writable','dateformat','defaultText'), + 'list' =>array('inherit','subtype','withIcon','allLanguages','writable','folderObjectId','defaultObjectId'), + 'insert' =>array('inherit','subtype','withIcon','allLanguages','writable','folderObjectId','defaultObjectId'), + 'copy' =>array('inherit','prefix','name','defaultText'), 'linkinfo'=>array('prefix','subtype','defaultText'), 'linkdate'=>array('prefix','subtype','dateformat'), 'code' =>array('code'), 'dynamic' =>array('subtype','code'), 'info' =>array('subtype'), 'infodate'=>array('subtype','dateformat') ); - return $prp[ $this->type ]; + return $prp[ $this->getTypeName() ]; } @@ -425,12 +433,12 @@ SQL } - /** - * Ermitteln aller benutzbaren Elementtypen. + /** + * Ermitteln aller benutzbaren Elementtypen. * - * @return array id->name - */ - public static function getAvailableTypes() + * @return array id->name + */ + public static function getAvailableTypes() { return array( ELEMENT_TYPE_TEXT => 'text', @@ -451,6 +459,22 @@ SQL } + /** + * Ermitteln aller benutzbaren Elementtypen. + * + * @return array id->name + */ + public static function getAvailableFormats() + { + return array( + ELEMENT_FORMAT_TEXT => 'text', + ELEMENT_FORMAT_WIKI => 'wiki', + ELEMENT_FORMAT_HTML => 'html', + ELEMENT_FORMAT_MARKDOWN => 'markdown' + ); + } + + /** * Ermittelt die Klasse des Element-Typs.<br> * Entweder "info", "text" oder "dynamic". @@ -549,6 +573,17 @@ SQL return $this->writable; } + + + /** + * The technical name of this element type. + * + * @return String + */ + public function getTypeName() { + return Element::getAvailableTypes()[ $this->typeid ]; // name of type + + } } ?> \ No newline at end of file diff --git a/modules/configuration/Configuration.class.php b/modules/configuration/Configuration.class.php @@ -1,153 +1,92 @@ <?php -/** - * Configuration Loader. +/* + * Liest einen Schluessel aus der Konfiguration * - * Loades the configuration values from a YAML file. - * - * @author Jan Dankert - * @package openrat.util + * @return String, leer falls Schluessel nicht vorhanden */ -class Configuration +function config( $part1=null,$part2=null,$part3=null ) { - public static $configFile = __DIR__.'/../../config/config.yml'; + global $conf; + + if ( $part1==null ) + return new Config( $conf ); + + if ( $part2 == null) + if ( isset($conf[$part1])) + return $conf[$part1]; + else + return ''; + + if ( $part3 == null) + if ( isset($conf[$part1][$part2])) + return $conf[$part1][$part2]; + else + return ''; + + if ( isset($conf[$part1][$part2][$part3])) + return $conf[$part1][$part2][$part3]; + else + return ''; +} + + +class Config +{ + private $config = array(); + /** - * Ermittelt den Zeitpunkt der letzten Änderung der Konfigurationsdatei. - * - * @return int Zeitpunkt der letzten Änderung als Unix-Timestamp + * Config constructor. + * @param $config */ - public static function lastModificationTime() + public function __construct( $config ) { - return filemtime(self::$configFile); + $this->config = $config; } /** - * Loads the custom configuration file. + * Giving the child configuration with a fluent interface. * - * @return array Configuration + * @param $name + * @return Config */ - public static function load() + public function subset( $name ) { - $customConfig = Configuration::loadCustomConfig(self::$configFile); - - - // Resolve dot-notated configuration keys to arrays. - // Means: a.b.c is converted to array['a']['b']['c'] - foreach ($customConfig as $key => $value) { - $parts = explode('.', $key); - if (count($parts) == 1) - ; // Kein Punkt enthalten. Dieser Konfigurationsschlüssel wird nicht geändert. - else { - - if (count($parts) == 2) - $customConfig[$parts[0]][$parts[1]] = $value; - elseif (count($parts) == 3) - $customConfig[$parts[0]][$parts[1]][$parts[2]] = $value; - elseif (count($parts) == 4) - $customConfig[$parts[0]][$parts[1]][$parts[2]][$parts[3]] = $value; - elseif (count($parts) == 5) - $customConfig[$parts[0]][$parts[1]][$parts[2]][$parts[3]][$parts[4]] = $value; - elseif (count($parts) == 6) - $customConfig[$parts[0]][$parts[1]][$parts[2]][$parts[3]][$parts[4]][$parts[5]] = $value; - unset($customConfig[$key]); - } - } - - - // Den Dateinamen der Konfigurationsdatei in die Konfiguration schreiben. - $customConfig['config']['filename' ] = self::$configFile; - $customConfig['config']['last_modification_time'] = filemtime(self::$configFile); - $customConfig['config']['last_modification' ] = date('r', filemtime(self::$configFile)); - $customConfig['config']['read' ] = date('r'); - - return $customConfig; + if ( isset( $this->config[ $name ] )) + return new Config( $this->config[$name] ); + else + return new Config( array() ); } - /** - * Loads the configuration file an resolves all include-commands. - * - * @return array Configuration - */ - private static function loadCustomConfig( $configFile ) + public function get( $name, $default = null ) { - if (!is_file($configFile) && !is_link($configFile)) { - error_log('Warning: Configuration file ' . $configFile . ' not found'); - return array(); + if ( isset( $this->config[ $name ] ) ) + { + $value = $this->config[$name]; + + // if default-value is given, the type of the default-value is forced. + if( !is_null( $default) ) + settype( $value, gettype($default) ); + return $value; } - - $customConfig = Spyc::YAMLLoad( $configFile ); - - // Resolve variables in all custom configuration values - array_walk_recursive( $customConfig, function(&$value,$key) - { - $value = Configuration::resolveVariables($value); - - } - ); - - // Does we have includes? - if (isset($customConfig['include'])) { - - if (is_string($customConfig['include'])) - $customConfig['include'] = array($customConfig['include']); - - // Load include files. - foreach ($customConfig['include'] as $key => $file) { - - if (substr($file, -4) == '.yml' || - substr($file, -5) == '.yaml' || - substr($file, -8) == '.yml.php' ) - $customConfig += Configuration::loadCustomConfig($file); - else - error_log('Warning: ' . $file . ' is no .yml file - not loaded'); - - } + else + { + return $default; } - - return $customConfig; } - /** - * Evaluates variables in a text value. - * Examples: - * - config-${http:host}.yml => config-yourdomain.yml - * - config-${server:http-host}.yml => config-yourdomain.yml - * - config-${env:myvar}.yml => config-myvalue.yml - * @param $value String Configuration value - * @return String - */ - private static function resolveVariables($value) + + public function is( $name ) { - return preg_replace_callback( - "|\\$\{([[:alnum:]]+)\:([[:alnum:]_]+)\}|", - - function ($match) - { - $type = $match[1]; - $value = $match[2]; - $value = str_replace('-', '_', $value); - - switch( strtolower( $type ) ) - { - case 'env': - return getenv(strtoupper($value)); - - case 'http': // http:... is a shortcut for server:http-... - return @$_SERVER['HTTP_' . strtoupper($value)]; - - case 'server': - return @$_SERVER[strtoupper($value)]; - default: - return ""; - } - }, - - $value); + if ( isset( $this->config[ $name ] ) ) + return (bool) $this->config[$name]; + else + return false; } -} +}+ \ No newline at end of file diff --git a/modules/configuration/ConfigurationLoader.class.php b/modules/configuration/ConfigurationLoader.class.php @@ -0,0 +1,153 @@ +<?php + + +/** + * Configuration Loader. + * + * Loades the configuration values from a YAML file. + * + * @author Jan Dankert + * @package openrat.util + */ +class ConfigurationLoader +{ + public static $configFile = __DIR__.'/../../config/config.yml'; + + /** + * Ermittelt den Zeitpunkt der letzten Änderung der Konfigurationsdatei. + * + * @return int Zeitpunkt der letzten Änderung als Unix-Timestamp + */ + public static function lastModificationTime() + { + return filemtime(self::$configFile); + } + + + /** + * Loads the custom configuration file. + * + * @return array Configuration + */ + public static function load() + { + $customConfig = ConfigurationLoader::loadCustomConfig(self::$configFile); + + + // Resolve dot-notated configuration keys to arrays. + // Means: a.b.c is converted to array['a']['b']['c'] + foreach ($customConfig as $key => $value) { + $parts = explode('.', $key); + if (count($parts) == 1) + ; // Kein Punkt enthalten. Dieser Konfigurationsschlüssel wird nicht geändert. + else { + + if (count($parts) == 2) + $customConfig[$parts[0]][$parts[1]] = $value; + elseif (count($parts) == 3) + $customConfig[$parts[0]][$parts[1]][$parts[2]] = $value; + elseif (count($parts) == 4) + $customConfig[$parts[0]][$parts[1]][$parts[2]][$parts[3]] = $value; + elseif (count($parts) == 5) + $customConfig[$parts[0]][$parts[1]][$parts[2]][$parts[3]][$parts[4]] = $value; + elseif (count($parts) == 6) + $customConfig[$parts[0]][$parts[1]][$parts[2]][$parts[3]][$parts[4]][$parts[5]] = $value; + unset($customConfig[$key]); + } + } + + + // Den Dateinamen der Konfigurationsdatei in die Konfiguration schreiben. + $customConfig['config']['filename' ] = self::$configFile; + $customConfig['config']['last_modification_time'] = filemtime(self::$configFile); + $customConfig['config']['last_modification' ] = date('r', filemtime(self::$configFile)); + $customConfig['config']['read' ] = date('r'); + + return $customConfig; + } + + + /** + * Loads the configuration file an resolves all include-commands. + * + * @return array Configuration + */ + private static function loadCustomConfig( $configFile ) + { + if (!is_file($configFile) && !is_link($configFile)) { + error_log('Warning: Configuration file ' . $configFile . ' not found'); + return array(); + } + + $customConfig = Spyc::YAMLLoad( $configFile ); + + // Resolve variables in all custom configuration values + array_walk_recursive( $customConfig, function(&$value,$key) + { + $value = ConfigurationLoader::resolveVariables($value); + + } + ); + + // Does we have includes? + if (isset($customConfig['include'])) { + + if (is_string($customConfig['include'])) + $customConfig['include'] = array($customConfig['include']); + + // Load include files. + foreach ($customConfig['include'] as $key => $file) { + + if (substr($file, -4) == '.yml' || + substr($file, -5) == '.yaml' || + substr($file, -8) == '.yml.php' ) + $customConfig += ConfigurationLoader::loadCustomConfig($file); + else + error_log('Warning: ' . $file . ' is no .yml file - not loaded'); + + } + } + + return $customConfig; + } + + /** + * Evaluates variables in a text value. + * Examples: + * - config-${http:host}.yml => config-yourdomain.yml + * - config-${server:http-host}.yml => config-yourdomain.yml + * - config-${env:myvar}.yml => config-myvalue.yml + * @param $value String Configuration value + * @return String + */ + private static function resolveVariables($value) + { + return preg_replace_callback( + "|\\$\{([[:alnum:]]+)\:([[:alnum:]_]+)\}|", + + function ($match) + { + $type = $match[1]; + $value = $match[2]; + $value = str_replace('-', '_', $value); + + switch( strtolower( $type ) ) + { + case 'env': + return getenv(strtoupper($value)); + + case 'http': // http:... is a shortcut for server:http-... + return @$_SERVER['HTTP_' . strtoupper($value)]; + + case 'server': + return @$_SERVER[strtoupper($value)]; + default: + return ""; + } + }, + + $value); + } + +} + diff --git a/modules/configuration/require.php b/modules/configuration/require.php @@ -1,3 +1,4 @@ <?php -require_once( __DIR__ ."/Configuration.class.php" ); +require_once(__DIR__ . "/ConfigurationLoader.class.php"); +require_once(__DIR__ . "/Configuration.class.php");