openrat-cms

# OpenRat Content Management System
git clone http://git.code.weiherhei.de/openrat-cms.git
Log | Files | Refs

commit 4c0c55c05fd331bef753c862056819feed75b3f7
parent 5bfef3945ca7a1b937cf9772aa396b1a7df1f8b0
Author: Jan Dankert <develop@jandankert.de>
Date:   Thu, 21 Nov 2019 23:52:14 +0100

New: VariableResolver in its own class. Keeps other code more tidy.

Diffstat:
index.php | 2+-
modules/cms-macros/MacroRunner.class.php | 18++++++++----------
modules/configuration/ConfigurationLoader.class.php | 35+++++++++++++++++------------------
modules/util/VariableResolver.class.php | 132+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
modules/util/require.php | 1+
5 files changed, 159 insertions(+), 29 deletions(-)

diff --git a/index.php b/index.php @@ -65,7 +65,7 @@ if (!headers_sent()) <p>Something went terribly wrong.</p> <?php // Display exceptions only in development mode, because the may contain sensitive internal information like passwords. - if (defined('DEVELOPMENT') && DEVELOPMENT ) { ?> + if (!defined('DEVELOPMENT') || DEVELOPMENT ) { ?> <pre><?php echo $e->__toString(); ?></pre> <?php } ?> </main> diff --git a/modules/cms-macros/MacroRunner.class.php b/modules/cms-macros/MacroRunner.class.php @@ -4,6 +4,7 @@ use cms\model\Element; use cms\model\Template; use cms\model\Value; +use util\VariableResolver; class MacroRunner { @@ -34,15 +35,15 @@ class MacroRunner $macro->setContextPage($page); - $parameters = $parameter; + $resolver = new VariableResolver(); - array_walk_recursive($parameters, function (&$item, $key) { + $parameters = $resolver->resolveVariablesInArrayWith( $parameter, - $item = \Text::resolveVariables($item, 'setting', function ($var) { + ['setting'=> function ($var) { return ArrayUtils::getSubValue($this->page->getSettings(), explode('.', $var)); - }); + }], - $item = \Text::resolveVariables($item, 'element', function ($var) { + ['element'=>function ($var) { $template = new Template($this->page->templateid); $elements = $template->getElementNames(); $elementid = array_search($var, $elements); @@ -57,11 +58,8 @@ class MacroRunner $value->load(); return $value->getRawValue(); - - }); - - return $item; - }); + }] + ); foreach ($parameters as $param_name => $param_value) { diff --git a/modules/configuration/ConfigurationLoader.class.php b/modules/configuration/ConfigurationLoader.class.php @@ -1,5 +1,7 @@ <?php +use util\VariableResolver; + /** * Configuration Loader. @@ -68,13 +70,8 @@ class ConfigurationLoader $customConfig = YAML::parse( file_get_contents($configFile) ); - // Resolve variables in all custom configuration values - array_walk_recursive( $customConfig, function(&$value,$key) - { - $value = ConfigurationLoader::resolveVariables($value); - - } - ); + // resolve variables + $customConfig = ConfigurationLoader::resolveVariables($customConfig); // Does we have includes? if (isset($customConfig['include'])) { @@ -106,23 +103,25 @@ class ConfigurationLoader } /** - * Evaluates variables in a text value. + * Evaluates variables in a config array. * Examples: - * - config-${http:host}.yml => config-yourdomain.yml + * - 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 + * - config-${env:myvar}.yml => config-myvalue.yml + * @param $config array Configuration + * @return array */ - private function resolveVariables($value) + private function resolveVariables($config) { - $value = Text::resolveVariables( $value, 'env' , function($var) { return getenv(strtoupper($var)); } ); + $resolver = new VariableResolver(); - // http:... is a shortcut for server:http-... - $value = Text::resolveVariables( $value,'http' , function($var) { return @$_SERVER['HTTP_' . strtoupper($var)]; } ); - $value = Text::resolveVariables( $value,'server', function($var) { return @$_SERVER[strtoupper($var)]; } ); + return $resolver->resolveVariablesInArrayWith($config,[ - return $value; + 'env' => function($var) { return getenv(strtoupper($var)); }, + // http:... is a shortcut for server:http-... + 'http' => function($var) { return @$_SERVER['HTTP_' . strtoupper($var)]; }, + 'server'=> function($var) { return @$_SERVER[strtoupper($var)]; } + ] ); } } diff --git a/modules/util/VariableResolver.class.php b/modules/util/VariableResolver.class.php @@ -0,0 +1,131 @@ +<?php + + +namespace util; + +/** + * VariableResolver for resolving variables in strings and arrays. + */ + +class VariableResolver +{ + public $begin = '${'; + public $end = '}'; + public $split = ':'; + + /** + * Resolving a variable in a text like 'name is ${env:username:default}.' + * + * @param $value array + * @param $key string + * @param $resolver callable + * @return array + */ + public function resolveVariablesInArray($value,$key,$resolver) { + + return $this->resolveVariablesInArrayWith( $value, [$key=>$resolver] ); + } + + + + /** + * Resolving a variable in a text like 'name is ${env:username:default}.' + * + * @param $value array + * @param $resolvers array List of resolvers + * @return array + */ + public function resolveVariablesInArrayWith($value,$resolvers) { + + // pass-by-reference + array_walk_recursive($value, function (&$item, $keyI) use ($resolvers) { + + $item = $this->resolveVariablesWith($item, $resolvers); + return $item; + }); + + return $value; + + } + + + + /** + * Resolving a variable in a text like 'name is ${env:username:default}'. + * + * @param $value + * @param $key + * @param $resolver + * @return string + */ + public function resolveVariables($value,$key,$resolver) + { + return $this->resolveVariablesWith( $value,[$key=>$resolver] ); + } + + + + /** + * Resolving a variable in a text like 'name is ${env:username:default}'. + * + * @param $value + * @param $key + * @param $resolver + * @return string + */ + public function resolveVariablesWith($value, $resolvers) + { + $offset = 0; + + while( true ) + { + if ( $offset >= strlen($value) ) + return $value; + + $pos = strpos($value, $this->begin, $offset); + + if ($pos === FALSE) + return $value; + + + $posEnd = strpos($value, $this->end, $offset); + + if ($posEnd === FALSE) + return $value; + + $names = explode( $this->split, substr($value, $pos + strlen($this->begin ), $posEnd - strlen($this->begin) - $pos )); + $resolverName = $names[0]; + $key = @$names[1]; + $default = @$names[2]; + + $varValue = $default; + + if ( isset( $resolvers[$resolverName] )) { + + $resolverFunction = $resolvers[ $resolverName ]; + + if ( is_callable($resolverFunction ) ) + { + $result = $resolverFunction($key); + + if ( $result ) + $varValue = $result; + } + } + + $value = substr($value, 0, $pos) . $varValue . substr($value,$posEnd + strlen($this->end)); + $offset = $pos + strlen($varValue); + } + + return $value; + } +} + +/** Usage: * + +$resolver = new VariableResolver(); +print_r( $resolver->resolveVariables('Born in the ${bruce:birthcountry}.','bruce',function($name){return 'USA';} ) ); +print_r( $resolver->resolveVariables('Born in ${bruce:birthyear:19??}.','bruce',function($name){return '';} ) ); +print_r( $resolver->resolveVariables('Born in the ${bruce:birthcountry}.${x:y}${x}','bruce',function($name){return 'USA';} ) ); +exit; +*/+ \ No newline at end of file diff --git a/modules/util/require.php b/modules/util/require.php @@ -39,4 +39,5 @@ require_once( __DIR__.'/'.'ArchiveTar.class.php' ); require_once( __DIR__.'/'.'ArchiveUnzip.class.php' ); require_once( __DIR__.'/'.'ArchiveZip.class.php' ); require_once( __DIR__.'/'.'Mustache.class.php' ); +require_once( __DIR__.'/'.'VariableResolver.class.php');