sarga/packages/Webkul/Cart/src/Cart.php

486 lines
16 KiB
PHP
Raw Normal View History

2018-09-11 11:19:40 +00:00
<?php
namespace Webkul\Cart;
use Carbon\Carbon;
//Cart repositories
use Webkul\Cart\Repositories\CartRepository;
use Webkul\Cart\Repositories\CartItemRepository;
2018-09-11 11:19:40 +00:00
//Customer repositories
use Webkul\Customer\Repositories\CustomerRepository;
2018-09-11 11:19:40 +00:00
use Cookie;
/**
2018-09-20 10:00:52 +00:00
* Facade for all
* the methods to be
2018-09-20 10:00:52 +00:00
* implemented in Cart.
*
* @author Prashant Singh <prashant.singh852@webkul.com>
* @copyright 2018 Webkul Software Pvt Ltd (http://www.webkul.com)
*/
2018-09-11 11:19:40 +00:00
class Cart {
protected $cart;
protected $cartItem;
protected $customer;
2018-09-19 07:00:24 +00:00
//Cookie expiry limit in minutes
protected $minutes;
2018-09-19 07:00:24 +00:00
public function __construct(CartRepository $cart, CartItemRepository $cartItem, CustomerRepository $customer, $minutes = 150) {
$this->customer = $customer;
$this->cart = $cart;
$this->cartItem = $cartItem;
2018-09-19 07:00:24 +00:00
$this->minutes = $minutes;
2018-09-11 11:19:40 +00:00
}
public function guestUnitAdd($id, $data) {
//empty array for storing the products.
$products = array();
2018-09-14 13:15:49 +00:00
if(Cookie::has('cart_session_id')) {
//getting the cart session id from cookie.
2018-09-13 11:50:12 +00:00
$cart_session_id = Cookie::get('cart_session_id');
2018-09-19 07:00:24 +00:00
//finding current cart instance in the database table.
2018-09-14 13:15:49 +00:00
$current_cart = $this->cart->findOneByField('session_id', $cart_session_id);
2018-09-13 11:50:12 +00:00
//check there is any cart or not.
2018-09-14 13:15:49 +00:00
if(isset($current_cart)) {
$current_cart_id = $current_cart['id'] ?? $current_cart->id;
2018-09-14 13:15:49 +00:00
$current_cart_session_id = $current_cart['session_id'] ?? $current_cart->session_id;
} else {
//if someone deleted handle flow to the normal.
2018-09-14 13:15:49 +00:00
$this->repairCart($cart_session_id, $id);
}
//Matching the session id present in the cookie and database are same or not.
2018-09-14 13:15:49 +00:00
if((session()->get('cart_session_id') == Cookie::get('cart_session_id')) && ($current_cart_session_id == session()->get('cart_session_id'))) {
$current_cart_items = $this->cart->items($current_cart_id);
2018-09-14 13:15:49 +00:00
$current_cart_products = array();
foreach($current_cart_items as $current_cart_item) {
array_push($current_cart_products, $this->cartItem->getProduct($current_cart_item->id));
}
2018-09-14 13:15:49 +00:00
2018-09-19 07:00:24 +00:00
//checking new product coming in the cart is new or previously added item.
2018-09-14 13:15:49 +00:00
foreach($current_cart_products as $key => $value) {
$product_id = $value;
2018-09-14 13:15:49 +00:00
if($product_id == $id) {
//create status code to communicate with session flash.
$cartItemId = $this->cartItem->findOneByField('product_id', $id)->id;
$cartItemQuantity = $this->cartItem->findOneByField('product_id', $id)->quantity;
$this->cartItem->update(['quantity' => $cartItemQuantity + $data['quantity']], $cartItemId);
2018-09-14 13:15:49 +00:00
session()->flash('error', 'Item Already In Cart');
//remove this its temporary.
2018-09-14 13:15:49 +00:00
dump('Item Already In Cart');
return redirect()->back();
}
}
2018-09-14 13:15:49 +00:00
2018-09-20 15:12:11 +00:00
//related record
$related['product_id'] = $id;
$related['quantity'] = $data['quantity'];
$related['price'] = $data['price'];
2018-09-19 07:00:24 +00:00
//cart data being attached to the instace.
2018-09-20 15:12:11 +00:00
$cart_data = $this->cart->createItem($current_cart_id, $related);
2018-09-14 13:15:49 +00:00
//getting the products after being attached to cart instance.
$cart_products = $this->cart->items($current_cart_id);
2018-09-14 13:15:49 +00:00
2018-09-19 07:00:24 +00:00
//storing the information in session.
2018-09-14 13:15:49 +00:00
session()->put('cart_data', [$current_cart, $cart_products]);
2018-09-19 07:00:24 +00:00
session()->flash('Success', 'Item Added To Cart Successfully');
2018-09-14 13:15:49 +00:00
//return the control to the controller.
2018-09-14 13:15:49 +00:00
return redirect()->back();
} else {
//repair the cart, will remake the session.
2018-09-19 07:00:24 +00:00
//and add the product in the new cart instance.
2018-09-14 13:15:49 +00:00
$this->repairCart($cart_session_id, $id);
}
2018-09-14 13:15:49 +00:00
} else {
2018-09-19 07:00:24 +00:00
//function call
$this->createNewCart($id, $data);
2018-09-14 13:15:49 +00:00
}
}
/*helpers*/
/**
* Create New Cart
* Cart, Cookie &
* Session.
*
* @return mixed
2018-09-19 07:00:24 +00:00
*/
2018-09-14 13:15:49 +00:00
public function createNewCart($id, $data) {
2018-09-14 13:15:49 +00:00
$fresh_cart_session_id = session()->getId();
if(!auth()->guard('customer')->check())
$data['session_id'] = $fresh_cart_session_id;
2018-09-14 13:15:49 +00:00
$data['channel_id'] = core()->getCurrentChannel()->id;
if($cart = $this->cart->create($data)) {
2018-09-19 07:00:24 +00:00
$this->makeCartSession($fresh_cart_session_id);
2018-09-14 13:15:49 +00:00
$new_cart_id = $cart->id ?? $cart['id'];
$cart_product['product_id'] = $id;
$cart_product['quantity'] = $data['quantity'];
2018-09-14 13:15:49 +00:00
$cart_product['cart_id'] = $new_cart_id;
2018-09-20 10:00:52 +00:00
$cart_product['price'] = $data['price'];
2018-09-20 15:12:11 +00:00
//related item
$related['product_id'] = $cart_product['product_id'];
$related['quantity'] = $cart_product['quantity'];
$related['price'] = $cart_product['price'];
if($cart_product = $this->cart->createItem($new_cart_id, $related)) {
2018-09-14 13:15:49 +00:00
session()->put('cart_data', [$cart, $cart_product]);
2018-09-19 07:00:24 +00:00
session()->flash('success', 'Item Added To Cart Successfully');
2018-09-13 13:40:01 +00:00
2018-09-13 11:50:12 +00:00
return redirect()->back();
}
2018-09-14 13:15:49 +00:00
}
session()->flash('error', 'Some Error Occured');
return redirect()->back();
}
/**
* This makes session
* cart.
*/
public function makeCartSession($cart_session_id) {
2018-09-19 07:00:24 +00:00
$fresh_cart_session_id = $cart_session_id;
Cookie::queue('cart_session_id', $fresh_cart_session_id, $this->minutes);
session()->put('cart_session_id', $fresh_cart_session_id);
}
2018-09-14 13:15:49 +00:00
/**
* Reset Session and
* Cookie values
* and sync database
* if present.
*
* @return mixed
*/
2018-09-19 07:00:24 +00:00
public function repairCart($cart_session_id ="null", $product_id = 0) {
2018-09-14 13:15:49 +00:00
if($cart_session_id == session()->get('cart_session_id')) {
$data['session_id'] = $cart_session_id;
$data['channel_id'] = core()->getCurrentChannel()->id;
$cart = $this->cart->create($data);
$cart_id = $cart['id'] ?? $cart->id;
$this->cart->attach($cart_id, $product_id, 1);
2018-09-19 07:00:24 +00:00
session()->flash('success', 'Item Added To Cart Successfully');
2018-09-14 13:15:49 +00:00
return redirect()->back();
} else {
2018-09-14 13:15:49 +00:00
Cookie::queue(Cookie::forget('cart_session_id'));
2018-09-14 13:15:49 +00:00
session()->forget('cart_session_id');
2018-09-13 11:50:12 +00:00
2018-09-14 13:15:49 +00:00
session()->regenerate();
session()->flash('error', 'Please Try Adding Product Again.');
return redirect()->back();
}
}
/**
* Function for guests
* user to remove the product
* in the cart.
*
* @return Mixed
*/
public function guestUnitRemove($id) {
//remove the products here
2018-09-19 07:00:24 +00:00
if(Cookie::has('session_cart_id')) {
$products = unserialize(Cookie::get('session_cart_id'));
foreach($products as $key => $value) {
if($value == $id) {
unset($products[$key]);
array_push($products, $id);
2018-09-19 07:00:24 +00:00
Cookie::queue('session_cart_id', serialize($products));
return redirect()->back();
}
}
}
}
/*
handle the after login event for the customers
when their are pruoducts in the session or cookie
of the logged in user.
*/
public function add($id, $itemdata) {
$products = array();
2018-09-19 07:00:24 +00:00
if(!auth()->guard('customer')->check()) {
throw new \Exception('This function is protected for auth customers only.');
}
$data['customer_id'] = auth()->guard('customer')->user()->id;
$data['channel_id'] = core()->getCurrentChannel()->id;
2018-09-19 07:00:24 +00:00
$customer_cart = $this->cart->findOneByField('customer_id', $data['customer_id']);
//if there are products already in cart of that customer.
2018-09-19 07:00:24 +00:00
$customer_cart_id = $customer_cart->id ?? $customer_cart['id'];
2018-09-19 07:00:24 +00:00
/**
* Check if their any
* instance of current
* customer in the cart
* table.
*/
if(isset($customer_cart)) {
$customer_cart_items = $this->cart->items($customer_cart_id);
$customer_cart_products = array();
foreach($customer_cart_items as $customer_cart_item) {
array_push($customer_cart_products, $this->cartItem->getProduct($customer_cart_item->id));
}
2018-09-19 07:00:24 +00:00
if (isset($customer_cart_products)) {
2018-09-19 07:00:24 +00:00
foreach ($customer_cart_products as $customer_cart_product) {
if($customer_cart_product == $id) {
$cartItemId = $this->cartItem->findOneByField('product_id', $id)->id;
$cartItemQuantity = $this->cartItem->findOneByField('product_id', $id)->quantity;
$this->cartItem->update(['quantity' => $cartItemQuantity + $itemdata['quantity']], $cartItemId);
2018-09-19 07:00:24 +00:00
session()->flash('error', 'Item already exists in cart');
2018-09-19 07:00:24 +00:00
return redirect()->back();
}
}
2018-09-19 07:00:24 +00:00
2018-09-20 15:12:11 +00:00
//related item
$related['product_id'] = $id;
$related['quantity'] = $itemdata['quantity'];
$related['price'] = $itemdata['price'];
//add the product in the cart
$this->cart->createItem($customer_cart_id, $related);
2018-09-19 07:00:24 +00:00
session()->flash('success', 'Item Added To Cart Successfully');
return redirect()->back();
} else {
$this->cart->destroy($customer_cart_id);
session()->flash('error', 'Try Adding The Item Again');
dd('cart instance without any product found, delete it and create a new one for the current product id');
return redirect()->back();
}
2018-09-19 07:00:24 +00:00
} else {
/**
* this will work
* for logged in users
* and they do not have
* any cart instance
* found in the database.
*/
2018-09-19 07:00:24 +00:00
if($new_cart = $this->cart->create($data)) {
$new_cart_id = $new_cart->id ?? $new_cart['id'];
2018-09-20 15:12:11 +00:00
//related item
$related['product_id'] = $id;
$related['quantity'] = $itemdata['quantity'];
$related['price'] = $itemdata['price'];
$this->cart->createItem($new_cart_id, $related);
2018-09-19 07:00:24 +00:00
session()->flash('success', 'Item Added To Cart Successfully');
2018-09-19 07:00:24 +00:00
return redirect()->back();
2018-09-19 07:00:24 +00:00
} else {
session()->flash('error', 'Cannot Add Item in Cart');
return redirect()->back();
}
}
}
/**
* use detach to remove the
* current product from cart tables
*
* @return Mixed
*/
public function remove($id) {
dd("Removing Item from Cart");
}
/**
* Function to handle merge
* and sync the cookies products
* with the existing data of cart
* in the cart tables;
2018-09-15 08:09:56 +00:00
*/
2018-09-14 13:15:49 +00:00
public function mergeCart() {
//considering cookie as a source of truth.
2018-09-14 13:15:49 +00:00
if(Cookie::has('cart_session_id')) {
/*
Check for previous cart of customer and
pull products from that cart instance
and then check for unique products
and delete the record with session id
and increase the quantity of the products
that are added again before deleting the
guest cart record.
*/
//To hold the customer ID which is currently logged in
$customer_id = auth()->guard('customer')->user()->id;
//having the session id saved in the cart.
2018-09-14 13:15:49 +00:00
$cart_session_id = Cookie::get('cart_session_id');
2018-09-13 11:50:12 +00:00
//pull the record from cart table for above session id.
$guest_cart = $this->cart->findOneByField('session_id', $cart_session_id);
if(!isset($guest_cart)) {
dd('Some One Deleted Cart');
2018-09-13 13:40:01 +00:00
return redirect()->back();
}
$guest_cart_items = $this->cart->items($guest_cart->id);
$guest_cart_products = array();
foreach($guest_cart_items as $guest_cart_item) {
array_push($guest_cart_products, $this->cartItem->getProduct($guest_cart_item->id));
}
//check if the current logged in customer is also
//having any previously saved cart instances.
$customer_cart = $this->cart->findOneByField('customer_id', $customer_id);
if(isset($customer_cart)) {
$customer_cart_items = $this->cart->items($customer_cart->id);
$customer_cart_products = array();
foreach($customer_cart_items as $customer_cart_item) {
array_push($customer_cart_products, $this->cartItem->getProduct($customer_cart_item->id));
}
foreach($guest_cart_products as $key => $guest_cart_product) {
foreach($customer_cart_products as $customer_cart_product) {
if($guest_cart_product == $customer_cart_product) {
$cartItemId = $this->cartItem->findWhere(['cart_id'=> $guest_cart->id, 'product_id' => $guest_cart_product])[0]->id;
$cartItemQuantity = $this->cartItem->findWhere(['cart_id'=> $guest_cart->id, 'product_id' => $guest_cart_product])[0]->quantity;
$customerItemId = $this->cartItem->findWhere(['cart_id'=> $customer_cart->id, 'product_id' => $customer_cart_product])[0]->id;
$customerItemQuantity = $this->cartItem->findWhere(['cart_id'=> $customer_cart->id, 'product_id' => $customer_cart_product])[0]->quantity;
2018-09-14 13:15:49 +00:00
$this->cartItem->delete($cartItemId);
$this->cartItem->update(['quantity' => $cartItemQuantity + $customerItemQuantity], $customerItemId);
2018-09-14 13:15:49 +00:00
unset($guest_cart_products[$key]);
}
}
}
//insert the new products here.
foreach ($guest_cart_products as $key => $guest_cart_product) {
// dd($this->cartItem->findWhere(['cart_id'=> $guest_cart->id, 'product_id' => $guest_cart_product])[0]);
$cartItemId = $this->cartItem->findWhere(['cart_id'=> $guest_cart->id, 'product_id' => $guest_cart_product])[0]->id;
$this->cartItem->update(['cart_id' => $customer_cart->id], $cartItemId);
}
//detach with guest cart records
$this->cart->deleteParent($guest_cart->id);
Cookie::queue(Cookie::forget('cart_session_id'));
return redirect()->back();
} else {
//this will just update the customer id column in the cart table
$this->cart->update(['customer_id' => $customer_id], $guest_cart->id);
Cookie::queue(Cookie::forget('cart_session_id'));
return redirect()->back();
}
}
return redirect()->back();
2018-09-11 11:19:40 +00:00
}
}