-
-
Save lukepolo/1a68a72963102e55e610cc2fe40b1c03 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
If had things with 500 lines of code in I woulnd't be proud of it because its not speific enough for the class, but you asked : | |
This is from my package : https://raw.githubusercontent.com/lukepolo/laracart/master/src/LaraCart.php V1 | |
V2 is much cleaner, and technically if you included the traits it would be still 500 lines :-) | |
https://raw.githubusercontent.com/lukepolo/laracart/2.0/src/LaraCart.php | |
<?php | |
namespace LukePOLO\LaraCart; | |
use Illuminate\Auth\AuthManager; | |
use Illuminate\Contracts\Events\Dispatcher; | |
use Illuminate\Database\Eloquent\Model; | |
use Illuminate\Session\SessionManager; | |
use LukePOLO\LaraCart\Contracts\CouponContract; | |
use LukePOLO\LaraCart\Contracts\LaraCartContract; | |
use LukePOLO\LaraCart\Exceptions\ModelNotFound; | |
/** | |
* Class LaraCart. | |
*/ | |
class LaraCart implements LaraCartContract | |
{ | |
const SERVICE = 'laracart'; | |
const HASH = 'generateCartHash'; | |
const RANHASH = 'generateRandomCartItemHash'; | |
protected $events; | |
protected $session; | |
protected $authManager; | |
public $cart; | |
public $prefix; | |
public $itemModel; | |
public $itemModelRelations; | |
/** | |
* LaraCart constructor. | |
* | |
* @param SessionManager $session | |
* @param Dispatcher $events | |
* @param AuthManager $authManager | |
*/ | |
public function __construct(SessionManager $session, Dispatcher $events, AuthManager $authManager) | |
{ | |
$this->session = $session; | |
$this->events = $events; | |
$this->authManager = $authManager; | |
$this->prefix = config('laracart.cache_prefix', 'laracart'); | |
$this->itemModel = config('laracart.item_model', null); | |
$this->itemModelRelations = config('laracart.item_model_relations', []); | |
$this->setInstance($this->session->get($this->prefix.'.instance', 'default')); | |
} | |
/** | |
* Gets all current instances inside the session. | |
* | |
* @return mixed | |
*/ | |
public function getInstances() | |
{ | |
return $this->session->get($this->prefix.'.instances', []); | |
} | |
/** | |
* Sets and Gets the instance of the cart in the session we should be using. | |
* | |
* @param string $instance | |
* | |
* @return LaraCart | |
*/ | |
public function setInstance($instance = 'default') | |
{ | |
$this->get($instance); | |
$this->session->set($this->prefix.'.instance', $instance); | |
if (!in_array($instance, $this->getInstances())) { | |
$this->session->push($this->prefix.'.instances', $instance); | |
} | |
$this->events->fire('laracart.new'); | |
return $this; | |
} | |
/** | |
* Gets the instance in the session. | |
* | |
* @param string $instance | |
* | |
* @return $this cart instance | |
*/ | |
public function get($instance = 'default') | |
{ | |
if (config('laracart.cross_devices', false) && $this->authManager->check()) { | |
if (!empty($cartSessionID = $this->authManager->user()->cart_session_id)) { | |
$this->session->setId($cartSessionID); | |
$this->session->start(); | |
} | |
} | |
if (empty($this->cart = $this->session->get($this->prefix.'.'.$instance))) { | |
$this->cart = new Cart($instance); | |
} | |
return $this; | |
} | |
/** | |
* Gets an an attribute from the cart. | |
* | |
* @param $attribute | |
* @param $defaultValue | |
* | |
* @return mixed | |
*/ | |
public function getAttribute($attribute, $defaultValue = null) | |
{ | |
return array_get($this->cart->attributes, $attribute, $defaultValue); | |
} | |
/** | |
* Gets all the carts attributes. | |
* | |
* @return mixed | |
*/ | |
public function getAttributes() | |
{ | |
return $this->cart->attributes; | |
} | |
/** | |
* Adds an Attribute to the cart. | |
* | |
* @param $attribute | |
* @param $value | |
*/ | |
public function setAttribute($attribute, $value) | |
{ | |
array_set($this->cart->attributes, $attribute, $value); | |
$this->update(); | |
} | |
/** | |
* Updates cart session. | |
*/ | |
public function update() | |
{ | |
$this->session->set($this->prefix.'.'.$this->cart->instance, $this->cart); | |
if (config('laracart.cross_devices', false) && $this->authManager->check()) { | |
$this->authManager->user()->cart_session_id = $this->session->getId(); | |
$this->authManager->user()->save(); | |
} | |
$this->session->save(); | |
$this->events->fire('laracart.update', $this->cart); | |
} | |
/** | |
* Removes an attribute from the cart. | |
* | |
* @param $attribute | |
*/ | |
public function removeAttribute($attribute) | |
{ | |
array_forget($this->cart->attributes, $attribute); | |
$this->update(); | |
} | |
/** | |
* Creates a CartItem and then adds it to cart. | |
* | |
* @param string|int $itemID | |
* @param null $name | |
* @param int $qty | |
* @param string $price | |
* @param array $options | |
* @param bool|true $taxable | |
* | |
* @return CartItem | |
*/ | |
public function addLine($itemID, $name = null, $qty = 1, $price = '0.00', $options = [], $taxable = true) | |
{ | |
return $this->add($itemID, $name, $qty, $price, $options, $taxable, true); | |
} | |
/** | |
* Creates a CartItem and then adds it to cart. | |
* | |
* @param $itemID | |
* @param null $name | |
* @param int $qty | |
* @param string $price | |
* @param array $options | |
* @param bool|false $taxable | |
* @param bool|false $lineItem | |
* | |
* @throws ModelNotFound | |
* | |
* @return CartItem | |
*/ | |
public function add( | |
$itemID, | |
$name = null, | |
$qty = 1, | |
$price = '0.00', | |
$options = [], | |
$taxable = true, | |
$lineItem = false | |
) { | |
if (!empty(config('laracart.item_model'))) { | |
$itemModel = $itemID; | |
if (!$this->isItemModel($itemModel)) { | |
$itemModel = (new $this->itemModel())->with($this->itemModelRelations)->find($itemID); | |
} | |
if (empty($itemModel)) { | |
throw new ModelNotFound('Could not find the item '.$itemID); | |
} | |
$bindings = config('laracart.item_model_bindings'); | |
$itemID = $itemModel[$bindings[\LukePOLO\LaraCart\CartItem::ITEM_ID]]; | |
$name = $itemModel[$bindings[\LukePOLO\LaraCart\CartItem::ITEM_NAME]]; | |
if (empty($qty = $name) || !is_int($name)) { | |
$qty = 1; | |
} | |
$price = $itemModel[$bindings[\LukePOLO\LaraCart\CartItem::ITEM_PRICE]]; | |
$options = array_merge($options, | |
$this->getItemModelOptions($itemModel, $bindings[\LukePOLO\LaraCart\CartItem::ITEM_OPTIONS])); | |
$taxable = $itemModel[$bindings[\LukePOLO\LaraCart\CartItem::ITEM_TAXABLE]] ? true : false; | |
} | |
$item = $this->addItem(new CartItem( | |
$itemID, | |
$name, | |
$qty, | |
$price, | |
$options, | |
$taxable, | |
$lineItem | |
)); | |
$this->update(); | |
return $this->getItem($item->getHash()); | |
} | |
/** | |
* Adds the cartItem into the cart session. | |
* | |
* @param CartItem $cartItem | |
* | |
* @return CartItem | |
*/ | |
public function addItem(CartItem $cartItem) | |
{ | |
$itemHash = $cartItem->generateHash(); | |
if ($this->getItem($itemHash)) { | |
$this->getItem($itemHash)->qty += $cartItem->qty; | |
} else { | |
$this->cart->items[] = $cartItem; | |
} | |
$this->events->fire('laracart.addItem', $cartItem); | |
return $cartItem; | |
} | |
/** | |
* Increment the quantity of a cartItem based on the itemHash. | |
* | |
* @param $itemHash | |
* | |
* @return CartItem | null | |
*/ | |
public function increment($itemHash) | |
{ | |
$item = $this->getItem($itemHash); | |
$item->qty++; | |
$this->update(); | |
return $item; | |
} | |
/** | |
* Decrement the quantity of a cartItem based on the itemHash. | |
* | |
* @param $itemHash | |
* | |
* @return CartItem | null | |
*/ | |
public function decrement($itemHash) | |
{ | |
$item = $this->getItem($itemHash); | |
if ($item->qty > 1) { | |
$item->qty--; | |
$this->update(); | |
return $item; | |
} | |
$this->removeItem($itemHash); | |
$this->update(); | |
} | |
/** | |
* Find items in the cart matching a data set. | |
* | |
* | |
* param $data | |
* | |
* @return array | |
*/ | |
public function find($data) | |
{ | |
$matches = []; | |
foreach ($this->getItems() as $item) { | |
if ($item->find($data)) { | |
$matches[] = $item; | |
} | |
} | |
return $matches; | |
} | |
/** | |
* Finds a cartItem based on the itemHash. | |
* | |
* @param $itemHash | |
* | |
* @return CartItem | null | |
*/ | |
public function getItem($itemHash) | |
{ | |
return array_get($this->getItems(), $itemHash); | |
} | |
/** | |
* Gets all the items within the cart. | |
* | |
* @return array | |
*/ | |
public function getItems() | |
{ | |
$items = []; | |
if (isset($this->cart->items) === true) { | |
foreach ($this->cart->items as $item) { | |
$items[$item->getHash()] = $item; | |
} | |
} | |
return $items; | |
} | |
/** | |
* Updates an items attributes. | |
* | |
* @param $itemHash | |
* @param $key | |
* @param $value | |
* | |
* @throws Exceptions\InvalidPrice | |
* @throws Exceptions\InvalidQuantity | |
* | |
* @return CartItem | |
*/ | |
public function updateItem($itemHash, $key, $value) | |
{ | |
if (empty($item = $this->getItem($itemHash)) === false) { | |
$item->$key = $value; | |
} | |
$item->generateHash(); | |
$this->update(); | |
return $item; | |
} | |
/** | |
* Removes a CartItem based on the itemHash. | |
* | |
* @param $itemHash | |
*/ | |
public function removeItem($itemHash) | |
{ | |
foreach ($this->cart->items as $itemKey => $item) { | |
if ($item->getHash() == $itemHash) { | |
unset($this->cart->items[$itemKey]); | |
break; | |
} | |
} | |
$this->events->fire('laracart.removeItem', $item); | |
$this->update(); | |
} | |
/** | |
* Empties the carts items. | |
*/ | |
public function emptyCart() | |
{ | |
unset($this->cart->items); | |
$this->update(); | |
$this->events->fire('laracart.empty', $this->cart->instance); | |
} | |
/** | |
* Completely destroys cart and anything associated with it. | |
*/ | |
public function destroyCart() | |
{ | |
$instance = $this->cart->instance; | |
$this->session->forget($this->prefix.'.'.$instance); | |
$this->events->fire('laracart.destroy', $instance); | |
$this->cart = new Cart($instance); | |
$this->update(); | |
} | |
/** | |
* Gets the coupons for the current cart. | |
* | |
* @return array | |
*/ | |
public function getCoupons() | |
{ | |
return $this->cart->coupons; | |
} | |
/** | |
* Finds a specific coupon in the cart. | |
* | |
* @param $code | |
* | |
* @return mixed | |
*/ | |
public function findCoupon($code) | |
{ | |
return array_get($this->cart->coupons, $code); | |
} | |
/** | |
* Applies a coupon to the cart. | |
* | |
* @param CouponContract $coupon | |
*/ | |
public function addCoupon(CouponContract $coupon) | |
{ | |
if (!$this->cart->multipleCoupons) { | |
$this->cart->coupons = []; | |
} | |
$this->cart->coupons[$coupon->code] = $coupon; | |
$this->update(); | |
} | |
/** | |
* Removes a coupon in the cart. | |
* | |
* @param $code | |
*/ | |
public function removeCoupon($code) | |
{ | |
$this->removeCouponFromItems($code); | |
array_forget($this->cart->coupons, $code); | |
$this->update(); | |
} | |
/** | |
* Removes all coupons from the cart. | |
*/ | |
public function removeCoupons() | |
{ | |
$this->removeCouponFromItems(); | |
$this->cart->coupons = []; | |
$this->update(); | |
} | |
/** | |
* Gets a specific fee from the fees array. | |
* | |
* @param $name | |
* | |
* @return mixed | |
*/ | |
public function getFee($name) | |
{ | |
return array_get($this->cart->fees, $name, new CartFee(null, false)); | |
} | |
/** | |
* Allows to charge for additional fees that may or may not be taxable | |
* ex - service fee , delivery fee, tips. | |
* | |
* @param $name | |
* @param $amount | |
* @param bool|false $taxable | |
* @param array $options | |
*/ | |
public function addFee($name, $amount, $taxable = false, array $options = []) | |
{ | |
array_set($this->cart->fees, $name, new CartFee($amount, $taxable, $options)); | |
$this->update(); | |
} | |
/** | |
* Removes a fee from the fee array. | |
* | |
* @param $name | |
*/ | |
public function removeFee($name) | |
{ | |
array_forget($this->cart->fees, $name); | |
$this->update(); | |
} | |
/** | |
* Removes all the fees set in the cart. | |
*/ | |
public function removeFees() | |
{ | |
$this->cart->fees = []; | |
$this->update(); | |
} | |
/** | |
* Gets the total tax for the cart. | |
* | |
* @param bool|true $format | |
* | |
* @return string | |
*/ | |
public function taxTotal($format = true) | |
{ | |
$totalTax = 0; | |
$discounted = 0; | |
$totalDiscount = $this->totalDiscount(false); | |
if ($this->count() != 0) { | |
foreach ($this->getItems() as $item) { | |
if ($discounted >= $totalDiscount) { | |
$totalTax += $item->tax(); | |
} else { | |
$itemPrice = $item->subTotal(false); | |
if (($discounted + $itemPrice) > $totalDiscount) { | |
$totalTax += $item->tax($totalDiscount - $discounted); | |
} | |
$discounted += $itemPrice; | |
} | |
} | |
} | |
foreach ($this->getFees() as $fee) { | |
if ($fee->taxable) { | |
$totalTax += $fee->amount * $fee->tax; | |
} | |
} | |
return $this->formatMoney($totalTax, null, null, $format); | |
} | |
/** | |
* Gets the total of the cart with or without tax. | |
* | |
* @param bool $format | |
* @param bool $withDiscount | |
* | |
* @return string | |
*/ | |
public function total($format = true, $withDiscount = true, $withTax = true) | |
{ | |
$total = $this->subTotal(false) + $this->feeTotals(false); | |
if ($withDiscount) { | |
$total -= $this->totalDiscount(false); | |
} | |
if ($withTax) { | |
$total += $this->taxTotal(false); | |
} | |
return $this->formatMoney($total, null, null, $format); | |
} | |
/** | |
* Gets the subtotal of the cart with or without tax. | |
* | |
* @param bool $format | |
* @param bool $withDiscount | |
* | |
* @return string | |
*/ | |
public function subTotal($format = true, $withDiscount = true) | |
{ | |
$total = 0; | |
if ($this->count() != 0) { | |
foreach ($this->getItems() as $item) { | |
$total += $item->subTotal(false, $withDiscount); | |
} | |
} | |
return $this->formatMoney($total, null, null, $format); | |
} | |
/** | |
* Get the count based on qty, or number of unique items. | |
* | |
* @param bool $withItemQty | |
* | |
* @return int | |
*/ | |
public function count($withItemQty = true) | |
{ | |
$count = 0; | |
foreach ($this->getItems() as $item) { | |
if ($withItemQty) { | |
$count += $item->qty; | |
} else { | |
$count++; | |
} | |
} | |
return $count; | |
} | |
/** | |
* Formats the number into a money format based on the locale and international formats. | |
* | |
* @param $number | |
* @param $locale | |
* @param $internationalFormat | |
* @param $format | |
* | |
* @return string | |
*/ | |
public static function formatMoney($number, $locale = null, $internationalFormat = null, $format = true) | |
{ | |
$number = number_format($number, 2, '.', ''); | |
if ($format) { | |
setlocale(LC_MONETARY, null); | |
setlocale(LC_MONETARY, empty($locale) ? config('laracart.locale', 'en_US.UTF-8') : $locale); | |
if (empty($internationalFormat) === true) { | |
$internationalFormat = config('laracart.international_format', false); | |
} | |
$number = money_format($internationalFormat ? '%i' : '%n', $number); | |
} | |
return $number; | |
} | |
/** | |
* Gets all the fee totals. | |
* | |
* @param bool $format | |
* | |
* @return string | |
*/ | |
public function feeTotals($format = true, $withTax = false) | |
{ | |
$feeTotal = 0; | |
foreach ($this->getFees() as $fee) { | |
$feeTotal += $fee->amount; | |
if ($withTax && $fee->taxable && $fee->tax > 0) { | |
$feeTotal += $fee->amount * $fee->tax; | |
} | |
} | |
return $this->formatMoney($feeTotal, null, null, $format); | |
} | |
/** | |
* Gets all the fees on the cart object. | |
* | |
* @return mixed | |
*/ | |
public function getFees() | |
{ | |
return $this->cart->fees; | |
} | |
/** | |
* Gets the total amount discounted. | |
* | |
* @param bool $format | |
* | |
* @return string | |
*/ | |
public function totalDiscount($format = true) | |
{ | |
$total = 0; | |
foreach ($this->cart->coupons as $coupon) { | |
if ($coupon->appliedToCart) { | |
$total += $coupon->discount(); | |
} | |
} | |
return $this->formatMoney($total, null, null, $format); | |
} | |
/** | |
* Checks to see if its an item model. | |
* | |
* @param $itemModel | |
* | |
* @return bool | |
*/ | |
private function isItemModel($itemModel) | |
{ | |
if (is_object($itemModel) && get_class($itemModel) == config('laracart.item_model')) { | |
return true; | |
} | |
return false; | |
} | |
/** | |
* Gets the item models options based the config. | |
* | |
* @param Model $itemModel | |
* @param array $options | |
* | |
* @return array | |
*/ | |
private function getItemModelOptions(Model $itemModel, $options = []) | |
{ | |
$itemOptions = []; | |
foreach ($options as $option) { | |
$itemOptions[$option] = $this->getFromModel($itemModel, $option); | |
} | |
return array_filter($itemOptions, function ($value) { | |
if ($value !== false && empty($value)) { | |
return false; | |
} | |
return true; | |
}); | |
} | |
/** | |
* Gets a option from the model. | |
* | |
* @param Model $itemModel | |
* @param $attr | |
* @param null $defaultValue | |
* | |
* @return Model|null | |
*/ | |
private function getFromModel(Model $itemModel, $attr, $defaultValue = null) | |
{ | |
$variable = $itemModel; | |
if (!empty($attr)) { | |
foreach (explode('.', $attr) as $attr) { | |
$variable = array_get($variable, $attr, $defaultValue); | |
} | |
} | |
return $variable; | |
} | |
/** | |
* Removes a coupon from the item. | |
* | |
* @param null $code | |
*/ | |
private function removeCouponFromItems($code = null) | |
{ | |
foreach ($this->getItems() as $item) { | |
if (isset($item->code) && (empty($code) || $item->code == $code)) { | |
$item->code = null; | |
$item->discount = null; | |
$item->couponInfo = []; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment