bnet/laravel-cart

Laravel 5 购物车

3.3.1 2020-01-27 17:03 UTC

README

Laravel 框架的购物车实现

本包基于 darryldecode/cart - 所有荣誉归他所有

安装

通过 Composer 安装此包。编辑你的项目 composer.json 文件,添加以下内容

composer require "bnet/laravel-cart"

配置

  1. 打开 config/app.php 并将此行添加到你的 Service Providers 数组中,如果你想使用整数值

    Bnet\Cart\CartServiceProvider::class
    

    或者,如果你想使用 Money() 价格

    Bnet\Cart\CurrencyCartServiceProvider::class
    
  2. 打开 config/app.php 并将此行添加到你的 Aliases 中

    'Cart' => Bnet\Cart\Facades\CartFacade::class
    

使用方法

使用

在购物车中添加项目: 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
 */

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

// array format
Cart::add(array(
    'id' => 456,
    '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,
      'quantity_independent' => true, // only one for item, not multiply with quantity
      'attributes' => array()
  ),
  array(
      'id' => 568,
      'name' => 'Sample Item 2',
      'price' => 69.25,
      'quantity' => 4,
      'attributes' => array(
        'size' => 'L',
        'color' => 'blue'
      )
  ),
));

// 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..

从购物车中移除项目: Cart::remove()

从购物车中移除项目非常容易

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

Cart::remove(456);

获取购物车中的项目: Cart::item()

/**
 * 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::item($itemId);

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

获取购物车内容和数量: Cart::items()

/**
 * get the cart
 *
 * @return Items
 */

$cartCollection = Cart::items();

// 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();

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

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

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

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

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

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

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

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

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

/**
* clear cart
*
* @return void
*/
Cart::clear();

条件

Laravel 购物车支持购物车条件。条件在优惠券、折扣、促销、按项目折扣和折扣等方面非常有用。请仔细阅读以下内容,了解如何使用条件。

条件可以添加在

  1. 整个购物车价值基础上
  2. 按项目基础上

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

还有几种方法可以在购物车中添加条件

注意

当在购物车基础上添加条件时,'target' 应该有 'subtotal' 的值。当在项目上添加条件时,'target' 应该是 'item'。计算操作的顺序也会根据你添加条件的顺序而变化。

此外,当添加条件时,'value' 字段将是计算的基础。

// add single condition on a cart bases
$condition = new \Bnet\Cart\CartCondition(array(
    'name' => 'VAT 12.5%',
    'type' => 'tax',
    'target' => 'cart',
    'value' => '12.5%',
    'attributes' => array( // attributes field is optional
    	'description' => 'Value added tax',
    	'more_data' => 'more data here'
    )
));

Cart::condition($condition);

// or add multiple conditions from different condition instances
$condition1 = new \Bnet\Cart\CartCondition(array(
    'name' => 'VAT 12.5%',
    'type' => 'tax',
    'target' => 'cart',
    'value' => '12.5%',
));
$condition2 = new \Bnet\Cart\CartCondition(array(
    'name' => 'Express Shipping $15',
    'type' => 'shipping',
    'target' => 'cart',
    'value' => '+15',
));
Cart::condition($condition1);
Cart::condition($condition2);

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

// To get all applied conditions on a cart, use below:
$cartConditions = Cart::getConditions();
foreach($carConditions 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->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::subTotal();
$condition = Cart::getCondition('VAT 12.5%');
$conditionCalculatedValue = $condition->getCalculatedValue($subTotal);

注意:所有基于购物车的条件应该在调用 Cart::total() 之前应用。

然后最终你可以调用 Cart::total() 来获取应用了条件的购物车总额。

// the total will be calculated based on the conditions you ave provided
$cartTotal = Cart::total();

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

如果你有优惠券需要专门应用于项目而不是整个购物车价值,这将非常有用。

注意:当在按项目基础上添加条件时,'target' 应该是 'item'。

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

// lets create first our condition instance
$saleCondition = new \Bnet\Cart\CartCondition(array(
            'name' => 'SALE 5%',
            'type' => 'tax',
            'target' => 'item',
            '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 \Bnet\Cart\CartCondition(array(
    'name' => 'SALE 5%',
    'type' => 'sale',
    'target' => 'item',
    'value' => '-5%',
));
$itemCondition2 = new CartCondition(array(
    'name' => 'Item Gift Pack 25.00',
    'type' => 'promo',
    'target' => 'item',
    'value' => '-25',
));
$itemCondition3 = new \Bnet\Cart\CartCondition(array(
    'name' => 'MISC',
    'type' => 'misc',
    'target' => 'item',
    'value' => '+10',
));

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

Cart::add($item);

注意:所有基于购物车的项目条件应该在调用 Cart::subTotal() 之前应用。

然后最终你可以调用 Cart::subTotal() 来获取应用了条件的购物车小计。

$cartSubTotal = Cart::subTotal(); // the subtotal will be calculated based on the conditions you have provided

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

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

这在结账过程中添加新条件(如优惠券和促销代码)时非常有用。让我们看看如何做到这一点

$productID = 456;
$coupon101 = new CartCondition(array(
            'name' => 'COUPON 101',
            'type' => 'coupon',
            'target' => 'item',
            '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::items() 返回商品集合。

要获取商品ID,使用属性 $item->id

要获取商品名称,使用属性 $item->name

要获取商品数量,使用属性 $item->quantity

要获取商品的属性,使用属性 $item->attributes

要获取未应用条件下的单件商品价格,使用属性 $item->price

要获取未应用条件下的商品小计,使用方法 $item->priceSum()

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

要获取未应用条件下的单件商品价格,使用方法

$item->priceWithConditions().

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

要获取应用条件下的商品小计,使用方法

$item->priceSumWithConditions()

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

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

实例

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

创建一个新的服务提供者,然后在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
    );
});

异常

目前只有两个例外。

异常描述
InvalidConditionException在实例化新的条件时存在无效的字段值
InvalidItemException当新产品的字段值无效(id、name、price、quantity)时

事件

购物车当前有9个事件可供监听和钩子操作。

事件触发
cart.created($cart)当购物车被实例化时
cart.adding($items, $cart)当尝试添加商品时
cart.added($items, $cart)当商品被添加到购物车时
cart.updating($items, $cart)当商品正在更新时
cart.updated($items, $cart)当商品被更新时
cart.removing($id, $cart)当商品正在被移除时
cart.removed($id, $cart)当商品被移除时
cart.clearing($cart)当尝试清除购物车时
cart.cleared($cart)当购物车被清除时

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

因此,对于您的“wishlist”购物车实例,事件将如下所示

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

示例

// 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::items();

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

    // Note that attribute returns Attribute 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->priceSum(); // the subtotal without conditions applied
    $item->priceWithConditions(); // the single price with conditions applied
    $item->priceSumWithConditions(); // 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
    }
});

变更日志

  • 3.1.3

    • 向购物车添加属性
    • 更改条件计算行为
    • 添加条件属性“quantity_independent”以对每个商品只计算一次条件,而不是乘以数量
  • 3.1.2

    • isset() 添加到 get() 函数
  • 3.1.1

    • 购物车完全“可数组化”
    • 条件目标是可选的,小计已更改为购物车
  • 3.1.0

    • 允许添加已创建的 Item Object 或商品列表
    • 添加 CurrencyCartServiceProvider
    • 更改货币商品的计算原则
  • 3.0.0

    • 金额的内部表示现在是 int 而不是 float
    • 重命名一些函数(items() 替换为 getItems())和类(Item 替换为 ItemCollection),以提高使用性(更符合 Laravel 风格)
    • 将命名空间更改为 BNet
    • 使 item_rules 可定制(为具有附加自定义商品字段的自己的 CartClass 准备)
    • 添加 CurrencyCart 以使用带有 Money() 价格的购物车而不是 int
  • 2.4.0

    • 在条件中添加了新方法:$condition->getAttributes();(请参阅条件部分)
  • 2.3.0

    • 添加了新购物车方法:Cart::addItemCondition($productId, $itemCondition)
    • 添加了新的购物车方法:Cart::totalQuantity()
  • 2.2.1

    • 修复了错误
  • 2.2.0

    • 添加了新的购物车方法:Cart::getConditionsByType($type)
    • 添加了新的商品方法:Cart::removeConditionsByType($type)
  • 2.1.1

    • 当在购物车中添加具有相同ID的新产品并提供了数量时,它将增加当前数量而不是覆盖它。也有可能您需要更新商品的数量,但不是增加而是减少,请参阅文档(请参阅Cart::update()部分,并仔细阅读)
  • 2.1.0

    • 添加了新的购物车方法:getCalculatedValue($totalOrSubTotalOrPrice)
    • 添加了新的商品方法:priceSum()
  • 2.0.0(破坏性变更)

    • 处理条件的主要变化(请参阅条件部分,并仔细阅读)
    • 现在所有在单个商品基础上添加的条件都应该有target => 'item'而不是'subtotal'
    • 现在所有在购物车基础上添加的条件都应该有target => 'subtotal'而不是'total'
  • 1.1.0

    • 添加了新方法:clearCartConditions()
    • 添加了新方法:removeItemCondition($itemId, $conditionName)
    • 添加了新方法:removeCartCondition($conditionName)

许可

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

免责声明

本软件按“现状”提供,并不承担任何明示或暗示的保证,包括但不限于对适销性和特定用途的暗示保证。在任何情况下,作者或任何贡献者都不应对任何直接、间接、偶然、特殊、示范性或连锁损害(包括但不限于替代商品或服务的采购;使用、数据或利润的损失;或业务的中断)承担责任,无论这些损害是否因本软件的使用或本软件使用不当而引起,即使已被告知此类损害的可能性。