. * *///}}} 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: }}}*/