Location: PHPKode > projects > MUSPA > modules/opcoes/opcoes.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.
*
*******************************************************************************/

define("OPCOES_USERS_PER_PAGE", 20);

class Opcoes extends admin
{
	/**	Nome do modulo */
	function moduleName()
	{
		return 'Op&ccedil;&otilde;es';
	}
	/** Descrição do modulo */
	function moduleDescription()
	{
		return 'Op&ccedil;&otilde;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&aacute;rios",
				"descricao" => "Cria um usu&aacute;rio",
				"link" => "?m=opcoes&action=listusers",
				"privs" => PRIV_ADMIN
			),
			array(
				"nome" => "M&oacute;dulos",
				"descricao" => "Habilita/desabilita m&oacute;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&aacute;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&aacute;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&aacute;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&aacute;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&oacute;dulos dispon&iacute;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 &quot;conf_modules.php&quot; precisa ter permissões de escrita (CHMOD 666).", "?m=opcoes&action=modules");
		fwrite($fp, $config);
		fclose($fp);

		Header("Location: ?m=opcoes&action=modulesupdated");
		exit;
	}
};
?>
Return current item: MUSPA