izyy123/cart

Laravel 购物车

v1.0.2 2022-08-28 08:54 UTC

This package is auto-updated.

Last update: 2024-09-28 13:32:25 UTC


README

Latest Stable Version Total Downloads License

Laravel 框架的购物车实现

重要通知

本包是从 https://github.com/darryldecode/laravelshoppingcart 分支出来的。

该包的主要优点是购物车效率得到了极大提升。

在原始包中,每次更改都会立即直接保存到存储(会话、数据库等)。从购物车检索各种数据也是如此——如果我们想获取购物车中产品总价的信息,首先会查询存储,然后进行重新计算。

在新包中,所有数据首先存储在购物车实例中。只有在调用 save() 方法时才会将数据保存到存储中。这可以大大减少执行的查询数量,例如数据库查询。

示例

$cart = \Cart::session(123); // <-- if you are using database as a storage then 2 SELECT queries are executed (1 to get the cart items, 1 to get the cart conditions)

$cart->add(array(
    'id' => 1,
    'name' => 'Product 1',
    'price' => 100,
    'quantity' => 4,
    'attributes' => array()
)); // <-- 0 queries are executed (everything is automatically saved only to the cart instance)

$cart->add(array(
    'id' => 2,
    'name' => 'Product 2',
    'price' => 150,
    'quantity' => 2,
    'attributes' => array()
)); // <-- 0 queries are executed (everything is automatically saved only to the cart instance)

$cart->addItemCondition(1, new CartCondition(array(
            'name' => 'COUPON 101',
            'type' => 'coupon',
            'value' => '-5%',
        )); // <-- 0 queries are executed (everything is automatically saved only to the cart instance)

$cart->update(2,[
	'quantity' => 2,
	'price' => 98.67
]); // <-- 0 queries are executed (everything is automatically saved only to the cart instance)

$cart->save(); // <-- if you are using database as a storage then 2 INSERT or UPDATE queries are executed (1 to insert/update the cart items, 1 to insert/update the cart conditions)

$cart->getSubTotal(); // <-- 0 queries are executed (all the necessary data for the calculation is obtained from the cart instance)

那么这个包有什么新功能?

1. 强制使用 session() 方法。

2. 只有在调用 save() 方法时,对购物车的所有更改才会保存到存储中。

有关使用说明的详细信息,请参阅以下原始包说明。

安装

通过 Composer 安装包。

对于 Laravel 5.5+

composer require "izyy123/cart"

快速部分演示

演示: https://shoppingcart-demo.darrylfernandez.com/cart

演示的 Git 仓库:https://github.com/darryldecode/laravelshoppingcart-demo

配置

  1. 打开 config/app.php 并将此行添加到您的 Service Providers 数组中。
Darryldecode\Cart\CartServiceProvider::class
  1. 打开 config/app.php 并将此行添加到您的 Aliases 中
  'Cart' => Darryldecode\Cart\Facades\CartFacade::class
  1. 可选配置文件(如果您需要完全控制,则很有用)
php artisan vendor:publish --provider="Darryldecode\Cart\CartServiceProvider" --tag="config"

使用方法

快速使用示例

// Quick Usage with the Product Model Association & User session binding

$Product = Product::find($productId); // assuming you have a Product model with id, name, description & price
$rowId = 456; // generate a unique() row ID
$userID = 2; // the user ID to bind the cart contents

// add the product to cart
\Cart::session($userID)->add(array(
    'id' => $rowId,
    'name' => $Product->name,
    'price' => $Product->price,
    'quantity' => 4,
    'attributes' => array(),
    'associatedModel' => $Product
));

// update the item on cart
\Cart::session($userID)->update($rowId,[
	'quantity' => 2,
	'price' => 98.67
]);

// delete an item on cart
\Cart::session($userID)->remove($rowId);

// view the cart items
$items = \Cart::getContent();
foreach($items as $row) {

	echo $row->id; // row ID
	echo $row->name;
	echo $row->qty;
	echo $row->price;
	
	echo $item->associatedModel->id; // whatever properties your model have
        echo $item->associatedModel->name; // whatever properties your model have
        echo $item->associatedModel->description; // whatever properties your model have
}

// FOR FULL USAGE, SEE BELOW..

使用方法

重要提示!

默认情况下,购物车有一个默认的 sessionKey,用于存储购物车数据。这也作为购物车唯一标识符,您可以使用它将购物车绑定到特定用户。要覆盖此默认 session Key,您只需在调用任何其他方法之前调用 \Cart::session($sessionKey) 方法即可!

示例

$userId // the current login user id

// This tells the cart that we only need or manipulate
// the cart data of a specific user. It doesn't need to be $userId,
// you can use any unique key that represents a unique to a user or customer.
// basically this binds the cart to a specific user.
\Cart::session($userId);

// then followed by the normal cart usage
\Cart::add();
\Cart::update();
\Cart::remove();
\Cart::condition($condition1);
\Cart::getTotal();
\Cart::getSubTotal();
\Cart::addItemCondition($productID, $coupon101);
// and so on..

以下有更多示例

在购物车中添加商品: Cart::add()

您可以通过以下几种方式向购物车中添加商品,请参阅以下内容

/**
 * add item to the cart, it can be an array or multi dimensional array
 *
 * @param string|array $id
 * @param string $name
 * @param float $price
 * @param int $quantity
 * @param array $attributes
 * @param CartCondition|array $conditions
 * @return $this
 * @throws InvalidItemException
 */

 # ALWAYS REMEMBER TO BIND THE CART TO A USER BEFORE CALLING ANY CART FUNCTION
 # SO CART WILL KNOW WHO'S CART DATA YOU WANT TO MANIPULATE. SEE IMPORTANT NOTICE ABOVE.
 # EXAMPLE: \Cart::session($userId); then followed by cart normal usage.
 
 # NOTE:
 # the 'id' field in adding a new item on cart is not intended for the Model ID (example Product ID)
 # instead make sure to put a unique ID for every unique product or product that has it's own unique prirce, 
 # because it is used for updating cart and how each item on cart are segregated during calculation and quantities. 
 # You can put the model_id instead as an attribute for full flexibility.
 # Example is that if you want to add same products on the cart but with totally different attribute and price.
 # If you use the Product's ID as the 'id' field in cart, it will result to increase in quanity instead
 # of adding it as a unique product with unique attribute and price.

// Simplest form to add item on your cart
Cart::add(455, 'Sample Item', 100.99, 2, array());

// array format
Cart::add(array(
    'id' => 456, // inique row ID
    'name' => 'Sample Item',
    'price' => 67.99,
    'quantity' => 4,
    'attributes' => array()
));

// add multiple items at one time
Cart::add(array(
  array(
      'id' => 456,
      'name' => 'Sample Item 1',
      'price' => 67.99,
      'quantity' => 4,
      'attributes' => array()
  ),
  array(
      'id' => 568,
      'name' => 'Sample Item 2',
      'price' => 69.25,
      'quantity' => 4,
      'attributes' => array(
        'size' => 'L',
        'color' => 'blue'
      )
  ),
));

// add cart items to a specific user
$userId = auth()->user()->id; // or any string represents user identifier
Cart::session($userId)->add(array(
    'id' => 456, // inique row ID
    'name' => 'Sample Item',
    'price' => 67.99,
    'quantity' => 4,
    'attributes' => array(),
    'associatedModel' => $Product
));

// NOTE:
// Please keep in mind that when adding an item on cart, the "id" should be unique as it serves as
// row identifier as well. If you provide same ID, it will assume the operation will be an update to its quantity
// to avoid cart item duplicates

更新购物车中的商品: Cart::update()

更新购物车中的商品非常简单

/**
 * update a cart
 *
 * @param $id (the item ID)
 * @param array $data
 *
 * the $data will be an associative array, you don't need to pass all the data, only the key value
 * of the item you want to update on it
 */

Cart::update(456, array(
  'name' => 'New Item Name', // new item name
  'price' => 98.67, // new item price, price can also be a string format like so: '98.67'
));

// you may also want to update a product's quantity
Cart::update(456, array(
  'quantity' => 2, // so if the current product has a quantity of 4, another 2 will be added so this will result to 6
));

// you may also want to update a product by reducing its quantity, you do this like so:
Cart::update(456, array(
  'quantity' => -1, // so if the current product has a quantity of 4, it will subtract 1 and will result to 3
));

// NOTE: as you can see by default, the quantity update is relative to its current value
// if you want to just totally replace the quantity instead of incrementing or decrementing its current quantity value
// you can pass an array in quantity value like so:
Cart::update(456, array(
  'quantity' => array(
      'relative' => false,
      'value' => 5
  ),
));
// so with that code above as relative is flagged as false, if the item's quantity before is 2 it will now be 5 instead of
// 5 + 2 which results to 7 if updated relatively..

// updating a cart for a specific user
$userId = auth()->user()->id; // or any string represents user identifier
Cart::session($userId)->update(456, array(
  'name' => 'New Item Name', // new item name
  'price' => 98.67, // new item price, price can also be a string format like so: '98.67'
));

从购物车中删除商品: Cart::remove()

从购物车中删除商品非常简单

/**
 * removes an item on cart by item ID
 *
 * @param $id
 */

Cart::remove(456);

// removing cart item for a specific user's cart
$userId = auth()->user()->id; // or any string represents user identifier
Cart::session($userId)->remove(456);

获取购物车中的商品: Cart::get()

/**
 * get an item on a cart by item ID
 * if item ID is not found, this will return null
 *
 * @param $itemId
 * @return null|array
 */

$itemId = 456;

Cart::get($itemId);

// You can also get the sum of the Item multiplied by its quantity, see below:
$summedPrice = Cart::get($itemId)->getPriceSum();

// get an item on a cart by item ID for a specific user's cart
$userId = auth()->user()->id; // or any string represents user identifier
Cart::session($userId)->get($itemId);

获取购物车的商品内容和数量: Cart::getContent()

/**
 * get the cart
 *
 * @return CartCollection
 */

$cartCollection = Cart::getContent();

// NOTE: Because cart collection extends Laravel's Collection
// You can use methods you already know about Laravel's Collection
// See some of its method below:

// count carts contents
$cartCollection->count();

// transformations
$cartCollection->toArray();
$cartCollection->toJson();

// Getting cart's contents for a specific user
$userId = auth()->user()->id; // or any string represents user identifier
Cart::session($userId)->getContent($itemId);

检查购物车是否为空: Cart::isEmpty()

/**
* check if cart is empty
*
* @return bool
*/
Cart::isEmpty();

// Check if cart's contents is empty for a specific user
$userId = auth()->user()->id; // or any string represents user identifier
Cart::session($userId)->isEmpty();

获取购物车总数量: Cart::getTotalQuantity()

/**
* get total quantity of items in the cart
*
* @return int
*/
$cartTotalQuantity = Cart::getTotalQuantity();

// for a specific user
$cartTotalQuantity = Cart::session($userId)->getTotalQuantity();

获取购物车小计: Cart::getSubTotal()

/**
* get cart sub total
*
* @return float
*/
$subTotal = Cart::getSubTotal();

// for a specific user
$subTotal = Cart::session($userId)->getSubTotal();

获取购物车总额: Cart::getTotal()

/**
 * the new total in which conditions are already applied
 *
 * @return float
 */
$total = Cart::getTotal();

// for a specific user
$total = Cart::session($userId)->getTotal();

清空购物车: Cart::clear()

/**
* clear cart
*
* @return void
*/
Cart::clear();
Cart::session($userId)->clear();

条件

Laravel 购物车支持购物车条件。条件在(优惠券、折扣、促销、单项促销和折扣等)方面非常有用。请仔细查看以下如何使用条件的说明。

条件可以添加在以下位置

1.) 整个购物车价值基础

2.) 每个商品基础

首先,让我们在购物车基础上添加一个条件

在购物车中添加条件也有几种方法:注意

当在购物车基础上添加条件时,'目标'应该有值'小计'或'总计'。如果目标是"小计",则此条件将应用于小计。如果目标是"总计",则此条件将应用于总计。在计算过程中,操作顺序也会根据您添加条件的顺序而变化。

此外,当添加条件时,'值'字段将是计算的基础。您可以通过在购物车条件中添加'顺序'参数来更改此顺序。

// add single condition on a cart bases
$condition = new \Darryldecode\Cart\CartCondition(array(
    'name' => 'VAT 12.5%',
    'type' => 'tax',
    'target' => 'subtotal', // this condition will be applied to cart's subtotal when getSubTotal() is called.
    'value' => '12.5%',
    'attributes' => array( // attributes field is optional
    	'description' => 'Value added tax',
    	'more_data' => 'more data here'
    )
));

Cart::condition($condition);
Cart::session($userId)->condition($condition); // for a speicifc user's cart

// or add multiple conditions from different condition instances
$condition1 = new \Darryldecode\Cart\CartCondition(array(
    'name' => 'VAT 12.5%',
    'type' => 'tax',
    'target' => 'subtotal', // this condition will be applied to cart's subtotal when getSubTotal() is called.
    'value' => '12.5%',
    'order' => 2
));
$condition2 = new \Darryldecode\Cart\CartCondition(array(
    'name' => 'Express Shipping $15',
    'type' => 'shipping',
    'target' => 'subtotal', // this condition will be applied to cart's subtotal when getSubTotal() is called.
    'value' => '+15',
    'order' => 1
));
Cart::condition($condition1);
Cart::condition($condition2);

// Note that after adding conditions that are targeted to be applied on subtotal, the result on getTotal()
// will also be affected as getTotal() depends in getSubTotal() which is the subtotal.

// add condition to only apply on totals, not in subtotal
$condition = new \Darryldecode\Cart\CartCondition(array(
    'name' => 'Express Shipping $15',
    'type' => 'shipping',
    'target' => 'total', // this condition will be applied to cart's total when getTotal() is called.
    'value' => '+15',
    'order' => 1 // the order of calculation of cart base conditions. The bigger the later to be applied.
));
Cart::condition($condition);

// The property 'order' lets you control the sequence of conditions when calculated. Also it lets you add different conditions through for example a shopping process with multiple
// pages and still be able to set an order to apply the conditions. If no order is defined defaults to 0

// NOTE!! On current version, 'order' parameter is only applicable for conditions for cart bases. It does not support on per item conditions.

// or add multiple conditions as array
Cart::condition([$condition1, $condition2]);

// To get all applied conditions on a cart, use below:
$cartConditions = Cart::getConditions();
foreach($cartConditions as $condition)
{
    $condition->getTarget(); // the target of which the condition was applied
    $condition->getName(); // the name of the condition
    $condition->getType(); // the type
    $condition->getValue(); // the value of the condition
    $condition->getOrder(); // the order of the condition
    $condition->getAttributes(); // the attributes of the condition, returns an empty [] if no attributes added
}

// You can also get a condition that has been applied on the cart by using its name, use below:
$condition = Cart::getCondition('VAT 12.5%');
$condition->getTarget(); // the target of which the condition was applied
$condition->getName(); // the name of the condition
$condition->getType(); // the type
$condition->getValue(); // the value of the condition
$condition->getAttributes(); // the attributes of the condition, returns an empty [] if no attributes added

// You can get the conditions calculated value by providing the subtotal, see below:
$subTotal = Cart::getSubTotal();
$condition = Cart::getCondition('VAT 12.5%');
$conditionCalculatedValue = $condition->getCalculatedValue($subTotal);

注意:所有基于购物车的条件应添加到购物车条件中,然后再调用Cart::getTotal(),如果还有针对小计的目标条件,则应添加到购物车条件中,然后再调用Cart::getSubTotal()

$cartTotal = Cart::getSubTotal(); // the subtotal with the conditions targeted to "subtotal" applied
$cartTotal = Cart::getTotal(); // the total with the conditions targeted to "total" applied
$cartTotal = Cart::session($userId)->getSubTotal(); // for a specific user's cart
$cartTotal = Cart::session($userId)->getTotal(); // for a specific user's cart

接下来是按项目基础添加的条件。

如果您有优惠券仅适用于特定项目而不是整个购物车价值,这非常有用。

注意:当按项目基础添加条件时,不需要或可以省略'target'参数,与添加条件或按购物车基础不同。

现在让我们添加一个项目条件。

// lets create first our condition instance
$saleCondition = new \Darryldecode\Cart\CartCondition(array(
            'name' => 'SALE 5%',
            'type' => 'tax',
            'value' => '-5%',
        ));

// now the product to be added on cart
$product = array(
            'id' => 456,
            'name' => 'Sample Item 1',
            'price' => 100,
            'quantity' => 1,
            'attributes' => array(),
            'conditions' => $saleCondition
        );

// finally add the product on the cart
Cart::add($product);

// you may also add multiple condition on an item
$itemCondition1 = new \Darryldecode\Cart\CartCondition(array(
    'name' => 'SALE 5%',
    'type' => 'sale',
    'value' => '-5%',
));
$itemCondition2 = new CartCondition(array(
    'name' => 'Item Gift Pack 25.00',
    'type' => 'promo',
    'value' => '-25',
));
$itemCondition3 = new \Darryldecode\Cart\CartCondition(array(
    'name' => 'MISC',
    'type' => 'misc',
    'value' => '+10',
));

$item = array(
          'id' => 456,
          'name' => 'Sample Item 1',
          'price' => 100,
          'quantity' => 1,
          'attributes' => array(),
          'conditions' => [$itemCondition1, $itemCondition2, $itemCondition3]
      );

Cart::add($item);

注意:所有购物车项目条件应在调用Cart::getSubTotal()之前添加

然后最后,您可以通过调用Cart::getSubTotal()来获取带有每个项目的应用条件的购物车小计。

// the subtotal will be calculated based on the conditions added that has target => "subtotal"
// and also conditions that are added on per item
$cartSubTotal = Cart::getSubTotal();

向购物车中的现有项目添加条件:Cart::addItemCondition($productId, $itemCondition)

向购物车中的现有项目添加条件也很简单。

在结账过程中添加新条件时,如优惠券和促销代码,这非常有用。让我们看看如何做的例子

$productID = 456;
$coupon101 = new CartCondition(array(
            'name' => 'COUPON 101',
            'type' => 'coupon',
            'value' => '-5%',
        ));

Cart::addItemCondition($productID, $coupon101);

清除购物车条件:Cart::clearCartConditions()

/**
* clears all conditions on a cart,
* this does not remove conditions that has been added specifically to an item/product.
* If you wish to remove a specific condition to a product, you may use the method: removeItemCondition($itemId,$conditionName)
*
* @return void
*/
Cart::clearCartConditions()

删除特定购物车条件:Cart::removeCartCondition($conditionName)

/**
* removes a condition on a cart by condition name,
* this can only remove conditions that are added on cart bases not conditions that are added on an item/product.
* If you wish to remove a condition that has been added for a specific item/product, you may
* use the removeItemCondition(itemId, conditionName) method instead.
*
* @param $conditionName
* @return void
*/
$conditionName = 'Summer Sale 5%';

Cart::removeCartCondition($conditionName)

删除特定项目条件:Cart::removeItemCondition($itemId, $conditionName)

/**
* remove a condition that has been applied on an item that is already on the cart
*
* @param $itemId
* @param $conditionName
* @return bool
*/
Cart::removeItemCondition($itemId, $conditionName)

清除所有项目条件:Cart::clearItemConditions($itemId)

/**
* remove all conditions that has been applied on an item that is already on the cart
*
* @param $itemId
* @return bool
*/
Cart::clearItemConditions($itemId)

按类型获取条件:Cart::getConditionsByType($type)

/**
* Get all the condition filtered by Type
* Please Note that this will only return condition added on cart bases, not those conditions added
* specifically on an per item bases
*
* @param $type
* @return CartConditionCollection
*/
public function getConditionsByType($type)

按类型删除条件:Cart::removeConditionsByType($type)

/**
* Remove all the condition with the $type specified
* Please Note that this will only remove condition added on cart bases, not those conditions added
* specifically on an per item bases
*
* @param $type
* @return $this
*/
public function removeConditionsByType($type)

商品

方法Cart::getContent()返回一个项目集合。

要获取项目的ID,请使用属性$item->id

要获取项目的名称,请使用属性$item->name

要获取项目的数量,请使用属性$item->quantity

要获取项目的属性,请使用属性$item->attributes

要获取单个项目未应用条件的价格,请使用属性$item->price

要获取单个项目未应用条件的小计,请使用方法$item->getPriceSum()

/**
* get the sum of price
*
* @return mixed|null
*/
public function getPriceSum()

要获取单个项目未应用条件的价格,请使用方法

$item->getPriceWithConditions().

/**
* get the single price in which conditions are already applied
*
* @return mixed|null
*/
public function getPriceWithConditions()

要获取单个项目应用条件的小计,请使用方法

$item->getPriceSumWithConditions()

/**
* get the sum of price in which conditions are already applied
*
* @return mixed|null
*/
public function getPriceSumWithConditions()

注意:当您获取应用条件的价格时,仅计算分配给当前项目的条件。购物车条件不会应用于价格。

关联模型

可以将购物车项目与模型关联。例如,您的应用程序中有一个Product模型。使用associate()方法,您可以告诉购物车购物车中的项目与Product模型相关联。

这样,您可以使用属性$item->model访问您的模型。

下面是一个例子

// add the item to the cart.
$cartItem = Cart::add(455, 'Sample Item', 100.99, 2, array())->associate('Product');

// array format
Cart::add(array(
    'id' => 456,
    'name' => 'Sample Item',
    'price' => 67.99,
    'quantity' => 4,
    'attributes' => array(),
    'associatedModel' => 'Product'
));

// add multiple items at one time
Cart::add(array(
  array(
      'id' => 456,
      'name' => 'Sample Item 1',
      'price' => 67.99,
      'quantity' => 4,
      'attributes' => array(),
      'associatedModel' => 'Product'
  ),
  array(
      'id' => 568,
      'name' => 'Sample Item 2',
      'price' => 69.25,
      'quantity' => 4,
      'attributes' => array(
        'size' => 'L',
        'color' => 'blue'
      ),
      'associatedModel' => 'Product'
  ),
));

// Now, when iterating over the content of the cart, you can access the model.
foreach(Cart::getContent() as $row) {
	echo 'You have ' . $row->qty . ' items of ' . $row->model->name . ' with description: "' . $row->model->description . '" in your cart.';
}

注意:这仅在添加项目到购物车时才有效。

实例

您可能还希望在同一个页面上使用多个购物车实例而不会发生冲突。为此,

创建一个新的服务提供者,然后在register()方法中,您可以这样做

$this->app['wishlist'] = $this->app->share(function($app)
		{
			$storage = $app['session']; // laravel session storage
			$events = $app['events']; // laravel event handler
			$instanceName = 'wishlist'; // your cart instance name
			$session_key = 'AsASDMCks0ks1'; // your unique session key to hold cart items

			return new Cart(
				$storage,
				$events,
				$instanceName,
				$session_key
			);
		});

// for 5.4 or newer
use Darryldecode\Cart\Cart;
use Illuminate\Support\ServiceProvider;

class WishListProvider extends ServiceProvider
{
    /**
     * Bootstrap the application services.
     *
     * @return void
     */
    public function boot()
    {
        //
    }
    /**
     * Register the application services.
     *
     * @return void
     */
    public function register()
    {
        $this->app->singleton('wishlist', function($app)
        {
            $storage = $app['session'];
            $events = $app['events'];
            $instanceName = 'cart_2';
            $session_key = '88uuiioo99888';
            return new Cart(
                $storage,
                $events,
                $instanceName,
                $session_key,
                config('shopping_cart')
            );
        });
    }
}

如果您在多个购物车实例上遇到问题,请查看此演示仓库中的代码:[DEMO](https://github.com/darryldecode/laravelshoppingcart-demo)。

异常

目前只有两个异常。

事件

购物车目前有9个事件您可以监听并挂钩一些操作。

注意:对于不同的购物车实例,处理事件很简单。例如,您创建了另一个名为“心愿单”的购物车实例。事件将类似于:{$instanceName}.created($cart)

因此,对于您的心愿单购物车实例,事件将如下所示

  • wishlist.created($cart)
  • wishlist.adding($items, $cart)
  • wishlist.added($items, $cart)等等。

格式化响应

现在您可以格式化所有响应。您可以从包中发布配置文件或使用环境变量来设置配置。您有的选项是

  • format_numbers 或 env('SHOPPING_FORMAT_VALUES', false) => 激活或停用此功能。默认为 false。
  • decimals 或 env('SHOPPING_DECIMALS', 0) => 您想显示的小数位数。默认为 0。
  • dec_point 或 env('SHOPPING_DEC_POINT', '.') => 小数点类型。默认为 '.'。
  • thousands_sep 或 env('SHOPPING_THOUSANDS_SEP', ',') => 价值的千位分隔符。默认为 ','。

示例

// add items to cart
Cart::add(array(
  array(
      'id' => 456,
      'name' => 'Sample Item 1',
      'price' => 67.99,
      'quantity' => 4,
      'attributes' => array()
  ),
  array(
      'id' => 568,
      'name' => 'Sample Item 2',
      'price' => 69.25,
      'quantity' => 4,
      'attributes' => array(
        'size' => 'L',
        'color' => 'blue'
      )
  ),
));

// then you can:
$items = Cart::getContent();

foreach($items as $item)
{
    $item->id; // the Id of the item
    $item->name; // the name
    $item->price; // the single price without conditions applied
    $item->getPriceSum(); // the subtotal without conditions applied
    $item->getPriceWithConditions(); // the single price with conditions applied
    $item->getPriceSumWithConditions(); // the subtotal with conditions applied
    $item->quantity; // the quantity
    $item->attributes; // the attributes

    // Note that attribute returns ItemAttributeCollection object that extends the native laravel collection
    // so you can do things like below:

    if( $item->attributes->has('size') )
    {
        // item has attribute size
    }
    else
    {
        // item has no attribute size
    }
}

// or
$items->each(function($item)
{
    $item->id; // the Id of the item
    $item->name; // the name
    $item->price; // the single price without conditions applied
    $item->getPriceSum(); // the subtotal without conditions applied
    $item->getPriceWithConditions(); // the single price with conditions applied
    $item->getPriceSumWithConditions(); // the subtotal with conditions applied
    $item->quantity; // the quantity
    $item->attributes; // the attributes

    if( $item->attributes->has('size') )
    {
        // item has attribute size
    }
    else
    {
        // item has no attribute size
    }
});

存储

使用不同的存储来存储购物车项非常直接。注入到购物车实例的存储类只需要方法。

例如,我们需要一个心愿单,并且我们希望将其键值对存储在数据库中而不是默认的会话中。

为此,我们首先需要一个数据库表来存储我们的购物车数据。让我们通过执行php artisan make:migration create_cart_storage_table来创建它。

示例代码

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateCartStorageTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('cart_storage', function (Blueprint $table) {
            $table->string('id')->index();
            $table->longText('cart_data');
            $table->timestamps();

            $table->primary('id');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('cart_storage');
    }
}

接下来,让我们为这个表创建一个eloquent模型,这样我们就可以轻松地处理数据。您想将此模型存储在哪里取决于您。对于这个例子,让我们假设将其存储在App命名空间中。

代码

namespace App;

use Illuminate\Database\Eloquent\Model;


class DatabaseStorageModel extends Model
{
    protected $table = 'cart_storage';

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'id', 'cart_data',
    ];

    public function setCartDataAttribute($value)
    {
        $this->attributes['cart_data'] = serialize($value);
    }

    public function getCartDataAttribute($value)
    {
        return unserialize($value);
    }
}

接下来,为您的存储创建一个新的类,以便将其注入到购物车实例中

例如:

class DBStorage {

    public function has($key)
    {
        return DatabaseStorageModel::find($key);
    }

    public function get($key)
    {
        if($this->has($key))
        {
            return new CartCollection(DatabaseStorageModel::find($key)->cart_data);
        }
        else
        {
            return [];
        }
    }

    public function put($key, $value)
    {
        if($row = DatabaseStorageModel::find($key))
        {
            // update
            $row->cart_data = $value;
            $row->save();
        }
        else
        {
            DatabaseStorageModel::create([
                'id' => $key,
                'cart_data' => $value
            ]);
        }
    }
}

例如,您也可以利用Laravel的缓存(redis、memcached、文件、dynamo等)使用下面的示例。示例还包括cookie持久性,因此购物车仍然可以在30天内可用。默认情况下,会话只能持续20分钟。

namespace App\Cart;

use Carbon\Carbon;
use Cookie;
use Darryldecode\Cart\CartCollection;

class CacheStorage
{
    private $data = [];
    private $cart_id;

    public function __construct()
    {
        $this->cart_id = \Cookie::get('cart');
        if ($this->cart_id) {
            $this->data = \Cache::get('cart_' . $this->cart_id, []);
        } else {
            $this->cart_id = uniqid();
        }
    }

    public function has($key)
    {
        return isset($this->data[$key]);
    }

    public function get($key)
    {
        return new CartCollection($this->data[$key] ?? []);
    }

    public function put($key, $value)
    {
        $this->data[$key] = $value;
        \Cache::put('cart_' . $this->cart_id, $this->data, Carbon::now()->addDays(30));

        if (!Cookie::hasQueued('cart')) {
            Cookie::queue(
                Cookie::make('cart', $this->cart_id, 60 * 24 * 30)
            );
        }
    }
}

要使这成为购物车的默认存储,让我们更新购物车的配置文件。首先,让我们首先发布购物车配置文件,以便我们能够覆盖它。php artisan vendor:publish --provider="Darryldecode\Cart\CartServiceProvider" --tag="config"

运行该命令后,您的配置文件夹中应该有一个新文件名为shopping_cart.php

打开此文件,让我们更新存储使用。找到键'storage' => null,并将其更新为您的DBStorage类,在我们的例子中为'storage' => \App\DBStorage::class,

或者,如果您有多个购物车实例(例如心愿单),您可以通过将其注入到心愿单购物车服务提供者中,将自定义数据库存储注入到购物车实例中,您将存储替换为您的自定义存储。以下是如何操作的示例

use Darryldecode\Cart\Cart;
use Illuminate\Support\ServiceProvider;

class WishListProvider extends ServiceProvider
{
    /**
     * Bootstrap the application services.
     *
     * @return void
     */
    public function boot()
    {
        //
    }
    /**
     * Register the application services.
     *
     * @return void
     */
    public function register()
    {
        $this->app->singleton('wishlist', function($app)
        {
            $storage = new DBStorage(); <-- Your new custom storage
            $events = $app['events'];
            $instanceName = 'cart_2';
            $session_key = '88uuiioo99888';
            return new Cart(
                $storage,
                $events,
                $instanceName,
                $session_key,
                config('shopping_cart')
            );
        });
    }
}

仍然对如何进行自定义数据库存储感到困惑?或者,也许在做多个购物车实例?请查看演示仓库中的代码以及如何根据您的需求进行扩展的方法,或者将其作为指南和参考。以下链接

在此查看演示应用程序

或者

在此查看演示应用程序仓库

许可协议

Laravel购物车是开源软件,许可协议为MIT许可

免责声明

本软件按“原样”提供,不承担任何明示或暗示的保证,包括但不限于适销性和特定用途的适用性保证。在任何情况下,作者或任何贡献者均不对任何直接、间接、偶然、特殊、示范性或后果性损害(包括但不限于替代商品或服务的采购;使用、数据或利润的损失;或业务中断)承担责任,无论损害发生的原因和责任理论是什么,即使被告知了此类损害的可能性。