Files
DomFramework/config.php
2016-07-26 07:31:42 +00:00

350 lines
12 KiB
PHP

<?php
/** DomFramework
@package domframework
@author Dominique Fournier <dominique@fournier38.fr> */
require_once ("domframework/form.php");
/** Manage the configurations of the module done by administrator in a config
file
It is based on the module configuration defaults
The DocType allow to define the configuration HTML page. It must contains
@param : the name of the parameter
@description : the textual description of the parameter
@type : the type of the parameter (string, integer, array)
@values : an array containing the allowed values to the parameter. Can be
a function like timezone_identifiers_list
@default : the default value (can be an array or a string or a number)
@group : Group all the parameters in a group
POC :
$config = new config();
$config->default = array ("param"=>"default",
"param2"=>array (1,2,3),
"param3"=>null);
$var = $config->get ("param");
*/
class config
{
/** All the parameters allowed with their default value */
public $default = array ();
/** Use the .php to protect the information */
public $confFile = null;
/** Select the configuration file */
public function selectConfFile ()
{
if ($this->confFile !== null)
$this->confFile = $this->confFile;
elseif (defined("CONFIGFILE"))
$this->confFile = CONFIGFILE;
elseif (file_exists ("./datas/configuration.php"))
$this->confFile = "./datas/configuration.php";
elseif (file_exists ("./data/configuration.php"))
$this->confFile = "./data/configuration.php";
else
$this->confFile = "./data/configuration.php";
}
/** List all the parameters configurable in the software */
public function params ()
{
$this->selectConfFile ();
return $this->default;
}
/** Return the defined values */
public function getAll ()
{
$this->selectConfFile ();
$conf = array ();
$rc = include ($this->confFile);
if ($rc !== 1)
throw new Exception ("Error in configuration file", 500);
return $conf;
}
/** Get the value of the provided parameter recorded in .php file
If it is not set in .php file, use the default value
@param string $param The option name to be returned */
public function get ($param)
{
$this->selectConfFile ();
if (!array_key_exists ($param, $this->default))
throw new Exception ("Unknown parameter '$param'", 500);
if (!file_exists ($this->confFile))
{
if (@file_put_contents ($this->confFile,
"<?php\r\n\$conf = array ();\r\n")
=== FALSE)
throw new Exception (sprintf (dgettext("domframework",
"No configuration file '%s' available and it can't be created"),
$this->confFile), 500);
}
elseif (! is_readable ($this->confFile))
throw new Exception (sprintf ( dgettext("domframework",
"The configuration file '%s' is not readable"),
$this->confFile));
$conf = array ();
$rc = include ($this->confFile);
if ($rc !== 1)
throw new Exception ("Error in configuration file", 500);
if (! array_key_exists ($param, $this->default))
throw new Exception (sprintf ("Configuration parameter '%s' not defined",
$param), 500);
// Create a conf where all the keys are defined. If the keys are already
// define, use them, or use the default ones
// Don't allow keys not defined in default ones
if (! is_array ($this->default[$param]))
{
if (! array_key_exists ($param, $conf))
return $this->default[$param];
return $conf[$param];
}
foreach ($this->default[$param] as $key=>$val)
{
if ($key === "not configured")
{
if (! array_key_exists ($param, $conf))
continue;
foreach ($conf[$param] as $k=>$v)
{
$conf[$param][$k] = array_replace_recursive ($val,
$conf[$param][$k]);
}
continue;
}
if (! isset ($conf[$param][$key]))
$conf[$param][$key] = $val;
elseif (is_array ($val))
$conf[$param][$key] = array_replace_recursive ($val,
$conf[$param][$key]);
}
if (! array_key_exists ($param, $conf))
return $this->default[$param];
return $conf[$param];
}
/** Define a value for the parameter in the config file. Add all the default
values if they are not defined
@param string $param The option name
@param mixed $value The option value
@return TRUE if the parameter is saved or an exception */
public function set ($param, $value)
{
$this->selectConfFile ();
if (!array_key_exists ($param, $this->default))
throw new Exception ("Unknown parameter '$param'", 500);
if (!file_exists ($this->confFile))
{
if (@file_put_contents ($this->confFile,
"<?php\r\n\$conf =array ();\r\n")
=== FALSE)
throw new Exception (sprintf (
"No configuration file '%s' available and it can't be created",
$this->confFile));
}
elseif (! is_readable ($this->confFile))
throw new Exception (sprintf (
dgettext("domframework",
"The configuration file '%s' is not readable"),
$this->confFile), 500);
if (!is_writeable ($this->confFile))
throw new Exception (sprintf (dgettext("domframework",
"Configuration file '%s' is write protected"),
$this->confFile), 500);
$conf = array ();
$rc = include ($this->confFile);
if ($rc !== 1)
throw new Exception (dgettext("domframework",
"Error in configuration file"), 500);
$newconf = array_merge ($this->default, $conf, array ($param=>$value));
$txt = "<?php\r\n";
$txt .= "\$conf = array(\r\n";
$txt = $this->writePHP ($newconf, $txt, 4);
$txt .= ");\r\n";
if (@file_put_contents ($this->confFile, $txt, LOCK_EX) === FALSE)
throw new Exception (sprintf (dgettext("domframework",
"Can't save configuration file '%s'"),
$this->confFile), 500);
return TRUE;
}
/** Display the $values in PHP format to be "require" easily
@param mixed $values Values to be recorded
@param string $phpcode Actual value of the php code
@param integer $indent Number of spaces in the indentation of config */
private function writePHP ($values, $phpcode, $indent)
{
foreach ($values as $key=>$val)
{
$phpcode .= str_pad (" ", $indent);
$phpcode .= (is_numeric ($key)) ? $key : "\"$key\"";
$phpcode .= " => ";
if (is_bool ($val))
{
if ($val === FALSE) $phpcode .= "FALSE,\r\n";
else $phpcode .= "TRUE,\r\n";
}
elseif (is_null ($val))
$phpcode .= "NULL,\r\n";
elseif (is_int ($val) || is_float ($val))
$phpcode .= "$val,\r\n";
elseif (is_string ($val))
$phpcode .= "\"$val\",\r\n";
elseif (is_array ($val))
{
$phpcode .= "array (\r\n";
$phpcode = $this->writePHP ($val, $phpcode, $indent+4);
$phpcode .= str_pad (" ", $indent);
$phpcode .= "),\r\n";
}
else
throw new Exception (dgettext("domframework",
"Config : missing type ").gettype ($val), 500);
}
return $phpcode;
}
/** Convert a string to the right PHP type, without using the eval function */
private function strToType ($values)
{
$values = str_replace ("array (", "array(", $values);
if (stripos ($values, "array(") !== false)
{
$values = substr ($values, 6, -1);
$values = explode (",", $values);
$new = array ();
foreach ($values as $key=>$val)
{
$val = trim ($val);
if (strpos ($val, "=>") !== false)
{
// Associated array
unset ($values[$key]);
list ($key1, $val1) = explode ("=>", $val);
$key1 = trim ($key1);
$val1 = trim ($val1);
if ($val1[0] === "\"" || $val1[0] === "'")
$val1 = substr($val1, 1, -1);
elseif (strpos ($val1, "."))
$val1 = floatval ($val1);
else
$val1 = intval ($val1);
$new[$key1] = $val1;
}
else
{
// Unique value (string or integer or float)
if ($val[0] === "\"" || $val[0] === "'")
$val = substr($val, 1, -1);
elseif (strpos ($val, "."))
$val = floatval ($val);
else
$val = intval ($val);
$new[$key] = $val;
}
}
}
else
{
if ($values[0] === "\"" || $values[0] === "'" )
$new = substr ($values, 1, -1);
elseif (strpos ($values, "."))
$new = floatval ($values);
else
$new = intval ($values);
}
return $new;
}
/** Return an array containing the definitions read from the default config
file */
public function docComment ($modelFile)
{
$debug = 0;
if (! file_exists ($modelFile))
throw new Exception (dgettext("domframework",
"The configuration model file is missing"), 500);
if (! is_readable ($modelFile))
throw new Exception (dgettext("domframework",
"The configuration model file is not readable"),
500);
$filecontent = file_get_contents ($modelFile);
$tokens = token_get_all ($filecontent);
$foundDefault = "";
$parenthesis = 0;
$params = array ();
$path = "";
$group = dgettext("domframework", "Default parameters");
foreach ($tokens as $token)
{
if (is_array ($token))
{
list ($id, $text) = $token;
if ($debug) echo "ARRAY : $id, $text\n";
if ($foundDefault === "" && $text === "->")
$foundDefault = $text;
if ($id === T_DOC_COMMENT)
{
// Look at @param, @description,@type, @values, @default
if ($debug) echo "DOC_COMMENT : $text\n";
// Append the not completed lines
$text = trim (substr ($text, 3, -2));
$text = preg_replace ("/\n\s+/", " ", $text);
$text = preg_replace (
"/(@(param|description|type|values|default|group|prefix))/",
"\n\${1}", $text);
$text = ltrim ($text);
// Look at each parameter and save them in a data array
$data = array ();
foreach (explode ("\n", $text) as $line)
{
$tmp = explode (" ", $line);
$key = reset ($tmp);
$key = substr ($key, 1);
$data[$key] = trim (implode (" ",array_slice ($tmp, 1)));
}
if (isset ($data["group"]))
$group = $data["group"];
if (! isset ($data["param"]))
continue;
$data["depth"] = $parenthesis;
$data["group"] = $group;
//if (isset ($data["values"]) && $data["values"][0] !== "\"")
if (isset ($data["values"]))
{
// A function or an array or a number is provided
if ( function_exists ($data["values"]))
$data["values"] = call_user_func ($data["values"]);
elseif (is_string ($data["values"]))
$data["values"] = $this->strToType ($data["values"]);
}
if (isset ($data["default"]))
$data["default"] = $this->strToType ($data["default"]);
if (isset ($data["prefix"]))
$data["prefix"] = $this->strToType ($data["prefix"]);
if ($debug) var_dump ($data);
$params[] = $data;
}
}
else
{
if ($debug) echo "TEXT : $token\n";
if ($foundDefault !== "" && $token === "(")
{
$parenthesis++;
}
if ($foundDefault !== "" && $token === ")")
{
$parenthesis--;
if ($parenthesis === 0)
break;
}
}
}
return $params;
}
}