Como fazer um Carrinho de Compras utilizando a biblioteca Cart

Update! 18/03/2015

A biblioteca Cart  foi descontinuada na versão 3.0 do CodeIgniter. Apesar de você conseguir encontrá-la na versão nova do CI, ela foi mantida somente por questões de retrocompatibilidade. Então, sugere-se que esta biblioteca não seja mais utilizada.

 

Olá.

Na era das Lojas-Virtuais é bem comum que você tenha que desenvolver algo parecido para algum cliente.

Apesar de já existirem excelentes sistemas prontos de lojas virtuais, é sempre bom saber como implementar a principal funcionalidade de uma Loja-Virtual. O Carrinho de Compras.

Antes de continuar no post, você pode ver este projeto funcionando clicando no link abaixo:

-> Carrinho de Compras do CodeIgniter.

Não é raro clientes desejarem ter suas próprias aplicações para gerenciar a venda de seus produtos, e se você não for usar um sistema de loja-virtual pronto, você vai ter que desenvolver um na unha.

No post de hoje vamos aprender a como fazer um carrinho de compras utilizando a biblioteca cart do CodeIgniter, que nos fornece a solução praticamente completa.

Digo praticamente completa porque esta biblioteca não vai gerenciar checkout ou os meios de pagamento e entrega.

Ela somente fornece a capacidade você criar um sistema de carrinho de compras, onde será possível adicionar ou remover produtos, atualizar suas quantidades, fazer o cálculo automático de preços vezes quantidade, listar quantos itens há no carrinho, listar o total dos produtos no carrinho, etc.

Apesar de ser uma solução excelente, ela tem um pequeno problema para quem usa acentos ou caracteres especiais como nós brasileiros.

Originalmente esta biblioteca não aceita que você insira um produto que tenha acentuação ou cedilha, til, circunflexo, etc, mas existe uma maneira bem tranquila de resolver isto. Lá embaixo no código você vai ver como.

Para começar nosso projeto, eu fiz uma instalação limpa do CI e configurei-o para acessar um Banco de Dados e para carregar automaticamente a biblioteca cart.

A biblioteca cart usa sessions para armazenar os dados do carrinho de compras, porém, se você não está utilizando sessions em outro lugar de sua aplicação, não vai ser preciso carregar esta biblioteca, pois o cart já faz isto automaticamente.

É importante destacar também que você deve configurar a session do CI para armazenar as informações no banco de dados, em vez de cookies.

Para isto, você deve mudar para TRUE a linha abaixo dentro do arquivo config.php

Esta será provavelmente a linha 251.

Depois, você precisa criar a tabela que as sessions irão utilizar. Abaixo estou também colando o código desta tabela. Basta executá-la a aba SQL do seu PHPMyAdmin.

Feito isso, vamos agora começar a configurar nosso carrinho de compras.

Como você viu, neste exemplo eu somente cadastrei alguns produtos em uma tabela produtos e os listei na página inicial do carrinho de compras, sendo que coloquei um botão de Comprar para cada produto, exatamente como seria em uma loja-virtual.

Eu só não deixei visualmente igual, pois não é o objetivo aqui.

Quando o usuário clicar no botão Comprar, o produto é adicionado ao carrinho de compras e em seguida o carrinho de compras é carregado na tela, mostrando o que existe nele.

Você pode clicar no link Continuar Comprando para testar novos produtos.

Para carregar os produtos, eu criei um model chamado m_produtos.php com o seguinte código:

Este código quando chamado sem a passagem de parâmetros, simplesmente retorna todos os produtos da tabela produtos.

No controller welcome.php eu o configurei para trazer estes produtos do banco de dados e disponibilizá-los para a view, através da variável produtos. Veja:

Após ele carregar os produtos, eu chamo a view principal, v_produtos, que é responsável pela tela inicial do nosso sistema.

Repare que eu também carreguei um helper chamado funcoes que foi onde eu coloque uma função de formatação de preço que costumo utilizar bastante.

Abaixo segue o código do arquivo funcoes_helper.php que deve ser colocado com este nome dentro da pasta helpers dentro de application.

Para usar esta função, você deve gravar os preços sem pontos ou zeros no banco de dados. Exemplo: se for armazenar R$ 100,00, então grave no banco assim: 10000. Depois passe este valor para a função que ela fará a conversão automática.

Feito isto, vamos agora ver a view v_produtos.php que é responsável por mostrar os produtos que podem ser comprados.

Neste código não tem nenhum mistério. É basicamente HTML com um loop onde eu listo os produtos.

Porém, para evitar o uso de AJAX neste post, eu tentei deixar da maneira mais compatível possível.

Quando você clicar no botão Comprar, a página na verdade faz um post dos dados do produto para uma função dentro do controller que é responsável pela inserção do produto no carrinho de compras.

Como cada produto tem seus respectivos dados, eu criei um <form></form> para cada um, e dentro deste form, eu coloquei em campos hidden as informações necessárias para que o produto seja inserido no banco de dados.

Os campos requeridos são:

  • id – Código que identifica cada produto.
  • qty – Quantidade sendo comprada.
  • price – O preço do produto.
  • name – O nome do produto.
  • options – Algum atributo do produto. Exemplo: se for uma camisa vermelha, tamanho P, ou um produto 127V ou 220V, etc. Deve ser passado via array.

Abaixo veja o formato que estas informações devem ser passadas:

Com exceção do item ‘options’, todos os outros são obrigatórios, caso contrário, o item não será inserido no carrinho de compras.

Quando um produto é inserido com sucesso, é retornado um código único, chamado rowid que é responsável por cada linha dentro do carrinho de compras.

Isto serve para que seja possível ao usuário inserir um mesmo produto porém com opções diferentes.

Bem, terminada a parte de listagem de produtos, vamos agora trabalhar no controller carrinho.php, que é responsável por gerenciar as funções do carrinho de compras.

Abaixo o código do controller carrinho.php:

A função listar somente carrega uma view que tem o código do Carrinho de Compras, que somente lista o que existe dentro ele.

A segunda função tem como objetivo atualizar os itens do carrinho de compras.

Ela serve para que quando o usuário deseje excluir ou alterar a quantidade de um determinado produto, ele consiga fazer sem maiores problemas.

Nesta função é atribuída na variável $conteudo_postado tudo o que vem via post do formulário que engloba o carrinho de compras.

Para que um produto seja atualizado, 2 parâmetros devem ser passados obrigatoriamente: o rowid e a quantidade a ser alterada.

Se for passada a quantidade zero, então o produto é excluído do carrinho.

Em seguida, eu varro a variável $conteudo_postado e acesso as duas informações que preciso através dos índices rowid e qty.

Tendo isto em mãos, eu crio uma array no formato requerido e passo como parâmetro para a função de atualização do carrinho de compras, deste jeito:

Em seguida, eu simplesmente recarrego o carrinho de compras com as informações atualizadas.

A função inserir também é bem simples.

Ela basicamente recebe os valores requeridos para a inserção no carrinho de compras, monta um array no formato necessário que é passada como parâmetro para a função de inserção no carrinho de compras:

Como falei lá no começo do post, antes de dar um insert, existe uma linha que devemos adicionar para informar ao CodeIgniter que ele deve aceitar todos os caracteres digitados. Veja abaixo a linha:

Chame esta linha antes de chamar a função insert do carrinho de compras.

Se você não colocar esta linha, seu carrinho de compras vai funcionar somente com produtos que não tenham acentos ou caracteres especiais escritos.

E por último a função que apenas limpa o carrinho de compras. Ao ser chamada, ela acessa a função da biblioteca cart que faz isto para nós. Veja:

Depois de limpar o carrinho, eu o mostro novamente.

Vamos ver agora o código a view do carrinho de compras:

Aqui também não há nenhum segredo.

O código eu copiei da ajuda do site do CI, e o que tive que mudar é somente o endereço do action do formulário, indicando qual é a função que irá tratar as atualizações do carrinho de compras.

Repare que antes do carrinho de compras, eu chamei uma função que me traz a quantidade de itens dentro do carrinho. Esta função é:

Viu como já está tudo pronto?

Esta biblioteca também faz o cálculo automático dos preços e quantidades dos itens inseridos no carrinho, assim como também calcula o total geral.

O próximo passo agora seria você criar um botão Fechar Compra e proceder para as etapas de cadastro, envio e pagamento, mas isto não será contemplado aqui.

Depois, para acessar o total do carrinho de compras, basta chamar a função:

Esta é a função que retorna o valor total que o comprador deverá pagar no checkout.

Bom, acredito que seja isso. Espero que o post tenha sido útil para você.

Abaixo você pode testar novamente o sistema e logo em seguida, um link para você baixar o projeto para o seu computador.

-> Carrinho de Compras do CodeIgniter.

O SQL que cria as tabelas está dentro do zip.

-> Baixar o projeto

Se tiver alguma dúvida, basta fazer um comentário nos campos abaixo.

Um abraço.

 

Fábio S. Reszko

Sou Programador PHP desde 2006 e eu acredito sinceramente que programar usando um Framework PHP é a solução para os problemas de códigos desorganizados, difíceis de entender e de dar manutenção no futuro. Se você também acredita nisto, então fique à vontade em explorar meu blog.

  • Muito bem explicado e de maneira bem fácil. Parabéns.
    Abraço.

  • Pingback: Como integrar o CodeIgniter com a Cielo - DICAS CI - Dicas CodeIgniter()

  • Betinho Silva

    Como eu posso implementar uma ação de dividir? Tipo: o cliente faz uma compra e escolhe a forma de pagamento e em quantas vezes e já sai o resultado dividido.
    Valor total da compra: R$ 300,00. o cliente escolhe como será pago.
    cartao de credito, cheque, debito em conta, à vista
    se escolher cheque coloca quantas vezes quer ex. 3 vezes.
    ae sai o resultado.
    3x no cheque
    cheque1: R$ 100,00
    cheque2: R$ 100,00
    cheque3: R$ 100,00

  • Bom dia Betinho

    Sua solicitação acredito que vá após o carrinho de compras, pois o comprador irá informar como deseja pagar após finalizar a compra.

    Neste caso acredito que a implementação não seja muito difícil, mas ela não tem ligação direta com este carrinho de compras.

    Bastaria você pegar o valor total do Carrinho de compras, e oferecer as opções de pagamento ao usuário, usando HTML e JavaScript, por exemplo.

    Baseado no que o usuário escolher, você mostra na tela.

    Dá pra fazer também no PHP, mas a cada seleção de forma de pagamento que o usuário fizer, você faz um post para alguma página, que devolve, então, as opções de pagamento baseado no que o usuário escolheu.

    Seria algo assim: após o usuário clicar em Fechar Compra no carrinho de compras, ele é direcionado para uma tela onde ele vai escolher a forma de pagamento. Pode ser um radiogroup contendo: Cartão de Crédito, Cheque, Débito em Conta, à Vista.

    Ao clicar em alguma opção, a página dá um post para uma outra página que processa esta informação, e dependendo do que o usuário escolheu, chama-se outra página com as subopções de pagamento.

    Sugiro você usar o raciocínio acima para tentar elaborar algo.

    Abraços
    Fabio

  • Betinho

    Obg… vou tentar desenvolver….

  • Betinho Silva

    Fabio, obg… consegui desenvolver onde divide em 3x
    Outra coisa que eu queria q vc me ajudasse era o seguinte….

    tenho 2 campos onde um pega o valor da base de dados ex. R$ 800,00.
    ele tem um input de parcelas e outro onde aparece o valor total já dividido…

    qdo eu colocar no input “parcelas” o valor 4 ele já aparece no input “total” já o valor dividido
    que no caso seria R$ 200,00 sem ter q dar refresh..

    colocou e mudou de frame atualiza automatico

  • Betinho Silva

    Tenho essas funcoes de autocompletar de cliente…. mas pra calculo como varia?

    model

    public function autoCompleteCliente($q){

    $this->db->select('*');
    $this->db->limit(5);
    $this->db->like('nomeCliente', $q);
    $query = $this->db->get('clientes');
    if($query->num_rows > 0){
    foreach ($query->result_array() as $row){
    $row_set[] = array('label'=>$row['nomeCliente'].' | Telefone: '.$row['telefone'],'id'=>$row['idClientes']);
    }
    echo json_encode($row_set);
    }
    }

    Controlle:

    public function autoCompleteCliente(){

    if (isset($_GET['term'])){
    $q = strtolower($_GET['term']);
    $this->os_model->autoCompleteCliente($q);
    }

    }

    View:

    $("#cliente").autocomplete({
    source: "index.php/os/autoCompleteCliente",
    minLength: 2,
    select: function( event, ui ) {

    $("#clientes_id").val(ui.item.id);

    }
    });

    espero que me ajude…

  • Não sei se entendi direito, mas não seria suficiente você colocar a chamada da função que faz a divisão dos valores no evento onchange do campo “parcelas”? Ao fazer isso, você pega o valor, faz a divisão e atribui o resultado para o campo “total”.

    Fabio

  • Betinho, algumas considerações no seu código.

    No Model
    Você está usando $this->db->select(‘*’);
    Não precisa. A função $this->db->get(‘tabela’) já faz isso pra você. Use o select somente se você quiser selecionar algum campo ou renomeá-lo.
    Você está dando um echo json_encode() no model. Isso não é correto. O certo é você dar um return $row_set; e faz o echo lá no controller.

    No Controller
    Você está usando $_GET[‘term’] para recuperar o valor de um get. Desta forma, seu campo está sujeito a ataques SQL INJECTION, pois o CodeIgniter não trata a função $_GET. O certo é usar $this->input->get(‘term’);
    Agora sim você faz um echo json_encode($this->os_model->autoCompleteCliente($q));
    Tenha em mente que o Model só tem como função devolver os dados para o controller, e o controller tem a função de devolver os dados para a view. Separando assim, fica mais fácil de entender a função de cada camada.

    Abraços

  • Cristovam

    Boa tarde! Ótima explicação!
    Mas diga uma coisa, no inicio do post vc fala sobre descontinuidade da class cart e sugere não usar mais.
    E como fica?
    Foi abandonado de vez mesmo o carrinho no Code?
    Então é realmente melhor não usar?

    abs

  • Olá Cristovam.

    Pois é, a equipe que agora é responsável pelo desenvolvimento e continuidade do CodeIgniter achou que esta biblioteca é para casos muito específicos, lojas virtuais, e resolveu descontinuar. Na versão 3.0 do CI ainda é possível usar esta biblioteca, mas em atualizações futuras certamente ela será removida.

    Sugere-se não criar sites novos usando esta biblioteca. Caso você tenha algum site que já a utilize, então talvez terá que verificar os reais benefícios de fazer uma atualização do CI para a versão 3.0.

    Fabio

  • Cristovam

    Entendi.
    Na verdade ainda não uso essa biblioteca. Iria usar.
    Pretendo fazer um carrinho de compras com o code.
    Mas não vou usar essa classe então.

    obrigado

  • Raquel

    Mas e quanto ao banco? CREATE TABLE IF NOT EXISTS ci_sessions (
    session_id varchar(40) DEFAULT ‘0’ NOT NULL,
    ip_address varchar(45) DEFAULT ‘0’ NOT NULL,
    user_agent varchar(120) NOT NULL,
    last_activity int(10) unsigned DEFAULT 0 NOT NULL,
    user_data text NOT NULL,
    PRIMARY KEY (session_id),
    KEY last_activity_idx (last_activity)
    );

    qual é o nome do banco? Porque só tem o nome da tabela menos do banco

  • Olá Raquel

    O banco você escolhe, você vai criar esta tabela dentro do banco de dados que já está usando no seu sistema, ou seja, é só mais uma tabela que você vai usar dentro do seu banco de dados que já deve estar criado.

    Fabio

  • Ernaldo Vieira

    Se a biblioteca vai ser descontinuada, o que usar entao?

    Fazer tudo na mao?

    Qual sua sugestão?

  • Ernaldo Vieira

    Estou precisando criar um formulario de pedidos.
    1. O meu representante sai com o mostruario.
    2. Chegando no cliente ele deve abrir o pedido.
    3. Nesta etapa ele deve pesquisar o cliente, se nao estiver cadastrado, ele poderar cadastra-lo.
    4. Informar plano de pagamento, forma de pagamento, periodo que o cliente deseja de entrega, e outras coisas mais.
    5. Feito o cabecalho do pedido, o representante ira digitar os itens.
    6. O nosso produto é do ramo de confeccoes, portanto ele tem cor e tamanho.
    7. O representante deve digitar a referencia do produto, o formulario deve mostrar a descricao do produto, o preco
    8. Logo abaixo deve mostrar todas as opcoes de cores e tamanhos:
    Ex: 002345 (digitei)
    Blusa masculina ( o sistema mostra)
    20,00 (o sistema mostra)
    Grade:
    cor tamanho quantidade
    azul P ——— (campo para ser digitado)
    azul m _________
    aamrelo p _________
    amarelo m _________
    9. Depois de digitar as quantidades: clicar num botao para gravar estes itens e totalizar o pedido.
    10. Cada linha desta e uma linha no meu pedido_detalhe.

    Sou iniciante em programaçao web e ja tenho todos os cruds preparados mas esta complicado para realizar este formulario.
    Alguma ajuda?
    Poderiamos negociar.
    Obrigado.

  • Ernaldo, neste caso só criando tudo na mão mesmo.

    Ou então, usar a última versão estável do CI que ainda contemple esta biblioteca, porém, neste último caso, você não poderia atualizá-lo para uma versão que tiver removido a biblioteca.

    Fábio

  • Ernaldo, o que posso lhe sugerir é que tente ir começando pelo mais básico da solução que você precisa, e após ter certeza que tal etapa esteja funcionando, para para a próxima, assim você consegue criar o que precisa, mesmo sendo mais complexo.

    No momento não desenvolvo projetos particulares ou prestação de consultoria.

    Abraços
    Fábio

  • Ernaldo Vieira

    Valeu, muito obrigado.

  • fernando

    faltou a finalização da loja, fechar pedido e apresentar o form do envio, nome, endereço,,, etc… e tem como colocar o calculo do frete na soma?

  • Olá Fernando.

    Realmente faltou muita coisa, inclusive uma loja-virtual, mas esta não era a ideia do post aqui. 🙂

    A ideia é somente apresentar como fazer um carrinho de compras, a parte anterior e posterior ao carrinho ficam a cargo do desenvolvedor ou para um outro post no futuro.

    Abraços
    Fábio

  • Olá Fábio gostei muito do codigo, teria como implementar com ajax onde as opções de alterar a quantidade do produto não necessitar clicar no botão atualizar, como também quando adicionamos algum produto ele voltar para o inicio da lista de produtos, como acontece no exemplo do link abaixo, sendo que neste exemplo não foi feito com CI.

    http://phppot.com/php/shopping-cart-with-multi-tab-wizard-using-jquery-ajax/

  • Olá Kerensky

    Com certeza dá pra implementar e tudo depende do seu conhecimento, porém, lembre-se que a biblioteca CART foi descontinuada no CI. Ela ainda existe na versão 3.0 mas nas próximas versões ela não estará mais disponível.

    Abraços
    Fabio

  • Ótima explicação, estava precisando muito obrigado.

    Uma pergunta seria possível dar uma ajuda para criar um contador de visitas com o codeigniter?

    Mais uma vez parabéns pelo post e obrigado pela atenção.

  • Anderson Moreira

    Oi Fabio, me explica por favor, no principio do post você afirma que a biblioteca CArt está descontinuada, bem, mas o que me sugeriria para poder estar criando um carrinho de compras para meu site? A biblioteca era muito boa, porque ela foi descontinuada?

  • Olá Anderson.

    A explicação do pessoal responsável pelo CodeIgniter é que a biblioteca era algo muito específico e por isso resolveram descontinuar.

    Abraços
    Fabio

  • Carlos Eduardo sds
  • Este é um erro que ocorre quando você roda a versão antiga do CI em uma versão do PHP mais recente, ou o PHP 7.

    Atualizando o CI para a versão 3.0 esse problema é resolvido, ou então, dá pra fazer uma alteração no arquivo core/Common.php, seguindo esta dica: http://stackoverflow.com/questions/28348879/only-variable-references-should-be-returned-by-reference-codeigniter

    Abraços
    Fábio

  • Carlos Eduardo sds

    Funcionou.
    Obrigado Fabio! Sucesso!!

  • Carlos Eduardo sds

    https://uploads.disquscdn.com/images/12760506a3c18cf4d5b162393f2cd405e20a2b65dacdd70aa8c7db22ab662529.png

    Me desculpe perguntar di novo. Mais sou novo nessa área de programação. E não estou conseguindo sair disso. Se você puder me ajudar em alguma coisa já agradeço

  • jose soarew

    Parabens fabio! to precisando do checkout pagamento atravez do paypal? alguem tem nocao?