application/modules/mod_discount/classes/BaseDiscount.php
<?php
namespace mod_discount\classes;
use Cart\BaseCart;
use CI;
use discount_model_front;
use MY_Controller;
use MY_Lang;
use ShopCore;
if (!defined('BASEPATH')) {
exit('No direct script access allowed');
}
/**
* Class BaseDiscount for Mod_Discount module
* @author DevImageCms
* @copyright (c) 2013, ImageCMS
* @package ImageCMSModule
* @property discount_model_front $discount_model_front
*/
class BaseDiscount
{
private static $object;
private static $totalPrice;
private static $reBuild;
private static $ignoreCart;
private static $userId;
private static $moduleInstalled;
/**
*
* @var MY_Controller
*/
public $ci;
/**
*
* @var BaseCart
*/
public $cart;
/**
*
* @var integer
*/
public $userGroupId;
/**
*
* @var array
*/
public $cartData;
/**
*
* @var double
*/
public $amoutUser;
/**
*
* @var array
*/
public $allDiscount;
/**
*
* @var array
*/
public $discountType;
/**
*
* @var array|false
*/
public $discountAllOrder;
/**
*
* @var array|false
*/
public $discountComul;
/**
*
* @var float
*/
public $discountProductVal;
/**
*
* @var array|false
*/
public $discountGroupUser;
/**
*
* @var array
*/
public $discountMax;
/**
* @var int
*/
public $user_Id;
/**
* @var float
*/
public $total_Price;
/**
* check_module_install
* @access public
* @author DevImageCms
* @return boolean
* @copyright (c) 2013, ImageCMS
*/
public static function checkModuleInstall() {
$ci = &get_instance();
if (self::$moduleInstalled == null) {
self::$moduleInstalled = count($ci->db->where('name', 'mod_discount')->get('components')->result_array()) !== 0;
}
return self::$moduleInstalled;
}
/**
* prepareOption
* @access public
* @author DevImageCms
* @param array $option params:
* - (float) price:
* - (int) userId:
* - (bool) ignoreCart: ignore cart Data:
* - (bool) reBuild: for redeclare singelton:
* @copyright (c) 2013, ImageCMS
*/
public static function prepareOption($option) {
if (isset($option['price'])) {
self::setTotalPrice($option['price']);
}
if (isset($option['userId'])) {
self::setUserId($option['userId']);
}
if (isset($option['ignoreCart'])) {
self::setIgnoreCart($option['ignoreCart']);
}
if (isset($option['reBuild'])) {
self::reBuild();
}
}
/**
* setTotalPrice
* @access private
* @author DevImageCms
* @param (float) price:
* @copyright (c) 2013, ImageCMS
*/
private static function setTotalPrice($price = null) {
self::$totalPrice = $price;
}
/**
* setTotalPrice
* @access private
* @author DevImageCms
* @param (int) userId:
* @copyright (c) 2013, ImageCMS
*/
private static function setUserId($userId = null) {
self::$userId = $userId ?: CI::$APP->dx_auth->get_user_id();
}
/**
* setIgnoreCart
* @access private
* @author DevImageCms
* @param (bool) ignoreCart
* @copyright (c) 2013, ImageCMS
*/
private static function setIgnoreCart($ignoreCart = null) {
self::$ignoreCart = $ignoreCart;
}
/**
* reBuild
* @access private
* @author DevImageCms
* @copyright (c) 2013, ImageCMS
*/
private static function reBuild() {
self::$reBuild = 1;
}
/**
* singelton method
* @return BaseDiscount
*/
public static function create() {
if (!self::$object || self::$reBuild) {
self::$object = new self;
}
return self::$object;
}
/**
* __construct base object loaded
* @access private
* @author DevImageCms
* @copyright (c) 2013, ImageCMS
*/
private function __construct() {
$this->ci = &get_instance();
if (BaseDiscount::checkModuleInstall()) {
include_once __DIR__ . '/../models/discount_model_front.php';
$this->ci->discount_model_front = new discount_model_front;
$lang = new MY_Lang();
$lang->load('mod_discount');
$this->cart = BaseCart::getInstance();
if (!self::$userId) {
$this->userGroupId = $this->ci->dx_auth->get_role_id();
$this->user_Id = $this->ci->dx_auth->get_user_id();
} else {
$this->user_Id = self::$userId;
$this->userGroupId = $this->ci->db->where('id', $this->user_Id)->get('users')->row()->role_id;
}
if (!self::$ignoreCart) {
$this->cartData = $this->getCartData();
}
$this->amoutUser = $this->ci->discount_model_front->getAmoutUser($this->user_Id);
$this->total_Price = (!self::$totalPrice) ? $this->cart->getOriginTotalPrice() : self::$totalPrice;
$this->allDiscount = $this->getAllDiscount();
$this->discountType = $this->collectType($this->allDiscount);
$this->discountAllOrder = $this->getAllOrderDiscountNotRegister();
if ($this->user_Id) {
$this->discountUser = $this->getUserDiscount();
$this->discountGroupUser = $this->getUserGroupDiscount();
$this->discountComul = $this->getComulativDiscount();
$this->discountAllOrder = $this->getAllOrderDiscountRegister();
}
$this->discountProductVal = (self::$ignoreCart) ? null : $this->getDiscountProducts();
$this->discountMax = $this->getMaxDiscount([$this->discountUser, $this->discountGroupUser, $this->discountComul, $this->discountAllOrder], $this->total_Price);
$this->discountNoProductVal = $this->getDiscountValue($this->discountMax, $this->total_Price);
}
}
/**
* get Cart items for current session
* @access private
* @author DevImageCms
* @return array
* @copyright (c) 2013, ImageCMS
*/
private function getCartData() {
$cart = $this->cart->getItems();
return $cart['data'];
}
/**
*
* @param string $type short type of discount (en)
* @return string full translated name of discount
*/
public static function getDiscountsLabels($type = NULL) {
$discounts = [
'all_order' => lang('Order amount of more than', 'mod_discount'),
'comulativ' => lang('Cumulative discount', 'mod_discount'),
'user' => lang('User', 'mod_discount'),
'group_user' => lang('Users group', 'mod_discount'),
'category' => lang('Category', 'mod_discount'),
'product' => lang('Product', 'mod_discount'),
'brand' => lang('Brand', 'mod_discount'),
];
if ($type == null) {
return $discounts;
}
if (isset($discounts[$type])) {
return $discounts[$type];
}
return false;
}
/**
* get all active discount joined whith his type
* @access private
* @author DevImageCms
* @return array
* @copyright (c) 2013, ImageCMS
*/
private function getAllDiscount() {
return $this->joinDiscountSettings($this->ci->discount_model_front->getDiscount());
}
/**
* joined discount whith his type
* @access private
* @author DevImageCms
* @param array $discount
* @return array
* @copyright (c) 2013, ImageCMS
*/
private function joinDiscountSettings($discount) {
foreach ($discount as $key => $disc) {
$discount[$key] = array_merge($discount[$key], $this->ci->discount_model_front->joinDiscount($disc['id'], $disc['type_discount']));
}
return $discount;
}
/**
* partitioning discounts on their types
* @access private
* @author DevImageCms
* @param array $discount
* @return array
* @copyright (c) 2013, ImageCMS
*/
private function collectType($discount) {
$arr = [];
foreach ($discount as $disc) {
$arr[$disc['type_discount']][] = $disc;
}
return $this->emptyToArray($arr);
}
/**
* set empty array for null element discount
* @access private
* @author DevImageCms
* @param array $discount
* @copyright (c) 2013, ImageCMS
* @return array
*/
private function emptyToArray($discount) {
$toEmpty = [
'product',
'brand',
'category',
'certificate',
'all_order',
'comulativ',
'group_user',
'user',
];
foreach ($toEmpty as $key) {
if (!isset($discount[$key])) {
$discount[$key] = [];
}
}
return $discount;
}
/**
* get max discount considering type value and price
* @access public
* @author DevImageCms
* @param array $discount
* @param float $price
* @return array
* @copyright (c) 2013, ImageCMS
*/
public function getMaxDiscount($discount, $price) {
$discount = array_filter(
$discount,
function ($el) {
return !empty($el);
}
);
$maxDiscount = 0;
$keyMax = 0;
foreach ($discount as $key => $disc) {
$discountValue = $this->getDiscountValue($disc, $price);
if ($maxDiscount <= $discountValue) {
$maxDiscount = $discountValue;
$keyMax = $key;
}
}
return $discount[$keyMax];
}
/**
* get value discount considering type value and price
* @access public
* @author DevImageCms
* @param array $discount
* @param float $price
* @return float
* @copyright (c) 2013, ImageCMS
*/
public function getDiscountValue($discount, $price) {
return ($discount['type_value'] == 1) ? $price * $discount['value'] / 100 : $discount['value'];
}
/**
* update discount apply
* @access public
* @author DevImageCms
* @param string $key
* @param string $gift optional
* @return int|null
* @copyright (c) 2013, ImageCMS
*/
public function updateDiskApply($key, $gift = null) {
return $this->ci->discount_model_front->updateApply($key, $gift);
}
public function getAppliesLeft($key) {
$result = CI::$APP->db
->select(['max_apply', 'count_apply'])
->where(['key' => $key])
->get('mod_shop_discounts')
->row_array();
if ($result['max_apply'] == null) {
return null;
}
if ($result) {
return (int) $result['max_apply'] - (int) $result['count_apply'];
}
}
/**
* get max discount for current user
* @access private
* @author DevImageCms
* @return array
* @copyright (c) 2013, ImageCMS
*/
private function getUserDiscount() {
$discountUser = [];
foreach ($this->discountType['user'] as $userDisc) {
if ($userDisc['user_id'] == $this->user_Id) {
$discountUser[] = $userDisc;
}
}
return (count($discountUser) > 0) ? $this->getMaxDiscount($discountUser, $this->total_Price) : false;
}
/**
* get max discount for current user_group
* @access private
* @author DevImageCms
* @return array
* @copyright (c) 2013, ImageCMS
*/
private function getUserGroupDiscount() {
$discountUserGr = [];
foreach ($this->discountType['group_user'] as $userGrDisc) {
if ($userGrDisc['group_id'] == $this->userGroupId) {
$discountUserGr[] = $userGrDisc;
}
}
return (count($discountUserGr) > 0) ? $this->getMaxDiscount($discountUserGr, $this->total_Price) : false;
}
/**
* get max comulativ discount for current user with current amout
* @access private
* @author DevImageCms
* @return array
* @copyright (c) 2013, ImageCMS
*/
private function getComulativDiscount() {
$discountComulativ = [];
foreach ($this->discountType['comulativ'] as $disc) {
if (($disc['begin_value'] <= (float) $this->amoutUser and $disc['end_value'] > (float) $this->amoutUser) or ( $disc['begin_value'] <= (float) $this->amoutUser and ! $disc['end_value'])) {
$discountComulativ[] = $disc;
}
}
return (count($discountComulativ) > 0) ? $this->getMaxDiscount($discountComulativ, $this->total_Price) : false;
}
/**
* get discount for product in cart with his discount
* @access private
* @author DevImageCms
* @return float
* @copyright (c) 2013, ImageCMS
*/
private function getDiscountProducts() {
$discountValue = 0;
foreach ($this->cartData as $item) {
$priceOrigin = number_format($item->originPrice, ShopCore::app()->SSettings->getPricePrecision(), '.', ''); // new Cart
if (abs($priceOrigin - $item->price) >= 1) {
$discountValue += ($priceOrigin - $item->price) * $item->quantity;
}
}
return $discountValue;
}
/**
* get max discount for all order for register and not register user
* @access private
* @author DevImageCms
* @return array
* @copyright (c) 2013, ImageCMS
*/
private function getAllOrderDiscountRegister() {
$allOrderArrReg = [];
foreach ($this->discountType['all_order'] as $disc) {
if (!$disc['is_gift']) {
if ($disc['begin_value'] <= (int) $this->total_Price) {
$allOrderArrReg[] = $disc;
}
}
}
return (count($allOrderArrReg) > 0) ? $this->getMaxDiscount($allOrderArrReg, $this->total_Price) : false;
}
/**
* get max discount for all order for not register user
* @access private
* @author DevImageCms
* @return array
* @copyright (c) 2013, ImageCMS
*/
private function getAllOrderDiscountNotRegister() {
$allOrderArrNotReg = [];
foreach ($this->discountType['all_order'] as $disc) {
if (!$disc['is_gift']) {
if ($disc['begin_value'] <= $this->total_Price and ! $disc['for_autorized']) {
$allOrderArrNotReg[] = $disc;
}
}
}
return (count($allOrderArrNotReg) > 0) ? $this->getMaxDiscount($allOrderArrNotReg, $this->total_Price) : false;
}
}