<?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.
*
*******************************************************************************/
define("OPCOES_USERS_PER_PAGE", 20);
class Opcoes extends admin
{
/** Nome do modulo */
function moduleName()
{
return 'Opções';
}
/** Descrição do modulo */
function moduleDescription()
{
return 'Opções gerais, dentre elas alterar senha.';
}
/**
* Meu lindo nome.
*/
function author()
{
return "Hugo P.L.";
}
/**
* Versão do módulo
*/
function version()
{
return "1.0";
}
/** Lista de submodulos */
function subModules()
{
return array(
array(
"nome" => "Alterar senha",
"descricao" => "Altera sua senha",
"link" => "?m=opcoes&action=alterarsenha",
"privs" => PRIV_NORMAL
),
array(
"nome" => "Usuários",
"descricao" => "Cria um usuário",
"link" => "?m=opcoes&action=listusers",
"privs" => PRIV_ADMIN
),
array(
"nome" => "Módulos",
"descricao" => "Habilita/desabilita módulos do sistema.",
"link" => "?m=opcoes&action=modules",
"privs" => PRIV_ADMIN
),
);
}
function run()
{
$template = null;
if (!isset($_GET['action'])) // default opt.
$_GET['action'] = null;
switch($_GET['action'])
{
// Úsuarios
case 'listusers':
$this->listUsers();
break;
case 'createuser':
$this->createUser();
break;
case 'showedituser':
$this->showEditUser();
break;
case 'edituser':
$this->editUser();
break;
// Módulos
case 'modules':
$this->listModules();
break;
case 'updatemodules':
$this->updateModules();
break;
case 'modulesupdated':
$this->setCaption('Lista de módulos atualizada');
// highlight_file('conf_modules.php');
$this->tmpl->readTemplatesFromFile('modules/opcoes/templates/modulesupdated.htm');
break;
// Alterar senha
case 'senhaalterada':
$this->setCaption('Senha alterada');
$this->tmpl->readTemplatesFromFile('modules/opcoes/templates/senhaalterada.htm');
break;
case 'alterarsenha':
default:
$this->alterarSenha();
}
$this->display();
}
/**
* Altera senha do usuário
*/
function alterarSenha()
{
$error = "";
if (count($_POST))
{
if (!isset($_POST['senha']) || !isset($_POST['confirmacao']))
$error = "Você precisa preencher o formulário por completo.";
elseif ($_POST['senha'] != $_POST['confirmacao'])
$error = "A senha digitada não confere com a confirmação.";
elseif (strlen($_POST['senha']) < 4)
$error = "A senha precisa ter pelo menos 4 caracteres.";
else
{
$senha = $this->db->escapeString(strlen($_POST['senha']));
$this->db->query('UPDATE '.PRE_TABLE.'users SET '
.'pwd = PASSWORD("'.$senha.'") '
.'WHERE id='.$this->aUser['id'].' LIMIT 1',
__FILE__, __LINE__);
header("Location: ?m=opcoes&action=senhaalterada");
exit;
}
}
$this->setCaption('Alterando senha');
$this->tmpl->readTemplatesFromFile('modules/opcoes/templates/alterarsenha.htm');
if ($error)
{
$this->tmpl->addVars('content', $_POST);
$this->tmpl->setAttribute('error', 'visibility', 'show');
$this->tmpl->addVar('error', 'ERROR', $error);
}
}
/**
* Mostra formulario para criação/edição de usuário
*/
function displayUserForm(&$aData)
{
$this->tmpl->readTemplatesFromFile('modules/opcoes/templates/userform.htm');
if (isset($aData['bloqueado']))
if ($aData['bloqueado'] != 'N')
$aData['bloqueado'] = 'checked="checked"';
if (isset($aData['privs']))
if ($aData['privs'] == 'Administrador')
$aData['ADMINISTRADOR'] = 'selected="selected"';
else
$aData['USUÁRIO'] = 'selected="selected"';
$this->tmpl->addVars('content', $aData);
}
/**
* Regras usadas no formulario de cadastro/edição de usuairo
*/
function userRules()
{
return array(
array('id', 'userid', FRM_OPCIONAL, "/^[0-9]+$/"),
array('nome', 'nome', FRM_OBRIGATORIO),
array('user', 'login', FRM_OBRIGATORIO, "/^[a-z0-9_-]+$/", "precisa ser em caixa baixa e sem acentos"),
array('pwd', 'senha', FRM_OBRIGATORIO, "/^[a-z0-9]+$/", "precisa ser em caixa baixa, sem acentos, hiféns ou underlines"),
array('privs', 'privilégios', FRM_OBRIGATORIO, "/^(Administrador|Usuário)$/"),
array('bloqueado', 'bloqueado', FRM_OPCIONAL, "/^1$/")
);
}
/**
* Cria um usuário
*/
function createUser()
{
if ($this->aUser['privs'] < PRIV_ADMIN)
FatalError(MSG_NOPRIVS);
$rules = $this->userRules();
$res = CheckForm($_POST, $rules);
if ($res === true)
{
// Verifica se existe alguém com esse login.
$this->db->query("SELECT id FROM ".PRE_TABLE."users "
." WHERE user='".$_POST['user']."'");
if ($this->db->numRows())
$res = array('ERROR' => 'Já existe um usuário cadastrado com este login.');
}
if ($res === true)
{
// TUdo Ok, cadastre
$this->db->query("INSERT INTO ".PRE_TABLE."users "
."(nome, user, pwd, privs, bloqueado) VALUES("
."'".$this->db->escapeString($_POST['nome'])."', "
."'".$_POST['user']."', "
."PASSWORD('".$_POST['pwd']."'), "
."'".$_POST['privs']."', "
."'".(($_POST['bloqueado']=='1') ? 'Y' : 'N')."' "
.");", __FILE__, __LINE__);
header("Location: ?m=opcoes&action=listusers");
exit;
}
else
{
$this->setCaption("Criando usuário");
$this->tmpl->readTemplatesFromFile('modules/opcoes/templates/userlist.htm');
$this->tmpl->setAttribute('lista', 'visibility', 'hidden');
$this->tmpl->setAttribute('error', 'visibility', 'show');
$this->tmpl->addVars('error', $res);
$this->displayUserForm($_POST);
}
}
function showEditUser()
{
if ($this->aUser['privs'] < PRIV_ADMIN)
FatalError(MSG_NOPRIVS);
if (isset($_GET['id']))
$id = (int)$_GET['id'];
if (!$id)
SemiFatalError("Este usuário não existe.", "?m=opcoes&action=listusers");
$this->setCaption("Editando usuário");
$this->db->query("SELECT id, nome, user, privs, bloqueado"
." FROM ".PRE_TABLE."users WHERE id=".$id, __FILE__, __LINE__);
$this->tmpl->readTemplatesFromFile('modules/opcoes/templates/edituser.htm');
$aUser = $this->db->fetchAssoc();
$this->displayUserForm($aUser);
}
function editUser()
{
if ($this->aUser['privs'] < PRIV_ADMIN)
FatalError(MSG_NOPRIVS);
$rules = $this->userRules();
// Senha é opcional!
$rules[3][2] = FRM_OPCIONAL;
$res = CheckForm($_POST, $rules);
if (!$_POST['id'])
SemiFatalError("Usuário não especificado!", "?m=opcoes&action=listusers");
if ($res === true)
{
// Verifica se existe alguém com esse login.
$this->db->query("SELECT id FROM ".PRE_TABLE."users "
." WHERE user='".$_POST['user']."' AND id != ".$_POST['id']);
if ($this->db->numRows())
$res = array('ERROR' => 'Já existe um outro usuário cadastrado com este login.');
}
if ($res === true)
{
$pwd = ($_POST['pwd']) ? ", pwd = PASSWORD('".$_POST['pwd']."')" : "";
// Tudo Ok, cadastre
$query = "UPDATE ".PRE_TABLE."users SET "
."nome = '".$this->db->escapeString($_POST['nome'])."', "
."user = '".$_POST['user']."'"
.$pwd;
// Não permite que o próprio usuário altere seus privs ou bloqueie sua própria conta.
if ($_POST['id'] != $this->aUser['id'])
{
$query .= ", privs = '".$_POST['privs']."', "
."bloqueado = '".(($_POST['bloqueado']=='1') ? 'Y' : 'N')."' ";
}
$this->db->query($query." WHERE id=".$_POST['id'], __FILE__, __LINE__);
header("Location: ?m=opcoes&action=listusers");
exit;
}
else
{
$this->setCaption("Criando usuário");
$this->tmpl->readTemplatesFromFile('modules/opcoes/templates/userlist.htm');
$this->tmpl->setAttribute('lista', 'visibility', 'hidden');
$this->tmpl->setAttribute('error', 'visibility', 'show');
$this->tmpl->addVars('error', $res);
$this->displayUserForm($_POST);
}
}
function listUsers()
{
if ($this->aUser['privs'] < PRIV_ADMIN)
FatalError(MSG_NOPRIVS);
if (isset($_GET['subaction']) && isset($_POST['usuario']))
{
$aIds = array();
foreach ($_POST['usuario'] as $id)
{
$id = (int) $id;
if ($id)
$aIds[] = $id;
}
if (sizeof($aIds))
{
$ids = implode(', ', $aIds);
$query = "";
switch ($_GET['subaction'])
{
case 'ban':
$query = "UPDATE ".PRE_TABLE."users SET "
." bloqueado='Y' WHERE id IN (".$ids.") "
." AND id != ".$this->aUser['id'];
break;
case 'unban':
$query = "UPDATE ".PRE_TABLE."users SET "
." bloqueado='N' WHERE id IN (".$ids.")";
break;
case 'del':
$query = "DELETE FROM ".PRE_TABLE."users "
." WHERE id IN (".$ids.") "
." AND id != ".$this->aUser['id'];
break;
}
if ($query)
$this->db->query($query, __FILE__, __LINE__);
header("Location: ?m=opcoes&action=listusers");
exit;
}
}
$this->setCaption("Listando usuários");
$this->tmpl->readTemplatesFromFile('modules/opcoes/templates/userlist.htm');
// Conta o total de usuários para fazer a paginação
$this->db->query("SELECT count(id) "
." FROM ".PRE_TABLE."users",__FILE__, __LINE__);
$total = (int) $this->db->result(0, 0);
$page = isset($_GET['page']) ? (int)$_GET['page'] : 1;
if (!$page)
$page = 1;
// Verifica se vai existir os botões de Próx. Pág. e Pág. Anterior
if ($page > 1)
{
// tem pág. anterior
$this->tmpl->setAttribute('prevpage', 'visibility', 'show');
$this->tmpl->addVar('prevpage', 'LINK',
'?m=opcoes&action=listusers&page='.($page-1));
}
if (($page*OPCOES_USERS_PER_PAGE) < $total)
{
// tem próx. pág.
$this->tmpl->setAttribute('nextpage', 'visibility', 'show');
$this->tmpl->addVar('nextpage', 'LINK',
'?m=opcoes&action=listusers&page='.($page+1));
}
$this->tmpl->addVar('lista', 'PAGE',
$page."/".ceil($total/OPCOES_USERS_PER_PAGE) );
// Pega lista de usuários
$this->db->query("SELECT id, nome, user, ip, privs, "
." IF(bloqueado='Y', 'bloqueado', IF(ISNULL(sessid), 'offline', IF(ADDDATE(loggedat, INTERVAL 3 HOUR) < NOW(), 'offline', 'online'))) AS status"
." FROM ".PRE_TABLE."users"
." LIMIT ".(($page-1)*OPCOES_USERS_PER_PAGE).", ".OPCOES_USERS_PER_PAGE
,__FILE__, __LINE__);
$aUsers = array();
while($row = $this->db->fetchAssoc())
{
$aUsers['ID'][] = $row['id'];
$aUsers['NOME'][] = $row['nome'];
$aUsers['USER'][] = $row['user'];
$aUsers['IP'][] = $row['ip'] ? long2ip($row['ip']) : '';
$aUsers['PRIVS'][] = $row['privs'];
$aUsers['STATUS'][] = $row['status'];
}
$this->tmpl->addVars('userlist', $aUsers);
$aData = array();
$this->displayUserForm($aData);
}
/**
* Mostra lista com todos os módulos disponiveis e opção para habilitar/desabilitar cada um.
*/
function listModules()
{
global $g_aModuleList;
if ($this->aUser['privs'] < PRIV_ADMIN)
FatalError(MSG_NOPRIVS);
$this->setCaption("Módulos disponíveis no sistema");
$this->tmpl->readTemplatesFromFile('modules/opcoes/templates/modules.htm');
$aCurOrdem = array_keys($g_aModuleList);
$aModules = array();
// Lista todos os modulos disponiveis
$dir = opendir('modules');
while(($file = readdir($dir)) !== false)
{
if ($file == "." || $file == "..")
continue;
if (!file_exists('modules/'.$file.'/'.$file.'.php'))
continue;
include_once('modules/'.$file.'/'.$file.'.php');
if (!class_exists($file))
continue;
if (get_parent_class($file) != 'admin')
continue;
$aModules['MODULO'][] = call_user_func(array($file, "moduleName"));
$aModules['DESCRICAO'][] = call_user_func(array($file, "moduleDescription"));
$aModules['AUTOR'][] = call_user_func(array($file, "author"));
$aModules['VERSAO'][] = call_user_func(array($file, "version"));
$aModules['CLASSNAME'][] = $file;
if (isset($g_aModuleList[$file]))
{
$aModules['SIM'][] = 'checked="checked"';
$aModules['NAO'][] = '';
}
else
{
$aModules['SIM'][] = '';
$aModules['NAO'][] = 'checked="checked"';
}
if ($file == 'opcoes')
$aModules['DISABLED'][] = 'disabled="disabled"';
else
$aModules['DISABLED'][] = '';
$ordem = array_search($file, $aCurOrdem);
$aModules['ORDEM'][] = ($ordem !== false) ? $ordem+1 : '';
}
closedir($dir);
$this->tmpl->addVars('modulelist', $aModules);
}
/**
* Atualiza a lista de módulos
* TODO: Fazer ser possivel o cara escolher a ordem de aparição dos módulos no
* menu.
*/
function updateModules()
{
if ($this->aUser['privs'] < PRIV_ADMIN)
FatalError(MSG_NOPRIVS);
$aTempModules = array();
foreach ($_POST['modules'] as $module=>$conf)
{
if (isset($conf[0]))
if ($conf[0] == '0')
continue;
if (!$conf[1])
$conf[1] = 99;
$aTempModules['NOME'][$conf[1]] = $module;
$aTempModules['PATH'][$conf[1]] = 'modules/'.$module.'/'.$module.'.php';
}
ksort($aTempModules['NOME']);
ksort($aTempModules['PATH']);
// Refaz a array para retirar os saltos de index.
$aModules = array();
foreach($aTempModules['NOME'] as $val)
$aModules['NOME'][] = $val;
foreach($aTempModules['PATH'] as $val)
$aModules['PATH'][] = $val;
unset($aTempModules);
$tmpl = new PatTemplate;
$tmpl->readTemplatesFromFile('modules/opcoes/config.tmpl');
$tmpl->addVar('config', 'DATE', date("d/m/Y H:i"));
$tmpl->addVars('modules', $aModules);
$config = $tmpl->getParsedTemplate('config');
$fp = @fopen('conf_modules.php', "w");
if (!$fp)
SemiFatalError("Erro de I/O, o arquivo "conf_modules.php" precisa ter permissões de escrita (CHMOD 666).", "?m=opcoes&action=modules");
fwrite($fp, $config);
fclose($fp);
Header("Location: ?m=opcoes&action=modulesupdated");
exit;
}
};
?>