asyou99 / yii2-cart
为Yii2添加购物车功能的扩展
v2.2
2016-01-17 23:24 UTC
Requires
- php: >=5.4.0
- yiisoft/yii2: *
README
此扩展是对omnilight/yii2-shopping-cart的改进。它为Yii框架2.0添加了购物车系统。它支持将购物车数据保存到多种媒介,包括会话(默认)、cookie、localStorage、数据库和多种存储。
多重存储的意义是什么?这是指可以处理两种存储方式的功能,即如果用户是访客,则将购物车数据保存到存储1,如果用户是登录用户,则保存到存储2。
安装
安装此扩展的首选方式是通过 composer。
运行
php composer.phar require --prefer-dist asyou99/yii2-cart "dev-master"
或添加
"asyou99/yii2-cart": "dev-master"
到您的 composer.json 文件的 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=@asyou99/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' => 'asyou99\cart\Cart', ], ] ]
存储的可能值有
- asyou99\cart\CookieStorage
- asyou99\cart\SessionStorage
- asyou99\cart\LocalStorage
- asyou99\cart\DatabaseStorage
- asyou99\cart\MultipleStorage
MultipleStorage 的示例配置。
[ 'components' => [ 'cart' => [ 'class' => 'asyou99\cart\Cart', 'storage' => [ 'class' => 'asyou99\cart\MultipleStorage', 'storages' => [ ['class' => 'asyou99\cart\SessionStorage'], [ 'class' => 'asyou99\cart\DatabaseStorage', 'table' => 'cart', ], ], ] ], ] ]
如果您使用多重存储,则应在配置文件中添加 bootstrap
'bootstrap' => [ ... 'asyou99\cart\CartBootstrap' ],
或者,您可以创建并使用自己的 storageClass,它应该扩展 asyou99\cart\Storage 的抽象类。它的样子如下
<?php
namespace app\foo;
use asyou99\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
使用折扣
折扣作为可以附加到购物车或其物品的行为实现。要使用它们,请按照以下步骤操作
- 将折扣类定义为 asyou99\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; });