<?PHP
/*****************************************************************************
| @script_type - PHP-CLASS
| @scriptname - hn_ini.class.php
| @version - 1.0
| -------------------------------------------------------------------------
| @author - Horst Nogajski <hide@address.com>
| @copyright - (c) 1999 - 2007
| @licence - LGPL
| -------------------------------------------------------------------------
| @credit - This class is a bugfixed and enhanced Version of the
| original class "Config Magik", written by Benny Zaminga.
| You can get it here:
| http://www.phpclasses.org/browse/package/1726.html
| -------------------------------------------------------------------------
| $Source: /WINBINDER/hnwb_ListViewClass/hn_ini.class.php,v $
| $Id: hn_ini.class.php,v 1.4 2007/01/04 22:21:42 horst Exp $
****************************************************************************/
// Enhanced storage with Win-Inifiles, preserving the type of variables.
// Supports Double | Integer | String | Boolean | Null | Array !!
// and also Linebreaks, Equalsigns and Doublequotes in strings.
// Usage-Example is at the end of this file.
class hn_ini
{
var $PATH = null;
var $VARS = array();
var $SYNCHRONIZE = FALSE;
var $PROCESS_SECTIONS = TRUE;
var $PROTECTED_MODE = FALSE;
var $ERRORS = array();
var $NL = "\r\n";
var $BadChars = array();
function hn_ini($path=null, $synchronize=false, $process_sections=true)
{
$this->BadChars["\r\n"] = chr(29);
$this->BadChars["\n"] = chr(30);
$this->BadChars["\r"] = chr(31);
$this->BadChars['"'] = chr(12);
$this->BadChars["="] = chr(5);
$this->NL = preg_match("/^Windows/",php_uname()) ? "\r\n" : "\n";
if(isset($process_sections)) $this->PROCESS_SECTIONS = $process_sections;
if(isset($synchronize)) $this->SYNCHRONIZE = $synchronize;
if($path===null)
{
return;
}
$this->PATH = $path;
if(!is_file($path))
{
$fp_new = @fopen($path, 'wb', false);
if(!$fp_new)
{
$err = "- Could not create new config-file('$path'), error.";
array_push($this->ERRORS, $err);
die($err);
}
else
{
fclose($fp_new);
}
}
else
{
// try to load and parse ini-file at specified path
$loaded = $this->load($path);
if(!$loaded) exit(1);
}
}
function set_Writeable_SectionName($strSectionName=null)
{
if($strSectionName===null)
{
unset($this->WriteableSection);
}
else
{
$this->WriteableSection = $strSectionName;
}
}
function get_Writeable_Section()
{
if(!isset($this->WriteableSection))
{
return NULL;
}
if(!isset($this->VARS[$this->WriteableSection]) || !is_array($this->VARS[$this->WriteableSection]))
{
return FALSE;
}
$this->VARS[$this->WriteableSection];
}
function get($key=null, $section=null)
{
$this->PROCESS_SECTIONS = $section!==null ? true : false;
if($this->PROCESS_SECTIONS)
{
$value = isset($this->VARS[$section][$key]) ? $this->VARS[$section][$key] : null;
$type = isset($this->VARS[$section]['_'.$key]) ? $this->VARS[$section]['_'.$key] : 'unknown';
}
else
{
$value = isset($this->VARS[$key]) ? $this->VARS[$key] : null;
$type = isset($this->VARS['_'.$key]) ? $this->VARS['_'.$key] : 'unknown';
}
return $this->_setType($value,$type);
}
function set($key, $value, $section=null)
{
if($this->PROCESS_SECTIONS and $section===null)
{
$err = "- Passed no section when in section-mode.";
array_push( $this->ERRORS, $err);
return false;
}
if($section!==null) $this->PROCESS_SECTIONS = true;
if($this->PROCESS_SECTIONS)
{
if(is_array($value))
{
$this->VARS[$section][$key] = $this->_iniAddSlashes(serialize($value));
$this->VARS[$section]['_'.$key] = 'array';
}
else
{
$type = $this->_getType($value);
$this->VARS[$section]['_'.$key] = $type;
$this->VARS[$section][$key] = $type=='string' ? $this->_iniAddSlashes($value) : $value;
}
}
else
{
if(is_array($value))
{
$this->VARS[$key] = $this->_iniAddSlashes(serialize($value));
$this->VARS['_'.$key] = 'array';
}
else
{
$type = $this->_getType($value);
$this->VARS['_'.$key] = $type;
$this->VARS[$key] = $type=='string' ? $this->_iniAddSlashes($value) : $value;
}
}
// synchronize file with memory if enabled
if($this->SYNCHRONIZE)
{
$this->save();
}
return true;
}
function load($path=null)
{
if(!$this->_checkPath($path,TRUE))
{
return FALSE;
}
$this->VARS = parse_ini_file($path, $this->PROCESS_SECTIONS);
return TRUE;
}
function save($path=null)
{
if(!$this->_checkPath($path))
{
return FALSE;
}
$content = '';
if($this->PROTECTED_MODE)
{
$content .= "<?PHP".$this->NL."; /*".$this->NL;
}
$content .= "; $path".$this->NL."; ".date('d.M.Y H:i:s').$this->NL;
// check if there are sections to process
if($this->PROCESS_SECTIONS)
{
// check if we are restricted to a Special Section with write access
$only = $this->get_Writeable_Section();
if($only===FALSE)
{
// an Error occured
return FALSE;
}
if(is_array($only))
{
// a restriction is set, we load from file
// and exchange only the Section
$this->load($path);
$this->VARS[$this->WriteableSection] = $only;
}
// process all Sections
foreach($this->VARS as $key=>$elem)
{
$content .= $this->NL."[$key]".$this->NL;
foreach ( $elem as $key2=>$elem2)
{
$content .= "$key2 = \"$elem2\"".$this->NL;
}
}
}
else
{
foreach($this->VARS as $key=>$elem)
{
$content .= "$key = \"$elem\"".$this->NL;
}
}
if($this->PROTECTED_MODE)
{
$content .= $this->NL."; */".$this->NL."?>";
}
// write to file
if(!$handle = @fopen($path, 'wb'))
{
$err = "- Could not open file('$path') for writing, error.";
array_push( $this->ERRORS, $err);
return false;
}
if(!fwrite($handle, $content))
{
$err = "- Could not write to open file('$path'), error.";
array_push( $this->ERRORS, $err);
return false;
}
else
{
// push a message onto error-stack
#$err = "- Sucessfully saved to file('$path').";
#array_push( $this->ERRORS, $err);
}
fclose($handle);
return true;
}
function removeSection($section)
{
// check if section exists
if(in_array( $section, array_keys( $this->VARS), true)===false)
{
$err = "- Section('$section') could not be found, nothing removed.";
array_push( $this->ERRORS, $err);
return false;
}
// find position of $section in current config
$pos = array_search($section, array_keys($this->VARS), true);
// remove section from current config
array_splice($this->VARS, $pos, 1);
if($this->SYNCHRONIZE) $this->save();
return true;
}
function removeKey($key, $section=null)
{
// with section
if($section!=null)
{
if(!isset($this->VARS[$section]))
{
$err = "- Could not find section('$section'), nothing was removed.";
array_push( $this->ERRORS, $err);
return false;
}
if(!isset($this->VARS[$section][$key]))
{
$err = "- Could not find key('$key'), nothing was removed.";
array_push($this->ERRORS, $err);
return false;
}
// remove key(s)
$pos = array_search($key, array_keys($this->VARS[$section]), true);
array_splice($this->VARS[$section], $pos, 1);
$pos = array_search('_'.$key, array_keys($this->VARS[$section]), true);
array_splice($this->VARS[$section], $pos, 1);
return true;
}
// without section
if(!isset($this->VARS[$key]))
{
$err = "- Could not find key('$key'), nothing was removed.";
array_push($this->ERRORS, $err);
return false;
}
// remove key(s)
$pos = array_search($key, array_keys($this->VARS), true);
array_splice($this->VARS, $pos, 1);
$pos = array_search('_'.$key, array_keys($this->VARS), true);
array_splice($this->VARS, $pos, 1);
return true;
}
function listSections()
{
$list = array();
// separate sections from normal keys
$all = array_keys($this->VARS);
foreach($all as $possible_section)
{
if(is_array($this->VARS[$possible_section]))
{
array_push($list, $possible_section);
}
}
sort($list);
return $list;
}
function listKeys($section=null,$onlyRealVars=TRUE)
{
// check if section was passed
if($section!==null)
{
// check if passed section exists
if(!isset($this->VARS[$section]))
{
array_push($this->ERRORS, "- Section('$section') could not be found.");
return false;
}
$keys = array_keys($this->VARS[$section]);
}
else
{
$keys = array_keys($this->VARS);
}
if(!$onlyRealVars)
{
sort($keys);
return $keys;
}
$list = array();
foreach($keys as $k)
{
if($k[0]=='_') continue;
array_push($list, $k);
}
sort($list);
return $list;
}
// private
function _getType(&$value)
{
if(in_array(gettype($value),array('integer','double','string')))
{
return gettype($value);
}
if(is_bool($value))
{
return 'bool';
}
if(!isset($value) || empty($value) || is_null($value))
{
return 'null';
}
return 'string';
}
function _setType($value,$type)
{
switch($type)
{
case 'array':
return unserialize($this->_iniRemoveSlashes($value));
break;
case 'bool':
return (bool)$value;
break;
case 'null':
return null;
break;
case 'integer':
return (int)$value;
break;
case 'double':
return (double)$value;
break;
case 'string':
return (string)$this->_iniRemoveSlashes($value);
break;
case 'unknown':
default:
return (string)$value;
break;
}
}
function _iniAddSlashes($v)
{
return str_replace(array_keys($this->BadChars),array_values($this->BadChars),$v);
}
function _iniRemoveSlashes($v)
{
return str_replace(array_values($this->BadChars),array_keys($this->BadChars),$v);
}
function _checkPath(&$path,$onlyReadable=FALSE)
{
$path = $path!==null ? $path : $this->PATH;
if(!is_file($path) || !is_readable($path))
{
$err = "- Path('$path') is invalid, nothing loaded.";
array_push( $this->ERRORS, $err);
return FALSE;
}
return ($onlyReadable || is_writable($path)) ? TRUE : FALSE;
}
} // End Class hn_ini
/*
// example usage:
$inifile = getenv('TEMP').'/example.ini';
$ini = new hn_ini($inifile,false,false);
#$ini = new hn_ini(null,false,false);
// string with linebreaks
$str = "This is sample-\r\nstring with line-\r\nbreaks and\tTabs,\n\tcool!";
$ini->set('str',$str);
// integer
$int = 123456;
$ini->set('int',$int);
// double
$dbl = 0.42;
$ini->set('dbl',$dbl);
// bool
$bolT = TRUE;
$ini->set('bolT',$bolT);
$bolF = FALSE;
$ini->set('bolF',$bolF);
// Key to remove later
$ini->set('removeme',TRUE);
// array
define('ZWEI',2);
$ary = array(0=>'Nothing',1=>'one','2'=>ZWEI,'three'=>3);
$ini->set('ary',$ary);
// null
$nll = null;
$ini->set('nll',$nll);
// empty string
$estr = '';
$ini->set('estr',$estr);
// integer zero
$int0 = 0;
$ini->set('int0',$int0);
// BadChars
$bch = array("\r\n","\n","\r","\\","\"","=","'");
$ini->set('bch',$bch);
// write to file
$ini->save();
// release Object
unset($ini);
// create new object and parse inifile
$new_ini = new hn_ini($inifile,false,false);
var_dump($new_ini->listKeys());
$new_ini->removeKey('removeme');
$new_ini->removeKey('removeme2');
var_dump($new_ini->listKeys(null,FALSE));
$keys = array_keys($new_ini->VARS);
foreach($keys as $k)
{
if($k[0]=='_') continue;
echo "\r\n$k = ".$new_ini->VARS[$k]."\r\n";
var_dump($new_ini->get($k));
echo "\r\n------------------\r\n";
}
unset($new_ini);
# unlink($inifile);
*/
?>