ronash-dhakal / yii2-cart
为Yii2框架添加购物车功能的扩展
dev-master
2019-04-15 13:22 UTC
Requires
- php: >=5.4.0
- yiisoft/yii2: *
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
使用折扣
折扣作为可以附加到购物车或其项目的行为实现。要使用它们,请按照以下步骤操作
- 将折扣类定义为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; } }
- 将此行为添加到购物车中
$cart->attachBehavior('myDiscount', ['class' => 'app\components\MyDiscount']);
如果折扣不适用于整个购物车,而是针对单个项目,则可以将折扣附加到购物车位置本身
$cart->getItemById($itemId)->attachBehavior('myDiscount', ['class' => 'app\components\MyDiscount']);
注意,相同的行可以用于购物车和项目类。
- 获取应用折扣后的总成本
$total = \Yii::$app->cart->getCost(true);
- 在计算过程中,将触发以下事件
Cart::EVENT_COST_CALCULATION每次计算时触发。ItemInterface::EVENT_COST_CALCULATION为购物车中的每个项目触发。
您还可以订阅这些事件以执行折扣计算
$cart->on(Cart::EVENT_COST_CALCULATION, function ($event) { $event->discountValue = 100; });