<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Robertson Freitas</title>
	<atom:link href="http://blog.robertsonfreitas.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.robertsonfreitas.com</link>
	<description>Produtividade, processos de desenvolvimento de software e PHP.</description>
	<lastBuildDate>Mon, 21 Sep 2009 02:19:41 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>CRUD Básico com CodeIgniter 1.7.2</title>
		<link>http://blog.robertsonfreitas.com/2009/09/20/crud-basico-com-codeigniter-1-7-2/</link>
		<comments>http://blog.robertsonfreitas.com/2009/09/20/crud-basico-com-codeigniter-1-7-2/#comments</comments>
		<pubDate>Mon, 21 Sep 2009 01:35:52 +0000</pubDate>
		<dc:creator>Robertson Freitas</dc:creator>
				<category><![CDATA[CodeIgniter]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://blog.robertsonfreitas.com/?p=98</guid>
		<description><![CDATA[For those who do not speak Portuguese,  you can see a working example here and download the source code here. The comments are in English.
Fiz algumas melhorias no código do post anterior:

A versão do CI foi atualizada. Este exemplo agora usa o CodeIgniter 1.7.2.
As configurações de layout da paginação foram transferidas para o lugar [...]]]></description>
			<content:encoded><![CDATA[<p><em><span style="color: #808080;">For those who do not speak Portuguese,  you can see a working example <a href="http://www.robertsonfreitas.com/ci_sandbox2/user" target="_blank">here</a> and download the source code <a href="http://www.robertsonfreitas.com/files/ci_sandbox2.rar" target="_blank">here</a>. The comments are in English.</span></em></p>
<p>Fiz algumas melhorias no código do <a title="CRUD Básico com CodeIgniter 1.7.1" href="http://blog.robertsonfreitas.com/2009/08/24/crud-basico-com-codeigniter/">post anterior</a>:</p>
<ul>
<li>A versão do CI foi atualizada. Este exemplo agora usa o CodeIgniter 1.7.2.</li>
<li>As configurações de layout da paginação foram transferidas para o lugar correto (<strong>config/pagination.php</strong>).</li>
<li>O uso da função <strong>set_value</strong> do Form helper, como sugerido no manual do CI, ajudou a enxugar o código do Controller.</li>
<li>Pequenos ajustes no método <strong>_save</strong> do Controller.</li>
<li>As pastas<strong> i</strong>, <strong>js</strong> e <strong>css</strong> foram movidas para dentro da nova pasta <strong>web</strong>, organizando os arquivos e eliminando a necessidade de manutenção nas excessões do .htaccess.</li>
<li>O profiler foi habilitado para exibir informações de performance da aplicação.</li>
</ul>
<p>Antes de continuar, veja o exemplo funcionando <a href="http://www.robertsonfreitas.com/ci_sandbox2/user" target="_blank">aqui</a>.</p>
<p>Disponibilizei o código fonte completo, junto com o codeigniter 1.7.2 e o script de criação do banco <a href="http://www.robertsonfreitas.com/files/ci_sandbox2.rar" target="_blank">aqui</a>.</p>
<p><span id="more-98"></span>Decidi deixar o conteúdo e os comentários em inglês para alcançar mais pessoas.</p>
<p><strong> </strong></p>
<p><strong> </strong></p>
<p><span style="color: #333399;"><strong>Passo 1 &#8211; Criação do banco de dados</strong></span><strong> </strong></p>
<p>Execute o script abaixo (utilizando o <a href="http://www.google.com/url?sa=t&amp;source=web&amp;ct=res&amp;cd=1&amp;url=http%3A%2F%2Fwww.phpmyadmin.net%2F&amp;ei=DwSSSpDSO4-GlAfBpNClDA&amp;usg=AFQjCNEVUIHBxbZboIeYNUd_4abvz6M1zw" target="_blank">phpMyAdmin</a>, por exemplo) para criar o banco &#8220;<strong>ci_sandbox</strong>&#8220;, criar e popular a tabela &#8220;<strong>users</strong>&#8221; no MySQL 5. Note que estou utilizando codificação UTF-8, que vem configurada por padrão no CodeIgniter (no arquivo <strong>application/config/database.php</strong>).</p>
<pre class="brush: sql;">
CREATE DATABASE `ci_sandbox` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;

CREATE TABLE IF NOT EXISTS `users` (
  `id` int(11) NOT NULL auto_increment,
  `name` varchar(100) NOT NULL,
  `email` varchar(100) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `users` (`id`, `name`, `email`) VALUES
(1, 'Bob', 'bob@bob.com'),
(2, 'Philip', 'philip@philip.com'),
(3, 'Paty', 'paty@paty.com'),
(4, 'Kelly', 'kelly@kelly.com'),
(5, 'Bill', 'bill@bill.com'),
(6, 'Tedd', 'tedd@tedd.com'),
(7, 'John', 'john@john.com'),
(8, 'Paul', 'paul@paul.com'),
(9, 'Anna', 'anna@anna.com'),
(10, 'Hellen', 'hellen@hellen.com'),
(11, 'Kate', 'kate@kate.com');
</pre>
<p><strong> </strong></p>
<p><span style="color: #333399;"><strong>Passo 2 &#8211; Criação do CSS da aplicação</strong></span><strong> </strong></p>
<p>Veja abaixo a folha de estilo usada na listagem, paginação e mensagens (arquivo <strong>web/css/style.css</strong>):</p>
<pre class="brush: css;">
*{
	margin: 0;
	padding: 0;
}

body {
	background:#FFFFFF;
	font-family:verdana,arial,helvetica,sans-serif;
	font-size:10px;
	margin:2px;
	padding:2px;
}

#container h1 {
	color:#678197;
	border: 2px solid #E5EFF8;
	margin-bottom: 10px;
	padding: 5px;
	width: 686px;
	_width: 700px;
	background-color: #F2F6F7;
	font-size: 20px;
}

#listing {
	width:700px;
	color:#678197;
	font-family:verdana,arial,helvetica,sans-serif;
	font-size:8pt;
	border-spacing: 0px;
	border: 1px solid #E5EFF8;
}

#listing td {
	padding:5px;
	font-size:8pt;
	border: 1px solid #E5EFF8;
}
#listing th {
	color:#21497D;
	font-weight:bold;
	background:#F2F6F7;
	font-size:8pt;
	padding:5px;
	text-align: left;
	border: 1px solid #E5EFF8;
}

ul {
	border:0; margin:0; padding:0;
}

#pagination li {
	border:0; margin:0; padding:0;
	font-size:11px;
	list-style:none;
	float:left;
}

#pagination a {
	border:solid 1px #DDDDDD;
	margin-right:2px;
}

#pagination .previous-off, #pagination .next-off {
	color:#666666;
	display:block;
	float:left;
	font-weight:bold;
	padding:3px 4px;
}

#pagination .next a, #pagination .previous a {
	font-weight:bold;
	border:solid 1px #FFFFFF;
}

#pagination .active {
	color:#ff0084;
	font-weight:bold;
	display:block;
	float:left;
	padding:4px 6px;
}

#pagination a:link, #pagination a:visited {
	color:#678197;
	display:block;
	float:left;
	padding:3px 6px;
	text-decoration:none;
}

#pagination a:hover {
	border:solid 1px #666666;
}

.error_field {
	padding:5px;
	margin-bottom:3px;
	margin-top:3px;
	border: 1px solid red;
	background: yellow;
	width: 300px;
}

.footer_info {
	color:#6f8dA1;
}

/* Content Elements: Messages */

.message, .warning, .success, .error {
	width: 690px;
	_width: 700px;
	padding: 5px;
	margin-bottom: 3px;
	font-size: 12px;
}

.message {
	color: #ffffff;
	background-color: #aaa9a6;
}

.warning {
	color: #ffffff;
	background-color: #ff9900;
}

.success {
	color: #ffffff;
	background-color: #009000;
}

.error {
	color: #ffffff;
	background-color: #900000;
}
</pre>
<p><strong> </strong></p>
<p><span style="color: #333399;"><strong>Passo 3 &#8211; Instalação da Library e do Helper Message</strong></span></p>
<p>Para facilitar o envio e a exibição de mensagens para o usuário, encontrei esta prática biblioteca chamada Message no Wiki (<a href="http://codeigniter.com/wiki/Messages/" target="_blank">confira</a>) do Codeigniter, e no fórum encontrei um Helper (<a href="http://codeigniter.com/forums/viewthread/84694/" target="_blank">confira</a>) para reduzir a exibição de código nas views.</p>
<p>Crie o arquivo <strong>application/libraries/messages.php</strong> com o conteúdo abaixo:</p>
<pre class="brush: php;">
&lt;?php if (!defined('BASEPATH')) exit('No direct script access allowed');

/**
* Message:: a class for writing feedback message information to the session
*
* Copyright 2006 Vijay Mahrra &amp;amp; Sheikh Ahmed &lt;webmaster@designbyfail.com&gt;
*
* See the enclosed file COPYING for license information (LGPL).  If you
* did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
*
* @author  Vijay Mahrra &amp;amp; Sheikh Ahmed &lt;webmaster@designbyfail.com&gt;
* @url http://www.designbyfail.com/
* @version 1.0
*/

class Messages
{
    var $_ci;
    var $_types = array('success', 'error', 'warning', 'message');

    function Messages($params = array())
    {
        $this-&gt;_ci =&amp;amp; get_instance();
        $this-&gt;_ci-&gt;load-&gt;library('session');
        // check if theres already messages, if not, initialise the messages array in the session
        $messages = $this-&gt;_ci-&gt;session-&gt;userdata('messages');
        if (empty($messages)) {
            $this-&gt;clear();
        }
    }

    // clear all messages
    function clear()
    {
        $messages = array();
        foreach ($this-&gt;_types as $type) {
            $messages[$type] = array();
        }
        $this-&gt;_ci-&gt;session-&gt;set_userdata('messages', $messages);
    }

    // add a message, default type is message
    function add($message, $type = 'message')
    {
        $messages = $this-&gt;_ci-&gt;session-&gt;userdata('messages');
        // handle PEAR errors gracefully
        if (is_a($message, 'PEAR_Error')) {
            $message = $message-&gt;getMessage();
            $type = 'error';
        } else if (!in_array($type, $this-&gt;_types)) {
            // set the type to message if the user specified a type that's unknown
            $type = 'message';
        }
        // don't repeat messages!
        if (!in_array($message, $messages[$type]) &amp;amp;&amp;amp; is_string($message)) {
            $messages[$type][] = $message;
        }
        $messages = $this-&gt;_ci-&gt;session-&gt;set_userdata('messages', $messages);
    }

    // return messages of given type or all types, return false if none
    function sum($type = null)
    {
        $messages = $this-&gt;_ci-&gt;session-&gt;userdata('messages');
        if (!empty($type)) {
            $i = count($messages[$type]);
            return $i;
        }
        $i = 0;
        foreach ($this-&gt;_types as $type) {
            $i += count($messages[$type]);
        }
        return $i;
    }

    // return messages of given type or all types, return false if none, clearing stack
    function get($type = null)
    {
        $messages = $this-&gt;_ci-&gt;session-&gt;userdata('messages');
        if (!empty($type)) {
            if (count($messages[$type]) == 0) {
                return false;
            }
            return $messages[$type];
        }
        // return false if there actually are no messages in the session
        $i = 0;
        foreach ($this-&gt;_types as $type) {
            $i += count($messages[$type]);
        }
        if ($i == 0) {
            return false;
        }

        // order return by order of type array above
        // i.e. success, error, warning and then informational messages last
        foreach ($this-&gt;_types as $type) {
            $return[$type] = $messages[$type];
        }
        $this-&gt;clear();
        return $return;
    }
}
</pre>
<p>Crie o arquivo <strong>application/helpers/msg_helper.php</strong> com o conteúdo abaixo:</p>
<pre class="brush: php;">
&lt;?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

if ( ! function_exists('output_msg')) {
    function output_msg($type = null) {
        $CI =&amp;amp; get_instance();

        if ($CI-&gt;messages-&gt;sum($type) &gt; 0) {
        $messages = $CI-&gt;messages-&gt;get($type);
        // display all messages of the type
        if (is_array($messages)) {
            $output = '';
            foreach ($messages as $type =&gt; $msgs) {
                if (count($msgs) &gt; 0) {
                    $output .= '&lt;div class=&amp;quot;' . $type . '&amp;quot;&gt;';
                    $output .= '&lt;ul&gt;';
                    foreach ($msgs as $message) {
                        $output .= $message;
                    }
                    $output .= '&lt;/ul&gt;';
                    $output .= '&lt;/div&gt;';
                }
            }
        }
        return $output;
        }
    }
}
</pre>
<p><strong> </strong></p>
<p><span style="color: #333399;"><strong>Passo 4 &#8211; Criação do Model</strong></span></p>
<p>O model anêmico abaixo (que está mais para um Active Record Layer), incrivelmente reusável, foi <span style="text-decoration: line-through;">inspirado no</span> copiado deste <a href="http://henrihnr.wordpress.com/2009/04/26/simple-crud-application/" target="_blank">exemplo de CRUD</a>. Controller gordo + Model magro é considerado um anti-pattern, mas eu gosto que as coisas estejam distribuídas assim, e o CodeIgniter, pelo que vi no manual, também. (O que você acha?)</p>
<p>Arquivo <strong>application/models/user_model.php</strong></p>
<pre class="brush: php;">
&lt;?php
class User_model extends Model {

    private $table = 'users';

    function User_model() {
        parent::Model();
    }

    function list_all($order_by = 'id') {
        $this-&gt;db-&gt;order_by($order_by,'asc');
        return $this-&gt;db-&gt;get($table);
    }

    function count_all() {
        return $this-&gt;db-&gt;count_all($this-&gt;table);
    }

    function get_paged_list($limit = 10, $offset = 0, $order_by = 'id') {
        $this-&gt;db-&gt;order_by($order_by,'asc');
        return $this-&gt;db-&gt;get($this-&gt;table, $limit, $offset);
    }

    function get_by_id($id) {
        $this-&gt;db-&gt;where('id', $id);
        return $this-&gt;db-&gt;get($this-&gt;table);
    }

    function save($obj) {
        $this-&gt;db-&gt;insert($this-&gt;table, $obj);
        return $this-&gt;db-&gt;insert_id();
    }

    function update($id, $obj) {
        $this-&gt;db-&gt;where('id', $id);
        $this-&gt;db-&gt;update($this-&gt;table, $obj);
    }

    function delete($id) {
        $this-&gt;db-&gt;where('id', $id);
        $this-&gt;db-&gt;delete($this-&gt;table);
    }
}
?&gt;
</pre>
<p><strong> </strong></p>
<p><span style="color: #333399;"><strong>Passo 5 &#8211; Criação da view para listagem</strong></span></p>
<p>Nesta view é exibida a listagem paginada. Note a simplicidade da exibição de mensagens através da função <strong>output_msg</strong>, do Helper que instalamos acima.</p>
<p>Arquivo <strong>application/views/user_list.php</strong></p>
<pre class="brush: php;">
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;
&lt;head&gt;
	&lt;meta http-equiv=&quot;content-type&quot; content=&quot;text/html; charset=utf-8&quot; /&gt;
	&lt;title&gt;User List&lt;/title&gt;
	&lt;link href=&quot;&lt;?php echo base_url(); ?&gt;web/css/style.css&quot; rel=&quot;stylesheet&quot; type=&quot;text/css&quot; /&gt;
	&lt;script&gt;
		function remove(id) {
			if (confirm(&quot;Are you sure?&quot;)) {
				window.location = '&lt;?php echo base_url(); ?&gt;user/delete/'+id;
			}
		}
	&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;?php
	// show user messages sent by controller
	echo output_msg($type = null);
?&gt;
&lt;div id=&quot;container&quot;&gt;
	&lt;h1&gt;USER LIST&lt;/h1&gt;
	&lt;table id=&quot;listing&quot; cellspacing=0&gt;
		&lt;tr&gt;
			&lt;th width=45%&gt;Name&lt;/th&gt;
			&lt;th width=45%&gt;E-mail&lt;/th&gt;
			&lt;th width=10%&gt;Actions&lt;/th&gt;
		&lt;/tr&gt;
		&lt;?php foreach($list as $user): ?&gt;
			&lt;tr&gt;
				&lt;td&gt;&lt;?php echo $user-&gt;name; ?&gt;&lt;/td&gt;
				&lt;td&gt;&lt;?php echo $user-&gt;email; ?&gt;&lt;/td&gt;
				&lt;td align=&quot;center&quot;&gt;
					&lt;a href=&quot;&lt;?php echo base_url(); ?&gt;user/prepareUpdate/&lt;?php echo $user-&gt;id; ?&gt;&quot;&gt;&lt;img src=&quot;&lt;?php echo base_url(); ?&gt;web/i/icon/b_edit.png&quot; border=0 title=&quot;Edit&quot;&gt;&lt;/a&gt;
					&lt;a href=&quot;#&quot; onclick=&quot;remove(&lt;?php echo $user-&gt;id; ?&gt;);&quot;&gt;&lt;img src=&quot;&lt;?php echo base_url(); ?&gt;web/i/icon/b_drop.png&quot; border=0 title=&quot;Delete&quot;&gt;&lt;/a&gt;
				&lt;/td&gt;
			&lt;/tr&gt;
		&lt;?php endforeach ?&gt;
	&lt;/table&gt;
	&lt;div style=&quot;padding:10px;&quot;&gt;&lt;?php echo $pagination; ?&gt;&lt;br clear=&quot;all&quot; /&gt;&lt;/div&gt;
	&lt;input type=button onclick=&quot;location.href='&lt;?php echo base_url(); ?&gt;user/prepareInsert/';&quot; value=&quot;New User&quot; class=&quot;buttonAdmin&quot;&gt;
&lt;/div&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;p class=&quot;footer_info&quot;&gt;
	Total execution time: &lt;?php echo $this-&gt;benchmark-&gt;elapsed_time() ?&gt; seconds;
	Memory usage: &lt;?php echo $this-&gt;benchmark-&gt;memory_usage() ?&gt;
&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<p><strong> </strong></p>
<p><span style="color: #333399;"><strong>Passo 6 &#8211; Criação da view contendo o formulário de cadastro e edição</strong></span></p>
<p>Esta view contém o formulário que será exibido para criar e editar usuários. Observe o uso da função <strong>set_value()</strong> e da variável <strong>$values</strong>, que contém as informações para popular os campos com os dados do item.</p>
<p>Arquivo <strong>application/views/user_form.php</strong></p>
<pre class="brush: php;">
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;
&lt;head&gt;
	&lt;meta http-equiv=&quot;content-type&quot; content=&quot;text/html; charset=utf-8&quot; /&gt;
	&lt;title&gt;&lt;?php echo $title; ?&gt;&lt;/title&gt;
	&lt;link href=&quot;&lt;?php echo base_url(); ?&gt;web/css/style.css&quot; rel=&quot;stylesheet&quot; type=&quot;text/css&quot; /&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;?php
	// show user messages sent by controller
	echo output_msg($type = null);
?&gt;
&lt;form method=&quot;post&quot; action=&quot;&lt;?php echo $action; ?&gt;&quot;&gt;
	&lt;div id=&quot;container&quot;&gt;
		&lt;h1&gt;&lt;?php echo $title; ?&gt;&lt;/h1&gt;
				&lt;label&gt;Name*&lt;/label&gt;&lt;br&gt;
				&lt;input type=&quot;text&quot; name=&quot;name&quot; value=&quot;&lt;?php echo set_value('name', $values['name']); ?&gt;&quot; style=&quot;width:500px;&quot; maxlength=&quot;100&quot;&gt;
				&lt;?php echo form_error('name'); ?&gt;&lt;br&gt;&lt;br&gt;

				&lt;label&gt;E-mail*&lt;/label&gt;&lt;br&gt;
				&lt;input type=&quot;text&quot; name=&quot;email&quot; value=&quot;&lt;?php echo set_value('email', $values['email']); ?&gt;&quot; style=&quot;width:500px;&quot; maxlength=&quot;100&quot;&gt;
				&lt;?php echo form_error('email'); ?&gt;&lt;br&gt;&lt;br&gt;

				&lt;input type=submit value=&quot; Save &quot;&gt;

				&lt;input type=button onclick=&quot;location.href='&lt;?php echo base_url(); ?&gt;user/index/';&quot; value=&quot;Back to listing&quot; class=&quot;buttonAdmin&quot; style=&quot;margin-left:20px;&quot;&gt;
	&lt;/div&gt;
	&lt;input type=hidden name=id value=&quot;&lt;?php echo set_value('id', $values['id']); ?&gt;&quot;&gt;
&lt;/form&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;p class=&quot;footer_info&quot;&gt;
	Total execution time: &lt;?php echo $this-&gt;benchmark-&gt;elapsed_time() ?&gt; seconds;
	Memory usage: &lt;?php echo $this-&gt;benchmark-&gt;memory_usage() ?&gt;
&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<p><strong> </strong></p>
<p><span style="color: #333399;"><strong>Passo 7 &#8211; O Controller</strong></span></p>
<p>O controller começa com duas variáveis de configuração: quantidade de linhas exibidas por página na listagem (<strong>$limit</strong>) e nome da coluna que determinará a ordenação da listagem (<strong>$order_by</strong>).</p>
<p>No construtor, carregamos as libraries e helpers necessários.</p>
<p>Entenda o papel de cada método:</p>
<p>O <strong>index()</strong> prepara os dados da paginação, invoca os dados do modelo e transfere esses dados para a view <strong>user_list.php</strong>.</p>
<p>O <strong>prepareInsert()</strong> monta um formulário de cadastro em branco.</p>
<p>O <strong>prepareUpdate()</strong> consulta o modelo e monta um formulário preenchido com os dados do <strong>$id</strong> solicitado.</p>
<p>O <strong>insert()</strong> e o <strong>update()</strong> são apenas chamadas para o <strong>_save()</strong>. Foram criados assim para facilitar a visualização e compreensão do fluxo da aplicação.</p>
<p>O método privado <strong>_save()</strong> cria ou edita um item, de acordo com a <strong>$action</strong> solicitada. Nesse método são configuradas as regras de validação dos dados vindos do formulário.</p>
<p>O <strong>delete() </strong>exclui o item com o <strong>$id</strong> informado, e retorna para a listagem de usuários.</p>
<p>Arquivo <strong>application/controllers/user.php</strong></p>
<pre class="brush: php;">
&lt;?php
	class User extends Controller {

		// records per page
		private $limit = 5;

		// column to order by at listing
		private $order_by = 'name';

		function User()  {
			parent::Controller();

			$this-&gt;load-&gt;database();
			$this-&gt;load-&gt;library('form_validation');
			$this-&gt;load-&gt;helper('url');

			// send and show messages to user
			$this-&gt;load-&gt;library('messages');
			$this-&gt;load-&gt;helper('msg');

			$this-&gt;load-&gt;model('user_model', '', TRUE);

			$this-&gt;output-&gt;enable_profiler($this-&gt;config-&gt;item('profiler'));
		}

		function index($offset = 0) {
			$data = array();

			// http://.../ci_sandbox(1)/index(2)/&lt;offset&gt;(3)
			$uri_segment = 3;
			// where this page begins
			$offset = $this-&gt;uri-&gt;segment($uri_segment);
			// load data list
			$data['list'] = $this-&gt;user_model-&gt;get_paged_list($this-&gt;limit, $offset, $this-&gt;order_by)-&gt;result();

			// generate pagination
			$this-&gt;load-&gt;library('pagination');
			$config['base_url'] = site_url('user/index/');
	 		$config['total_rows'] = $this-&gt;user_model-&gt;count_all();
	 		$config['per_page'] = $this-&gt;limit;
			$config['uri_segment'] = $uri_segment;
			$this-&gt;pagination-&gt;initialize($config);
			$data['pagination'] = $this-&gt;pagination-&gt;create_links();

			$this-&gt;load-&gt;view('user_list',$data);
		}

		function prepareInsert() {
			// set validation properties
			$data['values'] = NULL;

			// set common properties
			$data['title'] = 'NEW USER';
			$data['action'] = site_url('user/insert');

			$this-&gt;load-&gt;view('user_form', $data);
		}

		function prepareUpdate($id) {
			// prefill form values
			$obj = $this-&gt;user_model-&gt;get_by_id($id)-&gt;row();
			$data['values']['id'] = $id;
			$data['values']['name'] = $obj-&gt;name;
			$data['values']['email'] = $obj-&gt;email;

			// set common properties
			$data['title'] = 'EDIT USER';
			$data['action'] = site_url('user/update');

			$this-&gt;load-&gt;view('user_form', $data);
		}

		function insert() {
			$this-&gt;_save('insert');
		}

		function update() {
			$this-&gt;_save('update');
		}

		function _save($action = 'insert') {
			// set common properties
			if ($action == 'update') {
				$data['title'] = 'EDIT USER';
				$data['action'] = site_url('user/update');
			} else {
				$data['title'] = 'NEW USER';
				$data['action'] = site_url('user/insert');
			}

			// set validation properties
			$this-&gt;form_validation-&gt;set_rules('id','','');
			$this-&gt;form_validation-&gt;set_rules('name','Name','trim|required|max_length[100]|xss_clean');
			$this-&gt;form_validation-&gt;set_rules('email','E-mail','trim|required|max_length[100]|valid_email|xss_clean');
			$this-&gt;form_validation-&gt;set_error_delimiters('&lt;p class=&quot;error_field&quot;&gt;', '&lt;/p&gt;');

			// run validation
			if ($this-&gt;form_validation-&gt;run() == FALSE) {
				$data['values'] = NULL;

				// set user message
				$this-&gt;messages-&gt;add('Important: please see the itens below.', 'warning');

				$this-&gt;load-&gt;view('user_form', $data);
			} else {

				$obj-&gt;name = $this-&gt;input-&gt;post('name');
				$obj-&gt;email = $this-&gt;input-&gt;post('email');

				if ($action == 'update') {
					$id = $this-&gt;input-&gt;post('id');
					$this-&gt;user_model-&gt;update($id, $obj);
					$this-&gt;messages-&gt;add('User updated', 'success'); // ser user message
				} else {
					$id = $this-&gt;user_model-&gt;save($obj);
					$this-&gt;messages-&gt;add('User created', 'success'); // set user message
				}

				// redirect to list page
				redirect('user/index/','refresh');
			}
		}

		function delete($id) {
			$this-&gt;user_model-&gt;delete($id);

			// set user message
			$this-&gt;messages-&gt;add('User removed', 'success');

			// redirect to list page
			redirect('user/index/','refresh');
		}

	}
?&gt;
</pre>
<p>Espero que esse exemplo simples seja útil para quem está iniciando, e que os mais experientes comentem e sugiram melhorias.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.robertsonfreitas.com/2009/09/20/crud-basico-com-codeigniter-1-7-2/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>CRUD Básico com CodeIgniter 1.7.1</title>
		<link>http://blog.robertsonfreitas.com/2009/08/24/crud-basico-com-codeigniter/</link>
		<comments>http://blog.robertsonfreitas.com/2009/08/24/crud-basico-com-codeigniter/#comments</comments>
		<pubDate>Mon, 24 Aug 2009 03:02:18 +0000</pubDate>
		<dc:creator>Robertson Freitas</dc:creator>
				<category><![CDATA[CodeIgniter]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[CRUD]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Pagination]]></category>
		<category><![CDATA[Validation]]></category>

		<guid isPermaLink="false">http://blog.robertsonfreitas.com/?p=72</guid>
		<description><![CDATA[Atenção: existe uma atualização para este post: CRUD Básico com CodeIgniter 1.7.2
Estou há algumas semanas utilizando o framework PHP CodeIgniter. A documentação é incrível, muito detalhada e organizada, com muitos exemplos simples, porém poucos exemplos completos, voltados para o mundo real. Senti falta de modelos de CRUD completos, por exemplo.
Mesmo procurando em outros sites, blogs [...]]]></description>
			<content:encoded><![CDATA[<p><span style="color: #ff0000;"><em>Atenção: existe uma atualização para este post: </em><a href="http://blog.robertsonfreitas.com/2009/09/20/crud-basico-com-codeigniter-1-7-2/">CRUD Básico com CodeIgniter 1.7.2</a></span></p>
<p>Estou há algumas semanas utilizando o framework PHP <a href="http://codeigniter.com/" target="_blank">CodeIgniter</a>. A <a href="http://codeigniter.com/user_guide/" target="_blank">documentação</a> é incrível, muito detalhada e organizada, com muitos exemplos simples, porém poucos exemplos completos, voltados para o mundo real. Senti falta de modelos de CRUD completos, por exemplo.</p>
<p>Mesmo procurando em outros sites, blogs e fóruns, só vi implementações muito básicas, ou utilizando libraries antigas. O melhor que encontrei foi <a href="http://henrihnr.wordpress.com/2009/04/26/simple-crud-application/" target="_blank">este</a>, que usa uma versão anterior do CI (utiliza a classe Validation, que está <em>deprecated</em>). Baseado nesse exemplo, criei um outro modelo de CRUD com paginação, validação e um sistema de exibição de mensagens utilizando o CodeIgniter 1.7.1. É o exemplo que eu gostaria de ter visto quando comecei a conhecer o framework.</p>
<p>Antes de continuar, veja o exemplo funcionando <a href="http://www.robertsonfreitas.com/ci_sandbox/user" target="_blank">aqui</a>.</p>
<p>Disponibilizei o código fonte completo, junto com o codeigniter e o script de criação do banco <a href="http://www.robertsonfreitas.com/files/ci_sandbox.rar" target="_blank">aqui</a>.</p>
<p><span id="more-72"></span>Decidi deixar o conteúdo e os comentários em inglês para alcançar mais pessoas.</p>
<p><strong> </strong></p>
<p><strong> </strong></p>
<p><span style="color: #333399;"><strong>Passo 1 &#8211; Criação do banco de dados</strong></span><strong> </strong></p>
<p>Execute o script abaixo (utilizando o <a href="http://www.google.com/url?sa=t&amp;source=web&amp;ct=res&amp;cd=1&amp;url=http%3A%2F%2Fwww.phpmyadmin.net%2F&amp;ei=DwSSSpDSO4-GlAfBpNClDA&amp;usg=AFQjCNEVUIHBxbZboIeYNUd_4abvz6M1zw" target="_blank">phpMyAdmin</a>, por exemplo) para criar o banco &#8220;<strong>ci_sandbox</strong>&#8220;, criar e popular a tabela &#8220;<strong>users</strong>&#8221; no MySQL 5. Note que estou utilizando codificação UTF-8, que vem configurada por padrão no CodeIgniter (no arquivo <strong>application/config/database.php</strong>).</p>
<pre class="brush: sql;">
CREATE DATABASE `ci_sandbox` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;

CREATE TABLE IF NOT EXISTS `users` (
  `id` int(11) NOT NULL auto_increment,
  `name` varchar(100) NOT NULL,
  `email` varchar(100) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `users` (`id`, `name`, `email`) VALUES
(1, 'Bob', 'bob@bob.com'),
(2, 'Philip', 'philip@philip.com'),
(3, 'Paty', 'paty@paty.com'),
(4, 'Kelly', 'kelly@kelly.com'),
(5, 'Bill', 'bill@bill.com'),
(6, 'Tedd', 'tedd@tedd.com'),
(7, 'John', 'john@john.com'),
(8, 'Paul', 'paul@paul.com'),
(9, 'Anna', 'anna@anna.com'),
(10, 'Hellen', 'hellen@hellen.com'),
(11, 'Kate', 'kate@kate.com');
</pre>
<p><strong> </strong></p>
<p><span style="color: #333399;"><strong>Passo 2 &#8211; Criação do CSS da aplicação</strong></span><strong> </strong></p>
<p>Veja abaixo a folha de estilo usada na listagem, paginação e mensagens (arquivo <strong>css/style.css</strong>):</p>
<pre class="brush: css;">
*{
    margin: 0;
    padding: 0;
}

body {
    background:#FFFFFF;
    font-family:verdana,arial,helvetica,sans-serif;
    font-size:10px;
    margin:2px;
    padding:2px;
}

#container h1 {
    color:#678197;
    border: 2px solid #E5EFF8;
    margin-bottom: 10px;
    padding: 5px;
    width: 686px;
    _width: 700px;
    background-color: #F2F6F7;
    font-size: 20px;
}

#listing {
    width:700px;
    color:#678197;
    font-family:verdana,arial,helvetica,sans-serif;
    font-size:8pt;
    border-spacing: 0px;
    border: 1px solid #E5EFF8;
}

#listing td {
    padding:5px;
    font-size:8pt;
    border: 1px solid #E5EFF8;
}
#listing th {
    color:#21497D;
    font-weight:bold;
    background:#F2F6F7;
    font-size:8pt;
    padding:5px;
    text-align: left;
    border: 1px solid #E5EFF8;
}

ul {
    border:0; margin:0; padding:0;
}

#pagination li {
    border:0; margin:0; padding:0;
    font-size:11px;
    list-style:none;
    float:left;
}

#pagination a {
    border:solid 1px #DDDDDD;
    margin-right:2px;
}

#pagination .previous-off, #pagination .next-off {
    color:#666666;
    display:block;
    float:left;
    font-weight:bold;
    padding:3px 4px;
}

#pagination .next a, #pagination .previous a {
    font-weight:bold;
    border:solid 1px #FFFFFF;
}

#pagination .active {
    color:#ff0084;
    font-weight:bold;
    display:block;
    float:left;
    padding:4px 6px;
}

#pagination a:link, #pagination a:visited {
    color:#678197;
    display:block;
    float:left;
    padding:3px 6px;
    text-decoration:none;
}

#pagination a:hover {
    border:solid 1px #666666;
}

.error_field {
    padding:5px;
    margin-bottom:3px;
    margin-top:3px;
    border: 1px solid red;
    background: yellow;
    width: 300px;
}

/* Content Elements: Messages */

.message, .warning, .success, .error {
    width: 690px;
    _width: 700px;
    padding: 5px;
    margin-bottom: 3px;
    font-size: 12px;
}

.message {
    color: #ffffff;
    background-color: #aaa9a6;
}

.warning {
    color: #ffffff;
    background-color: #ff9900;
}

.success {
    color: #ffffff;
    background-color: #009000;
}

.error {
    color: #ffffff;
    background-color: #900000;
}
</pre>
<p><strong> </strong></p>
<p><span style="color: #333399;"><strong>Passo 3 &#8211; Instalação da Library e do Helper Message</strong></span></p>
<p>Para facilitar o envio e a exibição de mensagens para o usuário, encontrei esta prática biblioteca chamada Message no Wiki (<a href="http://codeigniter.com/wiki/Messages/" target="_blank">confira</a>) do Codeigniter, e no fórum encontrei um Helper (<a href="http://codeigniter.com/forums/viewthread/84694/" target="_blank">confira</a>) para reduzir a exibição de código nas views.</p>
<p>Crie o arquivo <strong>application/libraries/messages.php</strong> com o conteúdo abaixo:</p>
<pre class="brush: php;">
&lt;?php if (!defined('BASEPATH')) exit('No direct script access allowed');

/**
* Message:: a class for writing feedback message information to the session
*
* Copyright 2006 Vijay Mahrra &amp;amp; Sheikh Ahmed &lt;webmaster@designbyfail.com&gt;
*
* See the enclosed file COPYING for license information (LGPL).  If you
* did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
*
* @author  Vijay Mahrra &amp;amp; Sheikh Ahmed &lt;webmaster@designbyfail.com&gt;
* @url http://www.designbyfail.com/
* @version 1.0
*/

class Messages
{
    var $_ci;
    var $_types = array('success', 'error', 'warning', 'message');

    function Messages($params = array())
    {
        $this-&gt;_ci =&amp;amp; get_instance();
        $this-&gt;_ci-&gt;load-&gt;library('session');
        // check if theres already messages, if not, initialise the messages array in the session
        $messages = $this-&gt;_ci-&gt;session-&gt;userdata('messages');
        if (empty($messages)) {
            $this-&gt;clear();
        }
    }

    // clear all messages
    function clear()
    {
        $messages = array();
        foreach ($this-&gt;_types as $type) {
            $messages[$type] = array();
        }
        $this-&gt;_ci-&gt;session-&gt;set_userdata('messages', $messages);
    }

    // add a message, default type is message
    function add($message, $type = 'message')
    {
        $messages = $this-&gt;_ci-&gt;session-&gt;userdata('messages');
        // handle PEAR errors gracefully
        if (is_a($message, 'PEAR_Error')) {
            $message = $message-&gt;getMessage();
            $type = 'error';
        } else if (!in_array($type, $this-&gt;_types)) {
            // set the type to message if the user specified a type that's unknown
            $type = 'message';
        }
        // don't repeat messages!
        if (!in_array($message, $messages[$type]) &amp;amp;&amp;amp; is_string($message)) {
            $messages[$type][] = $message;
        }
        $messages = $this-&gt;_ci-&gt;session-&gt;set_userdata('messages', $messages);
    }

    // return messages of given type or all types, return false if none
    function sum($type = null)
    {
        $messages = $this-&gt;_ci-&gt;session-&gt;userdata('messages');
        if (!empty($type)) {
            $i = count($messages[$type]);
            return $i;
        }
        $i = 0;
        foreach ($this-&gt;_types as $type) {
            $i += count($messages[$type]);
        }
        return $i;
    }

    // return messages of given type or all types, return false if none, clearing stack
    function get($type = null)
    {
        $messages = $this-&gt;_ci-&gt;session-&gt;userdata('messages');
        if (!empty($type)) {
            if (count($messages[$type]) == 0) {
                return false;
            }
            return $messages[$type];
        }
        // return false if there actually are no messages in the session
        $i = 0;
        foreach ($this-&gt;_types as $type) {
            $i += count($messages[$type]);
        }
        if ($i == 0) {
            return false;
        }

        // order return by order of type array above
        // i.e. success, error, warning and then informational messages last
        foreach ($this-&gt;_types as $type) {
            $return[$type] = $messages[$type];
        }
        $this-&gt;clear();
        return $return;
    }
}
</pre>
<p>Crie o arquivo <strong>application/helpers/msg_helper.php</strong> com o conteúdo abaixo:</p>
<pre class="brush: php;">
&lt;?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

if ( ! function_exists('output_msg')) {
    function output_msg($type = null) {
        $CI =&amp;amp; get_instance();

        if ($CI-&gt;messages-&gt;sum($type) &gt; 0) {
        $messages = $CI-&gt;messages-&gt;get($type);
        // display all messages of the type
        if (is_array($messages)) {
            $output = '';
            foreach ($messages as $type =&gt; $msgs) {
                if (count($msgs) &gt; 0) {
                    $output .= '&lt;div class=&amp;quot;' . $type . '&amp;quot;&gt;';
                    $output .= '&lt;ul&gt;';
                    foreach ($msgs as $message) {
                        $output .= $message;
                    }
                    $output .= '&lt;/ul&gt;';
                    $output .= '&lt;/div&gt;';
                }
            }
        }
        return $output;
        }
    }
}
</pre>
<p><strong> </strong></p>
<p><span style="color: #333399;"><strong>Passo 4 &#8211; Criação do Model</strong></span></p>
<p>O model anêmico abaixo (que está mais para um Active Record Layer), incrivelmente reusável, foi <span style="text-decoration: line-through;">inspirado no</span> copiado do <a href="http://henrihnr.wordpress.com/2009/04/26/simple-crud-application/" target="_blank">exemplo de CRUD</a> que mencionei acima. Controller gordo + Model magro é considerado um anti-pattern, mas eu gosto que as coisas estejam distribuídas assim, e o CodeIgniter, pelo que vi no manual, também. (O que você acha?)</p>
<p>Arquivo <strong>application/models/user_model.php</strong></p>
<pre class="brush: php;">
&lt;?php
class User_model extends Model {

    private $table = 'users';

    function User_model() {
        parent::Model();
    }

    function list_all($order_by = 'id') {
        $this-&gt;db-&gt;order_by($order_by,'asc');
        return $this-&gt;db-&gt;get($table);
    }

    function count_all() {
        return $this-&gt;db-&gt;count_all($this-&gt;table);
    }

    function get_paged_list($limit = 10, $offset = 0, $order_by = 'id') {
        $this-&gt;db-&gt;order_by($order_by,'asc');
        return $this-&gt;db-&gt;get($this-&gt;table, $limit, $offset);
    }

    function get_by_id($id) {
        $this-&gt;db-&gt;where('id', $id);
        return $this-&gt;db-&gt;get($this-&gt;table);
    }

    function save($obj) {
        $this-&gt;db-&gt;insert($this-&gt;table, $obj);
        return $this-&gt;db-&gt;insert_id();
    }

    function update($id, $obj) {
        $this-&gt;db-&gt;where('id', $id);
        $this-&gt;db-&gt;update($this-&gt;table, $obj);
    }

    function delete($id) {
        $this-&gt;db-&gt;where('id', $id);
        $this-&gt;db-&gt;delete($this-&gt;table);
    }
}
?&gt;
</pre>
<p><strong> </strong></p>
<p><span style="color: #333399;"><strong>Passo 5 &#8211; Criação da view para listagem</strong></span></p>
<p>Nesta view é exibida a listagem paginada. Note a simplicidade da exibição de mensagens através da função <strong>output_msg</strong>, do Helper que instalamos acima.</p>
<p>Arquivo <strong>application/views/user_list.php</strong></p>
<pre class="brush: php;">
&lt;html xmlns=&amp;quot;http://www.w3.org/1999/xhtml&amp;quot;&gt;
&lt;head&gt;
    &lt;meta http-equiv=&amp;quot;content-type&amp;quot; content=&amp;quot;text/html; charset=utf-8&amp;quot; /&gt;
    &lt;title&gt;User List&lt;/title&gt;
    &lt;link href=&amp;quot;&lt;?php echo base_url(); ?&gt;css/style.css&amp;quot; rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; /&gt;
    &lt;script&gt;
        function remove(id) {
            if (confirm(&amp;quot;Are you sure?&amp;quot;)) {
                window.location = '&lt;?php echo base_url(); ?&gt;user/delete/'+id;
            }
        }
    &lt;/script&gt;
&lt;/head&gt;

&lt;body&gt;

&lt;?php
    // show user messages sent by controller
    echo output_msg($type = null);
?&gt;

&lt;div id=&amp;quot;container&amp;quot;&gt;
    &lt;h1&gt;USER LIST&lt;/h1&gt;
    &lt;table id=&amp;quot;listing&amp;quot; cellspacing=0&gt;
        &lt;tr&gt;
            &lt;th width=45%&gt;Name&lt;/th&gt;
            &lt;th width=45%&gt;E-mail&lt;/th&gt;
            &lt;th width=10%&gt;Actions&lt;/th&gt;
        &lt;/tr&gt;
        &lt;?php foreach($list as $user): ?&gt;
            &lt;tr&gt;
                &lt;td&gt;&lt;?php echo $user-&gt;name; ?&gt;&lt;/td&gt;
                &lt;td&gt;&lt;?php echo $user-&gt;email; ?&gt;&lt;/td&gt;
                &lt;td align=&amp;quot;center&amp;quot;&gt;
                    &lt;a href=&amp;quot;&lt;?php echo base_url(); ?&gt;user/prepareUpdate/&lt;?php echo $user-&gt;id; ?&gt;&amp;quot;&gt;&lt;img src=&amp;quot;&lt;?php echo base_url(); ?&gt;i/icon/b_edit.png&amp;quot; border=0 title=&amp;quot;Edit&amp;quot;&gt;&lt;/a&gt;
                    &lt;a href=&amp;quot;#&amp;quot; onclick=&amp;quot;remove(&lt;?php echo $user-&gt;id; ?&gt;);&amp;quot;&gt;&lt;img src=&amp;quot;&lt;?php echo base_url(); ?&gt;i/icon/b_drop.png&amp;quot; border=0 title=&amp;quot;Delete&amp;quot;&gt;&lt;/a&gt;
                &lt;/td&gt;
            &lt;/tr&gt;
        &lt;?php endforeach ?&gt;
    &lt;/table&gt;
    &lt;div style=&amp;quot;padding:10px;&amp;quot;&gt;&lt;?php echo $pagination; ?&gt;&lt;br clear=&amp;quot;all&amp;quot; /&gt;&lt;/div&gt;
    &lt;input type=button onclick=&amp;quot;location.href='&lt;?php echo base_url(); ?&gt;user/prepareInsert/';&amp;quot; value=&amp;quot;New User&amp;quot;&gt;
&lt;/div&gt;

&lt;/body&gt;
&lt;/html&gt;
</pre>
<p><strong> </strong></p>
<p><span style="color: #333399;"><strong>Passo 6 &#8211; Criação da view contendo o formulário de cadastro e edição</strong></span></p>
<p>Esta view contém o formulário que será exibido para criar e editar usuários. Observe o uso da variável <strong>$values</strong>, que contém as informações para popular os campos com os dados do item.</p>
<p>Arquivo <strong>application/views/user_form.php</strong></p>
<pre class="brush: php;">
&lt;html xmlns=&amp;quot;http://www.w3.org/1999/xhtml&amp;quot;&gt;
&lt;head&gt;
    &lt;meta http-equiv=&amp;quot;content-type&amp;quot; content=&amp;quot;text/html; charset=utf-8&amp;quot; /&gt;
    &lt;title&gt;&lt;?php echo $title; ?&gt;&lt;/title&gt;
    &lt;link href=&amp;quot;&lt;?php echo base_url(); ?&gt;css/style.css&amp;quot; rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; /&gt;
&lt;/head&gt;

&lt;body&gt;

&lt;?php
    // show user messages sent by controller
    echo output_msg($type = null);
?&gt;

&lt;form method=&amp;quot;post&amp;quot; action=&amp;quot;&lt;?php echo $action; ?&gt;&amp;quot;&gt;
    &lt;div id=&amp;quot;container&amp;quot;&gt;
        &lt;h1&gt;&lt;?php echo $title; ?&gt;&lt;/h1&gt;
                &lt;label&gt;Name*&lt;/label&gt;&lt;br&gt;
                &lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;name&amp;quot; value=&amp;quot;&lt;?php echo $values['name']; ?&gt;&amp;quot; style=&amp;quot;width:500px;&amp;quot; maxlength=&amp;quot;100&amp;quot;&gt;
                &lt;?php echo form_error('name'); ?&gt;&lt;br&gt;&lt;br&gt;

                &lt;label&gt;E-mail*&lt;/label&gt;&lt;br&gt;
                &lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;email&amp;quot; value=&amp;quot;&lt;?php echo $values['email']; ?&gt;&amp;quot; style=&amp;quot;width:500px;&amp;quot; maxlength=&amp;quot;100&amp;quot;&gt;
                &lt;?php echo form_error('email'); ?&gt;&lt;br&gt;&lt;br&gt;

                &lt;input type=submit value=&amp;quot; Save &amp;quot;&gt;

                &lt;input type=button onclick=&amp;quot;location.href='&lt;?php echo base_url(); ?&gt;user/index/';&amp;quot; value=&amp;quot;Back to listing&amp;quot; style=&amp;quot;margin-left:20px;&amp;quot;&gt;
    &lt;/div&gt;
    &lt;input type=hidden name=id value=&amp;quot;&lt;?php echo $values['id']; ?&gt;&amp;quot;&gt;
&lt;/form&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<p><strong> </strong></p>
<p><span style="color: #333399;"><strong>Passo 7 &#8211; O Controller</strong></span></p>
<p>O controller começa com duas variáveis de configuração: quantidade de linhas exibidas por página na listagem (<strong>$limit</strong>) e nome da coluna que determinará a ordenação da listagem (<strong>$order_by</strong>).</p>
<p>No construtor, carregamos as libraries e helpers necessários.</p>
<p>Confira o papel de cada método:</p>
<p>O <strong>index()</strong> prepara os dados da paginação, invoca os dados do modelo e transfere esses dados para a view <strong>user_list.php</strong>.</p>
<p>O <strong>prepareInsert()</strong> monta um formulário de cadastro em branco.</p>
<p>O <strong>prepareUpdate()</strong> consulta o modelo e monta um formulário preenchido com os dados do <strong>$id</strong> solicitado.</p>
<p>O <strong>insert()</strong> e o <strong>update()</strong> são apenas chamadas para o <strong>_save()</strong>. Foram criados assim para facilitar a visualização e compreensão do fluxo da aplicação.</p>
<p>O método privado <strong>_save()</strong> cria ou edita um item, de acordo com a <strong>$action</strong> solicitada. Nesse método são configuradas as regras de validação dos dados vindos do formulário.</p>
<p>O <strong>delete() </strong>exclui o item com o <strong>$id</strong> informado, e retorna para a listagem de usuários.</p>
<p>Arquivo <strong>application/controllers/user.php</strong></p>
<pre class="brush: php;">
&lt;?php
    class User extends Controller {

        // records per page
        private $limit = 5;

        // column to order by at listing
        private $order_by = 'name';

        function User()  {
            parent::Controller();

            $this-&gt;load-&gt;database();
            $this-&gt;load-&gt;library('form_validation');
            $this-&gt;load-&gt;helper('url');

            // send and show messages to user
            $this-&gt;load-&gt;library('messages');
            $this-&gt;load-&gt;helper('msg');

            $this-&gt;load-&gt;model('user_model', '', TRUE);
        }

        function index($offset = 0) {
            $data = array();

            // http://localhost/ci_sandbox/index/(offset)
            $uri_segment = 3;
            // where this page begins
            $offset = $this-&gt;uri-&gt;segment($uri_segment);

            // load data list
            $data['list'] = $this-&gt;user_model-&gt;get_paged_list($this-&gt;limit, $offset, $this-&gt;order_by)-&gt;result();

            // generate pagination
            $this-&gt;load-&gt;library('pagination');
            $config['base_url'] = site_url('user/index/');
             $config['total_rows'] = $this-&gt;user_model-&gt;count_all();
             $config['per_page'] = $this-&gt;limit;
            $config['uri_segment'] = $uri_segment;
            $this-&gt;pagination-&gt;initialize($config);
            $data['pagination'] = $this-&gt;pagination-&gt;create_links();

            $this-&gt;load-&gt;view('user_list',$data);

        }

        function prepareInsert() {
            // set validation properties
            $data['values']['id'] = '';
            $data['values']['name'] = '';
            $data['values']['email'] = '';

            // set common properties
            $data['title'] = 'NEW USER';
            $data['action'] = site_url('user/insert');

            $this-&gt;load-&gt;view('user_form', $data);
        }

        function prepareUpdate($id) {

            // prefill form values
            $obj = $this-&gt;user_model-&gt;get_by_id($id)-&gt;row();
            $data['values']['id'] = $id;
            $data['values']['name'] = $obj-&gt;name;
            $data['values']['email'] = $obj-&gt;email;

            // set common properties
            $data['title'] = 'EDIT USER';
            $data['action'] = site_url('user/update');

            $this-&gt;load-&gt;view('user_form', $data);
        }

        function insert() {
            $this-&gt;_save('insert');
        }

        function update() {
            $this-&gt;_save('update');
        }

        function _save($action = 'insert') {
            // set common properties
            if ($action == 'update') {
                $data['title'] = 'EDIT USER';
                $data['action'] = site_url('user/update');
            } else {
                $data['title'] = 'NEW USER';
                $data['action'] = site_url('user/insert');
            }

            // set validation properties
            $this-&gt;form_validation-&gt;set_rules('id','','');
            $this-&gt;form_validation-&gt;set_rules('name','Name','trim|required|max_length[100]|xss_clean');
            $this-&gt;form_validation-&gt;set_rules('email','E-mail','trim|required|max_length[100]|valid_email|xss_clean');
            $this-&gt;form_validation-&gt;set_error_delimiters('&lt;p class=&amp;quot;error_field&amp;quot;&gt;', '&lt;/p&gt;');

            // run validation
            if ($this-&gt;form_validation-&gt;run() == FALSE) {
                $data['values']['name'] = set_value('name');
                $data['values']['email'] = set_value('email');
                $data['values']['id'] = set_value('id');

                $this-&gt;load-&gt;view('user_form', $data);
            } else {
                // save data
                if ($action == 'update') {
                    $id = $this-&gt;input-&gt;post('id');
                }
                $obj = array(
                    'name' =&gt; $this-&gt;input-&gt;post('name'),
                    'email' =&gt; $this-&gt;input-&gt;post('email')
                );
                if ($action == 'update') {
                    $this-&gt;user_model-&gt;update($id, $obj);
                } else {
                    $id = $this-&gt;user_model-&gt;save($obj);
                }

                // set user message
                if ($action == 'update') {
                    $this-&gt;messages-&gt;add('User updated', 'success');
                } else {
                    $this-&gt;messages-&gt;add('User created', 'success');
                }

                // redirect to list page
                redirect('user/index/','refresh');
            }

        }

        function delete($id) {
            $this-&gt;user_model-&gt;delete($id);

            // set user message
            $this-&gt;messages-&gt;add('User removed', 'success');

            // redirect to list page
            redirect('user/index/','refresh');
        }

    }
?&gt;
</pre>
<p>Espero que esse exemplo simples seja útil para quem está iniciando, e que os mais experientes comentem e sugiram melhorias.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.robertsonfreitas.com/2009/08/24/crud-basico-com-codeigniter/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Acessando o MySQL pelo Eclipse com o plugin SQL Explorer</title>
		<link>http://blog.robertsonfreitas.com/2009/07/23/acessando-o-mysql-pelo-eclipse-com-o-plugin-sql-explorer/</link>
		<comments>http://blog.robertsonfreitas.com/2009/07/23/acessando-o-mysql-pelo-eclipse-com-o-plugin-sql-explorer/#comments</comments>
		<pubDate>Thu, 23 Jul 2009 21:37:35 +0000</pubDate>
		<dc:creator>Robertson Freitas</dc:creator>
				<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[Produtividade]]></category>
		<category><![CDATA[explorer]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[sql]]></category>
		<category><![CDATA[sql explorer]]></category>

		<guid isPermaLink="false">http://blog.robertsonfreitas.com/?p=52</guid>
		<description><![CDATA[O SQL Explorer é um plugin que permite acessar e fazer consultas SQL a bancos de dados a partir do Eclipse. Veja abaixo os passos para instalar e configurar a conexão ao banco. Utilizei o Eclipse Ganymede (3.4.1).
Instalando o plugin
- Acesse o menu Help &#62; Software Updates&#8230;
- Na aba Available Software, clique no botão Add [...]]]></description>
			<content:encoded><![CDATA[<p>O SQL Explorer é um plugin que permite acessar e fazer consultas SQL a bancos de dados a partir do Eclipse. Veja abaixo os passos para instalar e configurar a conexão ao banco. Utilizei o Eclipse Ganymede (3.4.1).</p>
<div id="attachment_59" class="wp-caption alignnone" style="width: 432px"><a href="http://blog.robertsonfreitas.com/wp-content/uploads/sql_explorer_eclipse.png" target="_blank"><img class="size-full wp-image-59" title="Sql Explorer" src="http://blog.robertsonfreitas.com/wp-content/uploads/sql_explorer_mini2.png" alt="SQL Explorer - clique na imagem para ampliar" width="422" height="254" /></a><p class="wp-caption-text">SQL Explorer - clique na imagem para ampliar</p></div>
<p><strong><span id="more-52"></span>Instalando o plugin</strong><br />
- Acesse o menu Help &gt; Software Updates&#8230;<br />
- Na aba Available Software, clique no botão Add Site&#8230;<br />
- Informe no campo Location o endereço http://eclipsesql.sourceforge.net/ e clique OK.<br />
- A opção SQLExplorer Updates aparecerá na listagem. Dentro desta opção, selecione Eclipse SQL Explorer e Eclipse SQL Explorer RC6 P6<br />
- Clique no botão Install&#8230;<br />
- Confirme os plugins e clique Next<br />
- Aceite a licença e clique em Finish<br />
- Reinicie o Eclipse</p>
<p><strong>Configurando o conector do MySQL</strong><br />
- Acesse o menu Window &gt; Preferences<br />
- Acesse a opção SQL Explorer &gt; JDBC Drivers<br />
- Selecione a opção MySQL Driver e clique no botão Edit<br />
- Se você não tem um conector ainda, baixe um do site do MySQL&lt;http://dev.mysql.com/downloads/connector/j/5.1.html&gt;<br />
- Na aba Extra Class Path, clique no botão New<br />
- Selecione o caminho do arquivo jar do conector<br />
- Após informar o arquivo, clique no botão List Drivers<br />
- Selecione o driver apropriado (normalmente com.mysql.jdbc.Driver)<br />
- Clique no botão OK para concluir.</p>
<p><strong> </strong></p>
<p><strong>Configurando uma conexão ao MySQL</strong><br />
- Acesse o menu Window &gt; Open Perspective &gt; Other<br />
- Selecione a perspectiva SQL Explorer<br />
- Na janela Connections, clique com o botão direito do mouse e selecione a opção New Connection Profile&#8230;<br />
- Dê um nome para a conexão, selecione o driver do MySQL<br />
- Informe a URL do banco (exemplo: jdbc:mysql://localhost:3306/nome_do_banco)<br />
- Informe o usuário no campo User<br />
- Expanda a árvore da conexão criada, clique com o botão direito do mouse sobre o usuário root, Connect<br />
- Após informar a senha, você estará conectado ao banco<br />
- Faça suas consultas na janela SQL Editor<br />
- Se uma janela SQL Editor não abrir automaticamente, botão direito sobre o nome da conexão &gt; New SQL Editor</p>
<p>Passei algumas horas usando o plugin. Embora eu saiba que os propósitos das duas ferramentas sejam diferentes, cheguei à conclusão de que nada substitui o <a href="http://www.google.com/url?sa=t&amp;source=web&amp;ct=res&amp;cd=1&amp;url=http%3A%2F%2Fwww.phpmyadmin.net%2F&amp;ei=aJVpSsaJGtCStgeo-py4Cw&amp;usg=AFQjCNEVUIHBxbZboIeYNUd_4abvz6M1zw&amp;sig2=erSpAgqyP7rXQjeMXQQH6w" target="_blank">phpMyAdmin</a>, que tem wizards para tudo.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.robertsonfreitas.com/2009/07/23/acessando-o-mysql-pelo-eclipse-com-o-plugin-sql-explorer/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Acessando FTP, SFTP e SSH via Eclipse</title>
		<link>http://blog.robertsonfreitas.com/2009/07/18/acessando-ftp-sftp-ssh-via-eclipse/</link>
		<comments>http://blog.robertsonfreitas.com/2009/07/18/acessando-ftp-sftp-ssh-via-eclipse/#comments</comments>
		<pubDate>Sat, 18 Jul 2009 22:47:48 +0000</pubDate>
		<dc:creator>Robertson Freitas</dc:creator>
				<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[Produtividade]]></category>
		<category><![CDATA[FTP]]></category>
		<category><![CDATA[Remote System]]></category>
		<category><![CDATA[SSH]]></category>

		<guid isPermaLink="false">http://robertsonfreitas.wordpress.com/?p=29</guid>
		<description><![CDATA[Uma dica da série Pragmatic Programming: aumente sua produtividade acessando seu servidor  SSH ou FTP a partir do Eclipse com o Remote System Explorer.
Utilizando o Remote System Explorer você pode:
- Conectar-se a servidores Windows/Linux/Unix remotamente.
- Explorar o sistema de arquivos desses servidores.
- Editar e salvar arquivos remotamente.
- Abrir um terminal e executar comandos remotamente [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_32" class="wp-caption alignright" style="width: 248px"><img class="size-full wp-image-32" title="imagemxx" src="http://blog.robertsonfreitas.com/wp-content/imagemxx.png" alt="Eclipse Remote Systems Explorer" width="238" height="317" /><p class="wp-caption-text">Eclipse Remote Systems Explorer</p></div>
<p>Uma dica da série <em>Pragmatic Programming</em>: aumente sua produtividade acessando seu servidor  SSH ou FTP a partir do Eclipse com o <em>Remote System Explorer</em>.</p>
<p>Utilizando o <em>Remote System Explorer</em> você pode:</p>
<p>- Conectar-se a servidores Windows/Linux/Unix remotamente.<br />
- Explorar o sistema de arquivos desses servidores.<br />
- Editar e salvar arquivos remotamente.<br />
- Abrir um terminal e executar comandos remotamente (adeus Putty!).</p>
<p>A funcionalidade é parte do <a href="http://www.eclipse.org/dsdp/tm/" target="_blank">Target Management</a> que, por sua vez, é um subprojeto do Device Software Development Platform (<a href="http://www.eclipse.org/dsdp/" target="_blank">DSDP</a>).</p>
<p><span id="more-29"></span>Nos passos descritos a seguir, usei o Eclipse Ganymede (3.4.1). No Galileo (3.5.0), os passos devem ser parecidos.</p>
<p><strong>Instalando o plugin</strong><br />
Acesse o menu Help &gt; Software Updates&#8230;<br />
Na aba Available Software, clique no [+] da fonte http://download.eclipse.org/releases/ganymede<br />
Clique no [+] da seção Remote Access and Device Development<br />
Marque a opção Remote System Explorer End-User Runtime<br />
Clique no botão Install&#8230;</p>
<p><strong>Abrindo a view</strong><br />
Após a instalação, acesse o menu Window &gt; Show View &gt; Other&#8230;<br />
Dentro da pasta Remote Systems, selecione a view Remote Systems.</p>
<p><strong>Configurando uma conexão FTP</strong><br />
Dentro da view Remote Systems, clique com o botão direito do mouse e selecione New &gt; Connection&#8230;<br />
Selecione General &gt; FTP Only, botão Next.<br />
Informe os dados do host, botão Next, botão Finish.<br />
Para se conectar ao servidor, botão direito sobre o nome da conexão, opção Connect. Informe usuário e senha.</p>
<p>Você pode transferir os arquivos arrastando de qualquer view Explorer para dentro da pasta da view Remote Systems, ou com Ctrl+C no arquivo local, Ctrl+V na pasta remota. Você ainda pode editar os arquivos diretamente no servidor.</p>
<p><strong>Configurando uma conexão SFTP ou SSH:</strong></p>
<div id="attachment_44" class="wp-caption alignnone" style="width: 369px"><img class="size-full wp-image-44 " title="Terminal SSH" src="http://blog.robertsonfreitas.com/wp-content/uploads/3b.png" alt="Terminal SSH" width="359" height="200" /><p class="wp-caption-text">Terminal SSH</p></div>
<p>Dentro da view Remote Systems, clique com o botão direito do mouse e selecione New &gt; Connection&#8230;<br />
Selecione General &gt; SSH Only, botão Next.<br />
Informe os dados do host, botão Next, botão Finish.<br />
Para se conectar ao servidor, botão direito sobre o nome da conexão, opção Connect. Informe usuário e senha.</p>
<p>Para abrir um terminal, botão direito sobre a opção Ssh Terminals, Lauch Terminal.</p>
<p>A dica foi útil para você?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.robertsonfreitas.com/2009/07/18/acessando-ftp-sftp-ssh-via-eclipse/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Hello world!</title>
		<link>http://blog.robertsonfreitas.com/2009/07/18/hello-world/</link>
		<comments>http://blog.robertsonfreitas.com/2009/07/18/hello-world/#comments</comments>
		<pubDate>Sat, 18 Jul 2009 14:21:59 +0000</pubDate>
		<dc:creator>Robertson Freitas</dc:creator>
				<category><![CDATA[Geral]]></category>

		<guid isPermaLink="false">http://blog.robertsonfreitas.com/?p=4</guid>
		<description><![CDATA[Olá, sou Robertson Freitas, trabalho como gerente de produto na Fortes Informática e me interesso por desenvolvimento web, especialmente utilizando PHP e Java.
Neste blog quero publicar minhas  opiniões e dicas nas áreas de produtividade, processos de desenvolvimento de software e PHP.
Aguarde novidades.
]]></description>
			<content:encoded><![CDATA[<p>Olá, sou Robertson Freitas, trabalho como gerente de produto na Fortes Informática e me interesso por desenvolvimento web, especialmente utilizando PHP e Java.</p>
<p>Neste blog quero publicar minhas  opiniões e dicas nas áreas de produtividade, processos de desenvolvimento de software e PHP.</p>
<p>Aguarde novidades.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.robertsonfreitas.com/2009/07/18/hello-world/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
