domingo, 7 de julio de 2013

Implementación del carro de compras

Continuamos con el Tema 4 de la creación de un carrito de compras con CodeIgniter, hoy vamos a usar la Librería Cart para la implementación del carro de compras. Haremos las últimas modificaciones a los archivos: products_model.php, products.php, content.php y header.php, también crearemos una nueva vista para mostrar el carrito que es donde se verá cada uno de los productos añadidos con la opción seleccionada, cantidad y valor, donde además podremos añadir más productos
o eliminarlos uno por uno, o vaciar el carro completamente; aunque para seguir adicionando algún producto ya elegido no será necesario estar en la página que muestra el carro de compras, porque cuando estemos en la página de los productos al dar en el botón comprar se irá actualizando la cantidad de los items ya seleccionados con su respectiva opción. Empecemos por añadir los métodos que hacen posible añadir, actualizar y eliminar los productos de la compra; los agregamos después del método index en el controlador products.php

Añadimos los métodos al controlador products.php

function add() {

    $segment = $this -> input -> post('segment');
    $url = base_url() . 'products/index/' . $segment;

    $id = $this -> input -> post('id');
    $product = $this -> Products_Model -> get_product($id);
    $option = $this -> input -> post($product -> opcion);

    if ($product -> opcion) {// si el producto tiene opciones las colocamos en un arreglo

        foreach ($product->valores as $key => $values) {

            $value[] = $values;

        }

        $id_option = $id . $value[$option];
        // se crea una variable como identificador único
        $selected = $value[$option];
        // la opción seleccionada está en la posición $option
    }

    $row = '';

    if ($cart = $this -> cart -> contents()) {// verificamos si el carrito existe

        foreach ($cart as $item) {//foreach contenedor

            if ($item['id'] === $id && !$product -> valores) {

                $row = $item['rowid'] . "-" . ($item['qty'] + 1);
                break;
                // si se cumple la condición el foreach dejará de ejecutarse
            }

            if ($this -> cart -> has_options($item['rowid'])) {

                foreach ($this->cart->product_options($item['rowid']) as $key => $options) {// foreach interno

                    $cart_option = $item['id'] . $options;

                    if ($cart_option === $id_option) {

                        $row = $item['rowid'] . "-" . ($item['qty'] + 1);
                        break;
                    }
                } // fin del foreach interno

            } // fin del if que evalua si los productos insertados en el carrtito tienen opciones

        }// fin del foreach contenedor

    }// fin del if que evalua si el carrito existe

    /* la variable $row contiene el rowid y el qty de cada producto concatenados; si esta
     * variable no está vacia significa que se debe actualizar el producto */

    if ($row !== '') {

        $this -> update($row, $url);

    } else {
        $insert = array('id' => $id, 'qty' => 1, 'price' => $product -> precio, 'name' => convert_accented_characters($product -> marca) // para quitar los acentos
        );

        if ($selected !== Null) {

            $insert['options'] = array($product -> opcion => $selected);

        }

        $this -> cart -> insert($insert);
        redirect($url);
        // si en Windows da algún problema remplazarlo por: redirect($url, 'refresh');
    }

}/// fin de la método  add

function update($row, $url) {

    $row = explode('-', $row);
    $this -> cart -> update(array('rowid' => $row[0], 'qty' => $row[1]));

    redirect($url);

}

function update_cart($row) {

    $row = explode('-', $row);
    $this -> cart -> update(array('rowid' => $row[0], 'qty' => $row[1]));

    redirect('products/cart');

}

function remove($rowid) {

    $this -> cart -> update(array('rowid' => $rowid, 'qty' => 0));

    redirect('products/cart');

}

function delete() {
    $message = 'El carrito se ha eliminado satisfactoriamente';
    $this -> cart -> destroy();
    $this -> cart($message);

}

function cart($message = NULL) {

    $data['message'] = $message;
    $data['title'] = 'Carrito de Compras';

    $this -> load -> view('front/header', $data);
    $this -> load -> view('front/cart');
    $this -> load -> view('front/footer');

}
Añadimos un método al modelo:

Colocamos un nuevo método en products_model.php

function get_product($id) {

    $query = $this->db->get_where('productos', array('id' => $id))->result();

    $result = $query[0];

    if ($result->valores) {
    $result->valores = explode(',',$result->valores);
    }

    return $result;
    }

Modificamos de content.php

<?=heading($title, 2);?>
<?php foreach($results as $result): ?>  
  <?=form_open('products/add'); ?>     
    <div class="products">  
     <p><?=$result->marca;?></p>
     
  <div class="image"><?=img('images/'.$result->imagen);?></div>
 
  <div class="detalles"><?='Pantalla: '.$result->pantalla.br(1).'Ram: '.$result->ram.br(1).
                           'Procesador: '.$result->procesador.br(1).'Disco Duro: '.$result->disco_duro;?></div>
              
  <div class="price"><?='Precio: '.'$'.$result->precio;?></div>

        <div class="option">
             <?php if($result->valores):?>
               
                    <?=form_label($result->opcion);?>
                    <?=form_dropdown($result->opcion,$result->valores);?>

                <?php endif; ?>
              
            <?=form_hidden('id', $result->id); ?>
            <?=form_hidden('segment', $this->uri->segment(3));?>
            <?=form_submit('action', 'Comprar'); ?>
      </div>      
  </div><!-- End Products -->
            <?=form_close(); ?>
  <?php endforeach; ?>   
           
<div id="pagination"><?=$this->pagination->create_links();?></div>
Ahora necesitamos adicionar un condicional en el hader.php para que evalue si el carro existe, si es así entonces va a aparecer un enlace para ver el carro mostrando la cantidad de items seleccionados. Buscamos las etiquetas <li></li> que contienen el enlace contactemos:
<li><a href="#">Contactenos</a></li>
y debajo añadimos el siguiente condicional:
<?php if($total_items=$this->cart->total_items()):?> <li><?=anchor('products/cart', 'Carrito - '.$total_items);?></li> <?php endif; ?>
Lo último que necesitamos hacer es crear una vista para mostrar el carro de compras; al igual que las otras vista la ubicamos en: cart/application/views/front/ y la llamamos cart.php

código de cart.php:

<?=heading($title, 2);?>
    <?php   if($message){echo $message;}
    if ($cart = $this->cart->contents()):   ?>      
<div id="cart">
<table cellpadding="4" cellspacing="1" style="width:70%" border="1">
<tr>
  <th>Portatil</th><th>Detalle</th><th>Cantidad</th><th colspan="3">Sub-Total</th>
</tr>
        <?php foreach($cart as $item): ?>
            <tr>
                <td><?=$item['name']; ?></td>
                <td>
                    <?php if ($this->cart->has_options($item['rowid'])) {
                        foreach ($this->cart->product_options($item['rowid']) as $option => $value) {
                            echo $option . ": <em>" . $value . "</em>";
                        }
                      
                    } ?>
                </td>
                <td><?=$item['qty']; ?></td>
                <td>$<?=$this->cart->format_number($item['subtotal'])?></td>
                    <td class="add">
                    <?php
                      $row = $item['rowid']."-".($item['qty']+1);
                    echo anchor('products/update_cart/'.$row,'+'); ?>
                </td>
                <td class="remove">
                    <?=anchor('products/remove/'.$item['rowid'],'X');?>
                </td>
                
    </tr>
          
        <?php endforeach; ?>
        <tr>
            <td colspan="2" ><strong>Total</strong></td>
            <td colspan="1"><strong><?=$this->cart->total_items()?></strong></td>
            <td colspan="5"><strong>$<?=$this->cart->format_number($this->cart->total());?></strong></td>
              
        </tr>
        <tr>
            <td colspan="2" class="pedido"><?=anchor('products/checkout/','Comprar Pedido'); ?></td>
            <td class="remove" colspan="4"><?=anchor('products/delete/','Vaciar Carrito'); ?></td>          
        </tr>
  
        </table>      
    </div>
      
    <?php endif; ?>
<?=br(1).anchor('products','Regresar'); ?>  
Con esto concluimos este tema; en el próximo vamos a crear un formulario que el cliente debe llenar con sus datos para enviar el pedido de la compra.

Descargar archivos del Tema 4

1 comentario :

  1. el tema 4 da el siguiente error esta mal.
    A PHP Error was encountered

    Severity: Notice

    Message: Undefined property: CI_Loader::$cart

    Filename: front/header.php

    Line Number: 20

    fijate siempre que funcione. Saludos

    ResponderBorrar