<?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);
}
};