ronash-dhakal/yii2-cart

为Yii2框架添加购物车功能的扩展

安装: 18

依赖项: 0

建议者: 0

安全: 0

星标: 0

关注者: 0

分支: 0

开放问题: 1

类型:yii2-extension

dev-master 2019-04-15 13:22 UTC

This package is auto-updated.

Last update: 2024-09-16 01:38:16 UTC


README

此扩展是对omnilight/yii2-shopping-cart的改进。它为Yii框架2.0添加了购物车系统。它支持将购物车数据保存到多种介质,包括session(默认)、cookie、localStorage、数据库和多种存储。

什么是“多种存储”?这是指它可以处理两种存储,如果用户是访客,则将购物车数据保存到存储1,如果用户是登录用户,则保存到存储2。

安装

安装此扩展的首选方式是通过composer

运行以下命令:

php composer.phar require --prefer-dist ronas-dhakal/yii2-cart "*"

或者将以下内容添加到您的composer.json文件的require部分:

"ronash-dhakal/yii2-cart": "*"

require

如果您计划将购物车数据保存到数据库中,那么您应该创建一个名为cart的表。

CREATE TABLE `cart` (
  `id` varchar(255) NOT NULL,
  `user_id` int(11) DEFAULT NULL,
  `name` varchar(255) NOT NULL,
  `value` text NOT NULL,
  `status` tinyint(1) NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `cart`
  ADD PRIMARY KEY (`id`);

或者使用迁移

yii migrate --migrationPath=@ronashDhakal/cart/migrations

如何使用

在您的模型中

class Product extends ActiveRecord implements ItemInterface
{
    use ItemTrait;

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

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

在您的控制器中

	public function actionCreate($id)
    {
        $product = Product::findOne($id);
        if ($product) {
            \Yii::$app->cart->create($product);
            $this->redirect(['index']);
        }
    }
    public function actionIndex()
    {
        $cart = \Yii::$app->cart;
        $products = $cart->getItems();
        $total = $cart->getCost();
        return $this->render('index', [
            'products' => $products,
            'total' => $total,
        ]);
    }
    public function actionDelete($id)
    {
        $product = Product::findOne($id);
        if ($product) {
            \Yii::$app->cart->delete($product);
            $this->redirect(['index']);
        }
    }
    public function actionUpdate($id, $quantity)
    {
        $product = Product::findOne($id);
        if ($product) {
            \Yii::$app->cart->update($product, $quantity);
            $this->redirect(['index']);
        }
    }
	
	public function actionCheckout(){
		\Yii::$app->cart->checkOut(false);
		$this->redirect(['index']);
	}

您还可以将购物车作为全局应用程序组件使用

[
    'components' => [
        'cart' => [
			'class' => 'ronashDhakal\cart\Cart',
		],
    ]
]

存储的可能值包括

  • ronashDhakal\cart\CookieStorage
  • ronashDhakal\cart\SessionStorage
  • ronashDhakal\cart\LocalStorage
  • ronashDhakal\cart\DatabaseStorage
  • ronashDhakal\cart\MultipleStorage

MultipleStorage的示例配置。

[
    'components' => [
        'cart' => [
			'class' => 'ronashDhakal\cart\Cart',
			'storage' => [
				'class' => 'ronashDhakal\cart\MultipleStorage',
				'storages' => [
					['class' => 'ronashDhakal\cart\SessionStorage'],
					[
						'class' => 'ronashDhakal\cart\DatabaseStorage',
						'table' => 'cart',
					],
				],
			]
		],
    ]
]

如果您使用多种存储,则应将引导程序添加到配置文件中

    'bootstrap' => [
		...
		'ronashDhakal\cart\CartBootstrap'
	],

或者您可以创建并使用自己的storageClass,它应扩展ronashDhakal\cart\Storage的抽象类。它看起来像

<?php

namespace app\foo;

use ronashDhakal\cart\Storage;

class ExampleStorage extends Storage
{
	public function read(Cart $cart)
	{
		// read cart data
	}
	
	public function write(Cart $cart)
	{
		// write cart data
	}
	
	public function lock($drop, Cart $cart)
	{
		// lock cart data, only for db
	}
}

并按以下方式使用它

\Yii::$app->cart->create($product, 1);

为了获取购物车中商品的数量

$itemsCount = \Yii::$app->cart->getCount();

为了获取购物车中商品的总成本

$total = \Yii::$app->cart->getCost();

如果用户已完成并进行了结账,则可以使用以下代码

\Yii::$app->cart->removeAll(); // will remove data
// or 
\Yii::$app->cart->checkOut(); // will remove data
// or
\Yii::$app->cart->checkOut(false); // will keep data, only update status to 1 and regenerate session ID

使用折扣

折扣作为可以附加到购物车或其项目的行为实现。要使用它们,请按照以下步骤操作

  1. 将折扣类定义为ronashDhakal\cart\DiscountBehavior的子类
// app/components/MyDiscount.php

class MyDiscount extends DiscountBehavior
{
    /**
     * @param CostCalculationEvent $event
     */
    public function onCostCalculation($event)
    {
        // Some discount logic, for example
        $event->discountValue = 100;
    }
}
  1. 将此行为添加到购物车中
$cart->attachBehavior('myDiscount', ['class' => 'app\components\MyDiscount']);

如果折扣不适用于整个购物车,而是针对单个项目,则可以将折扣附加到购物车位置本身

$cart->getItemById($itemId)->attachBehavior('myDiscount', ['class' => 'app\components\MyDiscount']);

注意,相同的行可以用于购物车和项目类。

  1. 获取应用折扣后的总成本
$total = \Yii::$app->cart->getCost(true);
  1. 在计算过程中,将触发以下事件
  • Cart::EVENT_COST_CALCULATION每次计算时触发。
  • ItemInterface::EVENT_COST_CALCULATION为购物车中的每个项目触发。

您还可以订阅这些事件以执行折扣计算

$cart->on(Cart::EVENT_COST_CALCULATION, function ($event) {
    $event->discountValue = 100;
});