You are on page 1of 205

SEM ...

FORÇA A ARMA
DE MAIS
VONTADE PODEROSA
... DO
UNIVERSO
...

...É INÚTIL
Criando uma aplicação MVC em
5
com Zend Framework 1.0.1

Palestrante:
Instrutor: Flávio Gomes da Silva Lisboa
AVISO: Os exemplos de código
neste treinamento são baseados
em um sistema fictício. As
referências na documentação ao
SERPRO são apenas
exemplificativas e não
constituem de modo algum
extração de código de sistemas
Palestrante:

do SERPRO.
Instrutor: Flávio Gomes da Silva Lisboa CETEC/CTSSP/CTDSP

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


AVISO: Este material não possui
nenhum vínculo com o
SERPRO. As referências ao
nome SERPRO resumem-se tão
somente ao curriculum do autor.
Palestrante:
Instrutor: Flávio Gomes da Silva Lisboa CETEC/CTSSP/CTDSP

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Introdução

PHP (Personal Home Page


Tools):

O PHP sucede de um produto


mais antigo, chamado PHP/FI,
criado por Rasmus Lerdorf em
1995, inicialmente como
simples scripts Perl como
estatísticas de acesso para
seu currículo online.

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Introdução

PHP (Personal Home Page


Tools):

Como mais funcionalidades


foram requeridas, Rasmus
escreveu uma
implementação C muito
maior, que era capaz de
comunicar-se com base de
dados, e permitia que
usuários desenvolvessem
simples aplicativos
dinâmicos para Web.

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Introdução

PHP (Personal Home Page Tools):

Rasmus resolveu disponibilzar o código fonte do


PHP/FI para que todos pudessem ver, e também
usá-lo, bem como fixar bugs e melhorar o código.

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Introdução

Versões do PHP:
➔ PHP/FI (1995) Rasmus Lerdorf cria a linguagem.

➔ PHP/FI 2.0 (1997) Suporte a acesso a bancos de

dados, como o mini-SQL.


➔ PHP 3.0 (1998) Zeev Suraski e Andi Gutmans.

Suporte à programação orientada a objetos e


extensões modulares.
➔ PHP 4.0 (2001) Web Server API (SAPI), Zend Engine

compila PHP em opcodes


➔ PHP 5.0 (2004) Evolução do modelo de objetos.

➔ PHP 6.0 (2007?) ???

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Introdução

PHP (PHP: Hypertext Preprocessor):

• Linguagem de programação de ampla utilização;


• Interpretada;
• Especialmente interessante para desenvolvimento
para a Web;
• Pode ser mesclada dentro do código HTML;
• A sintaxe da linguagem lembra C, Java e Perl;
• É fácil de aprender.

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Introdução

PHP (PHP: Hypertext Preprocessor):

O objetivo principal da linguagem é permitir que


desenvolvedores escrevam páginas que serão
geradas dinamicamente, mas você pode fazer muito
mais do que isso com PHP.

Do Manual do PHP em Português

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Objetivo do Curso

“Se você não sabe aonde ir, então qualquer


caminho serve”
Gato de Cheshire

O objetivo do curso é mostrar como criar uma


aplicação web completa com PHP usando
orientação a objetos através de um framework
MVC, neste caso o Zend Framework.
FLÁVIO GOMES DA SILVA LISBOA Treinamentowww.fgsl.eti.br
em PHP 5 módulo II
Expectativa

Que os alunos saiam do curso:

➔ Sabendo como programar PHP usando objetos.


➔ Sabendo programar em três camadas, usando MVC.
➔ Conhecendo uma alternativa de framework, o Zend
Framework.

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Metodologia

Aprendizado prático através de um projeto de um


portal de comércio eletrônico.

O importante agora é o aprendizado da linguagem e


seus recursos. Detalhes sobre a instalação e a
configuração do ambiente não interessam no
momento.

Por isso serão utilizados o pacote XAMPP Linux,


que agrega Apache (servidor web), PHP e MySQL
(banco de dados), e o IDE EasyEclipse for PHP.
Todos são softwares livres.

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Cronograma do Curso

Primeiro dia: Introdução


Segundo dia: ?
Terceiro dia: ?
Quarto dia: ?
Quinto dia: ?

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Cronograma do Curso

Sexto dia: ?
Sétimo dia: ?
Oitavo dia: ?
Nono dia: ?
Décimo dia: Conclusão

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Etapa Atual

Primeiro dia

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Pacotes

➔ ApacheFriends XAMPP Linux versão 1.6.1

+ Apache 2.2.4
+ MySQL 5.0.45 O projeto será
+ PHP 5.2.3 + PHP 4.4.7 em PHP 5
+ phpMyAdmin 2.10.3

➔ PostgreSQL 8.2.4
➔ PhpPgAdmin 4.1.3
➔ EasyEclipse for PHP 1.2.1.1
➔ Smarty Engine Template 2.6.18
➔ Zend Framework 1.0.1

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Instalação dos Pacotes

Os guias de instalação
encontram-se na parte
de anexos da apostila
“Ambiente para o Zend
Framework”

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Iniciando o XAMPP

O XAMPP tem de ser iniciado pelo usuário root,


através do comando:
/opt/lampp/lampp start

Esse comando inicia o Apache com suporte para o


PHP e o MySQL.

Para pará-lo:
/opt/lampp/lampp stop

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Iniciando o PostgreSQL

O PostgreSQL deve ser iniciado pelo usuário


postgres, com o comando:

postgres -D /usr/local/postgres/data

Ou com o comando:

pg_ctl start

Para pará-lo:

pg_ctl stop

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Iniciando o EasyEclipse for PHP

É só clicar no
ícone, no
Desktop, iac,
iac!

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Testando o Ambiente

Abra o navegador de Internet.

Vamos ver se o XAMPP está rodando:


http://localhost/

Depois veja se o PostgreSQL está rodando:


http://localhost/phppgadmin

Depois veja se o Zend Framework está instalado:


http://localhost/zendframework

Agora, está quase na hora de entrar em ação!


FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br
Treinamento em PHP 5 módulo II
Projeto de Sistema

As Lojas Acme, grande comércio varejista, quer


agora começar a vender pela Internet.

Para isso, ela contrata uma empresa, a


Corporação NF, para desenvolver uma loja virtual.

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Projeto de Sistema

Nessa loja, serão exibidos produtos com sua


respectiva quantidade em estoque.
O cliente pode selecionar os produtos e suas
quantidades montando um carrinho de compras
virtual.
Quando e se quiser efetuar a compra, o cliente se
identifica. Se ele não estiver cadastrado, a loja
deve fazer seu cadastro e prosseguir com a
compra.

Assim que for efetivada a compra, a quantidade


disponível de produtos deve ser atualizada.

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Projeto de Sistema

A Corporação NF, empresa especializada em


aplicações para Web, decide criar um portal de
compras usando PHP e PostgreSQL. Esse sistema
será construído usando Orientação a Objetos. Por
isso, a Corporação NF irá utilizar o PHP 5.

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Orientação a Objetos

Como esse não é um curso de OO, podemos usar a


seguinte frase como referência:

Grandes poderes
trazem grandes
responsabilidades...

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Orientação a Objetos

O fundamento da Orientação a Objetos são as


classes.

As classes nada mais são que estruturas de dados


acopladas a funções.

As estruturas de dados de uma classe só podem


ser manipuladas diretamente pelas funções da
mesma.

Chamamos as estruturas de dados de atributos e as


funções de métodos.

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Orientação a Objetos

Uma classe é responsável pelos seus atributos e


somente ela tem poder de alterá-los e dispor deles.

Podemos diferenciar o enfoque entre a


programação estruturada e a orientada a objetos da
seguinte maneira:

Estruturada: o foco está em coisas que devem ser


feitas.
Orientada a Objetos: o foco está em quem faz
essas coisas.

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Orientação a Objetos

Um modo de enxergar os responsáveis pelas


operações que irão afetar as variáveis do sistema é
esboçar a interface com o usuário do sistema e
simular os fluxos operacionais.

Por isso, iremos esboçar as páginas do site da loja,


e conforme as construirmos, criaremos as classes
envolvidas com essas páginas.

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Interface Gráfica

Página principal

Logomarca da loja
Acessar Cadastre-se
Busca produtos:

Nome do produto: Nome do produto:


Valor do produto: Valor do produto:
Quantidade Disponível: Quantidade Disponível:
Comprar Comprar

Logomarca do desenvolvedor

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando a página inicial

A página inicial já possui elementos que irão se


repetir nas demais páginas: o cabeçalho com a
logomarca da Acme e o rodapé com a autoria da
Corporação NF.

Além disso, toda página HTML possui uma


estrutura padrão, que se repetirá.

Assim, vamos definir um cabeçalho e um rodapé


fixos, uma única vez.

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando a página inicial
No diretório zendframework criaremos um arquivo
.htaccess com a linha:

RewriteRule .* /acme/index.php

Abra o EasyEclipse. Crie um novo PHP Project com o


nome de acme.
O workspace será
/opt/lampp/htdocs/zendframework/acme.

Dentro desse projeto, criaremos a estrutura padrão do


Zend Framework.

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando a página inicial

A estrutura do projeto deve ficar assim:

Esses diretórios
representam o
MVC no Zend
Framework

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando a página inicial

MVC?
Pelas balbas do
plofeta, o que é
isso?!

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando a página inicial

Calma,
velhinho! Você
vai entender
quando a gente
terminar!

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando a página inicial

O arquivo .htacess da raiz de acme, deve incluir as


seguintes linhas:

RewriteEngine on
RewriteRule .* index.php
php_flag magic_quotes_gpc off
php_flag register_globals off

Essas linhas ativam a reescrita de URL, redirecionam


todas as extensões de arquivo para index.php, que
tratará todas as requisições e desabilitam
magic_quotes_gpc e register_globals.

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando a página inicial

O arquivo .htacess do diretório acme/application, deve


incluir a seguinte linha:

deny from all

Agora só index.php terá acesso aos arquivos de


application. Já o arquivo .htacess, do diretório
acme/public, deve incluir a seguinte linha:

RewriteEngine off

Os arquivos de public podem ser acessados


diretamente pelo navegador.
FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br
Treinamento em PHP 5 módulo II
Criando a página inicial

O arquivo principal da aplicação é o index.php. O


conteúdo desse arquivo, comentado é o seguinte:

<?php
/**
* Arquivo principal da aplicação
* Define todos os caminhos onde os arquivos estão
armazenados,
* todos os includes necessários e todos os componentes
que a
* aplicação utilizará.
* Responsável por inicializar a aplicação, ele invoca os
* arquivos de controlador que são responsáveis pelo
funcionamento
* da aplicação.

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando a página inicial

Esse é o comentário estilo C do PHP, adaptado para


uso do phpDocumentor.

Os comentários que não forem fazer parte da


documentação podem simplesmente ficar entre os
delimitadores /* e */ e podem ocupar várias linhas.

Existe outro tipo de comentário, de uma linha só,


que é identificado pelo uso de // no início da linha. É
o estilo de comentário do C++.

Mas para facilitar a documentação, prefira o uso do


comentário estilo C.
FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br
Treinamento em PHP 5 módulo II
Criando a página inicial

PRECISO COLOCAR COMENTÁRIO NOS PROGRAMAS?

NÃO, SE VOCÊ FOR:


É, acho
➔ UM HIGHLANDER; que
precisa
➔ ANGUS MCGYVER; colocar...
➔ TOM CRUISE;
➔ JAMES BOND;
➔ SHERLOCK HOLMES;
➔ DRÁCULA;
➔ JOHN NASH;

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando a página inicial

LEGIBILIDADE

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando a página inicial

Falando sério, existe uma regra prática para saber


se um trecho precisa ou não de um comentário.
Chame um colega que conheça a mesma linguagem
e peça para ele dizer se entende o que o trecho faz.
Se ele demorar mais de 30 segundos pra entender,
comente!

“Regra dos 30 Segundos” in


Ambler, Scott W. (1998) Análise e Projeto Orientados a Objeto
volume 2, RJ, Infobook.

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando a página inicial

* @filesource
* @author Flávio Lisboa
* @copyright Copyright 2007 SERPRO
* @package zendframework
* @subpackage zendframework.acme
* @version 1.0
*/
/* Configura as mensagens de erro que devem ser
apresentadas. */
error_reporting(E_ALL | E_STRICT);

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando a página inicial

/*
* Configura o caminho a ser procurado em todos os
includes.
* Irá procurar no diretório ../library, no
application/models
* e no caminho original do PHP.
*/
/**
* É interessante utilizar set_include_path para definir
onde se encontram
* todos os arquivos do projeto, pois assim se evita que
o mesmo código
* seja escrito várias vezes, gerando menos linhas e
facilitando qualquer
* alteração de path.
*/

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando a página inicial

$path = ':/opt/lampp/htdocs/zend/library';
$path .= ':/opt/lampp/htdocs/zend/acme/application/models';

set_include_path(get_include_path().$path);

/*
* Faz o include do componente Zend_Loader.
* Este include é obrigatório.
* Zend_Loader carrega arquivos, classes e recursos
* dinamicamente em sua aplicação PHP.
* => suporta autocarregamento da SPL (Standard PHP Library)
* => suporta include_path
* => fornece mecanismo de falha baseado em exceção
*/
include('Zend/Loader.php');

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando a página inicial

/*
* O registro é um contâiner para armazenar objetos e valores
* no espaço da aplicação. Armazenar um objeto ou valor
* no registro torna o mesmo sempre disponível ao longo
* da aplicação durante o tempo de vida da requisição.
* Este mecanismo é freqüentemente uma alternativa aceitável
* ao uso de variáveis globais.
* => fornece armazenamento acessível globalmente para objetos
* e valores
* => fornece os padrões iterator, array e indexed access
*/
Zend_Loader::loadClass('Zend_Registry');

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando a página inicial

/* Inclui o suporte a sessões. Só é necessário caso seja


usado. */
Zend_Loader::loadClass('Zend_Session');

/* O método loadClass é responsável por incluir o arquivo


responsável pela classe */

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando a página inicial

/**
* Este método tenta carregar o arquivo passado como
parâmetro procurando no path
* definido com a função set_include_path. Caso ele não
consiga encontrar o arquivo,
* é gerada uma exceção que indica arquivo inexistente ou
sem acesso. O método
* considera os underscores no nome do arquivo como
subdiretórios. Por exemplo, o
* comando Zend::loadClass('Zend_Controller_Front') faz a
importação do arquivo
* ../zendframework/library/Zend/Controller/Front.php.
Seguir esse padrão facilita
* o entendimento da estrutura do projeto.
*/

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando a página inicial

Zend_Loader::loadClass('Zend_Controller_Front'); /*
Classe de controladores */
Zend_Loader::loadClass('Zend_View'); /* Classe
das visões */
Zend_Loader::loadClass('Zend_Config_Ini'); /* Classe
usada para configurações */
Zend_Loader::loadClass('Zend_Db'); /* Classe
para acesso a base de dados */
Zend_Loader::loadClass('Zend_Db_Table'); /* Classe
para usar as tabelas como objetos */
Zend_Loader::loadClass('Zend_Filter_Input'); /*
Classe usada para filtrar os dados */

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando a página inicial

/* O método register é responsável por armazenar


variáveis que podem ser usadas
* pelos aplicativos. Aqui, registrando os arrays post e
get com dados vindos do usuário.
* o Zend_Filter limpa os dados.
*/
Zend_Registry::set('post', new Zend_Filter_Input($_POST,
FALSE));
Zend_Registry::set('get', new Zend_Filter_Input($_GET,
FALSE));

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando a página inicial

/* Parte das visões */


$view = new Zend_View; /* Cria um novo
objeto do tipo view */

/* Configura a codificação das páginas */


$view->setEncoding('UTF-8');
$view->setEscape('htmlentities');

$view->setBasePath('./application/views'); /* Define o
diretório onde estarão as visões */
Zend_Registry::set('view', $view); /* Registra
na memória a variável view que indica a visão */

/* Inicia a sessão global */


Zend_Session::start();

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando a página inicial

/* Configura o controlador do projeto.


* O Controlador, por acaso, é o index.php
*/
$baseUrl = substr($_SERVER['PHP_SELF'], 0,
strpos($_SERVER['PHP_SELF'], '/index.php'));

/* Cria uma nova instância da classe controladora */


$frontController = Zend_Controller_Front::getInstance();

/* Configura o endereço do controlador do projeto */


$frontController->setbaseUrl($baseUrl);

/* Indica o diretório onde estão os outros controladores


da aplicação */
$frontController-
>setControllerDirectory('./application/controllers');
FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br
Treinamento em PHP 5 módulo II
Criando a página inicial

/* O controlador deve tratar as exceções */


$frontController->throwExceptions(TRUE);

/* Configurações da base de dados.


* Indica onde estão as configurações do projeto.
* Estão no arquivo config.ini na seção database.
*/
$config = new Zend_Config_Ini('./application/config.ini',
'database');

/* Registra na memória a variável config */


Zend_Registry::set('config', $config);

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando a página inicial

/* Configura a conexão com a base de dados, pegando as


variáveis do arquivo
* de configuração.
*/
$db = Zend_Db::factory($config->db->adapter, $config->db-
>config->toArray());
Zend_Db_Table_Abstract::setDefault($db);

/* Registra a variável db */
Zend_Registry::set('db', $db);

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando a página inicial

/* Configura o formato para moeda */


setlocale(LC_MONETARY,'ptb');

/* Executa o controlador do projeto.


* Ele irá receber todas as requisições e invocar os
arquivos correspondentes.
*/
$frontController->dispatch();
?>

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando a página inicial

Antes de criarmos a página inicial da aplicação,


precisamos criar os modelos, que são os arquivos
que contêm as classes que transformarão os
registros das tabelas correspondentes em objetos.
Essa transformação é necessária porque o sistema
será orientado a objetos, mas a base de dados é
relacional.

Eles devem ser criados dentro do diretório models,


seguindo o seguinte padrão: cada nome simples com
inicial maiúscula e o resto em minúsculo.

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando a página inicial

Usuarios.php
<?php
/**
* Modelo da classe Usuarios
* @filesource
* @author Flávio Lisboa
* @copyright Copyright 2007 SERPRO
* @package zendframework
* @subpackage zendframework.acme.application.models
* @version 1.0
*/
class Usuarios extends Zend_Db_Table
{
protected $_name = 'usuarios';
}
?>
FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br
Treinamento em PHP 5 módulo II
Criando a página inicial

Produtos.php
<?php
/**
* Modelo da classe Produtos
* @filesource
* @author Flávio Lisboa
* @copyright Copyright 2007 SERPRO
* @package zendframework
* @subpackage zendframework.acme.application.models
* @version 1.0
*/
class Produtos extends Zend_Db_Table
{
protected $_name = 'produtos';
}
?>
FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br
Treinamento em PHP 5 módulo II
Criando a página inicial

Itens.php
<?php
/**
* Modelo da classe Itens
* @filesource
* @author Flávio Lisboa
* @copyright Copyright 2007 SERPRO
* @package zendframework
* @subpackage zendframework.acme.application.models
* @version 1.0
*/
class Itens extends Zend_Db_Table
{
protected $_name = 'itens';
}
?>
FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br
Treinamento em PHP 5 módulo II
Criando a página inicial

Pedidos.php
<?php
/**
* Modelo da classe Pedidos
* @filesource
* @author Flávio Lisboa
* @copyright Copyright 2007 SERPRO
* @package zendframework
* @subpackage zendframework.acme.application.models
* @version 1.0
*/
class Pedidos extends Zend_Db_Table
{
protected $_name = 'pedidos';
}
?>
FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br
Treinamento em PHP 5 módulo II
Criando a página inicial

Através do phpPgAdmin, vamos abrir o banco de dados acme


e criar as tabelas que serão mapeadas pelos modelos que
criamos. Por enquanto crie as tabelas usuarios, pedidos e
itens apenas com o campo id, serial, não nulo, chave única e
primária.

Em seguida vamos criar uma tabela com o nome “produtos”,


com 4 campos:

➔ id : serial / (não nulo, chave única e chave primária)


➔ nome: text
➔ valor: money
➔ quantidade: integer

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando a página inicial

Grave a tabela.

Usando a botão Inserir inclua quatro ou mais registros de


produtos.

Pronto! Agora podemos criar a listagem de produtos, que


aparecerá na página inicial.

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando a página inicial

Precisamos definir os dados de conexão com o banco


no arquivo config.ini dentro de application.

[database]
db.adapter = PDO_PGSQL
db.config.host = localhost
db.config.username = acme
db.config.password = 123456
db.config.dbname = acme

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando a página inicial

Prosseguindo, temos de criar a aplicação inicial de


nosso projeto. Ela será responsável por mostrar a
página inicial com uma amostra dos produtos das
Lojas Acme e links para comprar, identificar-se ou
cadastrar-se.
Criaremos uma classe chamada IndexController, que
será o controlador padrão da aplicação.
Por padrão, os seguintes métodos serão executados,
automaticamente em seqüência: init (onde os
modelos serão carregados) e indexAction (que exibirá
a página inicial).

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando a página inicial

<?php
/**
* Controlador principal
* @filesource
* @author Flávio Lisboa
* @copyright Copyright 2007 SERPRO
* @package zendframework
* @subpackage
zendframework.acme.application.controllers
* @version 1.0
*/

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando a página inicial

class IndexController extends Zend_Controller_Action


{
/**
* Este método será executado sempre que a classe for
instanciada,
* depois do construtor.
* Faz o carregamento das classes que serão usadas pelo
controlador.
*
* @return void
*/
public function init()
{
Zend_Loader::loadClass('Usuarios');
Zend_Loader::loadClass('Produtos');
Zend_Loader::loadClass('Itens');
Zend_Loader::loadClass('Pedidos');
}
FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br
Treinamento em PHP 5 módulo II
Criando a página inicial

/**
* Método que mostra a página inicial
*
* @return void
*/
public function indexAction()
{
$view = Zend_Registry::get('view');

$view->assign('header','pageHeader.phtml');
$view->assign('body','index.phtml');
$view->assign('footer','pageFooter.phtml');
$this->_response->setBody($view->render('default.phtml'));
}
}
?>

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando a página inicial

Por força do esquema padrão do Zend, somos


obrigados a criar dentro de views/scripts um
diretório index contendo um arquivo index.phtml.

O que ocorre é o seguinte: todo método deve ter um


arquivo phtml com o mesmo nome (sem o sufixo
Action) dentro de uma pasta com o nome do
controlador (sem o sufixo Controller) dentro de
views/scripts.

Neste projeto, criaremos pares de visões com o


mesmo nome, mas você entenderá por que.

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando a página inicial

Como estamos criando uma página que sempre vai


ter um cabeçalho, corpo e rodapé definidos pelo
default.phtml. É assim porque queremos optar por
configurar esses itens. Então em
views/scripts/[metodo] teremos um arquivo
continente, que simplesmente é preenchido com o
conteúdo de default.phtml, configurado
previamente. O corpo desse arquivo que é chamado
automaticamente como a visão padrão do método
em questão, será um arquivo de mesmo nome,
localizado na raiz views/scripts.

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando a página inicial

Ao montar a visão, o Zend chamará o default.phtml


(que criaremos em seguida). Esse será configurado
para chamar um cabeçalho, um corpo e um rodapé.
O corpo será preenchido sempre com o arquivo de
conteúdo, que está na raiz de scripts. O outro
arquivo homônimo que está na pasta método, será
colado após o arquivo default.phtml.

Agora, dentro de views/scripts, criaremos um


template chamado default.phtml, que será o
esqueleto de página para a aplicação.

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
default.phtml

<!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>
<title>Zend Framework(tm) : index</title>
<link rel="stylesheet" type="text/css"
href="/zend/acme/public/styles/zend.generic.css" />
</head>
<body>
<?= $this->render($this->header) ?>
<div id="container">
<!-- Conteúdo da página -->
<?= $this->render($this->body) ?>
<div>
<?= $this->render($this->footer) ?>
</body>
</html>

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando a página inicial

Para que esse template seja renderizado, é preciso


criar os arquivos que ele referencia. Vamos
começar pelo arquivo que contém as folhas de
estilo. Dentro de public/styles vamos criar um
arquivo chamado zend.generic.css.

Definiremos alguns identificadores de estilo CSS.

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando a página inicial

Vamos criar o identificador CSS header:

#header{
background-color:green;
border:1px solid black;
Width:100%
}

Agora vamos incluir um identificador chamado


logomarca_customer. Ela será referida pela tag H1
dentro da divisão header de pageHeader.phtml.

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando a página inicial

O conteúdo de logomarca_customer será o seguinte:

#logomarca_customer{
background-color: green;
color:white;
font-family:Verdana;
font-size: xx-large;
font-weight:bold;
text-align:center;
}

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando a página inicial

Vamos agora criar o identificador CSS menu:

#menu {
background-color: yellow;
border:1px solid black;
color:darkblue;
font-family:Verdana;
font-size: medium;
font-weight:bold;
text-align:center;
width:100%
}
FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br
Treinamento em PHP 5 módulo II
Criando a página inicial
O código do identificador CSS footer ficará assim:

#footer{
background-color:blue;
border:1px solid black;
width:100%;
}

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando a página inicial

E o identificador CSS logomarca_maker ficará assim:

#logomarca_maker{
background-color: blue;
color: white;
font-family: Verdana;
font-size: xx-large;
font-weight: bold;
text-align: center;
}

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando a página inicial

Os seguintes identificadores formatarão a lista de produtos:

#sample {
background-color: deepskyblue;
border: 1px solid black;
width: 100%;
}

#product_box {
border: 1px;
border-style: solid;
font-size: large;
font-weight: bold;
text-align: left;
}

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando a página inicial

#buy_button {
background-color: red;
border: 1px solid black;
color: yellow;
font-family: Arial;
font-weight: bold;
}

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando a página inicial

Dentro de views/scripts, vamos criar os arquivos


pageHeader.phtml, pageFooter.phtml e index.phtml.

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
pageHeader.phtml

<div id="header">
<h1 id="logomarca_customer">Lojas Acme</h1>
</div>

<div id="menu">
<form action="zend/acme/buscas" method="post">
<a href="/zend/acme/index/acessar" >Acessar</a>
&nbsp;
<a href="zend/acme/cadastrar" >Cadastrar</a>
<label>Busca produtos:</label>
<input name="nome" value="" id="nome" type="text">
<input type="submit" value="Pesquisar" />
</form>
</div>

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
pageFooter.phtml

<div id="footer">
<div id="logomarca_maker">
Corpora&ccedil;&atilde;o NF
</div>
</div>

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
index.phtml

<table id="sample">
<?php
$counter = 1;
foreach ($this->produtos as $produto)
{
if ($counter % 2 != 0)
{
echo $counter == 1 ? '<tr>' : '</tr><tr>';
}
?>

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
index.phtml

<td id="product_box">
<?=$this->escape($produto['nome'])?><br/>
<?=$this->escape($produto['valor'])?><br/>
<?=$this->escape('Quantidade disponível: ')?>
<?=$this->escape($produto['quantidade'])?><br/>
</td>
<?php
$counter++;
}
?>
</table>
<a href="./carrinho/comprar">Comprar</a>

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando a página inicial

Agora, depois de tudo isso, se chamarmos a URL:


http://localhost/zend/acme

Teremos o seguinte resultado:

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando a página inicial

TUDO ISSO SÓ
PRA APARECER
ESSA PÁGINA?

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando a página inicial

Calma, vamos
explicar tudo o
que foi feito!

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Modelo MVC

PAUSA PARA ENTENDER O PADRÃO MVC

A arquitetura MVC divide uma aplicação em três


camadas:

MODELO VISÃO CONTROLADOR

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Modelo MVC

PAUSA PARA ENTENDER O PADRÃO MVC

O Modelo concentra as regras e objetos de negócio, o


acesso ao banco de dados e os métodos de serviço.

MODELO VISÃO CONTROLADOR

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Modelo MVC

PAUSA PARA ENTENDER O PADRÃO MVC

A Visão determina o layout e o design da aplicação. É


a interface com o usuário.

MODELO VISÃO CONTROLADOR

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Modelo MVC

PAUSA PARA ENTENDER O PADRÃO MVC

O Controlador recebe as requisições e controla o


acesso e o fluxo da aplicação.

MODELO VISÃO CONTROLADOR

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Modelo MVC

PAUSA PARA ENTENDER O PADRÃO MVC

As três camadas se relacionam assim:

requisição
CONTROLADOR

usuário

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Modelo MVC

PAUSA PARA ENTENDER O PADRÃO MVC

O Controlador interpreta a requisição e usa o Modelo


correspondente. O Modelo determina a próxima ação.

CONTROLADOR MODELO

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Modelo MVC

PAUSA PARA ENTENDER O PADRÃO MVC

O Controlador devolve para o usuário uma Visão,


selecionada a partir das regras de negócio do Modelo.

CONTROLADOR VISÃO

usuário

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Modelo MVC

APLICANDO NO QUE FIZEMOS

O Zend Framework direciona a requisição para o


controlador.

http://localhost/zend/acme
indexController.php

Você

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Modelo MVC

APLICANDO NO QUE FIZEMOS

Um objeto da classe IndexController interpreta a


requisição e cria um objeto da classe Produtos, que é
o Modelo que estamos tratando.

indexController.php Produtos.php

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Modelo MVC

APLICANDO NO QUE FIZEMOS

O objeto IndexController devolve para o usuário uma


Visão, criada a partir do arquivo default.phtml do
diretório view/scripts.

indexController.php default.phtml

você

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando a página inicial

Foi assim que chegamos neste resultado:

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando a página inicial

Que está de acordo com o esperado:

Logomarca da loja
Acessar Cadastre-se
Busca produtos:

Nome do produto: Nome do produto:


Valor do produto: Valor do produto:
Quantidade Disponível: Quantidade Disponível:
Comprar Comprar

Logomarca do desenvolvedor

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando a página inicial

Parece que esse


framework
funciona!

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando o carrinho de compras

Só que não acabou. Agora temos de implementar a


funcionalidade de carrinho de compras.

Quando o usuário der um clique no link “COMPRAR”, se já


não houver um, deverá ser criado um carrinho de compras
que irá acumular os produtos até que o usuário decida fechar
a compra. Precisaremos então de um link “FECHAR
COMPRA”.
E quando esse link for acionado, se o usuário ainda não se
logou, deverá se logar. Se ainda não tiver login, deverá
cadastrá-lo.

Bem, é muita coisa para fazer. Vamos primeiro ao carrinho de


compras. Criaremos os métodos no controlador que
manipularão o carrinho.

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando o carrinho de compras

<?php
/**
* Controlador do carrinho de compras
* @filesource
* @author Flávio Lisboa
* @copyright Copyright 2007 SERPRO
* @package zendframework
* @subpackage
zendframework.acme.application.controllers
* @version 1.0
*/

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando a página inicial

class CarrinhoController extends Zend_Controller_Action


{
/**
* Este método será executado sempre que a classe for
instanciada,
* depois do construtor.
* Faz o carregamento das classes que serão usadas pelo
controlador.
*
* @return void
*/
public function init()
{
Zend_Loader::loadClass('Usuarios');
Zend_Loader::loadClass('Produtos');
Zend_Loader::loadClass('Itens');
Zend_Loader::loadClass('Pedidos');
}
FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br
Treinamento em PHP 5 módulo II
Criando o carrinho de compras

Vamos criar um método na classe CarrinhoController


chamado comprar.
/* Página do carrinho de compras */
public function comprarAction()
{
$mensagem = '';

if (!isset($_SESSION['carrinho']))
{
$_SESSION['carrinho'] = array();
}

$carrinho = $_SESSION['carrinho'];

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando o carrinho de compras

if (!is_null($this->_request->getParam('id')))
{
$id = (int)$this->_request->getParam('id');

$incluido = FALSE;

foreach ($carrinho as $produto)


{
if (isset($produto['id']))
{
if ($produto['id'] == $id )
{
$incluido = TRUE;
$mensagem = 'Produto já selecionado';
break;
}
}
FLÁVIO GOMES DA SILVA LISBOA
}
www.fgsl.eti.br
Treinamento em PHP 5 módulo II
Criando o carrinho de compras

if (!$incluido)
{
$produtos = new Produtos();
$item = $produtos->find($id)->toArray();
$item[0]['quantidade']= 1;
$carrinho[] = $item[0];
$_SESSION['carrinho'] = $carrinho;
}

}
$view = Zend_Registry::get('view');

$view->assign('mensagem',$mensagem);
$view->assign('itens',$carrinho);

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando o carrinho de compras

$view->assign('header','pageHeader.phtml');
$view->assign('body','comprar.phtml');
$view->assign('footer','pageFooter.phtml');
$this->_response->setBody($view-
>render('default.phtml'));
}

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando o carrinho de compras

Agora é preciso criar o arquivo de visão para esse método.


Criaremos em views/principal o arquivo comprar.thtml.

<h3 id="warning"><?=$this->mensagem?></h3>
<table id="carrinho">
<thead>
<?php
$titulos = array('Código',
'Nome',
'Quantidade',
'Preço Unitário',
'Total',
'Editar',
'Excluir');
FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br
Treinamento em PHP 5 módulo II
Criando o carrinho de compras

foreach ($titulos as $titulo)


{
echo '<th>'.$this->escape($titulo).'</th>';
}
?>
</thead>
<?php
$somaTotal = 0;

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando o carrinho de compras

foreach ($this->itens as $item)


{
$codigo = $item['id'];
$nome = $this->escape($item['nome']);
$quantidade = $this-
>escape($item['quantidade']);
$preco = $this->escape($item['valor']);

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando o carrinho de compras

// Aqui foi necessário forçar o preço a


assumir o formato americano
// porque ele não estava convertendo a moeda
corretamente
$moeda =
str_replace('.','',substr($preco,2));
$moeda = str_replace(',','.',$moeda);

$valorTotal = (float)$quantidade *
(float)$moeda;
$totalItem = $this-
>escape(money_format('%.2n',$valorTotal));

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando o carrinho de compras

$editar = '<a
href="./editar?id='.$codigo.'">E</a>';
$excluir= '<a
href="./excluir?id='.$codigo.'">X</a>';

$somaTotal += $valorTotal;

$colunas = array($codigo,
$nome,
$quantidade,
$preco,
$totalItem,
$editar,
$excluir);

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando o carrinho de compras

echo '<tr>';

foreach ($colunas as $coluna)


{
echo '<td>';
echo $coluna;
echo '</td>';
}

echo '</tr>';
}
?>
</table>

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando o carrinho de compras

Total da compra:
<?='R$'.money_format('%.2n',$somaTotal)?><br/>
<a href="/zend/acme">Continuar comprando</a>
<a href="/zend/acme/carrinho/fechar">Fechar
compra</a>

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando o carrinho de compras

Vamos acrescentar no zend.generic.css uma formatação para


a mensagem que aparece no topo da lista de itens, que
alertará o usuário para os eventos e resultados ocorridos.

#warning {
color : red;
}

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando o carrinho de compras

E assim chegamos a esta tela:

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando o carrinho de compras

Podemos incluir um método indexAction no


ControladorCarrinho, caso o usuário dê uma de esperto e
digite a URL: http://localhost/zend/acme/carrinho

Nós apenas redirecionamos ele para o método


comprarAction, que simplesmente exibe o conteúdo do
carrinho quando não recebe parâmetros. Essa é uma boa
técnica quando não existir um index.phtml para a URL em
questão.

public function indexAction()


{
$this->_redirect('/carrinho/comprar');
}

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando o carrinho de compras

Vamos acrescentar uma linha à visão index.phtml, para que o


cliente possa ver o conteúdo do carrinho sem ser obrigado a
comprar um item:

<a id="buy_button"
href="./carrinho/comprar?id=<?=$produto['id']?>"
>Comprar</a>

Agora vamos criar as funcionalidades de remover e editar os


itens do carrinho. Comecemos pela remoção. Na classe
CarrinhoController iremos criar o método excluir, de acordo
com o link carrinho/excluir?id=[id].

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando o carrinho de compras

/* Exclusão de itens do carrinho de compras */


public function excluirAction()
{

$id = (int)$this->_request->getParam('id');

if (is_null($id))
{
$this->_redirect('/carrinho/');
exit;
}

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando o carrinho de compras
foreach ($_SESSION['carrinho'] as $chave =>
$produto)
{
if ($produto['id'] == $id )
{
unset($_SESSION['carrinho'][$chave]);
break;
}
}

$this->_redirect('/carrinho/');
}

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando o carrinho de compras

Ainda na classe CarrinhoController, criaremos o método


editar, que chamará responderá à requisição feita pelo link
carrinhor/editar?id=[id]:

/* Edição de quantidade de um item do carrinho */


public function editarAction()
{
$id = (int)$this->_request->getParam('id');

if (is_null($id))
{
$this->_redirect('/carrinho/');
exit;
}

$produtoSelecionado = array();
FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br
Treinamento em PHP 5 módulo II
Criando o carrinho de compras

foreach ($_SESSION['carrinho'] as $chave =>


$produto)
{
if (isset($produto['id']))
{
if ($produto['id'] == $id )
{
$produtoSelecionado = $produto;
break;
}
}
}

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando o carrinho de compras

$view = Zend_Registry::get('view');

$view-
>assign('produtoSelecionado',$produtoSelecionado);

$view->assign('header','pageHeader.phtml');
$view->assign('body','editar.phtml');
$view->assign('footer','pageFooter.phtml');
$this->_response->setBody($view-
>render('default.phtml'));
}

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando o carrinho de compras

Agora, criaremos a visão para exibir um formulário onde o


cliente poderá alterar a quantidade do produto selecionado.
Em views/principal criaremos o arquivo editar.thtml:

<center>
<form action="/zend/acme/carrinho/alterar"
method="post">
<?php
if (isset($this->produtoSelecionado['id']))
{
echo '<b>Produto: '.$this-
>produtoSelecionado['nome'].'</b><br/>';
echo '<b>Preço: '.$this-
>produtoSelecionado['valor'].'</b><br/>';
?>
FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br
Treinamento em PHP 5 módulo II
Criando o carrinho de compras
Quantidade:
<input name="quantidade" value="<?=$this-
>produtoSelecionado['quantidade']?>" id="nome"
type="text">
<input name="id" value="<?=$this-
>produtoSelecionado['id']?>" id="id"
type="hidden">
<?php
}
?>
<input type="submit" name="alterar"
value="Alterar"/>
</form>
</center>
<a href="/zend/acme/carrinho/">Carrinho de
compras</a>
FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br
Treinamento em PHP 5 módulo II
Criando o carrinho de compras

Agora, na classe CarrinhoController, criaremos o método


alterar, que responderá à requisição feita pelo formulário
anterior:
public function alterarAction()
{
/* Alteração de quantidade de um item do carrinho
*/
$id = (int)$this->_request->getParam('id');

if (is_null($id))
{
$this->_redirect('/carrinho/');
exit;
}

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Criando o carrinho de compras
$quantidade = (int) $this->_request-
>getParam('quantidade');

foreach ($_SESSION['carrinho'] as $chave => $produto)


{
if (isset($produto['id']))
{
if ($produto['id'] == $id )
{
$_SESSION['carrinho'][$chave]['quantidade']
= $quantidade;
break;
}
}
}

$this->_redirect('/carrinho/');
}
FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br
Treinamento em PHP 5 módulo II
Criando o carrinho de compras

Vamos testar as funcionalidades, comprando, alterando e


removendo itens do carrinho.
Carregue a URL http://localhost/zend/acme e execute essas
operações.
Agora falta somente uma coisa: finalizar a compra e gravar o
pedido.
Só que para fazer isso, o usuário tem de se identificar.
E não podemos esquecer de que, se o usuário não existir,
ele pode se cadastrar no ato da compra.

Já temos o link para o fechamento na visão comprar.phtml:

<a href="/zend/acme/carrinho/fechar">Fechar
compra</a>

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Fechando a compra

Agora criaremos na classe CarrinhoController o método


fechar.

/* Fechamento da compra */
public function fecharAction()
{
if (!isset($_SESSION['cliente']))
{
$this->_redirect('/index/acessar');
exit;
}
}

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Fechando a compra

$view = Zend_Registry::get('view');

$view-
>assign('header','pageHeader.phtml');
$view->assign('body','fechar.phtml');
$view-
>assign('footer','pageFooter.phtml');
$this->_response->setBody($view-
>render('default.phtml'));

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Fechando a compra

Dá pra perceber que esse método vai exigir a criação de


duas visões. Uma é fechar.phtml. Outra é acessar.phtml.

Vamos começar pela tela de identificação do cliente. Só que


antes, precisamos criar a tabela usuarios no banco de
dados, com os seguintes campos:

➔id : serial / (não nulo, chave única e chave primária)


➔cpf : text

➔email: text

➔senha: text

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Identificando o cliente

Vamos aproveitar esta oportunidade e alterar dois links do


arquivo pageHeader.phtml de:

<a href="./acessar" >Acessar</a>


&nbsp;
<a href="./cadastrar" >Cadastrar</a>

para

<a href="/zend/acme/index/acessar" >Acessar</a>


&nbsp;
<a href="/zend/acme/index/cadastrar"
>Cadastrar</a>

É que, como vamos criá-los agora, não vai dar erro.

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Identificando o cliente

No IndexController, vamos criar primeiro o método acessar:

/* Identificação do cliente */
public function acessarAction()
{
if (isset($_SESSION['cliente']))
{
$this->_redirect('/carrinho/comprar');
}
}

$view = Zend_Registry::get('view');

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Identificando o cliente

$view-
>assign('mensagem',isset($_SESSION['mensagem'])
? $_SESSION['mensagem'] : '');

$view-
>assign('header','pageHeader.phtml');
$view->assign('body','acessar.phtml');
$view-
>assign('footer','pageFooter.phtml');
$this->_response->setBody($view-
>render('default.phtml'));
}

Agora vamos criar a visão acessar.phtml em views/scripts:


FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br
Treinamento em PHP 5 módulo II
Identificando o cliente

<h3 id="warning"><?=$this->mensagem?></h3>
<center>
<form action="/zend/acme/index/login" method="post">
CPF:
<input name="cpf" value="" id="cpf" type="text">
e-mail:
<input name="email" value="" id="email" type="text">
senha:
<input name="senha" value="" id="senha" type="password">
<input type="submit" name="login" value="Login"/>
</form>
</center>
<a href="/zend/acme/carrinho">Carrrinho de compras</a>

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Identificando o cliente

Essa visão submete o formulário para o método login do


IndexController. Vamos criá-lo :

/* Efetua o login do cliente */


public function loginAction()
{
$cpf = $this->_request->getParam('cpf');
$email = $this->_request-
>getParam('email');
$senha = $this->_request-
>getParam('senha');

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Identificando o cliente
if ($cpf)
{
$campo = 'cpf';
}
else
{
$campo = 'email';
}

$where = $table->getAdapter()-
>quoteInto("$campo = ?", $cpf);
$usuario = $table->fetchAll($where)->toArray();

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Identificando o cliente
if (!empty($usuario) &&
$usuario[0]['senha'] == $senha)
{
$_SESSION['cliente'] = $usuario;
$this->_redirect('/carrinho');
}
else
{
$_SESSION['mensagem'] = 'Dados
inválidos';
$this->_redirect('/index/acessar');
}
}

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Cadastrando o cliente
Precisamos agora cadastrar um cliente. Vamos criar o método
cadastrar em IndexController. Ele só serve para exibir a visão
correspondente, que criaremos em seguida:

/* Cadastramento do cliente */
public function cadastrarAction()
{
$view = Zend_Registry::get('view');

$view-
>assign('mensagem',isset($_SESSION['mensagem'])
? $_SESSION['mensagem'] : '');

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Cadastrando o cliente
$_SESSION['mensagem'] = '';
$view-
>assign('header','pageHeader.phtml');
$view->assign('body','cadastrar.phtml');
$view-
>assign('footer','pageFooter.phtml');
$this->_response->setBody($view-
>render('default.phtml'));
}

Em seguida, vamos criar a visão cadastrar.phtml em


views/script.

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Cadastrando o cliente
<h2 id="warning"><?=$this->mensagem?></h2>
<center>
<form action="/zend/acme/index/gravarCliente"
method="post">
CPF:
<input name="cpf" value="" id="cpf"
type="text">
e-mail:
<input name="email" value="" id="email"
type="text">
senha:
<input name="senha" value="" id="senha"
type="password">

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Cadastrando o cliente
Confirme a senha:
<input name="senha2" value="" id="senha2"
type="password">
<input type="submit" name="cadastrar"
value="Cadastrar"/>
</form>
</center>
<a href="/zend/acme/carrinho">Carrinho de
compras</a>

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Gravando os dados do cliente
Como pode se ver, esse formulário submete os dados para a
ação gravarCliente. Temos de implementar esse método na
classe IndexController:

/* Persistência dos dados do cliente */


public function gravarClienteAction()
{
$cpf = $this->_request->getParam('cpf');
$email = $this->_request-
>getParam('email');
$senha = $this->_request-
>getParam('senha');
$senha2 = $this->_request-
>getParam('senha2');

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Gravando os dados do cliente
if ($senha != $senha2)
{
$_SESSION['mensagem'] = 'Dados
inválidos';
$this->_redirect('/index/cadastrar');
exit;
}

$table = new Usuarios();


$where = $table->getAdapter()->quoteInto('cpf
= ?', $cpf);
$usuario = $table->fetchAll($where)-
>toArray();

$cpfExiste = !empty($usuario);

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Gravando os dados do cliente
if ($cpfExiste)
{
$_SESSION['mensagem'] = 'CPF já
cadastrado';
$this->_redirect('/index/cadastrar');
exit;
}

$where = $table->getAdapter()-
>quoteInto('email = ?', $email);
$usuario = $table->fetchAll($where)-
>toArray();

$emailExiste = !empty($usuario);

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Gravando os dados do cliente
if ($emailExiste)
{
$_SESSION['mensagem'] = 'E-mail já
cadastrado';
$this->_redirect('/index/cadastrar');
exit;
}

$dados =
array('cpf'=>$cpf,'email'=>$email,'senha'=>$se
nha);

$table->insert($dados);
$this->_redirect('/index/acessar');
}

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Gerenciando a sessão do cliente
Precisamos agora colocar uma identificação visual que
indique que o cliente está identificado.

No arquivo pageHeader.phtml, incluiremos um bloco de


código no primeiro trecho em PHP antes do código HTML:

if (!isset($_SESSION['cliente']))
{ $cpf = ''; }
else
{
$cliente = $_SESSION['cliente'];
$cpf = $cliente['cpf'];
}

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Gerenciando a sessão do cliente
Perceba que os links Acessar e Cadastrar não fazem sentido se o
usuário já se identificou. Então temos que trocá-los por um outro
link, chamado Sair:

<?php
if ($cpf=='')
{
?>
<a href="/zend/acme/index/acessar" >Acessar</a>
&nbsp;
<a href="/zend/acme/index/cadastrar" >Cadastrar</a>
<?php
}
else
{
?>
<a href="/zend/acme/index/logout" >Sair</a>
<?php
}
?>

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Gerenciando a sessão do cliente
Agora seremos obrigado a criar o método logout na classe
IndexController:

/* Encerra a sessão do cliente, destruindo o


carrinho */
public function logoutAction()
{
/* Mata todas as variáveis de sessão */
$_SESSION = array();

/* Apaga o cookie de sessão */


if (isset($_COOKIE[session_name()])) {
setcookie(session_name(), '', time()-
42000, '/');
}

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Gerenciando a sessão do cliente
/* Destrói a sessão. */
session_destroy();

$this->_redirect('/');
}

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Fechando a compra
Finalmente, vamos retornar para o fechamento da compra e
finalizá-lo. Vamos criar o arquivo de visão fechar.phtml:

<center>
<form action="/zend/acme/carrinho/gravarCompra"
method="post">
<h2>Forma de pagamento:</h2>
<?=$this->escape('Boleto Bancário')?>
<input name="formaPagamento" value="boleto"
id="formaPagamento" type="radio"/>
<?=$this->escape('Cartão de Crédito')?>
<input name="formaPagamento" value="cartao"
id="formaPagamento" type="radio"/>
<input type="submit" name="gravar" value="Gravar"/>
</form>
</center>
<a href="/zend/acme/carrinho">Carrinho de compras</a>

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Fechando a compra

Agora, faremos o método gravarCompra, que efetivamente


fecha o pedido.
O pedido de compra será armazenado em uma tabela
chamada pedidos. Os itens do pedido serão guardados em
uma tabela chamada itens.
A tabela pedidos terá os seguintes campos:

➔id : serial / (não nulo, chave única e chave primária)


➔codigo : text

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Fechando a compra
A tabela itens terá os seguintes campos:

➔id : serial / (não nulo, chave única e chave primária)


➔pedido_id : integer

➔produto_id: integer

➔valor: money

➔quantidade: integer

Vamos ignorar a gravação da forma de pagamento.


Bem, agora sim, vamos construir o método gravarCompra:

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Fechando a compra

/* Grava o pedido de compra */


public function gravarCompra()
{
$formaEscolhida = $this->_request-
>getParam('formaPagamento');

$formasPagamento = array('boleto'=>'Boleto
Bancário','cartao'=>'Cartão de Crédito');

$codigo = mt_rand(10000,99999);

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Fechando a compra

$pedido = new Pedidos();

$idPedido = $pedido-
>insert(array('codigo'=>$codigo));

$itens = $_SESSION['carrinho'];

foreach ($itens as $item)


{
$dados = array('pedido_id'=>$idPedido,
'produto_id'=>$item['id'],
'valor'=>$item['valor'],
'quantidade'=>$item['quantidade']);

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Fechando a compra

$novoItem = new Itens();


$novoItem->insert($dados);
}

unset($_SESSION['carrinho']);

$mensagem = "O pedido $codigo pago com


{$formasPagamento[$formaEscolhida]} foi
finalizado com sucesso";

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Fechando a compra

$view = Zend_Registry::get('view');

$view->assign('mensagem',$mensagem);

$view-
>assign('header','pageHeader.phtml');
$view-
>assign('body','gravarCompra.phtml');
$view-
>assign('footer','pageFooter.phtml');
$this->_response->setBody($view-
>render('default.phtml'));
}

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Fechando a compra
E, para finalizar, vamos criar a visão que exibe a mensagem
com o número do pedido. Em views/scripts, crie o arquivo
gravarCompra.phtml. Aqui vai ter um problema. Em
views/scripts/carrinho o arquivo continente terá de se
chamar gravarcompra.phtml.

<h3 id="warning"><?=$this->mensagem?></h3>
<a href="/zend/acme/">Página inicial</a>

Agora, só falta implementar a busca de produtos por nome e


a parte do cliente está praticamente completa.

Vamos deixar a busca com outro controlador. No diretório


controllers, criaremos o arquivo BuscasController.php.

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Buscando produtos
<?php
/**
* Controlador de Buscas
* Controla as pesquisas e seus resultados
* @filesource
* @author Flávio Lisboa
* @copyright Copyright 2007 SERPRO
* @package zendframework
* @subpackage
zendframework.acme.application.controllers
* @version 1.0*/

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Buscando produtos
/**
* Este método será executado sempre que a classe
for instanciada,
* depois do construtor.
* Faz o carregamento das classes que serão
usadas pelo controlador.
*
* @return void
*/
public function init()
{
Zend_Loader::loadClass('Usuarios');
Zend_Loader::loadClass('Produtos');
Zend_Loader::loadClass('Itens');
Zend_Loader::loadClass('Pedidos');
}

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Buscando produtos
/**
* Método que mostra o resultado da pesquisa
*
* @return void
*/
public function indexAction()
{
$chave = (string)$this->_request-
>getParam('nome');

$view = Zend_Registry::get('view');

$table = new Produtos();

$where = "position('$chave' in nome)>0";


$produtos = $table->fetchAll($where);

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Buscando produtos

$view->assign('produtos',$produtos-
>toArray());

$view->assign('header','pageHeader.phtml');
$view->assign('body','index.phtml');
$view->assign('footer','pageFooter.phtml');
$this->_response->setBody($view-
>render('default.phtml'));
}
}

Não podemos esquecer de criar a visão buscas.phtml vazio


no diretório buscas de views/scripts. Não precisamos criar
um homônimo na raiz de views/scripts porque usaremos o
index.phtml para exibir os produtos encontrados.

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Controlando o Estoque

E assim, finalizamos a parte que interessa ao cliente. Agora


precisamos criar um módulo para que o estoquista da loja
consiga fazer a manutenção dos produtos em estoque.

Para isso, criaremos um outro controlador, que irá cuidar


dessa parte de estoque. O nome do arquivo será
EstoqueController.php.

O comportamento padrão (método index) será exibir uma


tela para o estoquista se logar no sistema. Vamos usar a
mesma tabela de usuários que criamos para os clientes.

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Controlando o Estoque
<?php
/**
* Controlador de Estoque
* Controla as operações de estoque
* @filesource
* @author Flávio Lisboa
* @copyright Copyright 2007 SERPRO
* @package zendframework
* @subpackage
zendframework.acme.controllers
* @version 1.0
*/

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Controlando o Estoque
class EstoqueController extends Zend_Controller_Action
{
/**
* Este método será executado sempre que a classe for
instanciada,
* depois do construtor.
* Faz o carregamento das classes que serão usadas pelo
controlador.
*
* @return void
*/
public function init()
{
Zend_Loader::loadClass('Usuarios');
Zend_Loader::loadClass('Produtos');
Zend_Loader::loadClass('Itens');
Zend_Loader::loadClass('Pedidos');
}
FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br
Treinamento em PHP 5 módulo II
Controlando o Estoque
O formulário de login estará em estoqueLogin.phtml dentro de
views/scripts:

<h2 id="warning"><?=$this->mensagem?></h2>
<center>
<form action="/zend/acme/estoque/login"
method="post">
CPF:
<input name="cpf" value="" id="cpf" type="text">
senha:
<input name="senha" value="" id="senha"
type="password">
<input type="submit" name="login" value="Login"/>
</form>
</center>

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Controlando o Estoque
Vamos usar um outro cabeçalho para o controle de estoque. Ele
ficará no arquivo estoqueHeader.phtml:

<div id="header">
<h1 id="logomarca_customer">Lojas Acme</h1>
</div>

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Controlando o Estoque
Agora vamos fazer o método padrão que irá gerar a página inicial
do controle de estoque:

public function indexAction()


{
$view = Zend_Registry::get('view');

$view-
>assign('mensagem',isset($_SESSION['mensagem']) ?
$_SESSION['mensagem'] : '');
$_SESSION['mensagem'] = '';
$view->assign('header','estoqueHeader.phtml');
$view->assign('body','estoqueLogin.phtml');
$view->assign('footer','pageFooter.phtml');
$this->_response->setBody($view-
>render('default.phtml'));
}
FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br
Treinamento em PHP 5 módulo II
Controlando o Estoque
O método login que responde ao formulário de login será este:

/* Efetua o login do estoquista */


public function loginAction()
{
$cpf = (string)$this->_request->getParam('cpf');
$senha = (string)$this->_request-
>getParam('senha');

if ($cpf)
{
$where = $table->getAdapter()->quoteInto('cpf
= ?', $cpf);
$usuario = $table->fetchAll($where)->toArray();
}
else
{ $usuario = NULL; }

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Controlando o Estoque
if (!empty($usuario) && $usuario[0]['senha']
== $senha)
{
$_SESSION['estoquista'] = $usuario[0];
$this->_redirect('/estoque/manterproduto');
}
else
{
$_SESSION['mensagem'] = 'dados inválidos';
$this->_redirect('/estoque');
}

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Controlando o Estoque
Agora o método manterProduto:

/* Exibe o menu de operações de estoque */


public function manterProduto()
{
if (!isset($_SESSION['estoquista']))
{ $this->_redirect('/estoque');}
else
{
$estoquista = $_SESSION['estoquista'];
$cpf' = $estoquista['cpf'];
$itens = $table->fetchAll());
}

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Controlando o Estoque
$view = Zend_Registry::get('view');

$view->assign('mensagem',isset($_SESSION['mensagem']) ?
$_SESSION['mensagem'] : '');
$_SESSION['mensagem'] = '';
$view->assign('cpf',$cpf);
$view->assign('itens',$itens->toArray());
$view->assign('header','estoqueHeader.phtml');
$view->assign('body','manterProduto.phtml');
$view->assign('footer','pageFooter.phtml');
$this->_response->setBody($view->render('default.phtml'));
}

Eserá necessário criar um arquivo manterproduto.phtml dentro


de views/scripts/estoque. Mas o corpo mesmo será o
manterProduto.phtml dentro de views/scripts (que é o associado
acima).

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Controlando o Estoque

Esse será o conteúdo do template manterProduto.phtml:

<h2 id="warning"><?=$this->mensagem?></h2>
<h2>Estoquista: <?=$this->cpf?></h2>
<table id="inventario">
<thead>
<?php
$titulos = array('Código',
'Nome',
'Quantidade',
'Preço Unitário',
'Dar entrada',
'Dar baixa',
'Excluir');
foreach ($titulos as $titulo)
{
echo '<th>'.$this->escape($titulo).'</th>';
}
?>
FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br
Treinamento em PHP 5 módulo II
Controlando o Estoque
</thead>
<?php
$somaTotal = 0;

foreach ($this->itens as $item)


{
$codigo = $item['id'];
$nome = '<a
href="/zend/acme/estoque/nome?id='.$codigo.'">'.$this-
>escape($item['nome']).'</a>';
$quantidade = $item['quantidade'];
$preco = '<a
href="/zend/acme/estoque/preco?id='.$codigo.'">'.$item['valor'].'
</a>';
$entrada = '<a
href="/zend/acme/estoque/entrada?id='.$codigo.'">E</a>';
$baixa = '<a
href="/zend/acme/estoque/baixa?id='.$codigo.'">B</a>';
$excluir = '<a
href="/zend/acme/estoque/excluir?id='.$codigo.'">X</a>';

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Controlando o Estoque
$colunas = array($codigo,
$nome,
$quantidade,
$preco,
$entrada,
$baixa,
$excluir);
echo '<tr>';

foreach ($colunas as $coluna)


{
echo '<td>';
echo $coluna;
echo '</td>';
}

echo '</tr>';
}
?>

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Controlando o Estoque

</table>
<a href="/zend/acme/estoque/logout">Sair</a>

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Controlando o Estoque

Agora vamos fazer o método logout, antes de


implementar os demais:

/* Encerra a sessão do estoquista */


public function logoutAction()
{
/* Mata todas as variáveis de sessão */
$_SESSION = array();

/* Apaga o cookie de sessão */


if (isset($_COOKIE[session_name()])) {
setcookie(session_name(), '', time()-42000,
'/');
}
session_destroy();
$this->redirect('/estoque');
}
FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br
Treinamento em PHP 5 módulo II
Controlando o Estoque
Vamos criar um método interno agora:

/* Retorna um produto de acordo com o


id passado */
private function selecionarProduto()
{
$id = (int)$this->_request-
>getParam('id');
if (!isset($id))
{
$this-
>_redirect('/estoque/manterproduto');
exit;
}
FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br
Treinamento em PHP 5 módulo II
Controlando o Estoque
$table = new Produto();

$produtoSelecionado = $table-
>find($id)->toArray();

return $produtoSelecionado[0];
}

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Controlando o Estoque
Esse método será aproveitado em uma série de
métodos públicos.

Vamos implementar os métodos: entrada, baixa, nome e


preco.

Todos terão o mesmo código, mudando apenas a


associação do corpo do documento HTML.

Basta fazer o método entradaAction e depois usá-lo de


modelo para os outros, pois basta mudar o nome do
método e o conteúdo da variável body da visão.

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Controlando o Estoque
public function entradaAction()
{
$produtoSelecionado = $this->selecionarProduto();

$view = Zend_Registry::get('view');

$view-
>assign('produtoSelecionado',$produtoSelecionado);
$view->assign('header','estoqueHeader.phtml');
$view->assign('body','entrada.phtml');
$view->assign('footer','pageFooter.phtml');
$this->_response->setBody($view-
>render('default.phtml'));
}

Agora faremos as respectivas visões.


FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br
Treinamento em PHP 5 módulo II
entrada.phtml

<center>
<form action="/zend/acme/estoque/adicionar"
method="post">
<?php
if (isset($this->produtoSelecionado['id']))
{
echo '<b>Produto: '.$this->escape($this-
>produtoSelecionado['nome']).'</b><br/>';
echo '<b>'.$this->escape('Preço: ').$this-
>produtoSelecionado['valor'].'</b><br/>';
echo '<b>'.$this->escape('Posição de estoque:
').$this-
>produtoSelecionado['quantidade'].'</b><br/>';
}
?>

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
entrada.phtml

Quantidade:
<input name="quantidade" value=""
id="quantidade" type="text">
<input name="id" value="<?=$this-
>produtoSelecionado['id']?>" id="id"
type="hidden">
<input type="submit" name="darentrada"
value="Dar entrada"/>
</form>
</center>
<a
href="/zend/acme/estoque/manterProduto">Inventá
rio</a>

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
baixa.phtml

<center>
<form action="/zend/acme/estoque/subtrair"
method="post">
<?php
if (isset($this->produtoSelecionado['id']))
{
echo '<b>Produto: '.$this->escape($this-
>produtoSelecionado['nome']).'</b><br/>';
echo '<b>'.$this->escape('Preço: ').$this-
>produtoSelecionado['valor'].'</b><br/>';
echo '<b>'.$this->escape('Posição de estoque:
').$this-
>produtoSelecionado['quantidade'].'</b><br/>';
}
?>

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
baixa.phtml
Quantidade:
<input name="quantidade" value=""
id="quantidade" type="text">
<input name="id" value="<?=$this-
>produtoSelecionado['id']?>" id="id"
type="hidden">
<input type="submit" name="darbaixa" value="Dar
baixa"/>
</form>
</center>
<a
href="/zend/acme/estoque/manterProduto">Inventá
rio</a>

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
nome.phtml
<center>
<form action="/zend/acme/estoque/alterarNome"
method="post">
<?php
if (isset($this->produtoSelecionado['id']))
{
?>
Nome:
<input name="nome" value="<?=$this-
>escape($this->produtoSelecionado['nome'])?>"
id="nome" type="text">
<input name="id" value="<?=$this-
>produtoSelecionado['id']?>" id="id"
type="hidden">
<?php
}
FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br
Treinamento em PHP 5 módulo II
nome.phtml
?>
<input type="submit" name="alterarnome"
value="Alterar nome"/>
</form>
</center>
<a
href="/zend/acme/estoque/manterProduto">Inventá
rio</a>

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
preco.phtml
<center>
<form action="/zend/acme/estoque/alterarPreco"
method="post">
<?php
if (isset($this->produtoSelecionado['id']))
{
?>
Preço :
<input name="preco" value="<?=$this-
>escape($this->produtoSelecionado['valor'])?>"
id="preco" type="text">
<input name="id" value="<?=$this-
>produtoSelecionado['id']?>" id="id"
type="hidden">
<?php
}
FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br
Treinamento em PHP 5 módulo II
preco.phtml
?>
<input type="submit" name="alterarpreco"
value="Alterar preço"/>
</form>
</center>
<a
href="/zend/acme/estoque/manterProduto">Inventá
rio</a>

Não esqueça de criar os arquivos phtml vazios


dentro de views/scripts/estoque.
E em seguida, faremos em EstoqueController os
métodos aos quais essas visões submetem seus
dados.

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Método adicionar
/* Adição de quantidade de estoque */
public function adicionarAction()
{
$id = (int)$this->_request->getParam('id');
if (!is_null($id))
{
$quantidade = (int)$this->_request-
>getParam('quantidade');

$table = new Produtos();

$produto = $table->find($id)->toArray();

$quantidade = $quantidade +
$produto[0]['quantidade'];

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Método adicionar

$dados = array('quantidade' => $quantidade);

$where = $table->getAdapter()->quoteInto('id = ?
', $id);

$table->update($dados, $where);
}

$this->_redirect('/estoque/manterproduto');
}

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Método subtrair

/* Subtração de quantidade de estoque */


public function subtrairAction()
{
$id = (int)$this->_request->getParam('id');
if (!is_null($id))
{
$quantidade = (int)$this->_request-
>getParam('quantidade');

$table = new Produtos();

$produto = $table->find($id)->toArray();

$quantidade = $produto[0]['quantidade'] -
$quantidade;

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Método subtrair

$dados = array('quantidade' => $quantidade);

$where = $table->getAdapter()->quoteInto('id = ?
', $id);

$table->update($dados, $where);
}

$this->_redirect('/estoque/manterproduto');
}

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Método alterarNome
/* Gravação de um novo nome */
public function alterarNomeAction()
{
$id = (int)$this->_request->getParam('id');
if (!is_null($id))
{
$nome = (string)$this->_request->getParam('nome');

$table = new Produtos();

$dados = array('nome' => $nome);

$where = $table->getAdapter()->quoteInto('id = ?',


$id);

$table->update($dados, $where);
}

$this->_redirect('/estoque/manterproduto');
}
FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br
Treinamento em PHP 5 módulo II
Método alterarPreco
/* Gravação de um novo preco */
public function alterarPrecoAction()
{
$id = (int)$this->_request->getParam('id');
if (!is_null($id))
{
$nome = (string)$this->_request->getParam('preco');

$table = new Produtos();

$dados = array('valor' => $nome);

$where = $table->getAdapter()->quoteInto('id = ?',


$id);

$table->update($dados, $where);
}

$this->_redirect('/estoque/manterproduto');
}
FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br
Treinamento em PHP 5 módulo II
Controlando o Estoque

Agora o método para excluir produtos:

/* Exclusão do produto */
public function excluirAction()
{
$id = (int)$this->_request->getParam('id');
if (!is_null($id))
{
$table = new Itens();

$where = $table->getAdapter()-
>quoteInto('produto_id = ?', $id);
$pedidos = $table->fetchAll($where)-
>toArray();

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Controlando o Estoque

if (empty($pedidos))
{
$table = NULL;
$table = new Produtos();
$where = $table->getAdapter()-
>quoteInto('id = ?', $id);
$table->delete($where);
}
else
{
$_SESSION['mensagem'] = 'produto
consta em pedido';
}
}
$this->_redirect('/estoque/manterproduto');
}
FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br
Treinamento em PHP 5 módulo II
Controlando o Estoque
Para renderizar a tela de inclusão de novos produtos,
precisamos criar um método com o nome incluir:

/* Inclusão de produto */
public function incluirAction()
{
$view = Zend_Registry::get('view');

$view->assign('header','estoqueHeader.phtml');
$view->assign('body','incluir.phtml');
$view->assign('footer','pageFooter.phtml');
$this->_response->setBody($view-
>render('default.phtml'));
}

Agora, precisamos criar a visão que é invocada por esse


método. Será o arquivo incluir.phtml em views/scripts.
FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br
Treinamento em PHP 5 módulo II
Controlando o Estoque

<center>
<form
action="/zend/acme/estoque/incluirProduto"
method="post">
Nome:
<input name="nome" value="" id="nome"
type="text">
<input type="submit" name="incluir"
value="Incluir"/>
</form>
</center>
<a
href="/zend/acme/estoque/manterProduto">Inven
tário</a>

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Controlando o Estoque
Esse formulário irá submeter os dados para o método
incluirProduto, de EstoqueController.

/* Gravação de novo produto */


public function incluirProdutoAction()
{
$nome = (string)$this->_request-
>getParam('nome');
if (isset($nome))
{
$table = new Produtos();

$dados = array( 'nome'=> $nome,


'quantidade'=> 0,
'valor' => 0);

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Controlando o Estoque

$table->insert($dados);
}
else
{
$_SESSION['mensagem'] = 'nome inválido';
}
$this->_redirect('/estoque/manterProduto');
}

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Controlando o Estoque
Agora o estoquista deve ter uma tela como esta:

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Treinamento em PHP 5 módulo II
Encerramento

Assim, encerra-se este curso.

Dúvidas? Se houverem...

... explicaremos tudo tintim por tintim.

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Programação para Web com PHP
Fontes de consulta

http://www.php.net (PHP Group)


http://phpbrasil.com
http://www.prophp.com.br
http://www.phpclasses.org
http://www.zend.com

Flávio Gomes da Silva Lisboa


Analista de Desenvolvimento de Sistemas
SERPRO
flaviogomesdasilva@yahoo.com.br
www.fgsl.eti.br

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Programação para Web com PHP
Agradecimentos

Elton Luís Minetto, por seu livro “Frameworks para Desenvolvimento em


PHP”
Felipe Tonello por sua palestra sobre Zend Framework no evento
“Frameworks para Desenvolvimento em PHP”, realizado na FIT, em São
Paulo.

Até a próxima!

FLÁVIO GOMES DA SILVA LISBOA www.fgsl.eti.br


Programação para Web com PHP