terça-feira, setembro 28, 2010

Tutorial CodeIgniter - Parte 3

Neste post, vamos criar as funções que irão realizar as operações inserir, atualizar e deletar os registros da tabela bacia_hidrografica.

Antes de começarmos a criar as funções, vamos habilitar a biblioteca "session" do codeigniter e o helper "form", para isso, abra o arquivo autoload.php e modifique as linhas 42 e 54, respectivamente para:

$autoload['libraries'] = array('database', 'session');
$autoload['helper'] = array('url', 'form');

Vamos começar definindo uma função no model que será responsável por inserir os registros na tabela, abra o arquivo bacia_model.php e adicione a seguinte função:

function insert()
{
  $data = $_POST;
  return $this->db->insert('bacia_hidrografica', $data);
}

Já a função abaixo, retorna a linha da tabela com o id_bacia informado, ela será usada para povoar o campo "nome da bacia" do formulário de atualização:

function get_where($id)
{
    $this->db->where('id_bacia', $id);
    $query = $this->db->get('bacia_hidrografica');
    return $query->row();
}

Para realizar o update, usaremos a função abaixo:
function update($id)
{
    $data = $_POST;
    $this->db->where('id_bacia', $id);
    $this->db->update('bacia_hidrografica', $data);
}

Para deletar um registro desta tabela, primeiro faz-se necessário verificar se a mesma não possui nenhum rio vinculado, pois isso vai gerar uma mensagem de erro vinda do banco de dados, em função da constraint foreign key, logo criaremos a função abaixo que fará essa verificação de vínculo:

function verifica_fk($id)
{
    $this->db->where('id_bacia', $id);
    $query = $this->db->get('rio');
    if ($query->num_rows > 0)
    {
        // se houver fk, retorne falso
        return false;
    } else
    {
        return true;
    }
} 

De posse da função acima,  criaremos a função delete():

function delete($id)
{
   // se for verdadeiro, pode apagar o registro
   if ($this->verifica_fk($id))
   {
      $this->db->where('id_bacia', $id);
      return $this->db->delete('bacia_hidrografica');
   }
   else
   {
      return false;
   }
}

Agora, vamos criar duas funções no controller bacia.php, uma para chamar o formulário que será utilizado para a inserção de novos registros, e a outra, que será responsável por efetivar esta operação, através da função definida no model anteriormente (função insert() ):

OBS: Não vamos usar nenhuma função de validação dos dados nesse momento, este será um assunto abordado em um próximo post.

function criar()
{
    $data['titulo'] = "SIRH - Nova Bacia Hidrográfica";
    $data['cabecalho'] = "Criar nova Bacia Hidrográfica";
    $this->load->view('bacia_new', $data);
}

function insere()
{
    $this->bacia_model->insert();
    $this->session->set_flashdata('msg', 'Registro Criado com Sucesso!');
    redirect('bacia');
}

Seguindo o mesmo raciocínio, para realizar a atualização dos registros, vamos criar mais duas funções no controller, editar() e atualizar():

function editar($id)
{
    $data['titulo'] = "SIRH - Editar Bacia Hidrográfica";
    $data['cabecalho'] = "Editar Bacia Hidrográfica";

    $data['registro'] = $this->bacia_model->get_where($id);

    $this->load->view('bacia_new', $data);
}

function atualizar()
{
    $id = $this->input->post('id_bacia');

    $this->bacia_model->update($id);
    $this->session->set_flashdata('msg', 'Registro Atualizado com Sucesso!');
    redirect('bacia');
}

Criamos então a view bacia_new.php, que tanto servirá para inserir, quanto para atualizar, isso é feito através da verificação da existência da variável $registro->id_bacia:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title><?= $titulo ?></title>
    </head>
    <body>
        <h2><?= $cabecalho ?></h2>
        <?php
            //verifica se o form vai ser usado para insert ou update
            if (!isset($registro->id_bacia))
            {
                echo form_open('bacia/insere');
            }
            else
            {
                echo form_open('bacia/atualizar');
                echo form_hidden('id_bacia', $registro->id_bacia);
            }
        ?>
        <p><label>Nome da Bacia:</label>
            <input name="nome_bacia" type="text" id="nome_bacia" size="40" value="<?= @$registro->nome_bacia ?>" />
        </p>

        <p>
            <input type="submit" id="Enviar" value="Enviar" />
        </p>

        <?= form_close() ?>
    </body>
</html>

Finalizando o controller bacia.php, adicionamos a função deletar(), que vai chamar a função delete() do model:

function deletar($id)
{
    if ($this->bacia_model->delete($id))
    {
        $this->session->set_flashdata('msg', 'Registro Deletado com Sucesso!');
    }
    else
    {
        $this->session->set_flashdata('msg', 'ERRO - Não foi possível deletar este registro!<br/>
                                              Primeiro apague os Rios que se relacionam com esta Bacia');
    }
    redirect('bacia');
}

Para terminar, abra o arquivo bacia_view.php e logo abaixo do cabeçalho, chame a função que irá exibir as mensagens para as operações realizadas pelo usuário:

 <p><?=@$this->session->flashdata('msg');?></p>  


Pronto!!! Já temos um CRUD funcional para a tabela bacia_hidrografica, porém sem a validação dos formulários, isso será o assunto da próxima postagem, até lá!

domingo, setembro 26, 2010

Tutorial CodeIgniter - parte 2

Vamos dar continuidade ao desenvolvimento da aplicação usando o CodeIgniter, na pasta sirh/system/application/controllers crie o arquivo bacia.php com o conteúdo abaixo:

<?php
class Bacia extends CI_Controller
{

    function __construct()
    {
        parent::__construct();
    }

    function index()
    {
        echo "<h1>Testando... 1, 2, 3</h1>";
    }
}
 No código anterior, criamos o controlador bacia, com a função index, que é exibida por default quando o controlador é chamado. Logo ao digitarmos a url:  http://localhost/sirh/index.php/bacia, veremos a mensagem de teste (Figura 1).

Figura 1 - teste do controlador bacia
Testado o funcionamento do controller bacia, vamos adicionar o cabeçalho e título da nossa página, modificando o código da função index:

function index()
{
  $data['titulo'] = "SIRH";
  $data['cabecalho'] = "Bacias Hidrográficas";

  $this->load->view('bacia_view', $data);
}

agora, dentro da pasta views, em sirh/system/application/, crie um arquivo com o nome bacia_view.php, com o seguinte conteúdo:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
   <head>
       <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
       <title><?=$titulo?></title>
   </head>

   <body>
      <h2><?=$cabecalho?></h2>
   </body>
</html>

Abra mais uma vez o endereço http://localhost/sirh/index.php/bacia , o resultado deve ser o da Figura 2

Figura 2 - definidos o título e o cabeçalho da página
Está na hora de inserirmos alguns dados para a visualização, execute o script abaixo no banco, para povoar as duas tabelas:

-- INSERINDO 3 Bacias Hidrográficas
INSERT INTO bacia_hidrografica(nome_bacia) VALUES ('Abiaí');
--
INSERT INTO bacia_hidrografica(nome_bacia) VALUES ('Mamanguape');
--
INSERT INTO bacia_hidrografica(nome_bacia) VALUES ('Gramame');

-- INSERINDO 6 Rios nas suas respectivas Bacias
INSERT INTO rio(nome_rio, comprimento_km, id_bacia) VALUES ('Papocas', 9, 1);
INSERT INTO rio(nome_rio, comprimento_km, id_bacia) VALUES ('Graú', 12, 1);
--
INSERT INTO rio(nome_rio, comprimento_km, id_bacia) VALUES ('Mogeiro', 23, 2);
INSERT INTO rio(nome_rio, comprimento_km, id_bacia) VALUES ('Gavião', 9, 2);
--
INSERT INTO rio(nome_rio, comprimento_km, id_bacia) VALUES ('Guarabira',31, 3);
INSERT INTO rio(nome_rio, comprimento_km, id_bacia) VALUES ('Jacaré', 7, 3);

vamos agora exibir os dados que foram inseridos na tabela bacia_hidrografica, para isso será necessário criar um model (dentro de sirh/system/application/model) , que chamaremos de bacia_model.php, com o seguinte conteúdo:

<?php
class Bacia_model extends CI_Model
{
    function  __construct()
    {
        parent:__construct();
    }

    function get_bacia()
    {
        $this->db->order_by('nome_bacia', 'asc');
        $query = $this->db->get('bacia_hidrografica');
        if ($query->num_rows() > 0)
        {
            return $query->result();
        }
        else
        {
            return false;
        }
    }
}

Agora, vamos modificar o nosso controlador, carregando o model criado e povoando uma variável com um array de objetos, obtidos através da função get_bacia():

<?php
class Bacia extends CI_Controller
{

    function __construct()
    {
        parent::__construct();
        $this->load->model('bacia_model');
    }

    function index()
    {
        $data['titulo'] = "SIRH";
        $data['cabecalho'] = "Bacias Hidrográficas";

        $data['bacias'] = $this->bacia_model->get_bacia();

        $this->load->view('bacia_view', $data);
    }
}

Para finalizar esta postagem, vamos agora modificar a nossa view, basicamente vamos varrer o array de objetos $data['bacias'] e exibir os resultados, também vamos utilizar a função anchor() do CodeIgniter para definir os links desta página, que serão finalizados no próximo Post:


<h2><?=$cabecalho ?></h2>

<p><?=anchor('bacia/criar', 'Criar Bacia Hidrográfica') ?></p>

<table border="1">
    <thead>
        <tr>
            <th>
                Nome da Bacia
            </th>
            <th>
                Ações
            </th>
        </tr>
    </thead>
    <tbody>
        <?php if ($bacias != false): ?>
        <?php foreach ($bacias as $bacia): ?>
            <tr>
            <td>
                <?=$bacia->nome_bacia ?>
            </td>
            <td>
                <?=anchor('bacia/editar/' . $bacia->id_bacia, 'Editar') ?> |
                <?=anchor('bacia/deletar/' . $bacia->id_bacia, 'Deletar') ?>
            </td>
        </tr>
        <?php endforeach; ?>
        <?php else: ?>
        <p>Não há registros cadastrados!</p>
        <?php endif ?>
    </tbody>
</table>

Salve todos os arquivos e abra o navegador e veja o resultado: http://localhost/sirh/index.php/bacia

Figura 3 - Exibição das Bacias Hidrográficas
  Bem pessoal, por hoje é só, para ajudar no entendimento deste exemplo, sugiro dar uma boa olhada na série de screencasts do Nettus+ sobre o CodeIgniter (item 5 do link).

Tutorial CodeIgniter - parte 1

O CRUD é definido como acrônimo da expressão inglesa (Create Retrieve Update and Delete), para as quatro operações básicas utilizadas em um bancos de dados relacionais (RDBMS).
Nesta série de  postagens, criaremos uma aplicação Web com CRUD através da linguagem PHP, para as duas tabelas do modelo lógico da Figura 1, utilizando o Framework CodeIgniter. Para codificar, sugiro o uso do Netbeans com o autocomplete do CodeIgniter, este último pode ser baixado no link: http://rhasan.com/blog/2009/09/codeigniter-auto-complete-with-netbeans/ . Já o banco que irei utilizar nesse exemplo, será o PostgreSQL.

OBS: É necessário que o leitor tenha uma base em PHP OO, pois não vou entrar em muitos detalhes, também sugiro, dar uma boa lida no Manual do CodeIgniter em português.


Figura 1 – modelo lógico do exemplo
 
1o Passo: criar o banco no PostgreSQL

Crie um banco com o nome sirh com a codificação UTF-8 e rode o modelo físico abaixo, observe que as chaves primárias foram definidas como serial, criando automaticamente o auto-incremento para esses dois campos:


CREATE TABLE bacia_hidrografica (
id_bacia serial PRIMARY KEY,
nome_bacia varchar(40)
);

CREATE TABLE rio (
id_rio serial PRIMARY KEY,
nome_rio varchar(40),
comprimento_km int,
id_bacia int,
FOREIGN KEY(id_bacia) REFERENCES bacia_hidrografica (id_bacia)
ON UPDATE CASCADE );

Após rodar o script acima, o seu banco ficará da seguinte forma (Figura 2):

Figura 2 - Banco com as duas tabelas criadas (PgAdmin)


2o Passo: download do CodeIgniter

Vá até o endereço: http://codeigniter.com/downloads/ e baixe a última versão do CI (nesse post, usei a versão 1.7.2), a instalação é bem simples, descompacte o arquivo zipado na pasta de publicação do seu servidor web, no meu caso “/var/www/”, para quem usa o MS4W (Mapserver for Windows), descompacte na pasta htdocs do servidor.
Agora, vamos mudar o nome da pasta que foi descompactada para sirh (abreviação de “sistema para recursos hídricos”).

3o Passo: configurar a url do sistema e a conexão com o banco PostgreSQL

Abra  o arquivo config.php, dentro de sirh/system/application/config. Mude a linha 14 para http://localhost/sirh/ , salve o arquivo em seguida.

Abra o arquivo database.php (na mesma pasta) e configure a conexão com o banco (em seguida salve o arquivo):

$db['default']['hostname'] = "localhost";
$db['default']['username'] = "postgres";
$db['default']['password'] = "postgres";
$db['default']['database'] = "sirh";
$db['default']['dbdriver'] = "postgre";

4° Passo: configurar as bibliotecas e os helpers que serão carregados de forma automática

Abra o arquivo autoload.php, modifique a linha 42 para:

 $autoload['libraries'] = array(‘database’); 

e a 54 para:

$autoload['helper'] = array(‘url’);

5° Passo: testar a instalação

Abra o seu navegador e digite a url: http://localhost/sirh, você verá a tela da Figura 3, caso a mesma não seja exibida dessa forma, verifique os passos anteriores. No próximo Post continuaremos a desenvolver esta aplicação, até lá!

figura 3 - tela de boas vindas do codeigniter