Paquete Laravel Shoppingcart en español


Victor Arana Flores

19 Jul 2022

Una implementación simple de carrito de compras para Laravel.

Instalación

Instale el paquete a través de Composer .

Ejecute el comando Composer require desde la Terminal:

composer require hardevine/shoppingcart

Si está utilizando Laravel 5.5 o superior, esto es todo lo que tiene que hacer.

Si todavía estás en la versión 5.4 de Laravel, los pasos finales para ti son añadir el proveedor de servicios del paquete y el alias del paquete. Para ello abre tu archivo config/app.php.

Añade una nueva línea a la matriz de proveedores:

Gloudemans\Shoppingcart\ShoppingcartServiceProvider::class

Y opcionalmente añadir una nueva línea a la matriz de alias:

'Cart' => Gloudemans\Shoppingcart\Facades\Cart::class,

Ahora está listo para comenzar a usar el carrito de compras en su aplicación.

A partir de la versión 2 de este paquete, es posible usar la inyección de dependencia para inyectar una instancia de la clase Cart en su controlador u otra clase.

Uso

El carrito de compras le ofrece los siguientes métodos para usar:

Cart::add()

Agregar un artículo al carrito es realmente simple, solo usa el add()método, que acepta una variedad de parámetros.

En su forma más básica, puede especificar la identificación, el nombre, la cantidad y el precio del producto que desea agregar al carrito.

Cart::add('293ad', 'Product 1', 1, 9.99);

Como quinto parámetro opcional, puede pasarle opciones, por lo que puede agregar varios elementos con la misma identificación, pero con (por ejemplo) un tamaño diferente.

Cart::add('293ad', 'Product 1', 1, 9.99, ['size' => 'large']);

Puede pasar opcionalmente diferentes tipos de impuestos a los artículos.

Cart::add('293ad', 'Product 1', 1, 9.99, ['size' => 'large'], 20);

El método add() devolverá una instancia de CartItem del artículo que acaba de añadir al carrito.

¿Quizás prefieras añadir el elemento utilizando un array? Mientras el array contenga las claves necesarias, puedes pasarlo al método. La clave options es opcional.

Cart::add(['id' => '293ad', 'name' => 'Product 1', 'qty' => 1, 'price' => 9.99, 'options' => ['size' => 'large']]);

La novedad de la versión 2 del paquete es la posibilidad de trabajar con la interfaz Buyable. La forma en que esto funciona es que tienes un modelo que implementa la interfaz Buyable, lo que hará que implementes algunos métodos para que el paquete sepa cómo obtener el id, el nombre y el precio de tu modelo. De esta manera sólo tienes que pasar al método add() un modelo y la cantidad y automáticamente lo añadirá al carrito.

La ruta de acceso a la interface Buyable es:

Gloudemans\Shoppingcart\Contracts\Buyable;

Como ventaja adicional, asociará automáticamente el modelo con el CartItem

Cart::add($product, 1, ['size' => 'large']);

Como tercer parámetro opcional puedes añadir opciones.

Cart::add($product, 1, ['size' => 'large']);

Por último, también puede añadir varios artículos al carrito a la vez. Puedes pasar al método add() un array de arrays, o un array de Buyables y se añadirán al carrito.

Cuando se añaden varios artículos al carrito, el método add() devolverá un array de CartItems.

Cart::add([
  ['id' => '293ad', 'name' => 'Product 1', 'qty' => 1, 'price' => 10.00],
  ['id' => '4832k', 'name' => 'Product 2', 'qty' => 1, 'price' => 10.00, 'options' => ['size' => 'large']]
]);

Cart::add([$product1, $product2]);

Cart::update()

Para actualizar un artículo en el carrito, primero necesitarás el rowId del artículo. A continuación, puede utilizar el método update() para actualizarlo.

Si simplemente quieres actualizar la cantidad, pasarás al método update el rowId y la nueva cantidad:

$rowId = 'da39a3ee5e6b4b0d3255bfef95601890afd80709';

Cart::update($rowId, 2); // Actualizará la cantidad

Si quieres actualizar más atributos del artículo, puedes pasar al método de actualización un array o un Buyable como segundo parámetro. De esta manera, puedes actualizar toda la información del artículo con el rowId dado.

Cart::update($rowId, ['name' => 'Product 1']); // Actualizará el nombre

Cart::update($rowId, $product); // Actualizará la identificación, el nombre y el precio

Cart::remove()

Para eliminar un artículo del carrito, necesitarás de nuevo el rowId. Este rowId simplemente lo pasas al método remove() y eliminará el artículo del carrito.

$rowId = 'da39a3ee5e6b4b0d3255bfef95601890afd80709';

Cart::remove($rowId);

Cart::get()

Si quieres obtener un artículo del carrito usando su rowId, puedes simplemente llamar al método get() del carrito y pasarle el rowId.

$rowId = 'da39a3ee5e6b4b0d3255bfef95601890afd80709';

Cart::get($rowId);

Cart::content()

Por supuesto, también quieres obtener el contenido de los carros. Aquí es donde usarás el método content. Este método devolverá una colección de CartItems sobre la que puedes iterar y mostrar el contenido a tus clientes.

Cart::content();

Este método devolverá el contenido de la instancia actual del carro, si quieres el contenido de otra instancia, simplemente encadena las llamadas.

Cart::instance('wishlist')->content();

Cart::destroy()

Si desea eliminar por completo el contenido de un carro, puede llamar al método de destrucción del carro. Esto eliminará todos los CartItems del carrito para la instancia actual del carrito.

Cart::destroy();

Cart::total()

El método total() puede utilizarse para obtener el total calculado de todos los artículos del carrito, dado su precio y cantidad.

Cart::total();

El método formateará automáticamente el resultado, que puede ajustarse utilizando los tres parámetros opcionales

Cart::total($decimals, $decimalSeperator, $thousandSeperator);

Puede establecer el formato numérico por defecto en el archivo de configuración.

Si no está utilizando la Fachada, sino que utiliza la inyección de dependencia en su (por ejemplo) Controlador, también puede simplemente obtener la propiedad total $cart->total

Cart::tax()

El método tax() puede utilizarse para obtener el importe calculado de los impuestos para todos los artículos del carrito, dado su precio y cantidad.

Cart::tax();

El método formateará automáticamente el resultado, que puede ajustarse utilizando los tres parámetros opcionales

Cart::tax($decimals, $decimalSeperator, $thousandSeperator);

Puede establecer el formato numérico por defecto en el archivo de configuración.

Si no está utilizando la Fachada, sino que utiliza la inyección de dependencia en su (por ejemplo) Controlador, también puede simplemente obtener la propiedad del impuesto $cart->tax

Cart::subtotal()

El método subtotal() puede utilizarse para obtener el total de todos los artículos del carrito, menos el importe total de los impuestos.

Cart::subtotal();

El método formateará automáticamente el resultado, que puede ajustarse utilizando los tres parámetros opcionales

Cart::subtotal($decimals, $decimalSeperator, $thousandSeperator);

Puede establecer el formato numérico por defecto en el archivo de configuración.

Si no está utilizando la fachada, sino que utiliza la inyección de dependencia en su (por ejemplo) controlador, también puede simplemente obtener la propiedad subtotal $cart->subtotal

Cart::count()

Si quieres saber cuántos artículos hay en tu carrito, puedes utilizar el método count(). Este método devolverá el número total de artículos en el carrito. Así que si has añadido 2 libros y 1 camisa, devolverá 3 artículos.

Cart::count();

Cart::search()

Para encontrar un artículo en la cesta, puede utilizar el método search().

Este método se modificó en la versión 2

Entre bastidores, el método simplemente utiliza el método filter de la clase Laravel Collection. Esto significa que debes pasarle un Closure en el que especificarás tus términos de búsqueda.

Si, por ejemplo, quieres encontrar todos los elementos con un id de 1:

$cart->search(function ($cartItem, $rowId) {
	return $cartItem->id === 1;
});

Como puede ver, el Closure recibirá dos parámetros. El primero es el CartItem para realizar la comprobación. El segundo parámetro es el rowId de este CartItem.

El método devolverá una colección que contiene todos los CartItems encontrados

Esta forma de buscar le da un control total sobre el proceso de búsqueda y le permite crear búsquedas muy precisas y específicas.

Colecciones

En múltiples instancias el Cart le devolverá una Colección. Esta es una simple colección de Laravel, por lo que todos los métodos que puedes llamar en una colección de Laravel también están disponibles en el resultado.

Como ejemplo, puede obtener rápidamente el número de productos únicos en un carrito:

Cart::content()->count();

O puede agrupar el contenido por el id de los productos:

Cart::content()->groupBy('id');

Instancias

Los paquetes admiten múltiples instancias del carro. La forma en que esto funciona es así:

Puedes establecer la instancia actual del carrito llamando a Cart::instance('newInstance'). A partir de este momento, la instancia activa del carrito será newInstance, así que cuando añadas, elimines u obtengas el contenido del carrito, estarás trabajando con la instancia newInstance del carrito. Si quieres cambiar de instancia, sólo tienes que llamar de nuevo a Cart::instance('otherInstance'), y estarás trabajando de nuevo con la otherInstance.

Así que un pequeño ejemplo:

Cart::instance('shopping')->add('192ao12', 'Product 1', 1, 9.99);

// Obtener el contenido del "carrito de compras"
Cart::content();

Cart::instance('wishlist')->add('sdjk922', 'Product 2', 1, 19.95, ['size' => 'medium']);

// Obtener el contenido de la "lista de deseos"
Cart::content();

// Si quieres volver a obtener el contenido del "carrito de compras"
Cart::instance('shopping')->content();

// Y el recuento de la "lista de deseos" de nuevo
Cart::instance('wishlist')->count();

N.B. Tenga en cuenta que el carro se mantiene en la última instancia establecida mientras no establezca una diferente durante la ejecución del script.

N.B.2 La instancia del carrito por defecto se llama default, por lo que cuando no se usan instancias,Cart::content(); es lo mismo que Cart::instance('default')->content().

Modelos

Porque puede ser muy conveniente poder acceder directamente a un modelo desde un CartItem es posible asociar un modelo con los artículos del carrito. Digamos que tienes un modelo de Producto en tu aplicación. Con el método associate(), puedes decirle al carrito que un artículo del carrito, está asociado al modelo Producto.

De esta manera, puedes acceder a tu modelo directamente desde el CartItem.

Se puede acceder al modelo a través de la propiedad model del CartItem.

Si tu modelo implementa la interfaz Buyable y has utilizado tu modelo para añadir el artículo al carrito, se asociará automáticamente.

He aquí un ejemplo:

// Primero añadiremos el artículo a la cesta.
$cartItem = Cart::add('293ad', 'Product 1', 1, 9.99, ['size' => 'large']);

// A continuación, asociamos un modelo al artículo.
Cart::associate($cartItem->rowId, 'Product');

// O incluso más fácil, ¡llamar al método de asociación en el CartItem!
$cartItem->associate('Product');

// Incluso puedes hacer que sea de una sola línea
Cart::add('293ad', 'Product 1', 1, 9.99, ['size' => 'large'])->associate('Product');

// Ahora, al iterar sobre el contenido del carro, puedes acceder al modelo.
foreach(Cart::content() as $row) {
	echo 'You have ' . $row->qty . ' items of ' . $row->model->name . ' with description: "' . $row->model->description . '" in your cart.';
}

Buyable

Para facilitar la adición de artículos al carrito y su asociación automática, su modelo puede implementar la interfaz Buyable. Para ello, debe implementar dichas funciones:

public function getBuyableIdentifier(){
	return $this->id;
}

public function getBuyableDescription(){
	return $this->name;
}

public function getBuyablePrice(){
	return $this->price;
}

Ejemplo

<?php

namespace App\Models;

use Gloudemans\Shoppingcart\Contracts\Buyable;
use Illuminate\Database\Eloquent\Model;

class Product exends Model implements Buyable {
    public function getBuyableIdentifier($options = null) {
        return $this->id;
    }

    public function getBuyableDescription($options = null) {
        return $this->name;
    }

    public function getBuyablePrice($options = null) {
        return $this->price;
    }
}

Base de datos

Configuración

Para guardar el carrito en la base de datos y poder recuperarlo más tarde, el paquete necesita saber qué conexión a la base de datos debe utilizar y cuál es el nombre de la tabla. Por defecto, el paquete utilizará la conexión a la base de datos por defecto y utilizará una tabla llamada shoppingcart. Si quieres cambiar estas opciones, tendrás que publicar el archivo de configuración.

php artisan vendor:publish --provider="Gloudemans\Shoppingcart\ShoppingcartServiceProvider" --tag="config"

Esto le dará un archivo de configuración cart.php en el que puede hacer los cambios.

Para facilitarte la vida, el paquete también incluye una migración lista para usar que puedes publicar ejecutando:

php artisan vendor:publish --provider="Gloudemans\Shoppingcart\ShoppingcartServiceProvider" --tag="migrations"

Esto colocará el archivo de migración de una tabla de shoppingcart en el directorio database/migrations. Ahora todo lo que tiene que hacer es ejecutar php artisan migrate para migrar su base de datos.

Cómo guardar el carro

Para almacenar su instancia de carrito en la base de datos, tiene que llamar al método store($identifier). Donde $identificador es una clave aleatoria, por ejemplo el id o nombre de usuario del usuario.

Cart::store('username');

// Para almacenar una instancia de carrito llamada 'wishlist'
Cart::instance('wishlist')->store('username');

Restaurar el carro

Si quieres recuperar el carrito de la base de datos y restaurarlo, todo lo que tienes que hacer es llamar a restore($identifier) donde $identifier es la clave que especificaste para el método store.

Cart::restore('username');

// Para restaurar una instancia de carrito llamada 'wishlist'
Cart::instance('wishlist')->restore('username');

Excepciones

El paquete Cart lanzará excepciones si algo va mal. De esta manera es más fácil depurar su código usando el paquete Cart o manejar el error basado en el tipo de excepciones. Los paquetes Cart pueden lanzar las siguientes excepciones:

ExcepciónRazón
CartAlreadyStoredExceptionAl intentar almacenar un carro que ya estaba almacenado con el identificador especificado
InvalidRowIDExceptionCuando el rowId que se ha pasado no existe en la instancia actual del carro
UnknownModelExceptionCuando se intenta asociar un modelo no existente a un CartItem.

Eventos

El carro también tiene eventos incorporados. Hay cinco eventos disponibles para que los escuches.

EventoDisparadoParámetro
cart.addedCuando se añade un artículo a la cesta.El CartItem que se ha añadido.
cart.updatedCuando se actualiza un artículo de la cesta.El CartItem que fue actualizado.
cart.removedCuando se retira un artículo de la cesta.El CartItem que fue eliminado.
cart.storedCuando se almacena el contenido de un carro.-
cart.restoredCuando se restablece el contenido de un carro.-

Ejemplo

A continuación se muestra un pequeño ejemplo de cómo listar el contenido del carrito en una tabla:

// Añade algunos elementos en tu Controlador.
Cart::add('192ao12', 'Product 1', 1, 9.99);
Cart::add('1239ad0', 'Product 2', 2, 5.95, ['size' => 'large']);

// Mostrar el contenido en una Vista.
<table>
   	<thead>
       	<tr>
           	<th>Product</th>
           	<th>Qty</th>
           	<th>Price</th>
           	<th>Subtotal</th>
       	</tr>
   	</thead>

   	<tbody>

   		<?php foreach(Cart::content() as $row) :?>

       		<tr>
           		<td>
               		<p><strong><?php echo $row->name; ?></strong></p>
               		<p><?php echo ($row->options->has('size') ? $row->options->size : ''); ?></p>
           		</td>
           		<td><input type="text" value="<?php echo $row->qty; ?>"></td>
           		<td>$<?php echo $row->price; ?></td>
           		<td>$<?php echo $row->total; ?></td>
       		</tr>

	   	<?php endforeach;?>

   	</tbody>
   	
   	<tfoot>
   		<tr>
   			<td colspan="2">&nbsp;</td>
   			<td>Subtotal</td>
   			<td><?php echo Cart::subtotal(); ?></td>
   		</tr>
   		<tr>
   			<td colspan="2">&nbsp;</td>
   			<td>Tax</td>
   			<td><?php echo Cart::tax(); ?></td>
   		</tr>
   		<tr>
   			<td colspan="2">&nbsp;</td>
   			<td>Total</td>
   			<td><?php echo Cart::total(); ?></td>
   		</tr>
   	</tfoot>
</table>

1 comentarios

Inicia sesión para comentar

Comentarios:

  • Arling Holguin

    Arling Holguin hace 3 meses

    Muy bueno, jejej estaba mirando Como funcionaba la caja de comentarios de codersfree y me parece genial.