<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
<channel>
<title>HUFERSIL.WEBDEVELOPER - Soluções em desenvolvimento Web - Tecnologia - TI</title>
<description>PHP, Lumine Framework e afins</description>
<link>http://www.revistaphp.com.br</link>
<language>pt-br</language><item>
<title><![CDATA[Exemplo de lançamento de frequencia escolar]]></title>
<description><![CDATA[<p>Como j&aacute; vi v&aacute;rios posts em alguns f&oacute;runs perguntando sobre este assunto, resolvi fazer um exemplo para elucidar/ajudar aos que ainda est&atilde;o come&ccedil;ando.</p>
<p>Neste exemplo, ao inv&eacute;s de criar um banco de dias letivos, como vi v&aacute;rias pessoas comentando, criei um banco de feriados, afinal, o n&uacute;mero de feriados/dias n&atilde;o letivos &eacute; menor do que o de dias letivos, consequentemente, as consultas ficam mais r&aacute;pidas.</p>
<p>S&oacute; lan&ccedil;amos os alunos que estiveram presentes, consequentemente, quem n&atilde;o tem o registro de presen&ccedil;a &eacute; porque faltou. Assim, tamb&eacute;m, as consultas ficam mais r&aacute;pidas.</p>
<p>&Eacute; um exemplo bem simples, mas bem &uacute;til.</p>
<p><a href="http://www.hufersil.com.br/lumine/exemplos">Voc&ecirc; pode baix&aacute;-lo na se&ccedil;&atilde;o de exemplos</a>.</p>
<p>@bra&ccedil;os e fiquem com Deus!</p>
<p>&nbsp;</p>]]></description>
<lastBuildDate><![CDATA[Sex, 17 de fevereiro de 2012 - as 09h26]]></lastBuildDate>
<link>http://www.hufersil.com.br/post/exemplo_lancamento_frequencia_escolar</link>
</item>
<item>
<title><![CDATA[Criando um catálogo de produtos com Lumine e CodeIgniter - Parte 5]]></title>
<description><![CDATA[<p>Ol&aacute; pessoal!</p>
<p>Hoje, vamos deixar nossa p&aacute;gina um pouco mais apresent&aacute;vel e tamb&eacute;m fazer o cadastro de categorias.</p>
<p>Neste sistema, as categorias podem ter v&aacute;rios n&iacute;veis. Ent&atilde;o, nosso sistema dever&aacute; contemplar o cadastro de categorias filhas, netas, bisnetas...</p>
<!-- more -->
<h2>Deixando a interface mais bonita</h2>
<p>Antes de continuar a desenvolver as funcionalidades, vamos deixar o visual mais bacana.</p>
<p>Abra o arquivo <b>application/views/admin/template.php</b> e adicione depois da tag <b>body</b> o c&oacute;digo abaixo:</p>
<div class="both">&nbsp;</div>
<pre class="brush: php">
&lt;!-- imediatamente ap&oacute;s o &lt;body&gt; --&gt;
&lt;div class=&quot;header&quot;&gt;
	&lt;?php if(!empty($_usuario)): ?&gt;
	&lt;ul&gt;
		&lt;li&gt;&lt;a href=&quot;&lt;?php echo site_url('admin/dashboard/index'); ?&gt;&quot;&gt;P&aacute;gina Inicial&lt;/a&gt;
		&lt;li&gt;&lt;a href=&quot;&lt;?php echo site_url('admin/categorias/index'); ?&gt;&quot;&gt;Categorias&lt;/a&gt;
		&lt;li&gt;&lt;a href=&quot;&lt;?php echo site_url('admin/produtos/index'); ?&gt;&quot;&gt;Produtos&lt;/a&gt;
		&lt;li&gt;&lt;a href=&quot;&lt;?php echo site_url('admin/usuarios/index'); ?&gt;&quot;&gt;Usu&aacute;rios&lt;/a&gt;
		&lt;li&gt;&lt;a href=&quot;&lt;?php echo site_url('admin/login/do_logout'); ?&gt;&quot;&gt;Sair&lt;/a&gt;
	&lt;/ul&gt;
	&lt;?php endif; ?&gt;
&lt;/div&gt;
</pre>
<p>Este ser&aacute; o cabe&ccedil;alho de nossa aplica&ccedil;&atilde;o. Ele tamb&eacute;m j&aacute; tem um menu  b&aacute;sico sobre as coisas que vamos desenvolver.</p>
<p>Agora criando um <em>footer</em> simples. Adicione <b>antes da tag de fechamento &quot;body&quot;</b>:</p>
<pre class="brush: php">
&lt;div class=&quot;footer&quot;&gt;
	HUFERSIL.WEBDEVELOPER - &lt;?php echo date('Y'); ?&gt;
&lt;/div&gt;
</pre>
<p>Ap&oacute;s adicionar estes c&oacute;digos, precisamos estiliza-los. Para isso, abra o arquivo <b>assets/css/admin.css</b> e adicione os estilos abaixo:</p>
<pre class="brush: css">
.header {
	width: 85%;
	margin-left: auto;
	margin-right: auto;
	margin-bottom: 20px;
	padding: 80px 10px 10px 10px;
	background-image: URL(../imagens/logo.gif);
	background-position: left top;
	background-repeat: no-repeat;
	border-bottom: 2px solid #FFCC00;
}

.header ul {
	padding: 0px;
	margin: 0px;
}

.header ul li {
	list-style: none;
	display: inline;
	margin-right: 20px;
}
.header ul li a {
	text-decoration: none;
	color: #000000;
}
.header ul li a:hover {
	font-weight: bold;
	color: #0000CC;
}

.footer {
	width: 85%;
	margin-left: auto;
	margin-right: auto;
	margin-top: 20px;
	padding: 10px;
	text-align: center;
	font-size: 9px;
	color: #CCCCCC;
}
</pre>
<p>Pronto agora, temos um visual mais bacana para podermos acessar os itens que criamos.</p>
<h2>Criando a controller de gerenciamento de categorias</h2>
<p>Agora, precisamos cadastrar as categorias, antes de podermos cadastrar produtos. Para esta parte de categorias, como vamos poder trabalhar com estrutura hierarquica, precisaremos de algumas fun&ccedil;&otilde;es extras para podermos exibir os dados de forma hierarquica/aninhada.</p>
<p>Este tipo de fun&ccedil;&atilde;o, na estrutura do CodeIgniter, fica dentro de arquivos chamados <b>helpers</b> (<a href="http://codeigniter.com/user_guide/general/helpers.html">http://codeigniter.com/user_guide/general/helpers.html</a>). Vamos criar um arquivo de helper, no caminho <b>application/helpers/util_helper.php</b>, com a seguinte fun&ccedil;&atilde;o:</p>
<pre class="brush: php">
/**
 * Recebe uma lista de elementos e os coloca de forma aninhada.
 * 
 * @param array $lista       Lista de elementos a ser aninhada
 * @param string $chave      Indice que contem o valor padrao (codcategoria, por exemplo)
 * @param string $chavePai   Indice que contem o valor do codigo pai (codpai, por exemplo)
 * @param string $propFilhos Novo indice a ser gerado que armazenara os elementos aninhados
 * @return array Lista com os elementos aninhados 
 * @author Hugo Ferreira da Silva
 */
function fncAninharElementos(array $lista, $chave, $chavePai, $propFilhos = '_filhos'){
	
	// 1 - colocando os itens indexados pelo codigo principal
	$tmp = array();
	foreach($lista as $item){
		$tmp[$item[$chave]] = $item;
	}
	
	
	// 2 - colocando um item dentro do outro,
	// conforme pais e filhos
	foreach($tmp as &amp;$item){
		if(!empty($item[$chavePai])){
			$tmp[$item[$chavePai]][$propFilhos][] = &amp;$item;
		}
	}
	
	// 3 - deixando somente os itens que nao tem pai
	$nova = array();
	foreach($tmp as $node){
		if(empty($node[$chavePai])){
			$nova[] = $node;
		}
	}
	
	// pronto, retornando os elementos
	return $nova;
}
</pre>
<p>Depois de criar o arquivo, temos que carregar ele. Poderiamos utilizar o autoload, mas neste exemplo, vamos fazer um pouco diferente. Abra o arquivo <b>application/core/MY_Controller.php</b> e adicione ao construtor as seguintes linhas:</p>
<pre class="brush: php">
// carregando a helper customizada
$this-&gt;load-&gt;helper('util');
</pre>
<p>Pronto. Agora podermos utilizar as fun&ccedil;&otilde;es que est&atilde;o dentro de arquivo. Agora, vamos criar nossa controller de gerenciamento de caregorias.</p>
<p>Crie um arquivo na estrutura <b>application/controllers/admin/categorias.php</b> com o seguinte conte&uacute;do:</p>
<pre class="brush: php">
&lt;?php
/**
 * Controller para gerenciamento dos categorias de produtos
 * 
 *
 * @link http://www.hufersil.com.br
 * @author Hugo Ferreira da Silva
 *
 */
class Categorias extends AdminController {

	/**
	 * Metodo para listar as categorias cadastradas
	 * 
	 * @author Hugo Ferreira da Silva
	 */
	public function index(){
		$listaAninhada = $this-&gt;getCategoriasAninhadas();
		
		// colocamos a lista de resultados
		$this-&gt;assign('lista', $listaAninhada);
		// exibimos o resultado
		$this-&gt;display('categorias/index');
	}
	
	/**
	 * Exibe a tela de inser&ccedil;&atilde;o/atualiza&ccedil;&atilde;o de categorias
	 * 
	 * @param int $id Codigo da categoria que esta sendo editada ou null para cadastrar uma nova
	 * @author Hugo Ferreira da Silva
	 */
	public function editar($id = null){
		// se tem codigo de usuario e o metodo &eacute; GET
		if(!empty($id) &amp;&amp; $_SERVER['REQUEST_METHOD'] == 'GET'){
			// resgatamos o registro do banco
			$obj = new Categoria();
			$obj-&gt;get($id);
			// colocamos os dados na variavel $_POST
			$_POST = $obj-&gt;toArray();
		}
		// colocamos a lista de categorias para exibirmos na combo
		$this-&gt;assign('categorias', $this-&gt;getCategoriasAninhadas());
		
		// exibimos a tela de inser&ccedil;&atilde;o/edi&ccedil;&atilde;o de categorias
		$this-&gt;display('categorias/editar');
	}
	
	/**
	 * Insere uma nova categoria ou altera os dados de uma existente
	 * 
	 * @param int $id C&oacute;digo da categoria ou null para uma nova
	 * @author Hugo Ferreira da Silva
	 */
	public function salvar($id = null){
		// cria um objeto para persistencia
		$dao = new Categoria();
		
		// se est&aacute; editando (informou o c&oacute;digo da categoria)
		if(!empty($id)){
			// pegamos o registro do banco de dados
			$dao-&gt;get($id);
		}
		
		// se n&atilde;o tiver c&oacute;digo pai, colocamos como NULL
		if(empty($_POST['codpai'])){
			$_POST['codpai'] = null;
		}
		
		// colocamos no objeto os valores que est&atilde;o no formulario
		// como os nomes dos campos tem os mesmos nomes dos campos,
		// este m&eacute;todo facilita o preenchimento do objeto
		$dao-&gt;populateFrom($_POST);
		
		// fazemos a valida&ccedil;&atilde;o dos dados
		$erros = $dao-&gt;validate();
		
		// se n&atilde;o houveram erros
		if(empty($erros)){
			// fazemos a persistencia
			$dao-&gt;save();
			
			// redirecionamos para a tela de listagem de categorias
			redirect('admin/categorias/index');
			
		// mas se n&atilde;o passou na valida&ccedil;&atilde;o
		} else {
			// informamos quais foram os erros
			$this-&gt;assign('erros', $erros);
			
			// exibimos a tela de inser&ccedil;&atilde;o/edi&ccedil;&atilde;o
			$this-&gt;editar($id);
		}
	}
	
	/**
	 * Remove uma categoria cadastrada
	 * 
	 * @param int $id C&oacute;digo da categoria a ser removida
	 * @author Hugo Ferreira da Silva
	 */
	public function remover($id){
		// criamos um objeto de categoria
		$user = new Categoria();
		
		// se informou o codigo da categoria e encontrou no banco
		if(!empty($id) &amp;&amp; $user-&gt;get($id) == 1){
			// removemos a categoria
			// as subcategorias ser&atilde;o removidas em cascata,
			// bem como os produtos
			$user-&gt;delete();
		}
		
		// redirecionamos para a tela de listagem de categorias
		redirect('admin/categorias/index');
	}
	
	/**
	 * Recupera as categorias de forma aninhada
	 * 
	 * @author Hugo Ferreira da Silva
	 */
	protected function getCategoriasAninhadas(){
		$lista = new Categoria();
		// fazemos a consulta
		$lista-&gt;alias('c')
			// ordenamos pelo nome
			-&gt;order('c.ordem asc')
			// efetuamos a consulta
			-&gt;find();
		
		// precisamos colocar um &quot;item dentro do outro&quot; para poder enviar
		// e montar o html corretamente
		$listaAninhada = fncAninharElementos($lista-&gt;allToArray()
			, 'codcategoria'
			, 'codpai'
			, 'categorias'
		);
		
		return $listaAninhada;
	}
}
</pre>
<p>Nesta parte de categorias, precisamos fazer uma verifica&ccedil;&atilde;o para saber se o usu&aacute;rio n&atilde;o est&aacute; inserindo refer&ecirc;ncias circulares (um objeto &eacute; pai/av&ocirc; dele mesmo).</p>
<p>Para adicionarmos esta valida&ccedil;&atilde;o, abra o arquivo <b>application/models/Categoria.php</b> e adicione os seguintes m&eacute;todos:</p>
<pre class="brush: php">
    public function validate(){
    	$this-&gt;addValidator(new Lumine_Validator_String('nome', 'Informe o nome da categoria'));
    	$this-&gt;addValidator(new Lumine_Validator_Custom('codpai', 'Refer&ecirc;ncia ciclica detectada', array($this,'validarCodPai')));
    	return parent::validate();
    }

    /**
     * Efetua a valida&ccedil;&atilde;o contra refer&ecirc;ncias circulares
     * 
     * @param Categoria $obj Referencia ao objeto que est&aacute; sendo validado
     * @param string $field  Nome do campo que est&aacute; sendo validado
     * @param mixed $value   Valor do campo que est&aacute; sendo validado
     * @return boolean
     * @author Hugo Ferreira da Silva
     */
    public function validarCodPai(Categoria $obj, $field, $value){
    	// se estiver inserindo, tudo bem
    	if(empty($obj-&gt;codcategoria)){
    		return true;
    	}
    	
    	// se tiver vazio, virou uma categoria principal
    	if(empty($value)){
    		return true;
    	}
    	
    	// ele n&atilde;o pode ser pai dele mesmo
    	if($value == $obj-&gt;codcategoria){
    		return false;
    	}
    	
    	// e nao pode ser avo, bisavo ... dele mesmo
    	$stack = array($obj-&gt;codpai);
    	$tmp = new Categoria();
    	
    	while(!empty($stack)){
    		$tmp-&gt;reset();
    		$tmp-&gt;select('codcategoria,codpai')
    			-&gt;where('{codcategoria} IN (?)', $stack)
    			-&gt;find();
    		
    		$stack = array();
    		foreach($tmp-&gt;allToArray(false,true) as $item){
    			$stack[] = $item['codpai'];
    		}
    		
    		if(in_array($obj-&gt;codcategoria, $stack)){
    			return false;
    		}
    	}
    	
    	return true;
    }
</pre>
<p>E, para completarmos esta parte, vamos criar as views. Primeiro, a de listagem de categorias (<b>application/views/admin/categorias/index.php</b>):</p>
<pre class="brush: php">
&lt;fieldset class=&quot;admin-container lista-resultados&quot;&gt;
	&lt;legend&gt;Categorias cadastradas&lt;/legend&gt;
	&lt;?php if(!empty($lista)): ?&gt;
		&lt;table class=&quot;tabela-resultados&quot;&gt;
			&lt;thead&gt;
				&lt;tr&gt;
					&lt;th&gt;C&oacute;digo&lt;/th&gt;
					&lt;th&gt;Nome&lt;/th&gt;
					&lt;th&gt;A&ccedil;&otilde;es&lt;/th&gt;
				&lt;/tr&gt;
			&lt;/thead&gt;
			&lt;?php 
			
			// funcao para criar uma linha na tabela de listagem
			// ela eh chamada recursivamente para mostrar os elementos aninhados
			function createRow($stack, $indent = 0){
				// para cada item na pilha 
				while(!empty($stack)){
					$item = array_shift($stack);
					
					// criamos uma linha na tabela
					printf('&lt;tr&gt;
							&lt;td width=&quot;5%%&quot;&gt;%d&lt;/td&gt;
							&lt;td width=&quot;85%%&quot; style=&quot;padding-left: %dpx&quot;&gt;%s&lt;/td&gt;
							&lt;td width=&quot;10%%&quot;&gt;
								&lt;a href=&quot;%s&quot; title=&quot;Editar&quot; class=&quot;btnEditar&quot;&gt;Editar&lt;/a&gt;
								&lt;a href=&quot;%s&quot; title=&quot;Remover&quot; class=&quot;btnRemover&quot;&gt;Remover&lt;/a&gt;
							&lt;/td&gt;
						&lt;/tr&gt;'
						, $item['codcategoria']
						, $indent * 30
						, $item['nome']
						, site_url('admin/categorias/editar/'.$item['codcategoria'])
						, site_url('admin/categorias/remover/'.$item['codcategoria'])
					);
					
					if(!empty($item['categorias'])){
						createRow($item['categorias'], $indent+1);
					} 
				}
			}
			
			createRow($lista);
			?&gt;
		&lt;/table&gt;
	&lt;?php else: ?&gt;
		&lt;p&gt;Nenhum registro encontrado&lt;/p&gt;
	&lt;?php endif; ?&gt;
&lt;/fieldset&gt;
</pre>
<p>E agora, a de inser&ccedil;&atilde;o e edi&ccedil;&atilde;o (<b>application/views/admin/categorias/editar.php</b>):</p>
<pre class="brush: php">
&lt;fieldset class=&quot;admin-container form-padrao&quot;&gt;
	&lt;legend&gt;Cadastro de Categorias - &lt;?php echo $this-&gt;uri-&gt;segment(4) == '' ? 'Adicionar' : 'Atualizar'; ?&gt;&lt;/legend&gt;
	&lt;?php
	// se houveram erros 
	if(!empty($erros)){
		// indicamos os erros
		echo '&lt;div class=&quot;erros&quot;&gt;', implode(&quot;&lt;br /&gt;&quot;, $erros), '&lt;/div&gt;';
	}
	?&gt;
	&lt;form action=&quot;&lt;?php echo site_url('admin/categorias/salvar/'.$this-&gt;uri-&gt;segment(4)); ?&gt;&quot; method=&quot;post&quot;&gt;
		&lt;p&gt;
			&lt;label for=&quot;codpai&quot;&gt;Categoria Pai: &lt;/label&gt;
			&lt;select id=&quot;codpai&quot; name=&quot;codpai&quot;&gt;
				&lt;option value=&quot;&quot;&gt;-- Esta ser&aacute; uma categoria pai --&lt;/option&gt;
				&lt;?php 
				
				// funcao para criar uma linha na combo
				function createOption($stack, $indent = 0){
					$codpai = empty($_POST['codpai']) ? 0 : $_POST['codpai'];
					// para cada item na pilha
					while(!empty($stack)){
						$item = array_shift($stack);
							
						// criamos uma linha na tabela
						printf('&lt;option value=&quot;%d&quot; %s&gt;%s&lt;/option&gt;'
							, $item['codcategoria']
							, $codpai == $item['codcategoria'] ? ' selected=&quot;selected&quot;' : ''
							, str_repeat('&nbsp;', $indent * 5) . $item['nome']
						);
							
						if(!empty($item['categorias'])){
							createOption($item['categorias'], $indent+1);
						}
					}
				}
					
				createOption($categorias);
				
				?&gt;
			&lt;/select&gt;
		&lt;/p&gt;
		&lt;p&gt;
			&lt;label for=&quot;nome&quot;&gt;Nome: &lt;/label&gt;
			&lt;input type=&quot;text&quot; name=&quot;nome&quot; id=&quot;nome&quot; value=&quot;&lt;?php echo $this-&gt;input-&gt;post('nome'); ?&gt;&quot; /&gt;
		&lt;/p&gt;
		&lt;p&gt;
			&lt;label for=&quot;ordem&quot;&gt;Ordem: &lt;/label&gt;
			&lt;input type=&quot;text&quot; name=&quot;ordem&quot; id=&quot;ordem&quot; value=&quot;&lt;?php echo $this-&gt;input-&gt;post('ordem'); ?&gt;&quot; /&gt;
		&lt;/p&gt;
		&lt;p&gt;
			&lt;input type=&quot;submit&quot; name=&quot;btnSalvar&quot; id=&quot;btnSalvar&quot; value=&quot;Salvar&quot; /&gt;
			&lt;input type=&quot;button&quot; name=&quot;btnCancelar&quot; id=&quot;btnCancelar&quot; value=&quot;Cancelar&quot; onclick=&quot;location.href='&lt;?php echo site_url('admin/categorias/index');?&gt;'&quot; /&gt;
		&lt;/p&gt;
	&lt;/form&gt;
&lt;/fieldset&gt;
</pre>
<p>&Eacute; isso. Efetue seu login e teste a aplica&ccedil;ao!</p>
<p>Abra&ccedil;os e fiquem com Deus!</p>]]></description>
<lastBuildDate><![CDATA[Qui, 16 de fevereiro de 2012 - as 10h08]]></lastBuildDate>
<link>http://www.hufersil.com.br/post/criando_catalogo_produtos_lumine_codeigniter_parte_5</link>
</item>
<item>
<title><![CDATA[Exemplo de Chat]]></title>
<description><![CDATA[<p>Fala galera,</p>
<p>Hoje resolvi colocar um exemplo diferente.&nbsp;<br />
Fiz um exemplozinho de chat.</p>
<!-- more -->
<p>Ele j&aacute; tem a estrutura de banco de dados. Basta:</p>
<ul>
    <li>criar a base,</li>
    <li>importar o &quot;dump&quot;,</li>
    <li>ajustar as configura&ccedil;&otilde;es no lumine-conf.php</li>
</ul>
<p>Para baixar, v&aacute; at&eacute; a <a href="http://www.hufersil.com.br/lumine/exemplos">parte de exemplos</a>.</p>
<p>Voc&ecirc; <a href="http://www.hufersil.com.br/exemplo/chat/">tamb&eacute;m pode conferir online.</a></p>
<p>@bra&ccedil;os e fiquem com Deus!</p>]]></description>
<lastBuildDate><![CDATA[Ter, 07 de fevereiro de 2012 - as 15h42]]></lastBuildDate>
<link>http://www.hufersil.com.br/post/exemplo_chat</link>
</item>
<item>
<title><![CDATA[Criando um catálogo de produtos com Lumine e CodeIgniter - Parte 4]]></title>
<description><![CDATA[<p>Nesta quarta parte de como integrar Lumine com CodeIgniter, vamos estudar sobre como criar nossa controller de cadastro de usu&aacute;rios.</p>
<p>Nela criaremos as opera&ccedil;&otilde;es de</p>
<ul>
    <li>Listar os usu&aacute;rios cadastrados</li>
    <li>Pesquisar os usu&aacute;rios cadastrados</li>
    <li>Inclus&atilde;o de usu&aacute;rios</li>
    <li>Edi&ccedil;&atilde;o de usu&aacute;rios</li>
    <li>Remo&ccedil;&atilde;o de usu&aacute;rios</li>
</ul>
<!-- more -->
<h2>Criando a controller de gerenciamento de usu&aacute;rios</h2>
<p>Crie um arquivo <b>usuarios.php</b> na seguinte estrutura:</p>
<ul>
    <li>application/controllers/admin/usuarios.php</li>
</ul>
<p>Abra o arquivo rec&eacute;m criado coloque o conte&uacute;do abaixo (as explica&ccedil;&otilde;es est&atilde;o nos coment&aacute;rios do arquivo):</p>
<pre class="brush: php">
&lt;?php
/**
 * Controller para gerenciamento dos usu&aacute;rios
 * 
 *
 * @link http://www.hufersil.com.br
 * @author Hugo Ferreira da Silva
 *
 */
class Usuarios extends AdminController {

	/**
	 * Metodo para listar os usuarios cadastrados
	 * 
	 * @param int $page Pagina inicial para listar os usuarios
	 * @author Hugo Ferreira da Silva
	 */
	public function index($page = 0){
		// objeto para consultar os usuarios
		$lista = new Usuario();
		$lista-&gt;alias('u');
		
		// se usuario informou o nome na pesquisa
		if($this-&gt;input-&gt;post('nome') != ''){
			// filtramos pelo nome
			$lista-&gt;where('u.nome like ?', $this-&gt;input-&gt;post('nome'));
		}
		
		// se usuario informou o email na pesquisa
		if($this-&gt;input-&gt;post('email') != ''){
			$lista-&gt;where('u.email like ?', $this-&gt;input-&gt;post('email'));
		}
		
		// contamos o numero de registros encontrados
		$total = $lista-&gt;count();
		// limitamos o numero de resultados
		$lista-&gt;limit(max(0, (int)$page - 1) * LIMITE_PAGINACAO_ADMIN, LIMITE_PAGINACAO_ADMIN)
			// ordenamos pelo nome
			-&gt;order('u.nome asc')
			// efetuamos a consulta
			-&gt;find();
		
		// colocamos nos dados para o template o numero de resultados...
		$this-&gt;assign('total', $total);
		// ... e a lista de resultados
		$this-&gt;assign('lista', $lista-&gt;allToArray());
		// exibimos o resultado
		$this-&gt;display('usuarios/index');
	}
	
	/**
	 * Exibe a tela de inser&ccedil;&atilde;o/atualiza&ccedil;&atilde;o de usu&aacute;rios
	 * 
	 * @param int $id Codigo do usuario que esta sendo editado ou null para cadastrar um novo
	 * @author Hugo Ferreira da Silva
	 */
	public function editar($id = null){
		// se tem codigo de usuario e o metodo &eacute; GET
		if(!empty($id) &amp;&amp; $_SERVER['REQUEST_METHOD'] == 'GET'){
			// resgatamos o registro do banco
			$user = new Usuario();
			$user-&gt;get($id);
			// colocamos os dados na variavel $_POST
			$_POST = $user-&gt;toArray();
			// tiramos a senha (est&aacute; em MD5)
			unset($_POST['senha']);
		}
		// exibimos a tela de inser&ccedil;&atilde;o/edi&ccedil;&atilde;o de usuarios
		$this-&gt;display('usuarios/editar');
	}
	
	/**
	 * Insere um novo usu&aacute;rio ou salva as altera&ccedil;&otilde;es feitas em um usu&aacute;rio existente
	 * 
	 * @param int $id C&oacute;digo do Usu&aacute;rio ou null para um novo usu&aacute;rio
	 * @author Hugo Ferreira da Silva
	 */
	public function salvar($id = null){
		// cria um objeto para persistencia
		$dao = new Usuario();
		
		// se est&aacute; editando (informou o c&oacute;digo do usu&aacute;rio)
		if(!empty($id)){
			// pegamos o registro do banco de dados
			$dao-&gt;get($id);
			
			// se n&atilde;o informou a senha, ent&atilde;o deixamos a mesma
			if(empty($_POST['senha'])){
				unset($_POST['senha']);
			}
		}
		
		// se tem senha enviada do formulario
		if(!empty($_POST['senha'])){
			// colocamos em MD5
			$_POST['senha'] = md5($_POST['senha']);
		}
		
		// colocamos no objeto os valores que est&atilde;o no formulario
		// como os nomes dos campos tem os mesmos nomes dos campos,
		// este m&eacute;todo facilita o preenchimento do objeto
		$dao-&gt;populateFrom($_POST);
		
		// fazemos a valida&ccedil;&atilde;o dos dados
		$erros = $dao-&gt;validate();
		
		// se n&atilde;o houveram erros
		if(empty($erros)){
			// fazemos a persistencia
			$dao-&gt;save();
			
			// redirecionamos para a tela de listagem de usu&aacute;rios
			redirect('admin/usuarios/index');
			
		// mas se n&atilde;o passou na valida&ccedil;&atilde;o
		} else {
			// informamos quais foram os erros
			$this-&gt;assign('erros', $erros);
			
			// exibimos a tela de inser&ccedil;&atilde;o/edi&ccedil;&atilde;o
			$this-&gt;editar($id);
		}
	}
	
	/**
	 * Remove um usu&aacute;rio cadastrado
	 * 
	 * @param int $id C&oacute;digo do usu&aacute;rio a ser removido
	 * @author Hugo Ferreira da Silva
	 */
	public function remover($id){
		// criamos um objeto de usuario
		$user = new Usuario();
		
		// se informou o codigo do usuario e encontrou no banco
		if(!empty($id) &amp;&amp; $user-&gt;get($id) == 1){
			// removemos o usuario
			$user-&gt;delete();
		}
		
		// redirecionamos para a tela de listagem de usu&aacute;rios
		redirect('admin/usuarios/index');
	}
}
?&gt;
</pre>
<p>Para podermos validar o cadastro de usu&aacute;rios, precisamos adicionar regras de valida&ccedil;&atilde;o de preenchimento de dados do formul&aacute;rio. Estas regras ficar&atilde;o dentro do arquivo de model de usu&aacute;rio, que est&aacute; em:</p>
<ul>
    <li>application/models/Usuario.php</li>
</ul>
<p>Adicione o m&eacute;todo abaixo:</p>
<pre class="brush: php">
    public function validate(){
    	
    	$this-&gt;addValidator(new Lumine_Validator_String('nome', 'Informe o nome do usu&aacute;rio', 3));
    	$this-&gt;addValidator(new Lumine_Validator_Email('email', 'Informe um e-mail v&aacute;lido'));
    	$this-&gt;addValidator(new Lumine_Validator_Unique('email', 'E-mail j&aacute; utilizado por outro usu&aacute;rio'));
    	$this-&gt;addValidator(new Lumine_Validator_String('senha', 'Informe uma senha com ao menos 4 caracteres', 4));
    	
    	return parent::validate();
    }
</pre>
<h2>Adicionando facilidades para desenvolver o admin.</h2>
<p>Para facilitar, iremos realizar algumas altera&ccedil;&otilde;es no arquivo <b>application/core/AdminController.php</b>. Vamos adicionar:</p>
<ol>
    <li>O carregamento da biblioteca <b>pagination</b> do CodeIgniter. Ela servir&aacute; para colocarmos o n&uacute;mero de p&aacute;ginas em resultados encontrados para listagem de registros.</li>
    <li>Criar uma fun&ccedil;&atilde;o para armazenar os dados da ultima pesquisa realizada. Assim, podemos fazer uma pesquisa, editar o registro encontrado e, quando retornarmos &agrave; tela de listagem, os dados da &uacute;ltima pesquisa continuam salvos.</li>
</ol>
<p>Encontre a linha onde est&aacute;:</p>
<pre class="brush: php">
	// verifica se a permiss&atilde;o do usu&aacute;rio de acessar a URL indicada
	$this-&gt;verificarPermissao();
	
	// -------- e adicione 
	
	// carrega a biblioteca de pagina&ccedil;&atilde;o
	$this-&gt;load-&gt;library('pagination');
	
	// fazemos um hook para formularios de pesquisa
	$this-&gt;hookFormularioPesquisa();
</pre>
<p>Adicione a seguinte fun&ccedil;&atilde;o:</p>
<pre class="brush: php">
	/**
	 * Grava os dados da pesquisa realizada.
	 * 
	 * &lt;p&gt;Ao realizar uma pesquisa, gravamos quais foram os dados 
	 * enviados pelo usu&aacute;rio na sess&atilde;o, para quando ele voltar
	 * na tela de pesquisa os dados continuem l&aacute;.&lt;/p&gt;
	 * 
	 * &lt;p&gt;Para funcionar corretamente, o nome do m&eacute;todo que realiza
	 * a consulta deve ser sempre o m&eacute;todo &quot;index&quot; da controller&lt;/p&gt;.
	 * 
	 * &lt;p&gt;Ao acessar uma controller diferente, limpamos os dados anteriores&lt;/p&gt;
	 * 
	 * @author Hugo Ferreira da Silva
	 */
	protected function hookFormularioPesquisa(){
		// pega  o nome da controller anterior e atual
		$ctrlAnterior = empty($_SESSION['_ctrl']) ? null : $_SESSION['_ctrl'];
		$ctrlAtual    = $this-&gt;uri-&gt;segment(2);
		
		// se enviou uma solicita&ccedil;&atilde;o via POST e foi pelo metodo index 
		if($_SERVER['REQUEST_METHOD'] == 'POST' &amp;&amp; strpos($this-&gt;uri-&gt;uri_string(), '/index') !== false){
			$_SESSION['_busca'] = $_POST;
			$_SESSION['_ctrl'] = $ctrlAtual;
			return;
		}
		
		// se n&atilde;o for a mesma controller
		if($ctrlAnterior != $ctrlAtual){
			// limpamos os dados
			unset($_SESSION['_busca'], $_SESSION['_ctrl']);
			return;
		}
		
		// se tem dados de busca e for o metodo index
		if(!empty($_SESSION['_busca']) &amp;&amp; $this-&gt;uri-&gt;segment(3) == 'index'){
			$_POST = $_SESSION['_busca'];
		}
	}
</pre>
<p>Agora que j&aacute; temos a l&oacute;gica de neg&oacute;cio, controller e auxiliadores criados, vamos construir nossas views.</p>
<p>Crie o arquivo <b>application/views/admin/usuarios/index.php</b> com o conte&uacute;do abaixo:</p>
<pre class="brush: php">
&lt;fieldset class=&quot;admin-container form-padrao&quot;&gt;
	&lt;legend&gt;Cadastro de Usu&aacute;rios - Pesquisar&lt;/legend&gt;
	&lt;form action=&quot;&lt;?php echo site_url('admin/usuarios/index'); ?&gt;&quot; method=&quot;post&quot;&gt;
		&lt;p&gt;
			&lt;label for=&quot;nome&quot;&gt;Nome: &lt;/label&gt;
			&lt;input type=&quot;text&quot; name=&quot;nome&quot; id=&quot;nome&quot; value=&quot;&lt;?php echo $this-&gt;input-&gt;post('nome'); ?&gt;&quot; /&gt;
		&lt;/p&gt;
		&lt;p&gt;
			&lt;label for=&quot;email&quot;&gt;E-mail: &lt;/label&gt;
			&lt;input type=&quot;text&quot; name=&quot;email&quot; id=&quot;email&quot; value=&quot;&lt;?php echo $this-&gt;input-&gt;post('email'); ?&gt;&quot; /&gt;
		&lt;/p&gt;
		&lt;p&gt;
			&lt;input type=&quot;submit&quot; name=&quot;btnBusca&quot; id=&quot;btnBusca&quot; value=&quot;Consultar&quot; /&gt;
			&lt;input type=&quot;button&quot; name=&quot;btnAdicionar&quot; id=&quot;btnAdicionar&quot; value=&quot;Adicionar Usu&aacute;rio&quot; onclick=&quot;location.href='&lt;?php echo site_url('admin/usuarios/editar');?&gt;'&quot; /&gt;
		&lt;/p&gt;
	&lt;/form&gt;
&lt;/fieldset&gt;

&lt;fieldset class=&quot;admin-container lista-resultados&quot;&gt;
	&lt;legend&gt;Usu&aacute;rios encontrados&lt;/legend&gt;
	&lt;?php if(!empty($lista)): ?&gt;
		&lt;table class=&quot;tabela-resultados&quot;&gt;
			&lt;thead&gt;
				&lt;tr&gt;
					&lt;th&gt;C&oacute;digo&lt;/th&gt;
					&lt;th&gt;Nome&lt;/th&gt;
					&lt;th&gt;E-mail&lt;/th&gt;
					&lt;th&gt;A&ccedil;&otilde;es&lt;/th&gt;
				&lt;/tr&gt;
			&lt;/thead&gt;
			&lt;?php 
			// para cada usuario encontrado 
			foreach($lista as $item){
				// criamos uma linha na tabela
				printf('&lt;tr&gt;
						&lt;td width=&quot;10%%&quot;&gt;%d&lt;/td&gt;
						&lt;td width=&quot;40%%&quot;&gt;%s&lt;/td&gt;
						&lt;td width=&quot;40%%&quot;&gt;%s&lt;/td&gt;
						&lt;td width=&quot;10%%&quot;&gt;
							&lt;a href=&quot;%s&quot; title=&quot;Editar&quot; class=&quot;btnEditar&quot;&gt;Editar&lt;/a&gt;
							&lt;a href=&quot;%s&quot; title=&quot;Remover&quot; class=&quot;btnRemover&quot;&gt;Remover&lt;/a&gt;
						&lt;/td&gt;
					&lt;/tr&gt;'
					, $item['codusuario']
					, $item['nome']
					, $item['email']
					, site_url('admin/usuarios/editar/'.$item['codusuario'])
					, site_url('admin/usuarios/remover/'.$item['codusuario'])
				);
			}
			
			// configura&ccedil;&otilde;es da paginacao
			// @link http://codeigniter.com/user_guide/libraries/pagination.html
			$config['uri_segment'] = 4;
			$config['total_rows'] = $total;
			$config['per_page'] = LIMITE_PAGINACAO_ADMIN;
			$config['base_url'] = site_url('admin/usuarios/index');
			$config['use_page_numbers'] = TRUE;
			$this-&gt;pagination-&gt;initialize($config);
			
			// exibe a paginacao
			printf('&lt;tr&gt;
					&lt;td colspan=&quot;4&quot;&gt; %s &lt;/td&gt;
				&lt;/tr&gt;'
				, $this-&gt;pagination-&gt;create_links()
			);
			?&gt;
		&lt;/table&gt;
	&lt;?php else: ?&gt;
		&lt;p&gt;Nenhum registro encontrado&lt;/p&gt;
	&lt;?php endif; ?&gt;
&lt;/fieldset&gt;
</pre>
<p>Crie o arquivo <b>application/views/admin/usuarios/editar.php</b> com o conte&uacute;do abaixo:</p>
<pre class="brush: php">
&lt;fieldset class=&quot;admin-container form-padrao&quot;&gt;
	&lt;legend&gt;Cadastro de Usu&aacute;rios - &lt;?php echo $this-&gt;uri-&gt;segment(4) == '' ? 'Adicionar' : 'Atualizar'; ?&gt;&lt;/legend&gt;
	&lt;?php
	// se houveram erros 
	if(!empty($erros)){
		// indicamos os erros
		echo '&lt;div class=&quot;erros&quot;&gt;', implode(&quot;&lt;br /&gt;&quot;, $erros), '&lt;/div&gt;';
	}
	?&gt;
	&lt;form action=&quot;&lt;?php echo site_url('admin/usuarios/salvar/'.$this-&gt;uri-&gt;segment(4)); ?&gt;&quot; method=&quot;post&quot;&gt;
		&lt;p&gt;
			&lt;label for=&quot;nome&quot;&gt;Nome: &lt;/label&gt;
			&lt;input type=&quot;text&quot; name=&quot;nome&quot; id=&quot;nome&quot; value=&quot;&lt;?php echo $this-&gt;input-&gt;post('nome'); ?&gt;&quot; /&gt;
		&lt;/p&gt;
		&lt;p&gt;
			&lt;label for=&quot;email&quot;&gt;E-mail: &lt;/label&gt;
			&lt;input type=&quot;text&quot; name=&quot;email&quot; id=&quot;email&quot; value=&quot;&lt;?php echo $this-&gt;input-&gt;post('email'); ?&gt;&quot; /&gt;
		&lt;/p&gt;
		&lt;p&gt;
			&lt;label for=&quot;senha&quot;&gt;Senha: &lt;/label&gt;
			&lt;input type=&quot;text&quot; name=&quot;senha&quot; id=&quot;senha&quot; value=&quot;&lt;?php echo $this-&gt;input-&gt;post('senha'); ?&gt;&quot; /&gt;
		&lt;/p&gt;
		&lt;p&gt;
			&lt;input type=&quot;submit&quot; name=&quot;btnSalvar&quot; id=&quot;btnSalvar&quot; value=&quot;Salvar&quot; /&gt;
			&lt;input type=&quot;button&quot; name=&quot;btnCancelar&quot; id=&quot;btnCancelar&quot; value=&quot;Cancelar&quot; onclick=&quot;location.href='&lt;?php echo site_url('admin/usuarios/index');?&gt;'&quot; /&gt;
		&lt;/p&gt;
	&lt;/form&gt;
&lt;/fieldset&gt;
</pre>
<p>E, para deixarmos nossas views um pouco mais amig&aacute;veis, vamos adicionar no arquivo <b>assets/css/admin.css</b> o conte&uacute;do abaixo:</p>
<pre class="brush: css">
/*************************************/
/* Estilos gerais para admin
/*************************************/
.admin-container {
	width: 85%;
	margin-left: auto;
	margin-right: auto;
	margin-bottom: 40px;
	padding: 10px;
}
.admin-container legend {
	font-weight: bold;
	font-size: 14px;
	color: #003300;
}
.admin-container input[type=&quot;submit&quot;], .admin-container input[type=&quot;button&quot;] {
	padding: 5px;
}
.admin-container .tabela-resultados {
	width: 100%;
	border: 1px solid black
}
.admin-container .tabela-resultados td, .admin-container .tabela-resultados th {
	padding: 3px;
}
.admin-container .tabela-resultados thead th {
	background-color: #EFEFEF;
	font-weight:bold;
	text-align: left; 
}
.admin-container .tabela-resultados tbody tr:hover {
	background-color: #EFEFEF;
}
.form-padrao p {
	clear: both;
	padding-bottom: 5px;
}
.form-padrao p label {
	display: block;
	float: left;
	width: 120px;
	padding-top: 2px;
	padding-right: 10px;
	text-align: right;
}
.btnEditar {
	background-image: url(&quot;http://www.iconfinder.com/ajax/download/png/?id=11450&amp;s=16&quot;);
	background-position: center center;
	background-repeat: no-repeat;
	width: 15px;
	height: 15px;
	display: inline-block;
	overflow:hidden;
	text-indent: -10000px;
}
.btnRemover {
	background-image: url(&quot;http://www.iconfinder.com/ajax/download/png/?id=10032&amp;s=16&quot;);
	background-position: center center;
	background-repeat: no-repeat;
	width: 15px;
	height: 15px;
	display: inline-block;
	overflow:hidden;
	text-indent: -10000px;
}
.erros {
	padding: 4px;
	background-color: #FFFF55;
	color: #FF0000;
	font-weight: bold;
	margin-bottom: 10px;
}
</pre>
<p>Pronto! Se tudo deu certo, efetue o login e depois acesse <a href="http://localhost/vitrine/admin/usuarios/index">http://localhost/vitrine/admin/usuarios/index</a> para ver a lista de usu&aacute;rios.</p>
<p>At&eacute; a pr&oacute;xima!</p>
<p>@bra&ccedil;os e fiquem com Deus!</p>]]></description>
<lastBuildDate><![CDATA[Seg, 06 de fevereiro de 2012 - as 16h44]]></lastBuildDate>
<link>http://www.hufersil.com.br/post/criando_catalogo_produtos_lumine_codeigniter_parte_4</link>
</item>
<item>
<title><![CDATA[Criando um catálogo de produtos com Lumine e CodeIgniter - Parte 3]]></title>
<description><![CDATA[<p>Hoje veremos:</p>
<blockquote> 	Como organizar nossos diret&oacute;rios<br />
Criar uma tela de login para a parte administrativa
<p>&nbsp;</p>
</blockquote> <!-- more -->
<h2>Como organizar nossos diret&oacute;rios</h2>
<p>Nesta aplica&ccedil;&atilde;o, iremos criar uma &aacute;rea administrativa e uma &aacute;rea publica.</p>
<p>A parte administrativa, iremos chamar de <b>admin</b>. A p&uacute;blica, de <b>site</b>.</p>
<p>Tudo que est&aacute; dentro da pasta &quot;application&quot; n&atilde;o poder&aacute; ser acessado externamente quando o sistema estiver em produ&ccedil;&atilde;o. Portanto, as imagens, arquivos CSS e JavaScript dever&atilde;o estar <b>fora</b> da pasta &quot;application&quot;. Ent&atilde;o, criaremos uma pasta para podermos armazenar estes tipos de arquivo.</p>
<p>Tendo isto em mente, crie a seguinte estrutura de diret&oacute;rios:</p>
<ul>
    <li>c:\www\vitrine\<b>assets</b></li>
    <li>c:\www\vitrine\<b>assets\css</b></li>
    <li>c:\www\vitrine\<b>assets\imagens</b></li>
    <li>c:\www\vitrine\<b>assets\js</b></li>
    <li>c:\www\vitrine\application\<b>views\admin</b></li>
    <li>c:\www\vitrine\application\<b>views\site</b></li>
</ul>
<p>Para cada controller criada, seja administativa ou p&uacute;blica, iremos tamb&eacute;m criar um diret&oacute;rio na &aacute;rea correspondente para podermos armazenar as <b>visualiza&ccedil;&otilde;es de comportamento</b>. Cada m&eacute;todo dentro de uma controller &eacute; um comportamento, e ficar&aacute; extremamente mais simples de manter o sistema se criarmos um arquivo <em>view</em> para cada m&eacute;todo.</p>
<p>Seguindo esta linha de racioc&iacute;nio, criaremos mais um diret&oacute;rio:</p>
<ul>
    <li>c:\www\vitrine\application\<b>views\admin\login</b></li>
</ul>
<p>Como podemos ver facilmente, este diret&oacute;rio armazenar&aacute; os arquivos de visualiza&ccedil;&atilde;o da controller &quot;login&quot; da parte administrativa.</p>
<p>Para facilitarmos o desenvolvimento, vamos criar um  &quot;template principal&quot; para a parte administrativa. As visualiza&ccedil;&otilde;es de comportamento de cada m&eacute;todo ser&atilde;o, na verdade, trechos menores que ir&atilde;o ser incorporados dentro do template principal. Em outras palavras, <b>vamos fazer um &quot;include&quot; do trecho a ser visualizado dentro do template principal.</b> Este template principal j&aacute; ter&aacute; as partes mais importantes, como topo, rodap&eacute;, menu principal de navega&ccedil;&atilde;o, etc. As visualiza&ccedil;&otilde;es ter&atilde;o somente o &quot;miolo&quot;, que ser&atilde;o incorporadas ao template.</p>
<p>Antes de criarmos o template, abaixo o arquivo CSS usado para o admin. Salve o arquivo em <b>assets/css/admin.css</b></p>
<pre class="brush: css">
@CHARSET &quot;UTF-8&quot;;
/*************************************/
/* Tela de Login
/*************************************/
* {
	margin: 0px;
	padding: 0px;
	font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
	font-size: 11px;
	font-weight: normal;
	font-style: normal;
}
.login-box {
	margin-top: 200px;
	width: 450px;
	margin-left: auto;
	margin-right: auto;
	border: 1px solid #999999;
	padding: 5px;
	border-radius: 5px;
}
.login-box p {
	clear: both;
	padding-bottom: 5px;
}
.login-box label {
	display: block;
	float: left;
	width: 120px;
	padding-top: 2px;
	padding-right: 10px;
	text-align: right;
}
.login-box #btnLogin {
	margin-left: 160px;
	padding: 4px;
}
.login-box h1 {
	border-radius: 5px;
	font-size: 14px;
	font-weight: bold;
	color: #555555;
	margin-bottom: 10px;
	background-color: #EFEFEF;
	padding: 4px 4px 4px 25px;
	background-image: url(&quot;http://www.iconfinder.com/ajax/download/png/?id=36090&amp;s=16&quot;);
	background-position: 3px center;
	background-repeat: no-repeat;
}
.login-box .erro{
	padding: 4px;
	background-color: #FFFF55;
	color: #FF0000;
	font-weight: bold;
	margin-bottom: 10px;
}
</pre>
<p>Nosso arquivo de template por enquanto ser&aacute; bem simples, para poder facilitar nossos estudos. Vamos criar uma estrutura b&aacute;sica e fazer a verifica&ccedil;&atilde;o de exist&ecirc;ncia do arquivo que ser&aacute; incluido. Salve este arquivo em <b>application/views/admin/template.php</b>:</p>
<pre class="brush: php">
	&lt;!DOCTYPE html&gt;
	&lt;html&gt;
	&lt;head&gt;
		&lt;title&gt;Sistema de Gerenciamento de Conteudo&lt;/title&gt;
		&lt;meta charset=&quot;UTF-8&quot; /&gt;
		
		&lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot;  href=&quot;&lt;?php echo base_url('assets/css/admin.css'); ?&gt;&quot; /&gt;
		
	&lt;/head&gt;
	&lt;body&gt;

	&lt;?php 
	// o arquivo de template a ser incluido foi informado?
	if(!empty($_template)){
		// procuramos ele a partir deste arquivo
		$_template = dirname(__FILE__) . '/' . $_template;
		// se existir, fazemos o include
		if(file_exists($_template)){
			include $_template;
			
		// se nao existir, enviamos uma mensagem
		} else {
			echo 'Template &quot;', $_template, '&quot; n&atilde;o existe!';
		}

	// se nao informou, enviamos uma mensagem
	} else {
		echo 'Template nao informado!';
	}
	?&gt;

	&lt;/body&gt;
	&lt;/html&gt;
</pre>
<p>Pronto! Agora nossas visualiza&ccedil;&otilde;es de comportamento (views) da &aacute;rea administrativa ser&atilde;o bem mais simples!</p>
<p>Vamos agora criar nossa visualiza&ccedil;&atilde;o da tela de login. Salve o arquivo em <b>application/views/admin/login/index.php</b></p>
<pre class="brush: php">
&lt;form action=&quot;&lt;?php echo site_url('admin/login/do_login'); ?&gt;&quot; method=&quot;post&quot;&gt;
	&lt;div class=&quot;login-box&quot;&gt;
		&lt;h1&gt;Efetue seu login&lt;/h1&gt;
		&lt;?php 
		// pegando o segmento de informacao na URL
		switch($this-&gt;uri-&gt;segment(4)){
			case 'informe_seus_dados':
				echo '&lt;div class=&quot;erro&quot;&gt;Usu&aacute;rio ou senha em branco&lt;/div&gt;';
			break;
			case 'usuario_nao_encontrado':
				echo '&lt;div class=&quot;erro&quot;&gt;Nenhum usu&aacute;rio encontrado com as credenciais informadas&lt;/div&gt;';
			break;
		}
		?&gt;
		&lt;p&gt;
			&lt;label for=&quot;email&quot;&gt;E-mail&lt;/label&gt;
			&lt;input type=&quot;email&quot; value=&quot;&quot; id=&quot;email&quot; name=&quot;email&quot; /&gt;
		&lt;/p&gt;
		&lt;p&gt;
			&lt;label for=&quot;senha&quot;&gt;Senha&lt;/label&gt;
			&lt;input type=&quot;password&quot; value=&quot;&quot; id=&quot;senha&quot; name=&quot;senha&quot; /&gt;
		&lt;/p&gt;
		
		&lt;input type=&quot;submit&quot; value=&quot;Efetuar Login&quot; id=&quot;btnLogin&quot; name=&quot;btnLogin&quot; /&gt;
	&lt;/div&gt;
&lt;/form&gt;
</pre>
<p>Note que para este arquivo fizemos somente o formul&aacute;rio de login sem a necessidade de outras informa&ccedil;&otilde;es, como topo, rodap&eacute;, etc, pois estas informa&ccedil;&otilde;es j&aacute; est&atilde;o no arquivo <b>template.php</b>. Bem mais simples, n&atilde;o?.</p>
<p>Agora que j&aacute; criamos nosso arquivo de visualiza&ccedil;&atilde;o principal (template.php) e login (login/index.php), vamos criar nossa controller para podermos fazer o login no sistema.</p>
<p>Para isso, crie uma controller chamada <b>login.php</b> com o conte&uacute;do abaixo:</p>
<pre class="brush: php">
&lt;?php
/**
* Controller para efetuar o login e logout do sistema administrativo.
*
* @author Hugo Ferreira da Silva
* @link http://www.hufersil.com.br
*
*/
class Login extends AdminController {
	/**
	 * Carrega a visualiza&ccedil;&atilde;o de login
	 * 
	 * @author Hugo Ferreira da Silva
	 */
	public function index(){
		$this-&gt;display('login/index');
	}
	
	/**
	 * Efetua a valida&ccedil;&atilde;o do usu&aacute;rio no sistema e efetua o login do mesmo.
	 * 
	 * Caso as credenciais estejam corretas, gravamos as informa&ccedil;&otilde;es de login
	 * na sess&atilde;o.
	 * 
	 * @author Hugo Ferreira da Silva
	 */
	public function do_login(){
		// nova instancia de usuario
		$user = new Usuario();
		
		// pegamos as informa&ccedil;&otilde;es do formulario.
		$user-&gt;email = $this-&gt;input-&gt;post('email');
		$user-&gt;senha = $this-&gt;input-&gt;post('senha');
		
		// se uma informa&ccedil;&atilde;o ficou em branco,
		// redirecionamos para a tela de login
		if(empty($user-&gt;email) || empty($user-&gt;senha)){
			redirect('admin/login/index/informe_seus_dados');
		}
		
		// colocamos a senha em md5
		$user-&gt;senha = md5($user-&gt;senha);
		
		// faz a consulta obtendo o numero de resultados
		$total = $user-&gt;find(true);
		
		// se n&atilde;o encontrou nada
		if( $total == 0 ){
			redirect('admin/login/index/usuario_nao_encontrado');
		}
		
		// se encontrou, colocamos os dados do usuario na sess&atilde;o
		$_SESSION['usuario'] = $user-&gt;toArray();
		
		// redirecionamos o usuario para a tela de produtos.
		redirect('admin/produtos/index');
	}
	
	/**
	 * Efetua o logout do usuario
	 * 
	 * Limpa os dados da se&ccedil;&atilde;o e envia o usu&aacute;rio para a tela de login
	 * 
	 * @author Hugo Ferreira da Silva
	 */
	public function do_logout(){
		$_SESSION = array();
		redirect('admin/login/index');
	}
}
</pre>
<p>Salve este arquivo como <b>application/controllers/admin/login.php</b></p>
<p>Se tudo foi seguido corretamente, ao acessar a URL <a href="http://localhost/vitrine/admin/login/index">http://localhost/vitrine/admin/login/index</a> voc&ecirc; dever&aacute; ver a tela abaixo:</p>
<p><img alt="" src="lumine-ci-login.png" /></p>
<p>Para praticar, tente fazer a controller de produtos com um m&eacute;todo <b>index</b> e uma visualiza&ccedil;&atilde;o simples.</p>
<p>Na pr&oacute;xima mat&eacute;ria vamos fazer a controller de usu&aacute;rios.</p>
<p>@bra&ccedil;os e fiquem com Deus!</p>]]></description>
<lastBuildDate><![CDATA[Sex, 03 de fevereiro de 2012 - as 11h12]]></lastBuildDate>
<link>http://www.hufersil.com.br/post/criando_catalogo_produtos_lumine_codeigniter_parte_3</link>
</item>
<item>
<title><![CDATA[Criando um catálogo de produtos com Lumine e CodeIgniter - Parte 2]]></title>
<description><![CDATA[<p>&nbsp;Dando continuidade <a href="http://www.hufersil.com.br/post/criando_catalogo_produtos_lumine_codeigniter">ao post anterior</a>, vamos ver hoje como:</p>
<div style="margin-left: 40px; ">Configurar a base do CodeIgniter</div>
<div style="margin-left: 40px; ">Criar uma controller base</div>
<div style="margin-left: 40px; ">Criar uma controller base de administra&ccedil;&atilde;o</div>
<div style="margin-left: 40px; ">&nbsp;</div>
<!-- more -->
<div>Para n&atilde;o estender muito o tutorial e ficar complicado, a tela de login vamos deixar para o pr&oacute;ximo post, juntamente sobre como configurar as &quot;Views&quot; de nosso projeto.</div>
<h2>Configurar a base do CodeIgniter</h2>
<p>Para torar as URL's mais amig&aacute;veis, vamos tirar o &quot;index.php&quot;.<br />
&Eacute; necess&aacute;rio que o ModRewrite do Apache esteja ativo.<br />
Crie um arquivo chamado &quot;.htaccess&quot; na pasta raiz do projeto (c:\www\vitrine).<br />
Coloque o conte&uacute;do abaixo dentro deste arquivo:</p>
<p class="both">&nbsp;</p>
<pre class="brush: text">
RewriteEngine On

RewriteCond $1 !^(index\.php|images|css|robots\.txt)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$2 [L]<font face="Arial, Verdana, sans-serif"><span style="white-space: normal;"> </span></font></pre>
<p>Com isto, toda requisi&ccedil;&atilde;o feita para o servidor que n&atilde;o possua um arquivo ou pasta existente ser&aacute; redirecionada para o CodeIgniter tratar.</p>
<p>A segunda coisa que iremos fazer, ser&aacute; configurar a URL base do nosso projeto.<br />
Abra o arquivo &quot;application/config/config.php&quot;.</p>
<p>Altere a linha:</p>
<pre class="brush: php">
$config['index_page'] = 'index.php';

// para

$config['index_page'] = '';</pre>
<p>Com isto, o segmento &quot;index.php&quot; n&atilde;o ser&aacute; mais apresentado quando formos construir URL's internas com a fun&ccedil;&otilde;es de cria&ccedil;&atilde;o de link do CodeIgniter.</p>
<p>Agora, precisamos colocar no arquivo &quot;application/config/autoload.php&quot; quais bibliotecas iremos carregar por padr&atilde;o.</p>
<p>Ele nos permite indicar v&aacute;rios tipos de arquivos, mas por enquanto, vamos nos atentar somente &agrave; algumas bibliotecas que j&aacute; vem com o CI.</p>
<p>Abra o arquivo mencionado e procure pela linha:</p>
<pre class="brush: php">
$autoload['libraries'] = array('');
// e troque para 
$autoload['libraries'] = array('uri');
</pre>
<p>A biblioteca URI nos d&aacute; acesso aos &quot;segmentos&quot; formados pelo endere&ccedil;o acessado pelo usu&aacute;rio.<br />
Exemplo: quando acessamos a URL:<br />
http://www.hufersil.com.br/post/nome_do_post<br />
<br />
Voc&ecirc; pode recuper&aacute;-la com o CodeIgniter desta forma:</p>
<pre class="brush: php">
echo $this-&gt;uri-&gt;segment(1); // exibir&aacute; &quot;post&quot;;
echo $this-&gt;uri-&gt;segment(2); // exibir&aacute; &quot;nome_do_post&quot;;
</pre>
<p>Entre outras fun&ccedil;&otilde;es &uacute;teis que veremos durantes os tutoriais. Voc&ecirc; pode conferir a lista de m&eacute;todos na <a href="http://codeigniter.com/user_guide/libraries/uri.html">documenta&ccedil;&atilde;o do CodeIgniter</a>.</p>
<p>Depois, procure:</p>
<pre class="brush: php">
$autoload['helper'] = array('');
// e troque para 
$autoload['helper'] = array('url');
</pre>
<p>Este &quot;helper&quot; na verdade &eacute; um conjunto de fun&ccedil;&otilde;es de auxilio na cria&ccedil;&atilde;o de URL's.<br />
Voc&ecirc; tamb&eacute;m pode ver melhor quais s&atilde;o estes m&eacute;todos na documenta&ccedil;&atilde;o do CodeIgniter (http://codeigniter.com/user_guide/helpers/url_helper.html)</p>
<p>A &uacute;ltima coisa que precisamos configurar no momento &eacute; a &quot;rota&quot; padr&atilde;o do CI.<br />
Como vamos come&ccedil;ar primeiro pelo admin, vamos configurar a rota padr&atilde;o sendo a nossa tela de autentica&ccedil;&atilde;o. <br />
Para isto, abra o arquivo &quot;application/config/routes.php&quot;.</p>
<p>Procure pela linha:</p>
<pre class="brush: php">
$route['default_controller'] = &quot;welcome&quot;;

// e troque para

$route['default_controller'] = &quot;admin/login/index&quot;;
</pre>
<p>Isto far&aacute; com que o CodeIgniter procure na pasta &quot;admin&quot; uma controller chamda &quot;login&quot; e acesse o m&eacute;todo &quot;index&quot;.</p>
<p>Pronto! A configura&ccedil;&atilde;o b&aacute;sica do CI est&aacute; montada!</p>
<p>Agora podemos avan&ccedil;ar um pouco mais.</p>
<h2>Criar uma controller base</h2>
<p>A controller que vem com o CodeIgniter &eacute; bem b&aacute;sica.<br />
Para melhorarmos o nosso trabalho, vamos criar a nossa pr&oacute;pria controller base <strong>extendendo a controller base do CI</strong>.</p>
<p>Por padr&atilde;o, quando queremos que o CodeIgniter carregue nossas implementa&ccedil;&otilde;es ao inv&eacute;s das implementa&ccedil;&otilde;es dele, criamos nossas classes com o prefixo &quot;MY_&quot;.<br />
Este prefixo tamb&eacute;m pode ser alterado no arquivo de configura&ccedil;&atilde;o (application/config/config.php), mas por enquanto vamos deixar o padr&atilde;o.</p>
<p>O que queremos &eacute; &quot;criar nossa controller base&quot;, extendendo a classe CI_Controller (que &eacute; base padr&atilde;o de todas as controllers do CI).<br />
Ent&atilde;o, para isso, crie um arquivo chamado &quot;MY_Controller.php&quot; dentro da pasta &quot;application/core&quot;. Sua estrutura dever&aacute; ser:<br />
<strong>C:\www\vitrine\application\core\MY_Controller.php</strong></p>
<p>Agora, implemente a classe abaixo (nos coment&aacute;rios est&atilde;o as responsabilidades de cada m&eacute;todo implementado):</p>
<pre class="brush: php">
/**
 * Controller base para as implementa&ccedil;&otilde;es de nosso Catalogo de Produtos
 * 
 * @author Hugo Ferreira da Silva
 * @link http://www.hufersil.com.br
 *
 */
class MY_Controller extends CI_Controller {

	/**
	 * Indica se a sess&atilde;o j&aacute; foi iniciada
	 * @var boolean
	 */
	protected static $sessionStarted = false;

	/**
	 * Indica o arquivo de layout padr&atilde;o
	 * @var string
	 */
	protected $layoutFile = 'template.php';
	
	/**
	 * Dados para serem enviados para o template
	 * @var array
	 */
	protected $data = array();
	
	/**
	 * Construtor
	 * 
	 * @author Hugo Ferreira da Silva
	 */
	public function __construct(){
		// chamamos o construtor pai
		parent::__construct();
		
		// carregamos a configuracao de Lumine
		// o CI j&aacute; cria a instancia
		$this-&gt;load-&gt;library('Lumine_ApplicationContext');
		
		// se a sess&atilde;o ainda n&atilde;o foi iniciada
		if(!self::$sessionStarted){
			// iniciamos e marcamos como iniciada
			session_start();
			self::$sessionStarted = true;
		}
	}
	
	/**
	 * Adiciona um valor para ser enviado para o template
	 * 
	 * @param string $key Nome da chave
	 * @param mixed $value Valor a ser enviado
	 * @author Hugo Ferreira da Silva
	 */
	public function assign($key, $value){
		$this-&gt;data[$key] = $value;
	}
	
	/**
	 * Renderiza uma view.
	 * 
	 * @link http://codeigniter.com/user_guide/general/views.html
	 * 
	 * @param string $tpl Nome do template &quot;miolo&quot;.
	 * @param boolean $return Indica se vamos renderizar na tela (false) ou retornar o resultado como string (true) 
	 * @author Hugo Ferreira da Silva
	 * @return string Resultado da renderiza&ccedil;&atilde;o
	 */
	public function display($tpl, $return = false){
		// so para garantir que a extensao sempre existir&aacute;
		$tpl = preg_replace('@\.php$@i', '', $tpl) . '.php';
		$tpl = (empty($this-&gt;uriSession) ? '' : trim($this-&gt;uriSession, '/') . '/') . $tpl;
		$this-&gt;assign('_template', $tpl);
		
		return $this-&gt;load-&gt;view($this-&gt;layoutFile, $this-&gt;data, $return);
	}
}
</pre>
<p>E esta ser&aacute; nossa controller base.<br />
Estes pequenos m&eacute;todos far&atilde;o uma grande diferen&ccedil;a enquanto estivermos trabalhando com nossas controllers finais.</p>
<h2>Criar uma controller base de administra&ccedil;&atilde;o</h2>
<p>A controller base nos fornece comportamentos comuns entre o que iremos usar no administrador e na parte p&uacute;blica.<br />
Por&eacute;m, precisamos de um comportamos um pouco mais especializado na tela &aacute;rea de administra&ccedil;&atilde;o.<br />
Para isso, criaremos uma controller base de administra&ccedil;&atilde;o.</p>
<p>Adicione ao final do arquivo <br />
C:\www\vitrine\application\core\MY_Controller.php</p>
<p>A linha:</p>
<pre class="brush: php">
require_once dirname(__FILE__) . '/AdminController.php';
</pre>
<p>Precisamos colocar neste arquivo porque o CI n&atilde;o tem como carregar este arquivo de forma autom&aacute;tica, <strong>mas ele carrega automaticamente a MY_Controller</strong>.<br />
Quando formos implementar a parte publica, veremos como fazer este carregamento de forma condicional.</p>
<p>Agora, crie um arquivo na estrutura:<br />
C:\www\vitrine\application\core\AdminController.php</p>
<p>E coloque o conte&uacute;do abaixo dentro deste arquivo criado:</p>
<pre class="brush: php">
/**
 * Controller base para se&ccedil;&atilde;o de administra&ccedil;&atilde;o
 *
 * @author Hugo Ferreira da Silva
 * @link http://www.hufersil.com.br
 *
 */
class AdminController extends MY_Controller {
	
	/**
	 * Caminhos que os usu&aacute;rios poder&atilde;o acessar sem a necessidade
	 * de estarem autenticados.
	 * 
	 * Cada caminho &eacute; uma entrada no array em forma de express&atilde;o regular.
	 * O mostrado abaixo d&aacute; acesso sem necessidade de autentica&ccedil;&atilde;o 
	 * a qualquer m&eacute;todo da controller &quot;login&quot;
	 * 
	 * @var array
	 */
	protected $allowedPaths = array(
		'^admin/login/.*?'
	);
	
	/**
	 * Contrutor
	 * 
	 * @author Hugo Ferreira da Silva
	 */
	public function __construct(){
		// chamamos o construtor &quot;pai&quot;
		parent::__construct();
		
		// indicamos o arquivo de layout da &aacute;rea de administra&ccedil;&atilde;o
		$this-&gt;layoutFile = 'admin/template.php';
		
		// verifica se a permiss&atilde;o do usu&aacute;rio de acessar a URL indicada
		$this-&gt;verificarPermissao();
		
		// ja colocamos os dados do usuario da sess&atilde;o para
		// podermos renderizar nos templates
		$this-&gt;assign('_usuario', $this-&gt;getUsuarioSessao());
	}
	
	/**
	 * Recupera os dados do usu&aacute;rio logado
	 * 
	 * @author Hugo Ferreira da Silva
	 * @return array
	 */
	protected function getUsuarioSessao(){
		return empty($_SESSION['usuario']) ? null : $_SESSION['usuario'];
	}
	
	/**
	 * Verifica a permiss&atilde;o de acesso do usu&aacute;rio.
	 * 
	 * <p>Por enquanto, somente verificamos se o usu&aacute;rio est&aacute; logado</p>;
	 * 
	 * @author Hugo Ferreira da Silva
	 */
	protected function verificarPermissao(){
		$user = $this-&gt;getUsuarioSessao();
		$uri = $this-&gt;uri-&gt;uri_string();
		
		// se n&atilde;o est&aacute; logado e esta acessando uma URL n&atilde;o permitida.
		if(empty($user) &amp;&amp; !preg_match('@' . implode('|', $this-&gt;allowedPaths) . '@', $uri)){
			// limpa a sess&atilde;o
			$_SESSION = array();
			// envia para tela de login
			redirect('admin/login/index/sem_permissao');
		}
	}
}
</pre>
<p>Agora, nosso trabalho dentro da parte de administra&ccedil;&atilde;o ser&aacute; bem mais f&aacute;cil ;)<br />
No pr&oacute;ximo post veremos como organizar nossas views e criaremos nossa tela de login.</p>
<p>@bra&ccedil;os e fiquem com Deus!</p>]]></description>
<lastBuildDate><![CDATA[Qui, 02 de fevereiro de 2012 - as 11h14]]></lastBuildDate>
<link>http://www.hufersil.com.br/post/geracao_imagem_drag_drop_jquery_jqueryui_php_parte_2</link>
</item>
<item>
<title><![CDATA[Criando um catálogo de produtos com Lumine e CodeIgniter.]]></title>
<description><![CDATA[<p>Criando um cat&aacute;logo de produtos com Lumine e CodeIgniter.</p>
<div>Como tive v&aacute;rios pedidos para mostrar melhor uma forma de integrar o Lumine com CodeIgniter, resolvi fazer um exemplo um pouco mais complexo, que estaremos montando ao longo de alguns tutoriais.</div>
<div>Neste primeiro artigo, iremos:</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span>Baixar os pacotes necess&aacute;rios e configurando a pasta corretamente;</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span>Criar o banco de dados;</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span>Efetuar a engenharia reversa;</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span>Testar se tudo est&aacute; correto.</div>
<!-- more -->
<h2>Baixar os pacotes necess&aacute;rios e configurando a pasta corretamente</h2>
<p>A pasta raiz durante esta s&eacute;rie de tutoriais ser&aacute; a &quot;C:\www\vitrine&quot;, sendo &quot;C:\www&quot; o document-root do servidor web.<br />
Sendo assim, a nossa URL padr&atilde;o ser&aacute;: http://localhost/vitrine/</p>
<p>Para este exemplo, vamos utilizar o Lumine vers&atilde;o 1.6 e CodeIgniter 2.1.0.</p>
<p>Baixe primeiramente o <a href="http://codeigniter.com/download.php">CodeIgniter</a> e descompacte dentro da pasta raiz. Sua estrutura de pastas e arquivos dever&aacute; ser:</p>
<p style="margin-left: 40px; ">C:\www\vitrine\application<br />
C:\www\vitrine\system<br />
C:\www\vitrine\user_guide<br />
C:\www\vitrine\index.php<br />
C:\www\vitrine\license.txt</p>
<p>Se quiser, voc&ecirc; poder&aacute; apagar a pasta &quot;user_guide&quot;. N&atilde;o usaremos ela durante o desenvolvimento.<br />
Feita esta estrutura, baixe o <a href="http://sourceforge.net/projects/lumine/files/latest/download?source=directory">Lumine</a>, vers&atilde;o 1.6</p>
<p>&nbsp;</p>
<p>Descompacte os arquivos de Lumine dentro do diret&oacute;rio &quot;C:\www\vitrine\application\libraries\lumine&quot;.</p>
<p>A estrutura final dever&aacute; ficar semelhante a&nbsp;</p>
<p><span class="Apple-tab-span" style="white-space:pre">	</span>C:\www\vitrine\application\libraries\lumine\lib\<br />
<span class="Apple-tab-span" style="white-space:pre">	</span>C:\www\vitrine\application\libraries\lumine\changelog.txt<br />
<span class="Apple-tab-span" style="white-space:pre">	</span>C:\www\vitrine\application\libraries\lumine\Lumine.php</p>
<p>Pronto. Agora vamos criar o nosso banco de dados.</p>
<h2>Criar o banco de dados.</h2>
<p>Crie um banco de dados chamado &quot;vitrine&quot;.</p>
<p>Importe a estrutura abaixo para criar as tabelas necessarias.</p>
<p>Este &quot;dump&quot; j&aacute; vem com um usu&aacute;rio padrao (e-mail: hufersil@gmail.com, senha: &quot;123456&quot;).</p>
<pre class="brush: sql">
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

--
-- Table structure for table `categoria`
--

DROP TABLE IF EXISTS `categoria`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `categoria` (
  `codcategoria` int(11) NOT NULL AUTO_INCREMENT,
  `codpai` int(11) DEFAULT NULL,
  `nome` varchar(100) DEFAULT NULL,
  `permalink` varchar(100) DEFAULT NULL,
  `ordem` int(11) DEFAULT NULL,
  PRIMARY KEY (`codcategoria`),
  KEY `codpai` (`codpai`),
  CONSTRAINT `categoria_ibfk_1` FOREIGN KEY (`codpai`) REFERENCES `categoria` (`codcategoria`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `categoria`
--

LOCK TABLES `categoria` WRITE;
/*!40000 ALTER TABLE `categoria` DISABLE KEYS */;
/*!40000 ALTER TABLE `categoria` ENABLE KEYS */;
UNLOCK TABLES;

--
-- Table structure for table `foto`
--

DROP TABLE IF EXISTS `foto`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `foto` (
  `codfoto` int(11) NOT NULL AUTO_INCREMENT,
  `codproduto` int(11) NOT NULL,
  `thumb` varchar(100) NOT NULL,
  `grande` varchar(100) NOT NULL,
  `ordem` int(11) NOT NULL DEFAULT '1',
  PRIMARY KEY (`codfoto`),
  KEY `codproduto` (`codproduto`),
  CONSTRAINT `foto_ibfk_1` FOREIGN KEY (`codproduto`) REFERENCES `produto` (`codproduto`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `foto`
--

LOCK TABLES `foto` WRITE;
/*!40000 ALTER TABLE `foto` DISABLE KEYS */;
/*!40000 ALTER TABLE `foto` ENABLE KEYS */;
UNLOCK TABLES;

--
-- Table structure for table `produto`
--

DROP TABLE IF EXISTS `produto`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `produto` (
  `codproduto` int(11) NOT NULL AUTO_INCREMENT,
  `codcategoria` int(11) NOT NULL,
  `nome` varchar(200) DEFAULT NULL,
  `permalink` varchar(200) DEFAULT NULL,
  `descricao` text,
  `valor` float DEFAULT NULL,
  `observacoes_tecnicas` text,
  `data_cadastro` datetime DEFAULT NULL,
  PRIMARY KEY (`codproduto`),
  KEY `codcategoria` (`codcategoria`),
  CONSTRAINT `produto_ibfk_1` FOREIGN KEY (`codcategoria`) REFERENCES `categoria` (`codcategoria`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `produto`
--

LOCK TABLES `produto` WRITE;
/*!40000 ALTER TABLE `produto` DISABLE KEYS */;
/*!40000 ALTER TABLE `produto` ENABLE KEYS */;
UNLOCK TABLES;

--
-- Table structure for table `usuario`
--

DROP TABLE IF EXISTS `usuario`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `usuario` (
  `codusuario` int(11) NOT NULL AUTO_INCREMENT,
  `nome` varchar(150) NOT NULL,
  `email` varchar(150) NOT NULL,
  `senha` varchar(32) NOT NULL,
  PRIMARY KEY (`codusuario`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `usuario`
--

LOCK TABLES `usuario` WRITE;
/*!40000 ALTER TABLE `usuario` DISABLE KEYS */;
INSERT INTO `usuario` VALUES (1,'Hugo Silva','hufersil@gmail.com','e10adc3949ba59abbe56e057f20f883e');
/*!40000 ALTER TABLE `usuario` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
</pre>
<h2>Efetuando a engenharia reversa</h2>
<p>&nbsp;</p>
<p>Com a estrutura do banco de dados criada, fica f&aacute;cil gerar as classes de acesso.<br />
Para isso, basta efetuar a engenharia reversa que Lumine (http://www.hufersil.com.br/lumine/engenharia_reversa) j&aacute; oferece.<br />
Acesse pelo browser: http://localhost/vitrine/application/libraries/lumine/lib/ui/reverse.php</p>
<p style="margin-left: 40px; ">Nota: caso apare&ccedil;a a mensagem &quot;Forbidden&quot;, &eacute; porque existe um arquivo chamado &quot;.htaccess&quot; dentro do diret&oacute;rio &quot;application&quot;.&nbsp;<br />
Renomeie este arquivo para poder acessar os arquivos dentro da pasta &quot;application&quot; <strong>durante o processo de desenvolvimento</strong>.<br />
Quando terminar e for colocar em produ&ccedil;&atilde;o, restaure este arquivo.</p>
<p>Dever&aacute; ser exibida a seguinte tela:</p>
<p><img width="863" height="482" border="1" alt="" src="http://www.hufersil.com.br/imagens/engenharia-reversa.PNG?" /></p>
<p>Preencha as abas como mostrado abaixo:</p>
<p><img width="866" height="491" alt="" src="http://www.hufersil.com.br/imagens/aba-dados-principais.PNG?" /></p>
<p><img width="864" height="512" alt="" src="http://www.hufersil.com.br/imagens/aba-personalizacao.PNG?" /></p>
<p><img width="864" height="409" alt="" src="http://www.hufersil.com.br/imagens/aba-integracao.PNG?" /></p>
<p>&nbsp;</p>
<p>Na aba &quot;Tabelas&quot;, clique em &quot;Atualizar Tabelas&quot;.</p>
<p>Dever&atilde;o ser exibidas as tabelas em seu banco de dados &quot;vitrine&quot;, como na tela abaixo:</p>
<p>&nbsp;</p>
<p><img width="863" height="332" alt="" src="http://www.hufersil.com.br/imagens/aba-tabelas.PNG?" /></p>
<p>&nbsp;</p>
<p>Selecione todas elas e clique no bot&atilde;o &quot;Gerar Classes&quot;. Voc&ecirc; ser&aacute; direcionado para a aba &quot;Log de gera&ccedil;&atilde;o&quot; onde poder&aacute; acompanhar o que Lumine est&aacute; fazendo.</p>
<p>Caso corra tudo sem problemas, a mensagem final dever&aacute; ser &quot;Engenharia reversa terminada!&quot;.</p>
<p>&nbsp;</p>
<p style="margin-left: 40px; ">Nota: o servidor web dever&aacute; ter permiss&atilde;o de escrita nas pastas:<br />
C:\www\vitrine\application<br />
C:\www\vitrine\application\libraries<br />
C:\www\vitrine\application\models</p>
<div>
<div>Os seguintes arquivos dever&atilde;o ter sido criados:</div>
<div>&nbsp;</div>
<div style="margin-left: 40px; ">C:\www\vitrine\application\lumine-conf.php</div>
<div style="margin-left: 40px; ">C:\www\vitrine\application\libraries\Lumine_ApplicationContext.php</div>
<div style="margin-left: 40px; ">C:\www\vitrine\application\models\Categoria.php</div>
<div style="margin-left: 40px; ">C:\www\vitrine\application\models\Foto.php</div>
<div style="margin-left: 40px; ">C:\www\vitrine\application\models\Produto.php</div>
<div style="margin-left: 40px; ">C:\www\vitrine\application\models\Usuario.php</div>
<div><span class="Apple-tab-span" style="white-space:pre">	</span></div>
<div>Confira se estes arquivos foram criados corretamente.</div>
<div>&nbsp;</div>
<div>Abra o arquivo &quot;Lumine_ApplicationContext.php&quot; e troque a linha</div>
</div>
<p>&nbsp;</p>
<pre class="brush: php">
require_once 'lumine/Lumine.php';
</pre>
<p>por</p>
<pre class="brush: php">
require_once APPPATH . '/libraries/lumine/Lumine.php';
</pre>
<p>e a linha</p>
<pre class="brush: php">
include 'lumine-conf.php';
</pre>
<p>por</p>
<pre class="brush: php">
include APPPATH . '/lumine-conf.php';
</pre>
<p>Pronto! Agora podemos testar nossa aplica&ccedil;&atilde;o.</p>
<h2>Testar se tudo est&aacute; correto</h2>
<p>Abra a controller padr&atilde;o que vem com a instala&ccedil;&atilde;o do CodeIgniter.<br />
Ela dever&aacute; estar em &quot;application/controllers/welcome.php&quot;.</p>
<p>Apague o m&eacute;todo &quot;index&quot; que ela possui e coloque este:</p>
<pre class="brush: php">
public function index(){
	// trocando o timezone para nao ficar aparecendo varios warnings
	// isto depende da configuracao do servidor, e nao do Lumine ou CodeIgniter
	date_default_timezone_set('America/Sao_Paulo');
	// importando a inicializacao de Lumine
	$this-&gt;load-&gt;library('Lumine_ApplicationContext');
	// ligando o log
	Lumine_Log::setLevel(3);
	// listando os usuarios
	$userList = new Usuario();
	$userList-&gt;find();
	
	while($userList-&gt;fetch()){
		echo 'Nome do usuario: ', $userList-&gt;nome, '<br />';
		echo 'E-mail: ', $userList-&gt;email, '<br />';
	}
}</pre>
<p>&nbsp;</p>
<p>Se aparecer um log e as informa&ccedil;&otilde;es:<br />
Nome do usuario: Hugo Silva<br />
E-mail: hufersil@gmail.com</p>
<p>Significa que est&aacute; tudo certo!</p>
<p>Na pr&oacute;xima mat&eacute;ria vamos aprender a:</p>
<p style="margin-left: 40px; ">configurar a base do CodeIgniter<br />
criar uma controller base<br />
criar uma controller base de administra&ccedil;&atilde;o<br />
criando a tela de login<span class="Apple-tab-span" style="white-space:pre">	</span></p>
<p>@bra&ccedil;os e fiquem com Deus!</p>
<p>&nbsp;</p>]]></description>
<lastBuildDate><![CDATA[Qua, 01 de fevereiro de 2012 - as 21h59]]></lastBuildDate>
<link>http://www.hufersil.com.br/post/criando_catalogo_produtos_lumine_codeigniter</link>
</item>
<item>
<title><![CDATA[Geração de imagem com JQuery/JQueryUI e PHP]]></title>
<description><![CDATA[<p>Ajudando uma pessoa no f&oacute;rum do iMasters, fiz um exemplo bem bacana de como gerar imagens com feedback visual de Drag-Drop.</p>
<p>Assim, a pessoa monta uma imagem composta por outas imagens. Bem simples por&eacute;m bem divertido e f&aacute;cil de fazer.</p>
<p>Vamos ver como faz&ecirc;-lo!</p>
<!-- more -->
<p>Iremos criar apenas dois arquivos e duas pastas para esta tarefa. As pastas s&atilde;o:</p>
<ul>
    <li><strong>imagens</strong> - coloque suas imagens originais aqui</li>
    <li><strong>geradas</strong> - pasta onde as imagens geradas ser&atilde;o salvas. <em><strong>N&atilde;o esque&ccedil;a de alterar o permissionamento para escrita</strong></em>.</li>
</ul>
<p>Depois de criar as pastas, vamos criar os arquivos. Os arquivos devem estar no mesmo n&iacute;vel das pastas.</p>
<p><strong>Arquivo de entrada e composi&ccedil;&atilde;o das imagens</strong> (index.php).</p>
<div class="both">&nbsp;</div>
<pre class="brush: html">
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta charset=&quot;UTF-8&quot;&gt;
&lt;title&gt;Imagens&lt;/title&gt;
	&lt;script type=&quot;text/javascript&quot; src=&quot;http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js&quot;&gt;&lt;/script&gt;
	&lt;script type=&quot;text/javascript&quot; src=&quot;http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.17/jquery-ui.min.js&quot;&gt;&lt;/script&gt;
	&lt;script type=&quot;text/javascript&quot;&gt;
	// quando terminar de carregar o script
	$(function(){
		// fazemos com que todas as imagens da lista possam ser arrastadas 
		$('.available li img').draggable({
			helper: 'clone'
		});

		// a &aacute;rea do &quot;papel&quot; ser&aacute; onde os itens podem ser soltos
		$('#area-itens').droppable({
			// quando soltar um item no &quot;papel&quot;...
			drop: function(evt, ui){
				// se o pai do item j&aacute; for o &quot;papel&quot;
				if(ui.draggable.parent()[0] == this){
					// nao faz nada
					return;
				}

				// referencia ao &quot;papel&quot;, mais curta
				var t = $(this);
				// copia do elemento arrastado
				var e = ui.draggable;
				// diferenca entre a posicao do mouse e a posicao do elemento quando for solto
				var diff = {x: evt.pageX - ui.position.left, y: evt.pageY - ui.position.top};
				// tiramos o &quot;helper&quot; do elemento ao ser arrastado
				e.draggable('option','helper','');
				// pegamos o elemento pai do elemento arrastado (a &quot;li&quot;)
				var parent = e.parent();
				// colocamos o elemento arrastado no papel
				e.appendTo(t);
				// removemos o elemento pai anterior do elemento arrastado (a &quot;li&quot;)
				parent.remove();

				// calculando novo posicionamento dentro do papel
				e.css({
					position: 'absolute',
					left: evt.pageX - t.offset().left - diff.x,
					top: evt.pageY - t.offset().top - diff.y
				});
			}
		});

		// ao clicar no botao de salvar a imagem
		$('#btnSalvar').click(function(evt){
			// elemento contendo o status
			var s = $('.status'), 
				// dados a serem enviados para o servidor
				data={}, 
				// area dos itens
				area = $('#area-itens'),
				// tamanho da pagina 
				pageSize = {width:area.width(),height:area.height()},
				// elementos escolhidos pelo usuario 
				itens=[];

			// para cada elemento dentro da pagina
			area.find('.itens').each(function(){
				// referencia ao elemento atual
				var t=$(this), 
					// criamos um novo objeto com as propriedades desejadas
					// para gera&ccedil;&atilde;o do arquivo final
					item = {
						src: this.src, 
						width: t.width(), 
						height: t.height(),
						x: t.position().left,
						y: t.position().top
					};
				// colocamos na lista de itens que ser&atilde;o usados para compor
				// a nova imagem
				itens.push(item);
			});

			// colocamos os dados no objeto para
			// enviar para gera&ccedil;&atilde;o da imagem
			data.area = pageSize;
			data.itens = itens;

			// muda o status para aguardar
			s.html('Aguarde...');
			// envia para o PHP gerar a imagem final
			$.post('gerar.php', data, function(link){
				// quando receber a resposta, mostra o Link para baixar a imagem
				s.html('Imagem gerada: &lt;a target=&quot;_blank&quot; href=&quot;'+link+'&quot;&gt;Clique aqui para baixar&lt;/a&gt;');
			});
		});
	});
	
	&lt;/script&gt;	
	
	&lt;style type=&quot;text/css&quot;&gt;
		#area-itens {
			position: relative;
			float: left;
			width: 300px;
			height: 450px;
			border: 1px solid black;
			overflow: hidden;
		}
		
		.available {
			float: right;
		}
		
		.buttons {
			clear: both;
		}
		
	&lt;/style&gt;
	
&lt;/head&gt;
&lt;body&gt;
	
	&lt;p&gt;Arraste as imagens da direita para a &quot;&aacute;rea do papel&quot; abaixo&lt;/p&gt;
	
	&lt;!--  area do &quot;papel&quot;  --&gt;
	&lt;div id=&quot;area-itens&quot;&gt;
	&lt;/div&gt;
	
	&lt;!--  lista de elementos que servem para o usuario compor a nova imagem --&gt;
	&lt;ul	class=&quot;available&quot;&gt;
		&lt;li&gt;&lt;img src=&quot;imagens/imagem1.jpg&quot; class=&quot;itens&quot; /&gt;&lt;/li&gt;
		&lt;li&gt;&lt;img src=&quot;imagens/imagem2.jpg&quot; class=&quot;itens&quot; /&gt;&lt;/li&gt;
		&lt;li&gt;&lt;img src=&quot;imagens/imagem3.jpg&quot; class=&quot;itens&quot; /&gt;&lt;/li&gt;
		&lt;li&gt;&lt;img src=&quot;imagens/imagem4.jpg&quot; class=&quot;itens&quot; /&gt;&lt;/li&gt;
	&lt;/ul&gt;
	
	&lt;div class=&quot;buttons&quot;&gt;
		&lt;input type=&quot;button&quot; value=&quot;Salvar Imagem&quot; id=&quot;btnSalvar&quot; /&gt;
	&lt;/div&gt;
	
	&lt;div class=&quot;status&quot;&gt;&lt;/div&gt;
	
&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>Como podemos ver, este arquivo &eacute; composto apenas de HTML, CSS e JavaScript. Simples e direto.</p>
<p><strong>Agora, vamos criar o arquivo que gera as imagens compostas</strong> (gerar.php):</p>
<pre class="brush: php">
&lt;?php

// mudamos o timezone para nao termos problema com datas
date_default_timezone_set('America/Sao_Paulo');

// pegamos a largura da pagina enviada via post,  ou usamos 300 como padrao
$width = empty($_POST['area']['width']) ? 300 : sprintf('%d', $_POST['area']['width']);
// pegamos a altura da pagina enviada via post,  ou usamos 450 como padrao
$height = empty($_POST['area']['height']) ? 450 : sprintf('%d', $_POST['area']['height']);

// criamos a imagem e colocamos um fundo branco
$img = imagecreatetruecolor($width, $height);
$white = imagecolorallocate($img, 255, 255, 255);
imagefilledrectangle($img, 0, 0, $width, $height, $white);

// se enviou imagens
if(!empty($_POST['itens'])){
	// para cada imagem enviada
	foreach($_POST['itens'] as $item){
		// se tem o elemento &quot;src&quot;
		if(!empty($item['src'])){
			// pegamos somente o nome do arquivo e ignoramos o restante
			// vamos procurar por ela dentro da pasta &quot;imagens&quot;
			$filename = 'imagens/' . pathinfo($item['src'], PATHINFO_BASENAME);
			//se existir
			if(file_exists($filename)){
				// pegamos o restante das informacoes enviadas
				// via post para esta imagem
				$w = sprintf('%d', $item['width']);
				$h = sprintf('%d', $item['height']);
				$x = sprintf('%d', $item['x']);
				$y = sprintf('%d', $item['y']);
				
				// criamos o elemento de imagem no PHP a partir do conteudo do arquivo
				$item = imagecreatefromstring(file_get_contents($filename));
				
				// copiamos a imagem informada na imagem final, 
				// com as medidas e posi&ccedil;&otilde;es informadas
				imagecopy($img, $item, $x, $y, 0, 0, $w, $h);
			}
		}
	}
}

// geramos o arquivo final
$imageFileName = 'geradas/imagem-'.time().'.jpg';
imagejpeg($img, $imageFileName, 90);

// informamos o link
echo $imageFileName;
</pre>
<p>Como podemos ver, s&atilde;o dois arquivos simples e pequenos, f&aacute;ceis de serem alterados para suas necessidades!</p>
<p>Voc&ecirc; pode <a href="http://www.hufersil.com.br/exemplo/drag-drop/">conferir um exemplo online</a> ou <a href="http://www.hufersil.com.br/lumine/exemplos">baixar os arquivos do tutorial na se&ccedil;&atilde;o de exemplos</a>.</p>
<p>@bra&ccedil;os e fiquem com Deus!</p>]]></description>
<lastBuildDate><![CDATA[Ter, 31 de janeiro de 2012 - as 10h27]]></lastBuildDate>
<link>http://www.hufersil.com.br/post/geracao_imagem_drag_drop_jquery_jqueryui_php</link>
</item>
<item>
<title><![CDATA[Exemplo de questionário]]></title>
<description><![CDATA[<p>Fala galera.</p>
<p>Ajudando uma pessoa no f&oacute;rum do iMasters / PHP esses dias atr&aacute;s, fiz um para ele um exemplo de como criar um question&aacute;rio e gravar as op&ccedil;&otilde;es selecionadas.</p>
<!-- more -->
<p>O usu&aacute;rio tamb&eacute;m pode definir quantas op&ccedil;&otilde;es podem ser selecionadas dentro de cada pergunta.</p>
<p>Tamb&eacute;m fiz um exemplo de como extrair os resultados do question&aacute;rio.</p>
<p>O exemplo pode ser baixado na <a href="/lumine/exemplos">se&ccedil;&atilde;o de exemplos</a>.</p>
<p>@bra&ccedil;os e fiquem com Deus!</p>]]></description>
<lastBuildDate><![CDATA[Seg, 30 de janeiro de 2012 - as 09h45]]></lastBuildDate>
<link>http://www.hufersil.com.br/post/exemplo_questionario</link>
</item>
<item>
<title><![CDATA[Exemplo de Jogo: Nave]]></title>
<description><![CDATA[<p>Mais um exemplozinho de jogo em HTML + JS + CSS:</p>
<p><a href="http://www.hufersil.com.br/exemplo/nave/">Link do Jogo</a></p>
<p><a href="http://www.hufersil.com.br/exemplo/nave/assets/js/game.js">Link do JS</a></p>
<p>@bra&ccedil;os e fiquem com Deus!</p>]]></description>
<lastBuildDate><![CDATA[Qui, 05 de janeiro de 2012 - as 16h38]]></lastBuildDate>
<link>http://www.hufersil.com.br/post/exemplo_jogo_nave</link>
</item>
</channel>
</rss>