Location: PHPKode > scripts > Config Manager > config-manager/class.config_base.php
<?php
/* vim: set ai tabstop=4: */
// $Date: 2002/04/09 01:29:38 $
// $Revision: 1.4 $
// +----------------------------------------------------------------------+
// | CONFIG MANAGER 0.1.2 - 09-Apr-2002                                   |
// +----------------------------------------------------------------------+
// | Author: Keyvan Minoukadeh - hide@address.com - http://www.k1m.com      |
// +----------------------------------------------------------------------+
// | PHP class for managing plain text config files.                      |
// +----------------------------------------------------------------------+
// | This program is free software; you can redistribute it and/or        |
// | modify it under the terms of the GNU General Public License          |
// | as published by the Free Software Foundation; either version 2       |
// | 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 General Public License for more details.                         |
// +----------------------------------------------------------------------+

// define some type constants
define('CONFIGMAN_TYPE_DOUBLE',		'double');
define('CONFIGMAN_TYPE_INTEGER',	'integer');
define('CONFIGMAN_TYPE_STRING',		'string');
define('CONFIGMAN_TYPE_BOOLEAN',	'boolean');

// fetch mode
define('CONFIGMAN_FETCH_ASSOC',		1);
define('CONFIGMAN_FETCH_OBJECT',	2);

/**
* Config manager base class
*
* This is the config manager base class, extensions include:
* - config_reader:	Read config files
* - config_writer:	Write config files
* - config_webedit:	Modify config files through a HTML form
*
* @author   Keyvan Minoukadeh <hide@address.com>
* @version  0.1.2
*/
class config_base
{
	/**
	* config file
	*/
	var $config					= '';

	/**
	* config cache directory
	*
	* Make sure this directory is writable, so the script can save serialized version
	* of the config.  Leave blank if you'd like the script to attempt to write the
	* serialized version to the same location as $this->config
	* NOTE: including trailing slash if specifying a directory
	*/
	var $config_cache_dir		= '';

	/**
	* comment string
	*/
	var $comment				= '#';

	/**
	* separator used to separate variable names and values
	*/
	var $separator				= '=';

	/**
	* parameters array
	* $array["var"]["section"]["value"] = val
	* $array["var"]["section"]["comment"] = comment
	*/
	var $param					= array();

	/**
	* default section name
	*/
	var $default_section		= 'Main';

	/**
	* regular expression for valid var name
	*/
	var $regex_var				= '[a-zA-Z_][a-zA-Z0-9_]*';

	/**
	* regular expression for valid section tag name
	*/
	var $regex_section			= '[a-zA-Z0-9_][a-zA-Z0-9_ ]*';

	/**
	* regular expression for valid array key name
	*/
	var $regex_assoc			= '[a-zA-Z0-9_]+';

	/**
	* regular expression for valid type prefix
	*/
	var $regex_type				= '(str_|int_|dbl_|bool_)';

	/**
	* max config file size (bytes)
	*/
	var $max_config_size		= 50000;

	/**
	* type prefixes
	*/
	var $type_prefix			= array('str_'	=> CONFIGMAN_TYPE_STRING,
										'int_'	=> CONFIGMAN_TYPE_INTEGER,
										'dbl_'	=> CONFIGMAN_TYPE_DOUBLE,
										'bool_'	=> CONFIGMAN_TYPE_BOOLEAN);
	/**
	* default type
	*
	* auto: determine based on quotes around value or no quotes
	* CONFIGMAN_TYPE_STRING: string
	* CONFIGMAN_TYPE_INTEGER: integer
	* CONFIGMAN_TYPE_DOUBLE: double
	* CONFIGMAN_TYPE_BOOLEAN: boolean
	*/
	var $default_type			= 'auto';

	/**
	* magic_quotes_runtime setting
	*
	* @access	private
	*/
	var $_magic_quotes_runtime	= null;

	/**
	* debug
	*/
	var $debug					= false;


	/////////////
	// methods
	/////////////


	/**
	* Constructor
	*
	* @param	string	$config		config file to use
	*/
	function config_base($config)
	{
		$this->config = trim($config);
	}

	/**
	* Strip Slashes
	* Strips slashes only if magic_quotes_gpc is on
	*
	* @param	mixed	$subject	array or string to strip slashes from (passed by ref)
	* @return	bool				true
	*/
	function strip_magic_slashes(&$subject) {
		if ((int)ini_get('magic_quotes_gpc') === 1) {
			if (is_string($subject)) {
				$subject = stripslashes($subject);
			} elseif (is_array($subject)) {
				foreach ($subject as $key => $val) {
					$this->strip_magic_slashes($subject[$key]);
				}
			}
		}
		return true;
	}

	/**
	* Toggle magic_quotes_runtime
	*
	* If you have magic_quotes_runtime on, call this before any other config function:
	* $reader->magic_quotes_runtime();
	* to revert back to the previous setting when you've finished with config manager:
	* $reader->magic_quotes_runtime(true);
	*
	* @param	bool	$action		true: restore previous magic quotes runtime setting, false: off
	* @return	bool				true
	* @access	public
	*/
	function magic_quotes_runtime($action=false) {
		// if first time calling, set current magic quotes runtime setting
		if (is_null($this->_magic_quotes_runtime)) {
			$this->_magic_quotes_runtime = ini_get('magic_quotes_runtime');
		}

		if (($action === false) && ((int)ini_get('magic_quotes_runtime') === 1)) {
			ini_set('magic_quotes_runtime', '0');
		} elseif (($action === true) && (!is_null($this->_magic_quotes_runtime))) {
			ini_set('magic_quotes_runtime', $this->_magic_quotes_runtime);
		}
		return true;
	}

	/**
	* Set
	*
	* Set class variable value, not config variable (use set_param for that)
	*
	* @param	string	$var		variable to update
	* @param	mixed	$val		value to assign to $var
	* @return	bool				true on success, false otherwise
	* @access	public
	*/
	function set($var, $val)
	{
		if (isset($this->$var)) {
			$this->$var = $val;
			return true;
		} else {
			return false;
		}
	}

	/**
	* Get
	*
	* Get class variable value, not config variable
	*
	* @param	string	$var	variable to update
	* @return	mixed			value, or false if $var does not exist
	* @access	public
	*/
	function get($var)
	{
		if (isset($this->$var)) {
			return $this->$var;
		} else {
			return false;
		}
	}

	/**
	* Set param from array
	*
	* @param	string	$var	var name
	* @param	array	$param	array holding parameter details
	* @return	bool			result of calling $this->set_param()
	* @access	public
	*/
	function set_param_from_array($var, $param)
	{
		$func_name = 'set_param_from_array';
		$section	= key($param);
		$val		=     $param[$section]['value'];
		$comment	=     $param[$section]['comment'];
		return $this->set_param($var, $val, $comment, $section);
	}

	/**
	* Var exists
	*
	* @param	string	$var		variable name to check for
	* @param	string	$section	section name (default: null - all sections)
	* @return	bool				true if exists, false otherwise
	* @access	public
	*/
	function var_exists($var, $section=null)
	{
		if (is_null($section)) {
			if (isset($this->param["$var"]) && is_array($this->param["$var"])) {
				return true;
			} else {
				return false;
			}
		} else {
			if (isset($this->param["$var"]) && isset($this->param["$var"]["$section"])) {
				return true;
			} else {
				return false;
			}
		}
	}

	/**
	* Delete param
	*
	* @param	string	$var	variable name to delete
	* @return	bool			true if deleted, false otherwise
	* @access	public
	*/
	function del_param($var)
	{
		if (isset($this->param["$var"])) {
			unset($this->param["$var"]);
			return true;
		} else {
			return false;
		}
	}

	/**
	* Clear param
	*
	* @access	public
	*/
	function clear_param()
	{
		$this->param = array();
		return true;
	}

	/**
	* Set param
	*
	* @param	string	$var		var
	* @param	string	$val		value
	* @param	string	$comment	comment
	* @param	string	$section	section name
	* @return	bool				true if success, false otherwise
	* @access	public
	*/
	function set_param($var, $val, $comment=null, $section=null)
	{
		$func_name = 'set_param';
		
		if (empty($var)) {
			if ($this->debug) $this->_debug("$func_name: Var not specified");
			return false;
		}

		if (is_null($comment)) {
			$comment = '';
		}

		if ($this->default_type != 'auto') {
			$type = $this->default_type;
		} else {
			$type = $this->_get_type($var);
		}

		if (is_null($section)) {
			$section = $this->default_section;
		}

		// check for valid section name
		if (!preg_match('!^'.$this->regex_section.'$!', $section)) {
			if ($this->debug) $this->_debug("$func_name: Invalid section name");
			return false;
		}

		// check for valid var name
		if (!preg_match('!^'.$this->regex_var.'$!', $var)) {
			if ($this->debug) $this->_debug("$func_name: Invalid var name");
			return false;
		}		

		// add/update var only if it doesn't already exist OR exists in this section
		if (!$this->var_exists($var) || $this->var_exists($var, $section)) {
			$this->param["$var"]["$section"]['value'] = $val;
			$this->param["$var"]["$section"]['comment'] = trim($comment);
		} else {
			if ($this->debug) $this->_debug("$func_name: Var '$var' already exists in another section");
			return false;
		}

		return true;
	}

	/**
	* Is file valid
	*
	* Checks to see if config exists, is readable and not above the filesize limit
	*
	* @param	string	$config					filename, null: use existing (default: null)
	* @return	bool
	* @access	public
	*/
	function is_file_valid($config=null)
	{
		$func_name = 'is_file_valid';

		if (is_null($config)) {
			$config = $this->config;
		}

		if (!empty($config) && file_exists($config) && is_readable($config)) {
			if (filesize($config) > $this->max_config_size) {
				if ($this->debug) $this->_debug("$func_name: Config file size is greater than max allowed");
				return false;
			} else {
				return true;
			}
		}
		return false;
	}

	/**
	* Is valid
	*
	* Checks to see if config is valid
	*
	* @param	array	$config					array containing each line of config file
	* @param	bool	$return_line_numbers	if true will return an array with line numbers which
	*											contain invalid syntax, if false, will return either
	*											true (if no problems encountered) or false (default: false)
	* @return	mixed							either bool or array, based on $return_line_numbers
	* @access	public
	*/
	function is_valid($config=null, $return_line_numbers=false)
	{
		$func_name = 'is_valid';

		$invalid = array();
		if (is_null($config) && $this->is_file_valid()) {
			$config = file($this->config);
		}

		if (!is_array($config)) {
			if ($this->debug) $this->_debug("$func_name: Config file not found or not readable or not passed as array");
			return false;
		}
			
		foreach ($config as $num => $line) {
			$line = trim($line);
			if (empty($line)) {
				continue;
			}

			// increment $num (array stars at 0)
			$num++;

			// match comment
			if (preg_match('!^'.preg_quote($this->comment).'!', $line)) {
				continue;
			}
			
			// match var name and val
			if (preg_match('!^'.$this->regex_type.'?('.$this->regex_var.')(\.'.$this->regex_assoc.')?\s*'.
				preg_quote($this->separator).'\s*(?'.'>(["\'])?)(.*)(?(4)\4)$!i', $line)) {
				continue;
			}

			// match section
			if (preg_match('!^\['.$this->regex_section.'\]!', $line)) {
				continue;
			}

			// if it's reached this far, this line is unrecongised
			if ($return_line_numbers) {
				$invalid[] = $num;
			} else {
				return false;
			}
		}

		if ($return_line_numbers && (count($invalid) > 0)) {
			return $invalid;
		} else {
			return true;
		}
	}




	///////////////////////
	// PRIVATE FUNCTIONS //
	///////////////////////

	/**
	* Debug
	*
	* Adds debug line to array and echos it if allowed
	*
	* @param	string	$msg	string to echo or store in debug log
	* @access	private
	*/
	function _debug($msg)
	{
		if ($this->debug) {
			echo "# $msg<br>\n";
		}
		return true;
	}

	/**
	* Error
	*
	* Outputs error message
	*
	* @param	string	$msg	string to output
	* @access	private
	*/
	function _error($msg)
	{
		die("\n<br /><b>Error:</b> $msg\n");
	}

	/**
	* Get type
	*
	* @param	mixed	$var	variable to return type
	* @access	private
	*/
	function _get_type($var)
	{
		switch(gettype($var)) {
			case 'boolean':
				return CONFIGMAN_TYPE_BOOLEAN;
				break;
	
			case 'integer':
				return CONFIGMAN_TYPE_INTEGER;
				break;

			case 'double':
				return CONFIGMAN_TYPE_DOUBLE;
				break;

			case 'string':
				return CONFIGMAN_TYPE_STRING;
				break;

			default:
				return (($this->default_type != 'auto') ? $this->default_type : CONFIGMAN_TYPE_STRING);
		}
	}

	/**
	* Cast type
	*
	* @param	string	$val	value to return
	* @param	string	$type	type
	* @access	private
	*/
	function _cast_type($val, $type)
	{
		switch($type) {
			case CONFIGMAN_TYPE_BOOLEAN:
				if (in_array($val, array('true','on','yes','1'))) {
					return true;
				} elseif (in_array($val, array('false','off','no','0'))) {
					return false;
				} else {
					return (bool)$val;
				}
				break;
	
			case CONFIGMAN_TYPE_INTEGER:
				return (int)$val;
				break;

			case CONFIGMAN_TYPE_DOUBLE:
				return (double)$val;
				break;

			default:
				return (string)$val;
				break;
		}
	}

}

?>
Return current item: Config Manager