Location: PHPKode > projects > Nzbirc > nzbirc-1.4/modules/config.php
<?php

/**************************************************
 * NZBirc v1
 * Copyright (c) 2006 Harry Bragg
 * tiberious.org
 * Module: config
 **************************************************
 *
 * Full GPL License: <http://www.gnu.org/licenses/gpl.txt>
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 */

class Net_SmartIRC_module_config extends Net_SmartIRC_module_base
{

	// default module variable
	var $name = 'config';
	var $version = 'v0.1';
	var $description = 'Configure the bot';
	
	/**
	 * Config Module
	 *
	 * STARTCONFIG
	 * @var array publicCommand  - Lists the commands that trigger this module, and return publicly
	 * @var array privateCommand - Lists the commands that trigger this module privatly (notice you)
	 * @var string configFile    - Define the configuration file (Only change if you know what you are doing)
	 * @var string configVar     - The configuration variable in $irc (Only change if you know what you are doing)
	 * ENDCONFIG
	 */  
	var $_config = array(
		'publicCommand' => array( '^config', '^!config' ),
		'privateCommand' => array( '^@config' ),
		'configFile' => 'config.inc.php',
		'configVar' => 'config'
		);

	var $_def = array(
		'regex' => array(
			'configVars' => '/\\\*\*\s+\*\s(.+)\s+\*\s+\*\sSTARTCONFIG\s+(?s:(.+?))\s+\*\sENDCONFIG\s+\*\//',
			'varVal' => '/\s*\* \@var(\s+)(\w+) (\w+)\s+(- (.+))?/'
			),
		'file' => array(
			'header' => "<?php\n\n/**************************************************\n * NZBirc v1\n * Copyright (c) 2006 Harry Bragg\n * tiberious.org\n * irc config\n **************************************************/\n",
			'footer' => "\nglobal \$config;\n\n?>",
			'sectionHeader' => "\n/**\n * %s\n *\n",
			'sectionVariable' => " * @var %s%s %s %s\n",
			'sectionFooter' => " */\n",
			'dataIRC' => "\$config->%s = %s;\n",
			'dataModule' => "\$config->moduleConf['%s'] = %s;\n"
			),
		'export' => array(
			'from' => array(
				'/^(\s+)(\d+) => (.+),$/im',
				'/=>(\s*)\n(\s+)array \(/',
				'/^(\s{2,})/im'
				),
			'to' => array(
				'$1$3,',
				'=> array (',
				'$1$1'
				)
			)
		);
	
	var $_template = array(
		'error' => '**Error:** {errormsg}',
		'avVar' => 'Available variables for __{pwd}__: {varList}',
		'avMod' => 'Available modules: {varList}',
		'varDetails' => '{type} **{name}** = {value} - {description}',
		'varSet' => 'Variable __{pwd}__: set to: {newVar}',
		'varAdd' => '{newVar} has been added to variable: __{pwd}__',
		'varDel' => '{oldVar} has been deleted from variable: __{pwd}__',
		'help' => '{command} - {description}',
		'helpList' => array(
			'Commands available for NZB: {helpCommands}',
			'Type: {trigger} {subTrigger} command, for more information on each command'
			)		
		);
	
	var $_help = array(
		'help' => array(
			'command' => '{trigger} help [command]',
			'description' => 'Display the available commands, if a __command__ is specified, then extra information is provided',
			'longDescription' => 'Display the available commands, if a __command__ is specified, then extra information is provided'
			),
		'commands' => array(
			'command' => '{trigger} commands',
			'description' => 'List the available commands with their descriptions',
			'longDescription' => 'List the available commands with their descriptions'
			),
		'set' => array(
			'command' => '{trigger} module variable =/+/- value',
			'description' => 'Set a config variable, __module__ can be **irc**, or the name of a module, __variable__ is a pathway to the variable, if the __variable__ is an array, use **+** and **-** to add or remove entries',
			'longDescription' => array(
				'Set a config variable, __module__ can be **irc**, or the name of a module, __variable__ is a pathway to the variable', 
				'if the __variable__ is an array, use **+** and **-** to add or remove entries'
				)
			),
		'get' => array(
			'command' => '{trigger} module variable',
			'description' => 'Get a config variable, __module__ can be **irc**, or the name of a module',
			'longDescription' => 'Get a config variable, __module__ can be **irc**, or the name of a module'
			)
		);

	function _registerCommands()
	{
	 	global $irc;
	 	
		$this->_setHandler( '^(\w+) (.+) (=|\+|-)\s?(.+)$', $this, 'botSet' );
		$this->_setHandler( '^(\w+)([^=\+\-]+)?$', $this, 'botGet' );
		$this->_setHandler( '^$', $this, 'botList' );
	}

	/*****************************************************
	 * Bot functions
	 *****************************************************/	

	function botList( &$irc, &$data, $notice )
	{
		// admin check
		if ( !$irc->_modules['func']->isAdmin( $irc, $data->nick ) )
		{
			$this->parseTemplate( $msg, 'error', array( 'errormsg' => 'Insufficient privaleges to run this command' ) );
			$irc->_modules['func']->reply( $irc, $data, $msg, $notice );
			return;
		}
		
		$vars['varList'][] = 'irc';
		foreach( $irc->_modules as $name => $module )
		{
			if ( isset( $module->_config ) )
			{
				$vars['varList'][] = $name;
			}
		}

		$this->parseTemplate( $msg, 'avMod', $vars );
		$irc->_modules['func']->reply( $irc, $data, $msg, $notice );				
	}

	function botSet( &$irc, &$data, $notice )
	{
		// admin check
		if ( !$irc->_modules['func']->isAdmin( $irc, $data->nick ) )
		{
			$this->parseTemplate( $msg, 'error', array( 'errormsg' => 'Insufficient privaleges to run this command' ) );
			$irc->_modules['func']->reply( $irc, $data, $msg, $notice );
			return;
		}
			
		if ( $data->trig[1] == 'irc' )
		{
			$opts = $this->getOptions( 'irc', 'irc.php' );
			$conf = (array)$irc->config;
		}
		else if ( $irc->isLoadedModule( $data->trig[1] ) )
		{
			$opts = $this->getOptions( $data->trig[1], $irc->config->modulePath.'/'.$data->trig[1].'.php' );
			$conf = $irc->_modules[$data->trig[1]]->_config;
		}
		else
		{
			$this->parseTemplate( $msg, 'error', array( 'errormsg' => 'Invalid Module: '.$data->trig[1] ) );
			$irc->_modules['func']->reply( $irc, $data, $msg, $notice );
			return;
		}		
		if ( strlen( $data->trig[2] ) > 0 ) {
			$pSplit = explode( ' ', trim( $data->trig[2] ) );
		}
		else
		{
			$pSplit = array();
		}

		$pwd[] = $data->trig[1];
		$irc->_modules['func']->array_append( $pwd, $pSplit );
		
		$pwd = implode( '__ > __', $pwd );
		
		if ( ( $val = $this->_gTravArray( $conf, $pSplit ) ) !== 'fakeFalse' )
		{
			$cInfo = $this->_gTravArray( $opts, $pSplit );
			if ( isset( $cInfo['description'] ) )
			{
				if ( $cInfo['name'] != 'password' )
				{
					if ( is_array( $val ) )
					{
						if ( $data->trig[3] != '=' )
						{
							if ( $data->trig[3] == '+' )
							{
								$val[] = $data->trig[4];
								$nConf = $this->_sTravArray( $conf, $pSplit, $val );

								$this->_setConfig( $data->trig[1], $nConf );
								
								$vars = array(
									'pwd' => $pwd,
									'newVar' => $data->trig[4]
								);
								
								$this->parseTemplate( $msg, 'varAdd', $vars );								
							}
							else
							{
								if ( ( $key = array_search( trim( $data->trig[4] ), $val ) ) !== false )
								{
									unset( $val[$key] );
									$nVal = $this->_resortArray( $val );
									
									$nConf = $this->_sTravArray( $conf, $pSplit, $nVal );
									$this->_setConfig( $data->trig[1], $nConf );
									
									$vars = array(
										'pwd' => $pwd,
										'oldVar' => $data->trig[4]
									);
									
									$this->parseTemplate( $msg, 'varDel', $vars );
									
								}
								else
								{
									$this->parseTemplate( $msg, 'error', array( 'errormsg' => 'Can not delete item: {oldVar}, does not exist in variable: __{pwd}__', 'oldVar' => $data->trig[4], 'pwd' => $pwd ) );
								}
							}
						}
						else
						{	
							$this->parseTemplate( $msg, 'error', array( 'errormsg' => 'Variable: __{pwd}__ is an array, use the **+** and **-** commands to add or remove items', 'pwd' => $pwd ) );
						}
					}
					else
					{
						switch( $cInfo['type'] )
						{
							case 'bool':
							{
								$nVar = ( $data->trig[4] == 'true' )? true:false;
								break;
							}
							case 'int':
							{
								if ( is_numeric( $data->trig[4] ) )
								{
									$nVar = $data->trig[4];
								}
								else
								{
									$this->parseTemplate( $msg, 'error', array( 'errormsg' => 'Failed to set variable: __{pwd}__, value: {newVal} is not numeric', 'pwd' => $pwd, 'newVal' => $data->trig[4] ) );
									$fail = true;
								}
								break;
							}
							default:
								$nVar = $data->trig[4];
						}
						
						if ( !$fail )
						{
							$nConf = $this->_sTravArray( $conf, $pSplit, $nVar );

							$this->_setConfig( $data->trig[1], $nConf );
							
							$vars = array(
								'pwd' => $pwd,
								'newVar' => $data->trig[4]
							);							
							
							$this->parseTemplate( $msg, 'varSet', $vars );
							
							$irc->_respawn();
						}
					}
				}
				else
				{
					$this->parseTemplate( $msg, 'error', array( 'errormsg' => 'Password Variables are out of bounds' ) );
					$notice = true;
				}
			}
			else
			{
				$this->parseTemplate( $msg, 'error', array( 'errormsg' => 'Variable: __{path}__ is not writeable', 'path' => $pwd ) );
			}
		}
		else
		{
			$this->parseTemplate( $msg, 'error', array( 'errormsg' => 'Invalid path: __{path}__', 'path' => $pwd ) );
		}	
		if ( isset( $msg ) ) 
		{
			$irc->_modules['func']->reply( $irc, $data, $msg, $notice );
		}	
	}

	function botGet( &$irc, &$data, $notice )
	{
		// admin check
		if ( !$irc->_modules['func']->isAdmin( $irc, $data->nick ) )
		{
			$this->parseTemplate( $msg, 'error', array( 'errormsg' => 'Insufficient privaleges to run this command' ) );
			$irc->_modules['func']->reply( $irc, $data, $msg, $notice );
			return;
		}
		
		if ( $data->trig[1] == 'help' )
		{
			$data->subMessage = trim( str_replace( $data->trig[1], '', $data->strippedMessage ) );
			$data->trig = array( 'help'	);
			return $this->botHelp( $irc, $data, $notice );
		}	
		else if ( $data->trig[1] == 'irc' )
		{
			$opts = $this->getOptions( 'irc', 'irc.php' );
			$conf = (array)$irc->config;
		}
		else if ( $irc->isLoadedModule( $data->trig[1] ) )
		{
			$opts = $this->getOptions( $data->trig[1], $irc->config->modulePath.'/'.$data->trig[1].'.php' );
			$conf = $irc->_modules[$data->trig[1]]->_config;
		}
		else
		{
			$this->parseTemplate( $msg, 'error', array( 'errormsg' => 'Invalid Module: '.$data->trig[1] ) );
			$irc->_modules['func']->reply( $irc, $data, $msg, $notice );
			return;
		}		
		if ( strlen( $data->trig[2] ) > 0 ) {
			$pSplit = explode( ' ', trim( $data->trig[2] ) );
		}
		else
		{
			$pSplit = array();
		}
		
		if ( ( $val = $this->_gTravArray( $conf, $pSplit ) ) !== 'fakeFalse' )
		{
			$cInfo = $this->_gTravArray( $opts, $pSplit );
			if ( isset( $cInfo['description'] ) )
			{
				if ( $cInfo['name'] != 'password' )
				{
					$vars = $cInfo;
					if ( is_array( $val ) )
					{
						$vars['value'] = 'array( {vals} )';
						$vars['vals'] = $val;
					}
					else if ( $cInfo['type'] == 'bool' )
					{
						$vars['value'] = ( $val )? 'true':'false';
					}
					else
					{
						$vars['value'] = $val;
					}
					$this->parseTemplate( $msg, 'varDetails', $vars );
				}
				else
				{
					$this->parseTemplate( $msg, 'error', array( 'errormsg' => 'Password Variables are out of bounds' ) );
					$notice = true;
				}
			}
			else
			{
				foreach( $val as $id => $item )
				{
					if ( $id != 'password' )
					{
						if ( isset( $cInfo[$id] ) )
						{
							if ( !isset( $cInfo[$id]['description'] ) )
								$id = '**'.$id.'**';
							$vars['varList'][] = $id;
						}
						else if ( count( $cInfo ) == 1 )
						{
							$keys = array_keys( $cInfo );
							if ( substr( $keys[0], -1 ) == '_' )
							{
								if ( !isset( $cInfo[$keys[0]]['description'] ) )
									$id = '**'.$id.'**';
								$vars['varList'][] = $id;
							}
						}
					}
				}
				
				// if i change the seperator part of the template system to allow 2 lists with different seperators in 1 template var this can be tidied up
				$tmp[] = $data->trig[1];
				$irc->_modules['func']->array_append( $tmp, $pSplit );
				$vars['pwd'] = implode( '__ > __', $tmp );
//				$irc->_modules['func']->array_append( $vars['pwd'], $pSplit );
				$this->parseTemplate( $msg, 'avVar', $vars );
			}
		}
		else
		{
			$tmp[] = $data->trig[1];
			$irc->_modules['func']->array_append( $tmp, $pSplit );		
			$this->parseTemplate( $msg, 'error', array( 'errormsg' => 'Invalid path: __{path}__', 'path' => implode( '__ > __', $tmp ) ) );
		}	
		if ( isset( $msg ) ) 
		{
			$irc->_modules['func']->reply( $irc, $data, $msg, $notice );
		}
	}
	
	function botHelp( &$irc, &$data, $notice )
	{
		if ( strlen( $data->subMessage ) > 0 )
		{
			if ( isset( $this->_help[$data->subMessage] ) )
			{
				$this->parseHelp( $msg, $data->subMessage, array( 'trigger' => $data->trigger ) );
			}
			else
			{
				//$this->parseTemplate( $msg, 'error', array( 'errormsg' => sprintf( 'Unknown command: %s', $data->subMessage ) ) );
			}
		}
		else
		{
			foreach ( $this->_help as $id => $helpItem )
			{
				$vars['helpCommands'][] = $id;
			}
			$vars['trigger'] = $data->trigger;
			$vars['subTrigger'] = $data->trig[0];
			$this->parseTemplate( $msg, 'helpList', $vars );
		}
		
		if ( isset( $msg ) )
		{
			$irc->_modules['func']->reply( $irc, $data, $msg, true );
		}
		
	}
	
	/*****************************************************
	 * Reading config options from a file
	 *****************************************************/
	function getOptions( $module, $file, $header = false )
	{ 
		global $irc;
			
		if ( is_file( $file ) )
		{
			$text = file_get_contents( $file );
			
			preg_match_all( $this->_def['regex']['configVars'], $text, $match );

			$conf = array();

			for( $i=0, $l=0; $i < count( $match[0] ); $i++ )
			{
				if ( $header )
				{
					$conf['configSplit'.$l++] = $match[1][$i];
				}
				preg_match_all( $this->_def['regex']['varVal'], $match[2][$i], $vars );
				
				for( $j=0; $j < count( $vars[0] ); $j++ )
				{
					$apos = ( strlen( $vars[1][$j] ) - 1 ) / 4;
					$pos[$apos] = $vars[3][$j];
					$pos = array_splice( $pos, 0, $apos + 1 );
					if ( ( !empty( $vars[5][$j] ) ) )
					{
						$tmp = array(
							'type' => $vars[2][$j],
							'name' => $vars[3][$j],
							'description' => $vars[5][$j]
						);
						$conf = $this->_sTravArray( $conf, $pos, $tmp );
					}
				}
			}
			return $conf;
		}
	}
	
	function _gTravArray( $array, $pos )
	{
		if ( count( $pos ) == 0 )
		{
			return $array;
		}
		else if ( !array_key_exists( $pos[0], $array ) )
		{
			if ( count( $array ) == 1 )
			{
				$keys = array_keys( $array );
				if ( substr( $keys[0], -1 ) == '_' )
				{
					$array[$pos[0]] = $array[$keys[0]];
					return $this->_gTravArray( $array[$pos[0]], array_splice( $pos, 1 ) );
				}
			}
			return 'fakeFalse';
		}	
		else
		{
			return $this->_gTravArray( $array[$pos[0]], array_splice( $pos, 1 ) );
		}
	}
	
	function _sTravArray( $array, $pos, $set )
	{
		if ( count( $pos ) == 0 )
		{
			$array = $set;
		}
		else
		{
			$array[$pos[0]] = $this->_sTravArray( $array[$pos[0]], array_splice( $pos, 1 ), $set );
		}
		return $array;
	}
	
	function _resortArray( $array )
	{
		$nArr = array();
		foreach( $array as $val )
		{
			$nArr[] = $val;
		}
		return $nArr;
	}
	
	function _setConfig( $module, $newConf )
	{
		global $irc;
		if ( $module == 'irc' )
		{
			$irc->config = (object)$newConf;
		}
		else
		{
			//print_r( $newConf );
			$irc->_modules[$module]->_config = $newConf;
		}
		
		// can not have a slash, because if basePath is not set it will write to root
		$this->_writeConfig( $irc->config->userPath.$this->_config['configFile'] );
	}
	
	function _writeConfig( $file )
	{
		global $irc;
		
		$text = $this->_def['file']['header'];
		
		// get irc options
		$text .= $this->_writeConfigModule( 'irc' );
		
		$mList = $irc->config->moduleConf;
		
		foreach( $irc->config->modules as $mod )
		{
			$text .= $this->_writeConfigModule( $mod );
			if ( isset( $mList[$mod] ) )
			{
				unset( $mList[$mod] );
			}
		}
		foreach( $mList as $mod => $bla )
		{
			$text .= $this->_writeConfigModule( $mod );
		}
		
		$text .= $this->_def['file']['footer'];
		
		$fp = @fopen( $file, 'w' );
		if (!$fp) {
			$irc->modDebug( 'config', 'unable to open config file: '.$file, __FILE__, __LINE__ );
			return 'unable to open file: '.$file;
		}		
		fwrite( $fp, $text );
		fclose( $fp );
		
		return true;		
	}
	
	function _writeConfigModule( $module )
	{
		global $irc;
		
		if ( $module == 'irc' ) 
		{
			$opts = $this->getOptions( 'irc', $irc->config->basePath.'/'.'irc.php', true );
		}
		else
		{
			$opts = $this->getOptions( $module, $irc->config->modulePath.'/'.$module.'.php', true );
		}
		
		$i = 0;
		
		foreach( $opts as $id => $item )
		{
			if ( substr( $id, 0, 11 ) == 'configSplit' )
			{
				// if not first, write everything down
				if ( $i > 0 )
				{
					$text .= $this->_writeConfigSection( $module, $section[$i] );
				}
				$section[++$i] = array(
					'header' => $item,
					'vars' => array()
				);
			}
			else
			{
				$section[$i]['vars'][$id] = $item;
			}
		}
		$text .= $this->_writeConfigSection( $module, $section[$i] );		
		
		return $text;
	}
	
	function _writeConfigSection( $module, $section )
	{
		global $irc;
		
		if ( !is_array( $section['vars'] ) )
		{
			return false;
		}
		$text = sprintf( $this->_def['file']['sectionHeader'], $section['header'] );
		
		$text .= $this->_writeConfigInfo( $section['vars'], 0 );
		
		$text .= $this->_def['file']['sectionFooter'];
		
		if ( $module == 'irc' ) 
		{
			foreach( $section['vars'] as $name => $var )
			{
				$text .= sprintf( $this->_def['file']['dataIRC'], $name, $this->_writeVarFormat( $irc->config->$name ) );
			}
		}
		else
		{
			if ( ( !isset( $irc->_modules[$module]->_config ) ) &&
			     ( isset( $irc->config->moduleConf[$module] ) ) )
			{
				$text .= sprintf( $this->_def['file']['dataModule'], $module, $this->_writeVarFormat( $irc->config->moduleConf[$module] ) );
			}
			else
			{
				$text .= sprintf( $this->_def['file']['dataModule'], $module, $this->_writeVarFormat( $irc->_modules[$module]->_config ) );
			}
		}
		
		return $text;
	}
	
	function _writeConfigInfo( $var, $spaces )
	{
		foreach( $var as $id => $item )
		{
			if ( !isset( $item['description'] ) )
			{
				// array
				$text .= sprintf( $this->_def['file']['sectionVariable'], str_repeat( ' ', $spaces ), 'array', $id, '' );
				$text .= $this->_writeConfigInfo( $item, $spaces + 4 );
			}
			else
			{
				$text .= sprintf( $this->_def['file']['sectionVariable'], str_repeat( ' ', $spaces ), $item['type'], $item['name'], '- '.$item['description'] );
			}
		}
		return $text;
	}
	
	function _writeVarFormat( $var )
	{
		// format
		$export = var_export( $var, true );
		
		return preg_replace( $this->_def['export']['from'], $this->_def['export']['to'], $export );		
	}
}

?>
Return current item: Nzbirc