Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F1974880
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
11 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/lib/Kolab/Config.php b/lib/Kolab/Config.php
index 2aa49bb..c83e146 100644
--- a/lib/Kolab/Config.php
+++ b/lib/Kolab/Config.php
@@ -1,378 +1,378 @@
<?php
/**
* Model class to give access to service configuration
*
* This file is part of the Kolab PHP Utilities library
*
* @author Thomas Bruederli <bruederli@kolabsys.com>
*
* Copyright (C) 2013, Kolab Systems AG <contact@kolabsys.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Kolab;
/**
* Wrapper class for service configuration
*/
class Config
{
const STRING = 0;
const BOOL = 1;
const INT = 2;
const FLOAT = 3;
const ARR = 4;
const HASH = 5;
const EMAIL = 6;
protected static $instance;
protected $env = '';
protected $basedir = '../config';
protected $data = array();
protected $valid = false;
/**
* Singelton getter
*
* @param string Path to load config from
*/
public static function get_instance($env = '', $dir = null)
{
if (!isset(self::$instance)) {
self::$instance = new Config($env);
if ($dir) self::$instance->basedir = $dir;
}
if (!self::$instance->valid) {
self::$instance->load('config.ini');
}
return self::$instance;
}
/**
* Default constructor
*/
function __construct($env = '')
{
$this->env = $env;
}
/**
* Load config from the given .ini file
*/
protected function load($file, $use_env = true)
{
// check for relative path
if (!is_readable($file) && is_readable($this->basedir . '/' . $file)) {
$file = $this->basedir . '/' . $file;
}
$inifile = $this->resolve_path($file, $use_env);
if ($raw = self::parse_ini_file($inifile, true)) {
foreach ($raw as $section => $values) {
$sub = null;
if (preg_match('/^(\w+)\s+"?(.+)"?$/i', $section, $m)) {
$section = $m[1];
$sub = trim($m[2], '"');
}
if (!empty($sub) && !empty($values)) {
$config[$section][$sub] = $values;
}
else if (!empty($values) && is_array($values)) {
$config[$section] = $values;
}
}
$this->register($config);
$this->valid = !empty($this->data);
}
else {
trigger_error("Failed to parse configuration from $inifile", E_USER_ERROR);
}
}
/**
* Helper method to resolve the absolute path to the given config file.
* This also takes the 'env' property into account.
*/
protected function resolve_path($file, $use_env)
{
- if ($file[0] != '/') {
+ if ($file[0] != '/' && $this->basedir[0] == '/') {
$file = realpath($this->basedir . '/' . $file);
}
// check if <file>-env.ini exists
if ($file && $use_env && !empty($this->env)) {
$envfile = preg_replace('/\.(ini|conf)$/', '-' . $this->env . '.\\1', $file);
if (is_file($envfile))
return $envfile;
}
return $file;
}
/**
* Replacement for PHP's parse_ini_file()
*/
protected static function parse_ini_file($filename)
{
$raw = array();
foreach (file($filename) as $_line) {
if ($_line[0] == ';') // skip comments
continue;
// chop off comments at the end of a line
$_line = preg_replace('/;[^\'"]*$/', '', $_line);
if (preg_match('/^\[([a-z0-9-_\.]+[^\]]*)\]/', $_line, $matches)) {
$_cur_section = $matches[1];
$raw[$_cur_section] = array();
unset($_cur_key);
}
if (preg_match('/^([a-z0-9\.-_]+)\s*=\s*(.*)/', $_line, $matches)) {
if (isset($_cur_section) && !empty($_cur_section)) {
$_cur_key = $matches[1];
$value = isset($matches[2]) ? trim($matches[2], ' "') : '';
if (preg_match('/^(true|yes|on)$/', $matches[2])) // convert boolean values right away
$value = true;
$raw[$_cur_section][$matches[1]] = $value;
}
}
else if (preg_match('/^\s+(.*)$/', $_line, $matches)) {
if (isset($_cur_key) && !empty($_cur_key)) {
$raw[$_cur_section][$_cur_key] .= $matches[1];
}
}
}
return $raw;
}
/**
* Dump the hierarchical structure of config options into a flat list with keys delimited by dots
*/
public function register($config, $prefix = '')
{
// merge the new config values over existing data
if (empty($prefix)) {
$this->data = array_replace_recursive($this->data, $config);
}
else if (is_array($config)) {
$pkey = rtrim($prefix, '.');
$this->data[$pkey] = is_array($this->data[$pkey]) ? array_replace_recursive((array)$this->data[$pkey], $config) : $config;
}
foreach ((array)$config as $key => $val) {
if (is_array($val)) {
$this->register($val, "$prefix$key.");
}
else {
$this->data[$prefix.$key] = $val;
}
}
// resolve references in config options (e.g. %(foo.bar))
if (empty($prefix)) {
array_walk_recursive($this->data, array($this, 'resolve_reference'));
}
}
/**
* Callback to resolve references in the given config option value
*/
protected function resolve_reference(&$value, $key)
{
if (is_string($value)) {
$value = preg_replace_callback('/%[({]([\w.]+)[})]/i', array($this, 'replace_reference'), $value);
}
}
/**
* Callback function to replace the given reference with the read config value
*/
protected function replace_reference($m)
{
return $this->data[$m[1]];
}
/**
* Magic getter for direct read-only access to config options
*/
public function __get($name)
{
return $this->data[$name];
}
/**
* Magic isset check
*/
public function __isset($name)
{
return array_key_exists($name, $this->data);
}
/**
* Common getter for config options with fallback to default values
*
* @param string Config option name
* @param mixed Default value if option isn't set in config
* @param integer Expected variable type
* @return mixed Config option value
*/
public function get($name, $default = null, $type = null)
{
switch ($name) {
case 'output.tempdir':
case 'session.savepath':
// return an absolute path for relative directory properties
if (isset($this->data[$name]) && $this->data[$name][0] != '/') {
if (!($value = realpath(INSTALL_PATH . '/' . $this->data[$name]))) {
$value = INSTALL_PATH . '/' . $this->data[$name];
}
break;
}
default:
$value = array_key_exists($name, $this->data) ? $this->data[$name] : $default;
}
// convert value to the requested type
return $type ? self::convert($value, $type) : $value;
}
/**
* Adjust, override a config option
*/
public function set($name, $value)
{
$this->data[$name] = $value;
if (is_array($value)) {
$this->register($this->data[$name], $name.'.');
}
}
/**
* Determines whether we have a valid configuration loaded
*
* @return boolean True if valid, False otherwise
*/
public function valid()
{
return !empty($this->data);
}
/**
* Convert the given (string) value to the requested type
*
* @param string Config value
* @param int Output type (one of this class constants)
* @return mixed The converted value
*/
public static function convert($value, $type)
{
// convert value to the requested type
switch ($type) {
case self::INT:
return intval($value);
case self::FLOAT:
return floatval($value);
case self::BOOL:
return (bool)preg_match('/^(true|1|on|enabled|yes)$/i', $value);
case self::ARR:
return array_filter(preg_split('/,\s*/', strval($value)));
case self::HASH:
$arr = array();
if (preg_match_all('/([\w]+)\s*=\s*([^,]*)(,\s*|$)/', trim(strval($value), '{} '), $matches, PREG_SET_ORDER)) {
foreach ($matches as $m) {
$arr[$m[1]] = is_numeric($m[2]) ? floatval($m[2]) : $m[2];
}
}
return $arr;
case self::EMAIL:
if (preg_match('/(\S+|("[^"]+"))@\S+/', $value, $m)) {
$email = trim($m[0], '<>');
}
return $email;
}
return $value;
}
/**
* Shortcut method to convert to a boolean value
*/
public static function boolean($value)
{
return self::convert($value, self::BOOL);
}
/**
* Shortcut method to convert to a integer value
*/
public static function intval($value)
{
return self::convert($value, self::INT);
}
/**
* Shortcut method to convert to a float value
*/
public static function floatval($value)
{
return self::convert($value, self::FLOAT);
}
/**
* Shortcut method to convert to an array value
*/
public static function arr($value)
{
return self::convert($value, self::ARR);
}
/**
* Shortcut method to convert to a hash array value
*/
public static function hash($value)
{
return self::convert($value, self::HASH);
}
/**
* Convenience method to check whether a certain value is part of an option (list)
*
* @param mixed Value to compare
* @param mixed Config option value
* @param boolean Treat undefined options as 'match'
* @return boolean True of the given value is listed in config
*/
public static function in_array($value, $option, $or_not_set = false)
{
// return true if option is not set (means 'allow all')
if (!isset($option) && $or_not_set) {
return true;
}
return in_array($value, self::convert($option, self::ARR));
}
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Mon, Sep 15, 7:51 AM (1 d, 14 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
287502
Default Alt Text
(11 KB)
Attached To
Mode
R28 freebusy
Attached
Detach File
Event Timeline
Log In to Comment