terça-feira, 23 de junho de 2009

Carrinho de compras com Zend Framework

E ai pessoal,
Desculpem minha ausência, tenho me ocupado muito com alguns projetos que tenho feito por fora.

Tenho mexido bastante com o Zend Framework e só tenho uma coisa a dizer: Estou tendo bem menos dor de cabeça do que quando programava com PHP puro. Isso sem falar da organização do projeto em MVC, os benefícios do Zend_Layout, etc.

Em um dos projetos, tive que construir um carrinho de compras utilizando Session.
Eu li um livro sobre Zend Framework, que ensina a criar um carrinho de compras com o Zend_Registry.
O problema do Zend_Registry é que ele não utiliza sessões, mas sim variáveis globais.

Eu não me basiei nesse livro, então caso saiba de qual livro estou me referindo, esqueça o carrinho que você aprendeu lá caso queira fazer um carrinho baseado em Session.

Para a criação de Sessions no Zend, nós utilizamos a classe Zend_Session_Namespace();

Como essa é uma classe singleton, caso já tenha sido criada uma instância da mesma, apenas é retornado a instância já criada. Você pode tentar criá-la várias vezes, mas ela apenas retornará a instância que já foi criada, até que ela seja liberada da memória.
Ou seja, o Zend simplesmente ignora a criação do novo objeto vazio e continua a session com os mesmos valores já gravados.


Eu ajustei uma classe que peguei em um forum sobre ZF. Ela "manuseia" uma session e achei que valeria a pena incluí-la no meu projeto.

Como tive muito problemas ao postar o código nesse blog, eu printei as telas.
Pois o blog não estava permitindo que eu colocasse os conteudos

Segue abaixo a classe. Você pode ajustá-la conforme suas necessidades. Para nosso carrinho, creio que seja o suficiente da forma como a deixei.

CLASSE "CONTROLADORA" DAS NOSSAS SESSIONS


Eu já dei o name do meu namespace de carrinho, mas você pode colocar no construtor da classe um parâmetro que seria o nome do seu namespace. Caso você não de um nome para o namespace, ele adota o valor Default.
Ficaria assim: Zend_Session_Namespace('Default');


ACTION DE INCLUSÃO DE ITEM NO CARRINHO



LISTANDO OS ITENS NO CARRINHO

Para listar os itens no carrinho é simples, basta fazer um foreach da variavel carrinho, que atribuimos o valor no nosso controller: "$this->view->carrinho = $carrinho;"

$carrinho = $this->carrinho;
$chave = @array_keys($carrinho);
for($ i = 0; $i < count ($chave);$ i ++){
$indice = $chave[$i];

//CRIANDO O OBJETO DA NOSSA CLASSE DE PERSISTENCIA COM A BASE DE DADOS, DA TABELA PRODUTOS.

$produtos = new Produtos();
$where = "idproduto = ".$carrinho[$indice]['idproduto'];
//PUXANDO OS DADOS DO PRODUTO
$produto = $produtos->fetchRow($where);
}


Eu estou criando um objeto da nossa classe de persistencia (model), para poder visualizar o nome do produto, qtde em estoque, entre outras coisas.
Você pode usar seu próprio modelo.
Caso queira apenas mostrar o código do produto e quantidade escolhida pelo usuário, você poderia implementar o código abaixo:

$carrinho = $this->carrinho;
$chave = @array_keys($carrinho);

for($ i = 0;$ i< sizeof ($chave); $ i ++){
//GUARDANDO O INDICE DO ARRAY
$indice = $chave[$i];
//MOSTRANDO OS DADOS INCLUIDOS NO CARRINHO
echo $carrinho[$indice]['idproduto']." - ".$carrinho[$indice]['qtde'];

}


ATUALIZANDO E EXCLUINDO ITENS DO CARRINHO
Para atualizar ou excluir itens de um carrinho, eu coloquei um checkbox em nosso carrinho de compras, contendo o indice do mesmo ($indice), então eu aplico um submit do formulário contendo os itens incluidos.
O formulário nos enviará para uma action chamada udcarrinhoAction().

Segue abaixo minha action udcarrinho:



Caso vocês queiram apagar todos os itens do carrinho, basta usar o método emptySess da nossa classe.

Caso tenham dúvidas em como montar o formulário do carrinho, entrem em contato comigo. Farei de tudo para ajudar.

The Best regards for you guys!! ;)

15 comentários:

Wellington disse...

Dei uma olhada por cima no seu código, depois com calma irei testar =D

Você sabe mexer com translated routes no ZF ? estou com um problema chato, que é na hora fazer a rota reconhecer os valores passados pela url, ela só funciona se eu setar o locale no código.

Maurício Vinicius de O. Santos disse...

E ai Wellington.
sinceramente nunca mexi com translated routes... :(

Giolvani disse...

blz Maurício,

cara, onde que eu coloco essa classe SessionWrapper???

parabéns pelo post!!

Giolvani

Maurício Vinicius de O. Santos disse...

E ai Giovani
vc pode criar um diretorio dentro de application chamado classes
Dai dentro desse diretorio, vc joga todas as suas classes que vc pode utilizar em todo o seu projeto, como a SessionWeapper.
Dai no seu bootstrap, vc insere o diretorio classes em seu include_path.
qq duvida posta ai cara...t+

Giolvani disse...

olá Maurício,

cara, se tu puder me ajudar nessa cara, ficarei agradecido...

entao criei a pasta como vc disse mas nao consigo carrega-lá...

fica dando um erro
Fatal error: Class 'Teste' not found in /var/www/siges/application/controllers/AuthController.php on line 22

nao sei mais o que fazer cara, preciso fazer isso funcionar senao to morto!!! heheh

to usando a versao 1.8 do ZF, e pelo que vi pra carregar os plugins fica diferente!!!

me ajuda ai velho...

vlw...
abraços

Maurício Vinicius de O. Santos disse...

E ai cara...
pelo que estou vendo, esse erro esta dando pq vc esta chamando uma classe chamada Teste mas o PHP não esta achando o arquivo dessa classe.
Se puder zipar seus arquivos (sem o diretorio Library) e me enviar por email, eu tento te ajudar
envie para mvosantos@yahoo.com.br
flw...t+

Fabiano Melo disse...

Achei muito bom seu post. A tempo procurava algo do genero. No final de seu post vc se coloca a disposição no caso de necessitar de ajuda no formulario. Gostaria de saber se tem um exemplo deste form, mesmo que seja bem básico.

Meu Blog disse...

Caro Mauricio,
estou desenvolvinde um upload de arquivos no qual é inserido em um campo binário utilizando MsSql, e esse exemplo de carrinho de compras vem de encontro ao que eu necessito, no entanto, quando chamo a função $arquivo = $sess->getSessVar('arquivo'); pra recuperar a sessão da o erro "Call to a member function getSessVar() on a non-object", o que poderia ser esse erro?? guerreiro777@gmail.com

thiago.adriano disse...

Boa Tarde Amigo poderia me enviar este codigo para o meu email estou a dois dias tentando criar um carrinho com o zend e ainda nao consegui.

Agradeço desde ja !!

thiago.adriano26@gmail.com

ou

adriano@microsistec.com.br

Rafael Querino disse...

estou com a seguinte dúvida, vc criou um controller chamado carrinhoController e colocou as actions nela, ou utilizou algum controller já existente, se tiver como passar algum exemplo funcionando pra tirar uma idéia eu agradeço.

marcos (Master) disse...

ei mano tudo??? , to iniciando no zend agora, gostari de saber se tem como vc postar um exemplo de um catalogo de produtos (exemplo simples) ai pode ser?

marcos (Master) disse...
Este comentário foi removido pelo autor.
Ramon disse...

Olá, será que é possível implementar todas etas ações em um objeto Carrinho e instancia-lo quando desejar usa-lo?

Vocês acham que é melhor ou terei alguma perda de desempenho?

Falows.

Uma rosa de ouro para a Virgem disse...
Este comentário foi removido pelo autor.
Júnior Lemes disse...

Olá, muito boa sua dica.
Utilizei o seu tutorial para criar um carrinho de compras mas estou com problemas. Eu não consigo inserir mais de um produto na session pois o último produto que insiro substitui o anterior. Saberia me dizer o que fazer?
Grato desde já.