Development

Documentation/es_ES/cookbook/1.0/shopping_cart

You must first sign up to be able to contribute.

Version 3 (modified by Javier.Eguiluz, 10 years ago)
--

Cómo gestionar un carrito de la compra

Artículo original: How to manage a shopping cart. Traducción realizada por Raúl Alonso - raul (arroba) raulalonso (punto) net

Descripción

Symfony ofrece un plugin para manejar carros de la compra en los sitios web ebusiness. Añadir un artículo, modificar las cantidades y mostrar el contenido de un carro de la compra resulta fácil y divertido valiéndonos de sfShoppingCartPlugin.

Instalación

Como el resto de plugins en Symfony, sfShoppingCart se instala a través de PEAR (más información acerca de los plugins en el capítulo 17 de la Guía definitiva). La instalación de sfShoppingCart plugin es muy sencilla, tal como se describe en la página del plugin. Sólo tiene que escribir en la línea de comandos:

$ symfony plugin-install http://plugins.symfonyproject.com/sfShoppingCartPlugin

Luego, borrar la memoria caché para permitir la auto-carga de las clases del plugin en el proyecto:

$ symfony cc

(próximamente el resto de la traducción...)

Constructor

La clase SfShoppingCart está dirigida a la gestión de carritos de la compra. Puede contener cualquier tipo de objeto. El constructor permite declarar el valor de algún tipo impositivo a aplicar a la cesta, como tasas o impuestos según las leyes comerciales del país:

[php] $my_shopping_cart = new sfShoppingCart(APP_CART_TAX);

En este ejemplo, la tasa de impuestos que se va aplicar en el carrito de la compra, se va a definir en el archivo de configuración app.yml de la aplicación, para facilitar el cambio:

all:

cart:

tax: 19.6

Crear un usuario para el carrito de la compra

Usted puede crear fácilmente un nuevo objeto sfShoppingCart (es decir, un nuevo carrito de la compra) en una acción con el nuevo constructor. Sin embargo, no será de ninguna utilidad si la acción no está vinculada a una sesión de usuario. La forma más fácil de mantener los artículos seleccionados por un usuario en su carrito de la compra es creando un objeto sfShoppingCart en la clase sfUser. Para ello, hay que añadir un método personalizado a la clase myUser en myproject/apps/myapp/lib/myUser.php:

[php] class myUser extends sfUser {

public function getShoppingCart() {

if (!$this->hasAttribute('shopping_cart'))

$this->setAttribute('shopping_cart', new sfShoppingCart(APP_CART_TAX));

return $this->getAttribute('shopping_cart');

}

...

}

El método $user->getShoppingCart() creará una nueva cesta de la compra si el usuario no tuviera ya una.

**Nota**: Si desea más información sobre la forma de saltarse la clase sfUser por defecto, para utilizar una clase myUser personalizada, debe leer la sección acerca de las factorías en el Capítulo 17 de la Guía definitva.

Añadir, modificar y eliminar elementos

La cesta de la compra puede contener cualquier cantidad de objetos de diferentes clases. Cada uno de los items almacenados en el carrito de la compra es una instancia de la clase sfShoppingCartItem. La clase sfShoppingCart cuenta con los métodos addItem() y deleteItem().

Como se puede añadir o eliminar cualquier tipo de objeto, el primer argumento de estas llamadas a los métodos es el nombre de la clase del objeto. Para modificar la cantidad de un artículo, en primer lugar se tiene que obtener el objeto sfShoppingCartItem a través del método getItems() del objeto sfShoppingCart, y después llamar a su método setQuantity().

El módulo shoppingcart

A continuación npresentamos un posible módulo de la aplicación de gestión de la cesta de la compra donde los objetos de la clase ‘Product’ (que representa a los productos), se pueden añadir, modificar o eliminar con las acciones ‘add ','update' y 'delete ':

[php] class shoppingcartActions extends sfActions {

...

public function executeIndex() {

$this->shopping_cart = $shopping_cart; $this->items = $shopping_cart->getItems(); ...

}

public function executeAdd() {

... if ($this->hasRequestParameter('id')) {

$product = ProductPeer::retrieveByPk($this->getRequestParameter('id')); $item = new sfShoppingCartItem('Product', $this->getRequestParameter('id')); $item->setQuantity(1); $item->setPrice($product->getPrice()); $shopping_cart = $this->getUser()->getShoppingCart(); $shopping_cart->addItem($item);

}

...

}

public function executeUpdate() {

$shopping_cart = $this->getUser()->getShoppingCart(); foreach ($shopping_cart->getItems() as $item) {

if ($this->hasRequestParameter('quantity_'.$item->getId())) {

$item->setQuantity($this->getRequestParameter('quantity_'.$item->getId()));

}

}

...

}

public function executeDelete() {

if ($this->hasRequestParameter('id')) {

$shopping_cart = $this->getUser()->getShoppingCart(); $shopping_cart->deleteItem('Product', $this->getRequestParameter('id'));

}

...

}

...

}

Añadir un item

Echemos un vistazo más de cerca a este código.

Para agregar un elemento a la cesta de la compra, usted llame al método addItem(), pasándole el objeto sfShoppingCartItem. Este objeto contiene la clase del objeto y el ID exclusivo del item que se agregó, la cantidad que debe incrementarse y el precio del artículo. Esto permite que la cesta pueda contener objetos de cualquier clase. Por ejemplo, usted podría tener un carrito de la compra con libros y CDs al mismo tiempo.

El precio se almacena en el mismo momento para evitar desajustes entre el número de artículos y el precio total de la compra, en caso de que un producto sea modificado en el precio en un "back-office" (o para que el carro puede mantenerse entre los períodos de sesiones). Esto también permite aplicar precios de descuento según la cantidad ordenada por el cliente:

[php] if ($quantity > 10) {

$item->setPrice($product->getPrice() * 0.8);

} else {

$item->setPrice($product->getPrice());

}

El problema es que usted pierde el precio original si aplica el descuento de esta manera. Esa es la razón por la que el objeto sfShoppingCartItem tiene un método setDiscount() que espera un porcentaje de descuento:

[php] if ($quantity > 10) {

$item->setPrice($product->getPrice()); $item->setDiscount(20);

} else {

$item->setPrice($product->getPrice());

}

Actualizar un item

Para cambiar la cantidad de un artículo en el carrito, se utiliza el método setQuantity() del objeto sfShoppingCartItem. Para eliminar un artículo, puede llamar al método deleteItem() o cambiar la cantidad a 0 llamando setQuantity(0).

Si un usuario añade el mismo item (la misma clase y el mismo id) varias veces, la cesta incrementará la cantidad de este item, y no añadirá un item nuevo:

[php] $item = new sfShoppingCartItem('Product', $this->getRequestParameter('id')); $item->setQuantity(1); $item->setPrice($product->getPrice()); $shopping_cart = $this->getUser()->getShoppingCart(); $shopping_cart->addItem($item); $shopping_cart->addItem($item);

// same as

$item = new sfShoppingCartItem('Product', $this->getRequestParameter('id')); $item->setQuantity(2); $item->setPrice($product->getPrice()); $shopping_cart = $this->getUser()->getShoppingCart(); $shopping_cart->addItem($item);

Eventualmente, es posible que se pregunte por qué la acción update utiliza argumentos como 'quantity_2313 = 4' en lugar de 'id=2313&cantidad=4'. Como cuestión de hecho, la forma en que esta acción se lleva a cabo permite la actualización de cantidades de múltiples artículos a la vez.

Eliminar toda una cesta de la compra

Para poner a cero la cesta de la compra, simplemente llame al método clear() de la instancia sfShoppingCart.

[php] $this->getUser()->getShoppingCart()->clear();

Mostrar la cesta de la compra en una plantilla

La acción shoppingcart/index debería mostrar el contenido del carrito de la compra. Vamos a examinar una posible aplicación:

Obtener el contenido del carrito de la compra

El objeto sfShoppingCart posee tres métodos que le ayudarán a procesar el contenido de un carrito de la compra:

* ->getItems(): conjunto de todos los objetos sfShoppingCartItem en el carrito de la compra. * ->getItem($class_name, $object_id): un objeto específico sfShoppingCartItem * ->getTotal(): Precio total de la cesta de la compra (suma de la cantidad * precio de cada item)

Los ítems del carrito de la compra también tienen un contenedor de parámetros (parameter holder). Esto significa que usted puede agregar información personalizada a cualquier item.

Por ejemplo, en un sitio web que vende partes de autos, los objetos sfShoppingCartItem necesitan almacenar los objetos añadidos, pero también el vehículo para el que la pieza fue comprada. Esto puede hacerse simplemente añadiendo:

[php] $item->setParameter('vehicle', $vehicle_id);

**Nota**: Puede que necesite un método getObjects() en lugar de getItems(). Este método existe, pero depende de la capa de acceso a datos Propel. Como el uso de Propel es opcional, es posible que no pueda utilizarlo. Más información sobre la capa de acceso a datos en el Capítulo 8 de la Guía definitiva.

Paso de los valores a la plantilla

Con el fin de mostrar el contenido del carrito, la acción del index tiene que definir algunas variables de acceso a la plantilla:

[php] ... $this->shopping_cart = $shopping_cart; $this->items = $shopping_cart->getItems();

El siguiente ejemplo muestra una simple plantilla indexSuccess.php sobre la base de una iteración sobre todos los items del carrito para mostrar información acerca de cada uno de ellos:

[php] <?php if ($shopping_cart->isEmpty()): ?>

Your shopping cart is empty.

<?php else: ?>

<?php foreach ($items as $item): ?>

<?php $object = call_user_func(array($item->getClass().'Peer', 'retrieveByPK'), $item->getId()) ?> <?php echo $object->getLabel() ?><br /> <?php echo $item->getQuantity() ?><br /> <?php echo currency_format($item->getPrice(), 'EUR' ) ?> <?php if ($item->getDiscount()): >

(- <?php echo $item->getDiscount() ?> %)

<?php endif ?><br />

<?php endforeach ?>

Total : <?php echo currency_format($shopping_cart->getTotal(), 'EUR' ) ?><br />

<?php endif ?>

Tenga en cuenta que este ejemplo se utiliza la capa de acceso a datos Propel. Si su proyecto usa otra capa de acceso a datos, este ejemplo puede necesitar adaptaciones.

Con o sin impuestos

Por defecto, todas las operaciones -incluido $shopping_cart->addItem(), el acceso con $item->getPrice() y $shopping_cart->getTotal()- utilizan los precios **sin impuestos**.

Para obtener la cantidad total de impuestos, usted tiene que proceder así:

[php] $total_with_taxes = $shopping_cart->getTotalWithTaxes()

Si lo necesita, el objeto sfShoppingCart puede ser inicializado de manera que procese al valor de una tasa o impuesto en sus métodos, para incluirlo en el precio de los artículos:

[php] class myUser extends sfUser {

public function getShoppingCart() {

if (!$this->hasAttribute('shopping_cart')) {

$this->setAttribute('shopping_cart', new sfShoppingCart(APP_CART_TAX));

} $this->getAttribute('shopping_cart')->setUnitPriceWithTaxes(APP_CART_WITHTAXES); return $this->getAttribute('shopping_cart');

}

...

}

Si APP_CART_WITHTAXES es true, los métodos $shopping_cart->addItem() y $item->getPrice() aplicarán el impuesto a los precios. Los métodos getTotal() y getTotalWithTaxes() darán resultados correctos.

Una vez más, es un buen hábito para definir el impuesto en un fichero de configuración: es la razón por la que el ejemplo anterior utiliza la constante APP_CART_WITHTAXES en lugar de un simple true. El archivo myproject/apps/myapp/config/app.yml debe contener:

all:

cart:

tax: 19.6 withtaxes: true

Si no está seguro de cómo aplicar los impuestos o tasas al carrito, haga la siguiente petición al carrito:

[php] $uses_tax = $shopping_cart->getUnitPriceWithTaxes();