![]() Server : Apache System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64 User : corals ( 1002) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system Directory : /home/corals/job-board.corals.io/Corals/modules/Ecommerce/Classes/ |
<?php namespace Corals\Modules\Ecommerce\Classes; use Illuminate\Auth\AuthManager; use Illuminate\Contracts\Events\Dispatcher; use Illuminate\Database\Eloquent\Model; use Illuminate\Session\SessionManager; use Corals\Modules\Ecommerce\Contracts\CouponContract; use Corals\Modules\Ecommerce\Contracts\ShoppingCartContract; use Corals\Modules\Ecommerce\Exceptions\ModelNotFound; /** * Class ShoppingCart. */ class ShoppingCart implements ShoppingCartContract { const SERVICE = 'shoppingcart'; protected $events; protected $session; protected $authManager; public $cart; public $prefix; public $itemModel; public $itemModelRelations; /** * ShoppingCart 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->guard(config('shoppingcart.guard', null)); $this->prefix = config('shoppingcart.cache_prefix', 'shoppingcart'); $this->itemModel = config('shoppingcart.item_model', null); $this->itemModelRelations = config('shoppingcart.item_model_relations', []); $this->setInstance('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 ShoppingCart */ public function setInstance($instance = 'default') { $this->get($instance); $this->session->put($this->prefix . '.instance', $instance); if (!in_array($instance, $this->getInstances())) { $this->session->push($this->prefix . '.instances', $instance); } $this->events->dispatch('shoppingcart.new'); return $this; } /** * Gets the instance in the session. * * @param string $instance * * @return $this cart instance */ public function get($instance = 'default') { if (config('shoppingcart.cross_devices', false) && $this->authManager->check()) { if (user() && !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; } /** * Clone the instance in the session. * * @param string $instance * * @return $this cart instance */ public function cloneTo($newInstance, $from = 'default') { $currentCart = $this->session->get($this->prefix . '.' . $from); $this->session->put($this->prefix . '.' . $newInstance, $currentCart); return $this; } /** * Gets the current instance namein the session. * */ public function getInstanceName() { return $this->session->get($this->prefix . '.instance'); } /** * Gets an an attribute from the cart. * * @param $attribute * @param $defaultValue * * @return mixed */ public function getAttribute($attribute, $defaultValue = null) { return \Arr::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) { \Arr::set($this->cart->attributes, $attribute, $value); $this->update(); } /** * Updates cart session. */ public function update() { $this->session->put($this->prefix . '.' . $this->cart->instance, $this->cart); if (user() && config('shoppingcart.cross_devices', false) && $this->authManager->check()) { $this->authManager->user()->cart_session_id = $this->session->getId(); $this->authManager->user()->save(); } $this->session->reflash(); $this->session->save(); $this->events->dispatch('shoppingcart.update', $this->cart); } /** * Removes an attribute from the cart. * * @param $attribute */ public function removeAttribute($attribute) { \Arr::forget($this->cart->attributes, $attribute); $this->update(); } /** * Creates a CartItem and then adds it to cart. * @param int|string $itemID * @param null $name * @param int $qty * @param string $price * @param array $options * @param bool $taxable * @return CartItem * @throws ModelNotFound */ 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('shoppingcart.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('shoppingcart.item_model_bindings'); $itemID = $itemModel[$bindings[\Corals\Modules\Ecommerce\Classes\CartItem::ITEM_ID]]; if (is_int($name)) { $qty = $name; } $name = $itemModel[$bindings[\Corals\Modules\Ecommerce\Classes\CartItem::ITEM_NAME]]; $price = $itemModel[$bindings[\Corals\Modules\Ecommerce\Classes\CartItem::ITEM_PRICE]]; //$options['model'] = $itemModel; // $options = array_merge($options, // $this->getItemModelOptions($itemModel, $bindings[\Corals\Modules\Ecommerce\Classes\CartItem::ITEM_OPTIONS])); $taxable = $itemModel[$bindings[\Corals\Modules\Ecommerce\Classes\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->dispatch('shoppingcart.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 | CartItem | null */ public function find($data) { $matches = []; foreach ($this->getItems() as $item) { if ($item->find($data)) { $matches[] = $item; } } switch (count($matches)) { case 0: return; break; case 1: return $matches[0]; break; default: return $matches; } } /** * Finds a cartItem based on the itemHash. * * @param $itemHash * * @return CartItem | null */ public function getItem($itemHash) { return \Arr::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 * * @return CartItem|null *@throws \Corals\Modules\Ecommerce\Exceptions\InvalidQuantity * * @throws \Corals\Modules\Ecommerce\Exceptions\InvalidPrice */ public function updateItem($itemHash, $key, $value) { if (empty($item = $this->getItem($itemHash)) === false) { if ($key == 'qty' && $value == 0) { return $this->removeItem($itemHash); } $item->$key = $value; } $this->update(); return $item; } /** * Removes a CartItem based on the itemHash. * * @param $itemHash */ public function removeItem($itemHash) { if (empty($this->cart->items) === false) { foreach ($this->cart->items as $itemKey => $item) { if ($item->getHash() == $itemHash) { unset($this->cart->items[$itemKey]); break; } } $this->events->dispatch('shoppingcart.removeItem', $item); $this->update(); } } /** * Empties the carts items. */ public function emptyCart() { unset($this->cart->items); $this->update(); $this->events->dispatch('shoppingcart.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->dispatch('shoppingcart.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 \Arr::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); \Arr::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 \Arr::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 $type * @param bool|false $taxable * @param array $options */ public function addFee($name, $amount, $type, $taxable = false, array $options = []) { \Arr::set($this->cart->fees, $name, new CartFee($amount, $type, $taxable, $options)); $this->update(); } /** * Removes a fee from the fee array. * * @param $name */ public function removeFee($name) { \Arr::forget($this->cart->fees, $name); $this->update(); } /** * Removes all the fees set in the cart. */ public function removeFees($type = null) { if ($type) { foreach ($this->cart->fees as $fee_name => $fee) { if ($fee->type == $type) { \Arr::forget($this->cart->fees, $fee_name); } } } else { $this->cart->fees = []; } $this->update(); } /** * Gets the total tax for the cart. * * @param bool|true $format * @param bool|true $withFees * * @return string */ public function taxTotal($format = true, $withFees = true) { $totalTax = 0; $discounted = 0; $totalDiscount = $this->totalDiscount(false, false); if ($this->count() != 0) { /** * @var * @var CartItem $item */ foreach ($this->getItems() as $index => $item) { if ($discounted >= $totalDiscount) { $totalTax += $item->tax(); } else { $itemPrice = $item->subTotal(false, config('shoppingcart.discountTaxable', false)); if (($discounted + $itemPrice) > $totalDiscount) { $totalTax += config('shoppingcart.discountTaxable', false) ? $item->tax($totalDiscount - $discounted) : $item->tax(); } $discounted += $itemPrice; } } } if ($withFees) { 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 * @param bool $withTax * @param bool $withFees * * @return string */ public function total($format = true, $withDiscount = true, $withTax = true, $withFees = true) { $total = $this->subTotal(false); if ($withFees) { $total += $this->feeTotals(false); } if ($withDiscount) { $total -= $this->totalDiscount(false, false); } if ($withTax) { $total += $this->taxTotal(false, $withFees); } 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 = false, $format = true) { /* $number = number_format($number, 2, '.', ''); if ($format) { setlocale(LC_MONETARY, null); setlocale(LC_MONETARY, empty($locale) ? config('shoppingcart.locale', 'en_US.UTF-8') : $locale); if (empty($internationalFormat) === true) { $internationalFormat = config('shoppingcart.international_format', false); } $number = currency_format($number); } */ if ($format) { $number = \Payments::currency($number); } return $number; } /** * Gets all the fee totals. * * @param bool $format * @param bool $withTax * * @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 * @param bool $withItemDiscounts * * @return string */ public function totalDiscount($format = true, $withItemDiscounts = true, $withFeesDiscounts = true) { $total = 0; if ($withItemDiscounts) { /** @var CartItem $item */ foreach ((array)$this->cart->items as $item) { $total += floatval($item->getDiscount(false)); } } 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('shoppingcart.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 = \Arr::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 = []; } } } }