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:
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');