.
*
*///}}}
declare(strict_types=1);
namespace rabe\Util;
/**
* Settings Class to read Configuration Files
* @author Norbert.e.Wagner dev@norb.me
*/
class Settings implements \Iterator
{
private const SITE = 0x01;
private array $settings = [];
private string $appPath;
private ?string $pkgPath = null;
private ?string $site = null;
protected string $confDir = 'config/';
protected string $filePrefix = 'VeruA.';
protected string $filePostfix = 'conf.php';
protected array $modes = [
'prod' => 'default',
'test' => 'testing',
];
private string $mode;
// Constructor {{{
/** {{{
* Construct a new Settings Object
*
* @param array $settings an array of settings to be used directly
* @param string $mode One of the keys of $this->modes
*///}}}
public function __construct( ?array $settings=null, ?string $mode=null )
{
if (isset($settings)) $this->settings = $settings;
if (isset($mode)) $this->mode = $mode;
}// }}}
// appPath() {{{
/** {{{
* Sets the application path where the config/ dirtectory is located
* If the package path is not set it is set to the appPath
*
*///}}}
public function appPath( string $path )
{
$this->appPath = $path;
if (! isset( $this->pkgPath )) $this->pkgPath = $path;
return $this;
}// }}}
// pkgPath() {{{
/** {{{
* Sets the package path where the config/ dirtectory for the default and mode files is located
*
*///}}}
public function pkgPath( string $path )
{
$this->pkgPath = $path;
return $this;
}// }}}
// prefix() {{{
/** {{{
*///}}}
public function prefix( string $prefix )
{
$this->filePrefix = "$prefix.";
return $this;
}// }}}
// addModes() {{{
/** {{{
*///}}}
public function addModes( array $modes )
{
$this->modes += $modes;
return $this;
}// }}}
// site() {{{
/** {{{
*///}}}
public function site( string $site )
{
$this->site = $site;
return $this;
}// }}}
// load() method {{{
/** {{{
* Load the configuration from the files and merge them
*
* @param array $settings uses the Settings as an Array.
*///}}}
public function load( ?array $settings=null )
{
if (isset($settings))
{
$this->settings = $settings;
}
else
{
$modes = $this->modes;
// load Prefix.default.conf.php
$defaultConf = $this->buildFileName( array_shift($modes) );
if ( file_exists($defaultConf) )
{
$this->settings = require( $defaultConf );
}
else
{
// echo "No settingsfile: $defaultConf";
throw new \ErrorException( "No settingsfile: $defaultConf" );
// throw new FileNotFoundException();
}
// load local config without merging - we need it here for the mode
$conf = $this->buildFileName();
$localConf = false;
if (file_exists($conf)) $localConf = require($conf);
if ( $this->site )
{
$siteConf = $this->buildFileName(self::SITE);
if (file_exists($siteConf))
{
$localConf = array_replace_recursive($localConf, require($siteConf));
}
}
if (! isset($this->mode))
{ // if a localConf Mode is set use it, or take the default conf mode
$this->mode = (isset($localConf['mode'])) ? $localConf['mode'] : $this->settings['mode'];
}
else
{
$this->settings['mode'] = $this->mode;
}
// load and merge Prefix.mode.conf.php
if ( isset( $modes[ $this->mode ] ) )
{
$modeConf = $this->buildFileName( $modes[ $this->mode ], $ext );
if ( file_exists($modeConf) )
{
$this->settings = array_replace_recursive( $this->settings, require($modeConf) );
}
else
{
// log no mode config File
}
}
else
{
// log invalid mode
}
// merge Prefix.conf.php (localConf)
if ($localConf !== false)
{
$this->settings = array_replace_recursive( $this->settings, $localConf );
}
}
// echo "
"; print_r( $this->settings ); echo ""; return $this; }// }}} // mergeFile() {{{ /** {{{ *///}}} public function mergeFile( ) { }// }}} // create() {{{ /** {{{ * Creates a copy of the Settingsobject without the Settings * *///}}} public function create( ?array $settings=null ) { $cfg = clone $this; if (isset($settings)) $cfg->load($settings); return $cfg; }// }}} // buildFileName() method {{{ /** {{{ * Compose the filename of the configuration File * @param string|hex $mode The name of the mode, null for localConf and self::SITE for the site config *///}}} public function buildFileName( $type=null ) { $mode = ''; $path = $this->appPath.$this->confDir; if ($tpye === self::SITE) $path .= $this->site.'/'; if (is_string( $type )) { $mode = "$type."; $path = $this->pkgPath.$this->confDir; } return $path.$this->filePrefix.$mode.$this->filePostfix; } // }}} // toArray() method {{{ /** * Return the internal settings array * * @return array */ public function toArray() { return $this->settings; }// }}} // __clone() {{{ /** {{{ *///}}} public function __clone() { $this->settings = []; }// }}} // Iterator methods {{{ /** * Rewind the Iterator to the first element * @link https://www.php.net/iterator.rewind */ public function rewind() { reset( $this->settings); } /** * Return the current element * @link https://www.php.net/iterator.current */ public function current() { return current( $this->settings ); } /** * Return the key of the current element * @link https://www.php.net/iterator.key */ public function key() { return key( $this->settings ); } /** * Move forward to next element * @link https://www.php.net/iterator.next */ public function next() { return next( $this->settings ); } /** * Checks if current position is valid * @link https://www.php.net/iterator.valid */ public function valid() { $key = key( $this->settings ); return ($key !== null && $key !== false); } // }}} // Magic getter/setter methods {{{ public function __set( $name, $value ) { // todo: throw new SettingsAreReadOnlyException(); } public function __get( $name ) { if ( !isset( $this->settings[$name] ) ) { throw new \Exception("Setting '$name' not found"); // todo: throw new SettingNotFoundException(); } return (is_array( $this->settings[$name] )) ? $this->create( $this->settings[$name] ) : $this->settings[$name]; } public function __isset( $name ) { return ( isset( $this->settings[$name] ) ); } public function __unset( $name ) { unset( $this->settings[$name] ); } // }}} } /* jEdit buffer local properties {{{ * :folding=explicit:collapseFolds=1: }}}*/