Location: PHPKode > projects > MUSPA > muspa/sys/admin.php
<?php
/*******************************************************************************
* MUSPA
*
* Copyright (C) 2004 MUSPA Project
*
* Este programa é software livre; você pode redistribuí-lo e/ou modificá-lo
* sob os termos da Licença Pública Geral GNU conforme publicada pela Free
* Software Foundation; tanto a versão 2 da Licença, como (a seu critério)
* qualquer versão posterior.
*
* Este programa é distribuído na expectativa de que seja útil, porém, SEM
* NENHUMA GARANTIA; nem mesmo a garantia implícita de COMERCIABILIDADE OU
* ADEQUAÇÃO A UMA FINALIDADE ESPECÍFICA. Consulte a Licença Pública Geral do
* GNU para mais detalhes.
*
* Você deve ter recebido uma cópia da Licença Pública Geral do GNU junto com
* este programa; se não, escreva para a Free Software Foundation, Inc., no
* endereço 59 Temple Street, Suite 330, Boston, MA 02111-1307 USA.
*
*******************************************************************************/

require_once('include/util.php');
require_once('include/db.php');
require_once('include/patTemplate.php');

//	Campos selecionados nas queries usadas para preencher
//	a array $admin::aUser
define('USERS_INFO_QUERY', 'id, user, nome, bloqueado, privs AS privs_descr, privs+0 AS privs, '
	.'UNIX_TIMESTAMP(NOW()) - UNIX_TIMESTAMP(loggedat) as loggedtime'
		);

// Privs
define('PRIV_ADMIN', 2);
define('PRIV_NORMAL', 1);

/**
*	Classe base para todos os modulos do admin
*/
class Admin {

	// Objetos
	var $db;		///	Conexão com o banco de dados
	var $tmpl;		///	patTemplate

	// Flags
	var $validate;	///	Valida o usuário ?
	var $inittemplate;	/// Inicia o template base na inicialização?
	var $magic_quotes;	/// Magic quotes ligado no servidor?

	// Todos os modulos do painel de controle
	var $aModules;

	// Atributos
	var $aUser;		///	Array com dados do usuario...
	var $ip;		///	IP do usuário
	var $error;		///	Último Erro

	/**
	*	Constructor
	*	@param	$validate		Valida usuário?
	*	@param	$inittemplate	Iniciar template engine?
	*/
	function Admin($validate = true, $inittemplate = true)
	{
		$this->validate = $validate;
		$this->inittemplate = $inittemplate;
		$this->aModules = array();
	}

	/**
	*	Executa o modulo.
	*	Obs.: Este metodo NÃO deve ser overlodeado... pena que terei que
	*	esperar até o PHP5 pela keyword "final"...
	*/
	function _run_()
	{
		global $g_aModuleList;

		// flags
		$this->error = null;
		$this->db = null;

		$this->ip = GetIp();
		$this->tmpl = new patTemplate();
		$this->db();

		// Guarda a configuração do magic quotes para saber quando usar
		// stripslashes, addslashes, etc...
		$this->magic_quotes = (bool) get_magic_quotes_gpc();

		//	Verifica as flags
		if ($this->validate)
			$this->validateUser();

		if ($this->inittemplate)
		{
			//	Escaneia todos os modulos que o usuário tem privilégio
			//	para ver.
			//	Cria um objeto de todos os modulos...
			//	parece loucura, mas ele apenas cria os objetos,
			//	não os executa.
			// Pretendo melhorar isso aqui em um futuro prospero... para ele
			// não precisar "parsear" todos os arquivos dos modulos
			foreach ( $g_aModuleList as $module=>$url )
			{
				include_once($url);

				$obj =& new $module;
				if ($obj->privs() <= $this->aUser['privs'])
					$this->aModules[] = $obj;
				else
					unset($obj);
			}

			//	Abre os templates
			$this->tmpl->readTemplatesFromFile('sys/templates/base.htm');
			$this->tmpl->readTemplatesFromFile('sys/templates/tip.htm');

			$this->_buildMenu();

			// Adiciona o tipo do usuário
			$this->tmpl->addVar('main', 'PRIVS',	$this->aUser['privs_descr']);
			// Adiciona a quanto tempo o usuário esta logado
			$this->tmpl->addVar('main', 'LOGGEDAT',
							 TimeToString($this->aUser['loggedtime']));
			// Usuário
			$this->tmpl->addVar('main', 'USER', $this->aUser['nome']);
			// Versão
			$this->tmpl->addVar('main', 'VERSION', VERSION);
		}
		// Chama o metodo run() do modulo
		$this->run();
	}

	/**
	*	Constroi o menu
	*/
	function _buildMenu()
	{
		$aMenu = array();
		// Adiciona Entradas de menu do sistema
		$aMenu['NOME'][] = 'Principal';
		$aMenu['DESCRICAO'][] = 'Entrada do sistema.';
		$aMenu['LINK'][] = '?m=entrada';
		$aMenu['TYPE'][] = 'directmenu';
		$aMenu['SELECTED'][] = '';

		foreach($this->aModules as $obj)
		{
			$aMenu['NOME'][] = $obj->moduleName();
			$aMenu['DESCRICAO'][] = $obj->moduleDescription();
			$aMenu['LINK'][] = '';
			$aMenu['TYPE'][] = 'menu';
			$aMenu['SELECTED'][] = (get_class($obj) == $_GET['m']) ? 'true' : 'false';

			$aSubMenu = $obj->subModules();
			foreach($aSubMenu as $submenu)
			{
				if ( $this->aUser['privs'] >= $submenu['privs'] )
				{
					$aMenu['NOME'][] = $submenu['nome'];
					$aMenu['DESCRICAO'][] = $submenu['descricao'];
					$aMenu['LINK'][] = $submenu['link'];
					$aMenu['TYPE'][] = 'submenu';
					$aMenu['SELECTED'][] = '';
				}
			}
		}

		// Adiciona Entradas de menu do sistema
		$aMenu['NOME'][] = 'Sair';
		$aMenu['DESCRICAO'][] = 'Sai do sistema.';
		$aMenu['LINK'][] = '?m=logout';
		$aMenu['TYPE'][] = 'directmenu';
		$aMenu['SELECTED'][] = '';

		$this->tmpl->addVars('menu', $aMenu);
	}

	/**
	*	Este metodo precisa ser implementado nos modulos, é aqui que começa
	*	o código dos módulos, use o constructor dos modulos APENAS para
	*	enviar novos parametros para o constructor da classe base (Admin)
	*/
	function run()
	{
		die('O método '.get_class($this).'::run() precisa ser implementado.');
	}

	/**
	*	Descrição do modulo
	*	@return String com descrição do módulo
	*/
	function moduleDescription()
	{
		return '[ModuleDescription]';
	}

	/**
	*	Nome do modulo
	*	@return Nome do módulo
	*/
	function moduleName()
	{
		return '[ModuleName]';
	}

	/**
	*	O autor do módulo precisa reimplementar este metodo com seu nome.
	*	@return String com versão do módulo
	*/
	function author()
	{
		return '';
	}

	/**
	*	Os módulos precisam reimplementar este metódo com a versão do módulo.
	*	@return String com versão do módulo
	*/
	function version()
	{
		return '';
	}

	/**
	*	Retorna lista de modulos disponiveis
	*/
	function modules()
	{
		return $this->aModules;
	}

	/**
	*	Retorna os sub-modulos do modulo
	*/
	function subModules()
	{
		// keys: nome, descricao, link, privs
		return array();
	}

	/**
	*	Retorna por referência a conexão ao DB usada pelo objeto, se
	*	a conexão ainda não tiver sido aberta, uma nova
	*	conexão será aberta.
	*	@return	DB Object por referência.
	*/
	function &db()
	{
		if (!$this->db)
			$this->db = new db(DB_HOST, DB_USER, DB_PWD, DB_DB);
		return $this->db;
	}

	/**
	*	Último erro.
	*/
	function error()
	{
		return $this->error;
	}

	/**
	*	Coloca o caption no template
	*	@param	caption	Texto usado
	*/
	function setCaption($caption)
	{
		if (!$this->inittemplate)
			FatalError('O módulo precisa iniciar o template pela classe '
						.' admin para você usar esta função.');
		$this->tmpl->addVar('main', 'CAPTION', $caption);
	}

	/**
	*	Privilégio necessário para acessar este modulo
	*/
	function privs()
	{
		return PRIV_NORMAL;
	}

	/**
	*	Valida o usuario
	*/
	function validateUser()
	{
		session_start();

		if (!isset($_SESSION['sys']['sessid']))
			FatalError('Seção inválida! Provavelmente você esta tentando entrar em um endereço sem estar logado.');

		$this->db->query('SELECT '.USERS_INFO_QUERY.' FROM '.PRE_TABLE.'users WHERE '
				.' sessid="'.$_SESSION['sys']['sessid'].'" AND ip='.$this->ip
				.' LIMIT 1', __FILE__, __LINE__);
		if ($this->db->numRows())
		{
			$this->aUser = $this->db->fetchAssoc();
			$this->aUser['privs'] = (int)$this->aUser['privs'];
			if ($this->aUser['bloqueado'] == 'Y')
			{
				session_destroy();
				FatalError('Sua conta foi bloqueada pelo administrador!');
			}
		}
		else
		{
			session_destroy();
			FatalError('Seção inválida!');
		}
	}

	/**
	*	Loga o usuario
	*	@param	user	usuario
	*	@param	pwd		senha
	*/
	function userLogon( $user, $pwd )
	{
		$user = $this->db->escapeString($user);
		$pwd = $this->db->escapeString($pwd);
		$this->db->query('SELECT '.USERS_INFO_QUERY.' FROM '.PRE_TABLE.'users WHERE '
				.'user="'.$user.'" AND pwd=PASSWORD("'.$pwd.'") LIMIT 1', __FILE__, __LINE__);

		if (!$this->db->numRows())
		{
			$this->error = 'Usuário e/ou senha inválidos.';
			return false;
		}
		else
		{
			$this->aUser = $this->db->fetchAssoc();

			// Verifica se a conta esta bloqueada
			if ($this->aUser['bloqueado'] == 'Y')
			{
				$this->error = 'Sua conta esta bloqueada.';
				return false;
			}
			elseif (!$this->aUser['privs'])
			{
				$this->error = 'Sua conta não esta devidamente configurada.';
				return false;
			}
			else
			{
				// Login/senha Ok, logue o usuario
				Mysrand();
				$sessid = md5(uniqid (mt_rand()));

				$this->db->query('UPDATE '.PRE_TABLE.'users SET sessid="'.$sessid.'", '
						.' ip = '.$this->ip.', loggedat = NOW()'
						.' WHERE id = '.$this->aUser['id'], __FILE__, __LINE__);
				session_start();
				$_SESSION['sys']['sessid'] = $sessid;
				return true;
			}
		}
	}

	/**
	*	Faz o logout do usuário, destroi a seção, etc...
	*	@static
	*/
	function cleanUp()
	{
		if (isset($this->aUser))
			$this->db->query('UPDATE '.PRE_TABLE.'users SET sessid=NULL, '
					.' ip = NULL, loggedat = NULL'
					.' WHERE id = '.$this->aUser['id'], __FILE__, __LINE__);
		if (session_id())
		{
			$_SESSION = array();
			session_destroy();
		}
	}

	/**
	*	Mostra o template 'main' na tela
	*/
	function display($template = 'main')
	{
		$this->tmpl->displayParsedTemplate($template);
	}

};

Return current item: MUSPA