2015-07-06 16:58:50 +02:00
< ? php
/*
* 2007 - 2015 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License ( OSL 3.0 )
* that is bundled with this package in the file LICENSE . txt .
* It is also available through the world - wide - web at this URL :
* http :// opensource . org / licenses / osl - 3.0 . php
* If you did not receive a copy of the license and are unable to
* obtain it through the world - wide - web , please send an email
* to license @ prestashop . com so we can send you a copy immediately .
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future . If you wish to customize PrestaShop for your
* needs please refer to http :// www . prestashop . com for more information .
*
* @ author PrestaShop SA < contact @ prestashop . com >
* @ copyright 2007 - 2015 PrestaShop SA
* @ license http :// opensource . org / licenses / osl - 3.0 . php Open Software License ( OSL 3.0 )
* International Registered Trademark & Property of PrestaShop SA
*/
class CartRuleCore extends ObjectModel
{
2015-09-22 18:22:11 +02:00
/* Filters used when retrieving the cart rules applied to a cart of when calculating the value of a reduction */
const FILTER_ACTION_ALL = 1 ;
const FILTER_ACTION_SHIPPING = 2 ;
const FILTER_ACTION_REDUCTION = 3 ;
const FILTER_ACTION_GIFT = 4 ;
const FILTER_ACTION_ALL_NOCAP = 5 ;
const BO_ORDER_CODE_PREFIX = 'BO_ORDER_' ;
/* This variable controls that a free gift is offered only once, even when multi-shippping is activated and the same product is delivered in both addresses */
protected static $only_one_gift = array ();
public $id ;
public $name ;
public $id_customer ;
public $date_from ;
public $date_to ;
public $description ;
public $quantity = 1 ;
public $quantity_per_user = 1 ;
public $priority = 1 ;
public $partial_use = 1 ;
public $code ;
public $minimum_amount ;
public $minimum_amount_tax ;
public $minimum_amount_currency ;
public $minimum_amount_shipping ;
public $country_restriction ;
public $carrier_restriction ;
public $group_restriction ;
public $cart_rule_restriction ;
public $product_restriction ;
public $shop_restriction ;
public $free_shipping ;
public $reduction_percent ;
public $reduction_amount ;
public $reduction_tax ;
public $reduction_currency ;
public $reduction_product ;
public $gift_product ;
public $gift_product_attribute ;
public $highlight ;
public $active = 1 ;
public $date_add ;
public $date_upd ;
/**
* @ see ObjectModel :: $definition
*/
public static $definition = array (
'table' => 'cart_rule' ,
'primary' => 'id_cart_rule' ,
'multilang' => true ,
'fields' => array (
'id_customer' => array ( 'type' => self :: TYPE_INT , 'validate' => 'isUnsignedId' ),
'date_from' => array ( 'type' => self :: TYPE_DATE , 'validate' => 'isDate' , 'required' => true ),
'date_to' => array ( 'type' => self :: TYPE_DATE , 'validate' => 'isDate' , 'required' => true ),
'description' => array ( 'type' => self :: TYPE_STRING , 'validate' => 'isCleanHtml' , 'size' => 65534 ),
'quantity' => array ( 'type' => self :: TYPE_INT , 'validate' => 'isUnsignedInt' ),
'quantity_per_user' => array ( 'type' => self :: TYPE_INT , 'validate' => 'isUnsignedInt' ),
'priority' => array ( 'type' => self :: TYPE_INT , 'validate' => 'isUnsignedInt' ),
'partial_use' => array ( 'type' => self :: TYPE_BOOL , 'validate' => 'isBool' ),
'code' => array ( 'type' => self :: TYPE_STRING , 'validate' => 'isCleanHtml' , 'size' => 254 ),
'minimum_amount' => array ( 'type' => self :: TYPE_FLOAT , 'validate' => 'isFloat' ),
'minimum_amount_tax' => array ( 'type' => self :: TYPE_BOOL , 'validate' => 'isBool' ),
'minimum_amount_currency' => array ( 'type' => self :: TYPE_INT , 'validate' => 'isInt' ),
'minimum_amount_shipping' => array ( 'type' => self :: TYPE_BOOL , 'validate' => 'isBool' ),
'country_restriction' => array ( 'type' => self :: TYPE_BOOL , 'validate' => 'isBool' ),
'carrier_restriction' => array ( 'type' => self :: TYPE_BOOL , 'validate' => 'isBool' ),
'group_restriction' => array ( 'type' => self :: TYPE_BOOL , 'validate' => 'isBool' ),
'cart_rule_restriction' => array ( 'type' => self :: TYPE_BOOL , 'validate' => 'isBool' ),
'product_restriction' => array ( 'type' => self :: TYPE_BOOL , 'validate' => 'isBool' ),
'shop_restriction' => array ( 'type' => self :: TYPE_BOOL , 'validate' => 'isBool' ),
'free_shipping' => array ( 'type' => self :: TYPE_BOOL , 'validate' => 'isBool' ),
'reduction_percent' => array ( 'type' => self :: TYPE_FLOAT , 'validate' => 'isPercentage' ),
'reduction_amount' => array ( 'type' => self :: TYPE_FLOAT , 'validate' => 'isFloat' ),
'reduction_tax' => array ( 'type' => self :: TYPE_BOOL , 'validate' => 'isBool' ),
'reduction_currency' => array ( 'type' => self :: TYPE_INT , 'validate' => 'isUnsignedId' ),
'reduction_product' => array ( 'type' => self :: TYPE_INT , 'validate' => 'isInt' ),
'gift_product' => array ( 'type' => self :: TYPE_INT , 'validate' => 'isUnsignedId' ),
'gift_product_attribute' => array ( 'type' => self :: TYPE_INT , 'validate' => 'isUnsignedId' ),
'highlight' => array ( 'type' => self :: TYPE_BOOL , 'validate' => 'isBool' ),
'active' => array ( 'type' => self :: TYPE_BOOL , 'validate' => 'isBool' ),
'date_add' => array ( 'type' => self :: TYPE_DATE , 'validate' => 'isDate' ),
'date_upd' => array ( 'type' => self :: TYPE_DATE , 'validate' => 'isDate' ),
/* Lang fields */
'name' => array ( 'type' => self :: TYPE_STRING , 'lang' => true , 'validate' => 'isCleanHtml' , 'required' => true , 'size' => 254 ),
),
);
/**
* @ see ObjectModel :: add ()
*/
public function add ( $autodate = true , $null_values = false )
{
if ( ! $this -> reduction_currency ) {
$this -> reduction_currency = ( int ) Configuration :: get ( 'PS_CURRENCY_DEFAULT' );
}
if ( ! parent :: add ( $autodate , $null_values )) {
return false ;
}
Configuration :: updateGlobalValue ( 'PS_CART_RULE_FEATURE_ACTIVE' , '1' );
return true ;
}
public function update ( $null_values = false )
{
Cache :: clean ( 'getContextualValue_' . $this -> id . '_*' );
if ( ! $this -> reduction_currency ) {
$this -> reduction_currency = ( int ) Configuration :: get ( 'PS_CURRENCY_DEFAULT' );
}
return parent :: update ( $null_values );
}
/**
* @ see ObjectModel :: delete ()
*/
public function delete ()
{
if ( ! parent :: delete ()) {
return false ;
}
Configuration :: updateGlobalValue ( 'PS_CART_RULE_FEATURE_ACTIVE' , CartRule :: isCurrentlyUsed ( $this -> def [ 'table' ], true ));
$r = Db :: getInstance () -> delete ( 'cart_cart_rule' , '`id_cart_rule` = ' . ( int ) $this -> id );
$r &= Db :: getInstance () -> delete ( 'cart_rule_carrier' , '`id_cart_rule` = ' . ( int ) $this -> id );
$r &= Db :: getInstance () -> delete ( 'cart_rule_shop' , '`id_cart_rule` = ' . ( int ) $this -> id );
$r &= Db :: getInstance () -> delete ( 'cart_rule_group' , '`id_cart_rule` = ' . ( int ) $this -> id );
$r &= Db :: getInstance () -> delete ( 'cart_rule_country' , '`id_cart_rule` = ' . ( int ) $this -> id );
$r &= Db :: getInstance () -> delete ( 'cart_rule_combination' , '`id_cart_rule_1` = ' . ( int ) $this -> id . ' OR `id_cart_rule_2` = ' . ( int ) $this -> id );
$r &= Db :: getInstance () -> delete ( 'cart_rule_product_rule_group' , '`id_cart_rule` = ' . ( int ) $this -> id );
$r &= Db :: getInstance () -> delete ( 'cart_rule_product_rule' , 'NOT EXISTS (SELECT 1 FROM `' . _DB_PREFIX_ . ' cart_rule_product_rule_group `
2015-07-06 16:58:50 +02:00
WHERE `'._DB_PREFIX_.'cart_rule_product_rule` . `id_product_rule_group` = `'._DB_PREFIX_.'cart_rule_product_rule_group` . `id_product_rule_group` ) ' );
2015-09-22 18:22:11 +02:00
$r &= Db :: getInstance () -> delete ( 'cart_rule_product_rule_value' , 'NOT EXISTS (SELECT 1 FROM `' . _DB_PREFIX_ . ' cart_rule_product_rule `
2015-07-06 16:58:50 +02:00
WHERE `'._DB_PREFIX_.'cart_rule_product_rule_value` . `id_product_rule` = `'._DB_PREFIX_.'cart_rule_product_rule` . `id_product_rule` ) ' );
2015-09-22 18:22:11 +02:00
return $r ;
}
/**
* Copy conditions from one cart rule to an other
*
* @ param int $id_cart_rule_source
* @ param int $id_cart_rule_destination
*/
public static function copyConditions ( $id_cart_rule_source , $id_cart_rule_destination )
{
Db :: getInstance () -> execute ( '
2015-07-06 16:58:50 +02:00
INSERT INTO `'._DB_PREFIX_.'cart_rule_shop` ( `id_cart_rule` , `id_shop` )
( SELECT '.(int)$id_cart_rule_destination.' , id_shop FROM `'._DB_PREFIX_.'cart_rule_shop` WHERE `id_cart_rule` = '.(int)$id_cart_rule_source.' ) ' );
2015-09-22 18:22:11 +02:00
Db :: getInstance () -> execute ( '
2015-07-06 16:58:50 +02:00
INSERT INTO `'._DB_PREFIX_.'cart_rule_carrier` ( `id_cart_rule` , `id_carrier` )
( SELECT '.(int)$id_cart_rule_destination.' , id_carrier FROM `'._DB_PREFIX_.'cart_rule_carrier` WHERE `id_cart_rule` = '.(int)$id_cart_rule_source.' ) ' );
2015-09-22 18:22:11 +02:00
Db :: getInstance () -> execute ( '
2015-07-06 16:58:50 +02:00
INSERT INTO `'._DB_PREFIX_.'cart_rule_group` ( `id_cart_rule` , `id_group` )
( SELECT '.(int)$id_cart_rule_destination.' , id_group FROM `'._DB_PREFIX_.'cart_rule_group` WHERE `id_cart_rule` = '.(int)$id_cart_rule_source.' ) ' );
2015-09-22 18:22:11 +02:00
Db :: getInstance () -> execute ( '
2015-07-06 16:58:50 +02:00
INSERT INTO `'._DB_PREFIX_.'cart_rule_country` ( `id_cart_rule` , `id_country` )
( SELECT '.(int)$id_cart_rule_destination.' , id_country FROM `'._DB_PREFIX_.'cart_rule_country` WHERE `id_cart_rule` = '.(int)$id_cart_rule_source.' ) ' );
2015-09-22 18:22:11 +02:00
Db :: getInstance () -> execute ( '
2015-07-06 16:58:50 +02:00
INSERT INTO `'._DB_PREFIX_.'cart_rule_combination` ( `id_cart_rule_1` , `id_cart_rule_2` )
( SELECT '.(int)$id_cart_rule_destination.' , IF ( id_cart_rule_1 != '.(int)$id_cart_rule_source.' , id_cart_rule_1 , id_cart_rule_2 ) FROM `'._DB_PREFIX_.'cart_rule_combination`
WHERE `id_cart_rule_1` = '.(int)$id_cart_rule_source.' OR `id_cart_rule_2` = '.(int)$id_cart_rule_source.' ) ' );
2015-09-22 18:22:11 +02:00
// Todo : should be changed soon, be must be copied too
// Db::getInstance()->execute('DELETE FROM `'._DB_PREFIX_.'cart_rule_product_rule` WHERE `id_cart_rule` = '.(int)$this->id);
// Db::getInstance()->execute('DELETE FROM `'._DB_PREFIX_.'cart_rule_product_rule_value` WHERE `id_product_rule` NOT IN (SELECT `id_product_rule` FROM `'._DB_PREFIX_.'cart_rule_product_rule`)');
2015-07-06 16:58:50 +02:00
2015-09-22 18:22:11 +02:00
// Copy products/category filters
$products_rules_group_source = Db :: getInstance () -> ExecuteS ( '
2015-07-06 16:58:50 +02:00
SELECT id_product_rule_group , quantity FROM `'._DB_PREFIX_.'cart_rule_product_rule_group`
WHERE `id_cart_rule` = '.(int)$id_cart_rule_source.' ' );
2015-09-22 18:22:11 +02:00
foreach ( $products_rules_group_source as $product_rule_group_source ) {
Db :: getInstance () -> execute ( '
2015-07-06 16:58:50 +02:00
INSERT INTO `'._DB_PREFIX_.'cart_rule_product_rule_group` ( `id_cart_rule` , `quantity` )
VALUES ( '.(int)$id_cart_rule_destination.' , '.(int)$product_rule_group_source[' quantity '].' ) ' );
2015-09-22 18:22:11 +02:00
$id_product_rule_group_destination = Db :: getInstance () -> Insert_ID ();
2015-07-06 16:58:50 +02:00
2015-09-22 18:22:11 +02:00
$products_rules_source = Db :: getInstance () -> ExecuteS ( '
2015-07-06 16:58:50 +02:00
SELECT id_product_rule , type FROM `'._DB_PREFIX_.'cart_rule_product_rule`
WHERE `id_product_rule_group` = '.(int)$product_rule_group_source[' id_product_rule_group '].' ' );
2015-09-22 18:22:11 +02:00
foreach ( $products_rules_source as $product_rule_source ) {
Db :: getInstance () -> execute ( '
2015-07-06 16:58:50 +02:00
INSERT INTO `'._DB_PREFIX_.'cart_rule_product_rule` ( `id_product_rule_group` , `type` )
VALUES ( '.(int)$id_product_rule_group_destination.' , " '.pSQL( $product_rule_source['type'] ).' " ) ' );
2015-09-22 18:22:11 +02:00
$id_product_rule_destination = Db :: getInstance () -> Insert_ID ();
2015-07-06 16:58:50 +02:00
2015-09-22 18:22:11 +02:00
$products_rules_values_source = Db :: getInstance () -> ExecuteS ( '
2015-07-06 16:58:50 +02:00
SELECT id_item FROM `'._DB_PREFIX_.'cart_rule_product_rule_value`
WHERE `id_product_rule` = '.(int)$product_rule_source[' id_product_rule '].' ' );
2015-09-22 18:22:11 +02:00
foreach ( $products_rules_values_source as $product_rule_value_source ) {
Db :: getInstance () -> execute ( '
2015-07-06 16:58:50 +02:00
INSERT INTO `'._DB_PREFIX_.'cart_rule_product_rule_value` ( `id_product_rule` , `id_item` )
VALUES ( '.(int)$id_product_rule_destination.' , '.(int)$product_rule_value_source[' id_item '].' ) ' );
2015-09-22 18:22:11 +02:00
}
}
}
}
/**
* Retrieves the id associated to the given code
*
* @ param string $code
* @ return int | bool
*/
public static function getIdByCode ( $code )
{
if ( ! Validate :: isCleanHtml ( $code )) {
return false ;
}
return Db :: getInstance ( _PS_USE_SQL_SLAVE_ ) -> getValue ( 'SELECT `id_cart_rule` FROM `' . _DB_PREFIX_ . 'cart_rule` WHERE `code` = \'' . pSQL ( $code ) . '\'' );
}
/**
* @ param $id_lang
* @ param $id_customer
* @ param bool $active
* @ param bool $includeGeneric
* @ param bool $inStock
* @ param Cart | null $cart
* @ param bool $free_shipping_only
* @ param bool $highlight_only
* @ return array
* @ throws PrestaShopDatabaseException
*/
public static function getCustomerCartRules ( $id_lang , $id_customer , $active = false , $includeGeneric = true , $inStock = false , Cart $cart = null , $free_shipping_only = false , $highlight_only = false )
{
if ( ! CartRule :: isFeatureActive ()) {
return array ();
}
$sql_part1 = '* FROM `' . _DB_PREFIX_ . ' cart_rule ` cr
2015-07-06 16:58:50 +02:00
LEFT JOIN `'._DB_PREFIX_.'cart_rule_lang` crl ON ( cr . `id_cart_rule` = crl . `id_cart_rule` AND crl . `id_lang` = '.(int)$id_lang.' ) ' ;
2015-09-22 18:22:11 +02:00
$sql_part2 = ' AND cr.date_from < "' . date ( 'Y-m-d H:i:s' ) . ' "
2015-07-06 16:58:50 +02:00
AND cr . date_to > " '.date('Y-m-d H:i:s').' "
'.($active ? ' AND cr . `active` = 1 ' : ' ').'
'.($inStock ? ' AND cr . `quantity` > 0 ' : ' ' );
2015-09-22 18:22:11 +02:00
if ( $free_shipping_only ) {
$sql_part2 .= ' AND free_shipping = 1 AND carrier_restriction = 1' ;
}
if ( $highlight_only ) {
$sql_part2 .= ' AND highlight = 1 AND code NOT LIKE "' . pSQL ( CartRule :: BO_ORDER_CODE_PREFIX ) . '%"' ;
}
$sql = '(SELECT SQL_NO_CACHE ' . $sql_part1 . ' WHERE cr.`id_customer` = ' . ( int ) $id_customer . ' ' . $sql_part2 . ')' ;
$sql .= ' UNION (SELECT ' . $sql_part1 . ' WHERE cr.`group_restriction` = 1 ' . $sql_part2 . ')' ;
if ( $includeGeneric && ( int ) $id_customer != 0 ) {
$sql .= ' UNION (SELECT ' . $sql_part1 . ' WHERE cr.`id_customer` = 0 ' . $sql_part2 . ')' ;
}
$result = Db :: getInstance ( _PS_USE_SQL_SLAVE_ ) -> executeS ( $sql , true , false );
if ( empty ( $result )) {
return array ();
}
// Remove cart rule that does not match the customer groups
$customerGroups = Customer :: getGroupsStatic ( $id_customer );
foreach ( $result as $key => $cart_rule ) {
if ( $cart_rule [ 'group_restriction' ]) {
$cartRuleGroups = Db :: getInstance () -> executeS ( 'SELECT id_group FROM ' . _DB_PREFIX_ . 'cart_rule_group WHERE id_cart_rule = ' . ( int ) $cart_rule [ 'id_cart_rule' ]);
foreach ( $cartRuleGroups as $cartRuleGroup ) {
if ( in_array ( $cartRuleGroup [ 'id_group' ], $customerGroups )) {
continue 2 ;
}
}
unset ( $result [ $key ]);
}
}
foreach ( $result as & $cart_rule ) {
if ( $cart_rule [ 'quantity_per_user' ]) {
$quantity_used = Order :: getDiscountsCustomer (( int ) $id_customer , ( int ) $cart_rule [ 'id_cart_rule' ]);
if ( isset ( $cart ) && isset ( $cart -> id )) {
$quantity_used += $cart -> getDiscountsCustomer (( int ) $cart_rule [ 'id_cart_rule' ]);
}
$cart_rule [ 'quantity_for_user' ] = $cart_rule [ 'quantity_per_user' ] - $quantity_used ;
} else {
$cart_rule [ 'quantity_for_user' ] = 0 ;
}
}
unset ( $cart_rule );
foreach ( $result as $key => $cart_rule ) {
if ( $cart_rule [ 'shop_restriction' ]) {
$cartRuleShops = Db :: getInstance () -> executeS ( 'SELECT id_shop FROM ' . _DB_PREFIX_ . 'cart_rule_shop WHERE id_cart_rule = ' . ( int ) $cart_rule [ 'id_cart_rule' ]);
foreach ( $cartRuleShops as $cartRuleShop ) {
if ( Shop :: isFeatureActive () && ( $cartRuleShop [ 'id_shop' ] == Context :: getContext () -> shop -> id )) {
continue 2 ;
}
}
unset ( $result [ $key ]);
}
}
if ( isset ( $cart ) && isset ( $cart -> id )) {
foreach ( $result as $key => $cart_rule ) {
if ( $cart_rule [ 'product_restriction' ]) {
$cr = new CartRule (( int ) $cart_rule [ 'id_cart_rule' ]);
$r = $cr -> checkProductRestrictions ( Context :: getContext (), false , false );
if ( $r !== false ) {
continue ;
}
unset ( $result [ $key ]);
}
}
}
foreach ( $result as $key => $cart_rule ) {
if ( $cart_rule [ 'country_restriction' ]) {
$countries = Db :: getInstance () -> ExecuteS ( '
2015-07-06 16:58:50 +02:00
SELECT `id_country`
FROM `'._DB_PREFIX_.'address`
WHERE `id_customer` = '.(int)$id_customer.'
AND `deleted` = 0 '
2015-09-22 18:22:11 +02:00
);
2015-07-06 16:58:50 +02:00
2015-09-22 18:22:11 +02:00
if ( is_array ( $countries ) && count ( $countries )) {
foreach ( $countries as $country ) {
$id_cart_rule = ( bool ) Db :: getInstance () -> getValue ( '
2015-07-06 16:58:50 +02:00
SELECT crc . id_cart_rule
FROM '._DB_PREFIX_.' cart_rule_country crc
WHERE crc . id_cart_rule = '.(int)$cart_rule[' id_cart_rule '].'
AND crc . id_country = '.(int)$country[' id_country ' ]);
2015-09-22 18:22:11 +02:00
if ( ! $id_cart_rule ) {
unset ( $result [ $key ]);
}
}
}
}
}
// Retrocompatibility with 1.4 discounts
foreach ( $result as & $cart_rule ) {
$cart_rule [ 'value' ] = 0 ;
$cart_rule [ 'minimal' ] = Tools :: convertPriceFull ( $cart_rule [ 'minimum_amount' ], new Currency ( $cart_rule [ 'minimum_amount_currency' ]), Context :: getContext () -> currency );
$cart_rule [ 'cumulable' ] = ! $cart_rule [ 'cart_rule_restriction' ];
$cart_rule [ 'id_discount_type' ] = false ;
if ( $cart_rule [ 'free_shipping' ]) {
$cart_rule [ 'id_discount_type' ] = Discount :: FREE_SHIPPING ;
} elseif ( $cart_rule [ 'reduction_percent' ] > 0 ) {
$cart_rule [ 'id_discount_type' ] = Discount :: PERCENT ;
$cart_rule [ 'value' ] = $cart_rule [ 'reduction_percent' ];
} elseif ( $cart_rule [ 'reduction_amount' ] > 0 ) {
$cart_rule [ 'id_discount_type' ] = Discount :: AMOUNT ;
$cart_rule [ 'value' ] = $cart_rule [ 'reduction_amount' ];
}
}
unset ( $cart_rule );
return $result ;
}
/**
* @ param $id_customer
* @ return bool
*/
public function usedByCustomer ( $id_customer )
{
return ( bool ) Db :: getInstance () -> getValue ( '
2015-07-06 16:58:50 +02:00
SELECT id_cart_rule
FROM `'._DB_PREFIX_.'order_cart_rule` ocr
LEFT JOIN `'._DB_PREFIX_.'orders` o ON ocr . `id_order` = o . `id_order`
WHERE ocr . `id_cart_rule` = '.(int)$this->id.'
AND o . `id_customer` = ' . ( int ) $id_customer );
2015-09-22 18:22:11 +02:00
}
/**
* @ param $name
* @ return bool
*/
public static function cartRuleExists ( $name )
{
if ( ! CartRule :: isFeatureActive ()) {
return false ;
}
return ( bool ) Db :: getInstance () -> getValue ( '
2015-07-06 16:58:50 +02:00
SELECT `id_cart_rule`
FROM `'._DB_PREFIX_.'cart_rule`
WHERE `code` = \ '' . pSQL ( $name ) . '\'' );
2015-09-22 18:22:11 +02:00
}
/**
* @ param $id_customer
* @ return bool
*/
public static function deleteByIdCustomer ( $id_customer )
{
$return = true ;
$cart_rules = new PrestaShopCollection ( 'CartRule' );
$cart_rules -> where ( 'id_customer' , '=' , $id_customer );
foreach ( $cart_rules as $cart_rule ) {
$return &= $cart_rule -> delete ();
}
return $return ;
}
/**
* @ return array
*/
public function getProductRuleGroups ()
{
if ( ! Validate :: isLoadedObject ( $this ) || $this -> product_restriction == 0 ) {
return array ();
}
$productRuleGroups = array ();
$result = Db :: getInstance () -> executeS ( 'SELECT * FROM ' . _DB_PREFIX_ . 'cart_rule_product_rule_group WHERE id_cart_rule = ' . ( int ) $this -> id );
foreach ( $result as $row ) {
if ( ! isset ( $productRuleGroups [ $row [ 'id_product_rule_group' ]])) {
$productRuleGroups [ $row [ 'id_product_rule_group' ]] = array ( 'id_product_rule_group' => $row [ 'id_product_rule_group' ], 'quantity' => $row [ 'quantity' ]);
}
$productRuleGroups [ $row [ 'id_product_rule_group' ]][ 'product_rules' ] = $this -> getProductRules ( $row [ 'id_product_rule_group' ]);
}
return $productRuleGroups ;
}
/**
* @ param $id_product_rule_group
* @ return array ( 'type' => ? , 'values' => ? )
*/
public function getProductRules ( $id_product_rule_group )
{
if ( ! Validate :: isLoadedObject ( $this ) || $this -> product_restriction == 0 ) {
return array ();
}
$productRules = array ();
$results = Db :: getInstance () -> executeS ( '
2015-07-06 16:58:50 +02:00
SELECT *
FROM '._DB_PREFIX_.' cart_rule_product_rule pr
LEFT JOIN '._DB_PREFIX_.' cart_rule_product_rule_value prv ON pr . id_product_rule = prv . id_product_rule
WHERE pr . id_product_rule_group = ' . ( int ) $id_product_rule_group );
2015-09-22 18:22:11 +02:00
foreach ( $results as $row ) {
if ( ! isset ( $productRules [ $row [ 'id_product_rule' ]])) {
$productRules [ $row [ 'id_product_rule' ]] = array ( 'type' => $row [ 'type' ], 'values' => array ());
}
$productRules [ $row [ 'id_product_rule' ]][ 'values' ][] = $row [ 'id_item' ];
}
return $productRules ;
}
/**
* Check if this cart rule can be applied
*
* @ param Context $context
* @ param bool $alreadyInCart Check if the voucher is already on the cart
* @ param bool $display_error Display error
* @ return bool | mixed | string
*/
public function checkValidity ( Context $context , $alreadyInCart = false , $display_error = true , $check_carrier = true )
{
if ( ! CartRule :: isFeatureActive ()) {
return false ;
}
if ( ! $this -> active ) {
return ( ! $display_error ) ? false : Tools :: displayError ( 'This voucher is disabled' );
}
if ( ! $this -> quantity ) {
return ( ! $display_error ) ? false : Tools :: displayError ( 'This voucher has already been used' );
}
if ( strtotime ( $this -> date_from ) > time ()) {
return ( ! $display_error ) ? false : Tools :: displayError ( 'This voucher is not valid yet' );
}
if ( strtotime ( $this -> date_to ) < time ()) {
return ( ! $display_error ) ? false : Tools :: displayError ( 'This voucher has expired' );
}
if ( $context -> cart -> id_customer ) {
$quantityUsed = Db :: getInstance () -> getValue ( '
2015-07-06 16:58:50 +02:00
SELECT count ( * )
FROM '._DB_PREFIX_.' orders o
LEFT JOIN '._DB_PREFIX_.' order_cart_rule od ON o . id_order = od . id_order
WHERE o . id_customer = '.$context->cart->id_customer.'
AND od . id_cart_rule = '.(int)$this->id.'
AND '.(int)Configuration::get(' PS_OS_ERROR ').' != o . current_state
' );
2015-09-22 18:22:11 +02:00
if ( $quantityUsed + 1 > $this -> quantity_per_user ) {
return ( ! $display_error ) ? false : Tools :: displayError ( 'You cannot use this voucher anymore (usage limit reached)' );
}
}
// Get an intersection of the customer groups and the cart rule groups (if the customer is not logged in, the default group is Visitors)
if ( $this -> group_restriction ) {
$id_cart_rule = ( int ) Db :: getInstance () -> getValue ( '
2015-07-06 16:58:50 +02:00
SELECT crg . id_cart_rule
FROM '._DB_PREFIX_.' cart_rule_group crg
WHERE crg . id_cart_rule = '.(int)$this->id.'
AND crg . id_group '.($context->cart->id_customer ? ' IN ( SELECT cg . id_group FROM '._DB_PREFIX_.' customer_group cg WHERE cg . id_customer = '.(int)$context->cart->id_customer.' ) ' : ' = '.(int)Configuration::get(' PS_UNIDENTIFIED_GROUP ' )));
2015-09-22 18:22:11 +02:00
if ( ! $id_cart_rule ) {
return ( ! $display_error ) ? false : Tools :: displayError ( 'You cannot use this voucher' );
}
}
// Check if the customer delivery address is usable with the cart rule
if ( $this -> country_restriction ) {
if ( ! $context -> cart -> id_address_delivery ) {
return ( ! $display_error ) ? false : Tools :: displayError ( 'You must choose a delivery address before applying this voucher to your order' );
}
$id_cart_rule = ( int ) Db :: getInstance () -> getValue ( '
2015-07-06 16:58:50 +02:00
SELECT crc . id_cart_rule
FROM '._DB_PREFIX_.' cart_rule_country crc
WHERE crc . id_cart_rule = '.(int)$this->id.'
AND crc . id_country = ( SELECT a . id_country FROM '._DB_PREFIX_.' address a WHERE a . id_address = '.(int)$context->cart->id_address_delivery.' LIMIT 1 ) ' );
2015-09-22 18:22:11 +02:00
if ( ! $id_cart_rule ) {
return ( ! $display_error ) ? false : Tools :: displayError ( 'You cannot use this voucher in your country of delivery' );
}
}
// Check if the carrier chosen by the customer is usable with the cart rule
if ( $this -> carrier_restriction && $check_carrier ) {
if ( ! $context -> cart -> id_carrier ) {
return ( ! $display_error ) ? false : Tools :: displayError ( 'You must choose a carrier before applying this voucher to your order' );
}
$id_cart_rule = ( int ) Db :: getInstance () -> getValue ( '
2015-07-06 16:58:50 +02:00
SELECT crc . id_cart_rule
FROM '._DB_PREFIX_.' cart_rule_carrier crc
INNER JOIN '._DB_PREFIX_.' carrier c ON ( c . id_reference = crc . id_carrier AND c . deleted = 0 )
WHERE crc . id_cart_rule = '.(int)$this->id.'
AND c . id_carrier = ' . ( int ) $context -> cart -> id_carrier );
2015-09-22 18:22:11 +02:00
if ( ! $id_cart_rule ) {
return ( ! $display_error ) ? false : Tools :: displayError ( 'You cannot use this voucher with this carrier' );
}
}
// Check if the cart rules appliy to the shop browsed by the customer
if ( $this -> shop_restriction && $context -> shop -> id && Shop :: isFeatureActive ()) {
$id_cart_rule = ( int ) Db :: getInstance () -> getValue ( '
2015-07-06 16:58:50 +02:00
SELECT crs . id_cart_rule
FROM '._DB_PREFIX_.' cart_rule_shop crs
WHERE crs . id_cart_rule = '.(int)$this->id.'
AND crs . id_shop = ' . ( int ) $context -> shop -> id );
2015-09-22 18:22:11 +02:00
if ( ! $id_cart_rule ) {
return ( ! $display_error ) ? false : Tools :: displayError ( 'You cannot use this voucher' );
}
}
// Check if the products chosen by the customer are usable with the cart rule
if ( $this -> product_restriction ) {
$r = $this -> checkProductRestrictions ( $context , false , $display_error , $alreadyInCart );
if ( $r !== false && $display_error ) {
return $r ;
} elseif ( ! $r && ! $display_error ) {
return false ;
}
}
// Check if the cart rule is only usable by a specific customer, and if the current customer is the right one
if ( $this -> id_customer && $context -> cart -> id_customer != $this -> id_customer ) {
if ( ! Context :: getContext () -> customer -> isLogged ()) {
return ( ! $display_error ) ? false : ( Tools :: displayError ( 'You cannot use this voucher' ) . ' - ' . Tools :: displayError ( 'Please log in first' ));
}
return ( ! $display_error ) ? false : Tools :: displayError ( 'You cannot use this voucher' );
}
if ( $this -> minimum_amount && $check_carrier ) {
// Minimum amount is converted to the contextual currency
$minimum_amount = $this -> minimum_amount ;
if ( $this -> minimum_amount_currency != Context :: getContext () -> currency -> id ) {
$minimum_amount = Tools :: convertPriceFull ( $minimum_amount , new Currency ( $this -> minimum_amount_currency ), Context :: getContext () -> currency );
}
$cartTotal = $context -> cart -> getOrderTotal ( $this -> minimum_amount_tax , Cart :: ONLY_PRODUCTS );
if ( $this -> minimum_amount_shipping ) {
$cartTotal += $context -> cart -> getOrderTotal ( $this -> minimum_amount_tax , Cart :: ONLY_SHIPPING );
}
$products = $context -> cart -> getProducts ();
$cart_rules = $context -> cart -> getCartRules ();
foreach ( $cart_rules as & $cart_rule ) {
if ( $cart_rule [ 'gift_product' ]) {
foreach ( $products as $key => & $product ) {
if ( empty ( $product [ 'gift' ]) && $product [ 'id_product' ] == $cart_rule [ 'gift_product' ] && $product [ 'id_product_attribute' ] == $cart_rule [ 'gift_product_attribute' ]) {
$cartTotal = Tools :: ps_round ( $cartTotal - $product [ $this -> minimum_amount_tax ? 'price_wt' : 'price' ], ( int ) $context -> currency -> decimals * _PS_PRICE_COMPUTE_PRECISION_ );
}
}
}
}
if ( $cartTotal < $minimum_amount ) {
return ( ! $display_error ) ? false : Tools :: displayError ( 'You have not reached the minimum amount required to use this voucher' );
}
}
/* This loop checks :
- if the voucher is already in the cart
- if a non compatible voucher is in the cart
- if there are products in the cart ( gifts excluded )
Important note : this MUST be the last check , because if the tested cart rule has priority over a non combinable one in the cart , we will switch them
*/
$nb_products = Cart :: getNbProducts ( $context -> cart -> id );
$otherCartRules = array ();
if ( $check_carrier ) {
$otherCartRules = $context -> cart -> getCartRules ();
}
if ( count ( $otherCartRules )) {
foreach ( $otherCartRules as $otherCartRule ) {
if ( $otherCartRule [ 'id_cart_rule' ] == $this -> id && ! $alreadyInCart ) {
return ( ! $display_error ) ? false : Tools :: displayError ( 'This voucher is already in your cart' );
}
if ( $otherCartRule [ 'gift_product' ]) {
-- $nb_products ;
}
if ( $this -> cart_rule_restriction && $otherCartRule [ 'cart_rule_restriction' ] && $otherCartRule [ 'id_cart_rule' ] != $this -> id ) {
$combinable = Db :: getInstance () -> getValue ( '
2015-07-06 16:58:50 +02:00
SELECT id_cart_rule_1
FROM '._DB_PREFIX_.' cart_rule_combination
WHERE ( id_cart_rule_1 = '.(int)$this->id.' AND id_cart_rule_2 = '.(int)$otherCartRule[' id_cart_rule '].' )
OR ( id_cart_rule_2 = '.(int)$this->id.' AND id_cart_rule_1 = '.(int)$otherCartRule[' id_cart_rule '].' ) ' );
2015-09-22 18:22:11 +02:00
if ( ! $combinable ) {
$cart_rule = new CartRule (( int ) $otherCartRule [ 'id_cart_rule' ], $context -> cart -> id_lang );
// The cart rules are not combinable and the cart rule currently in the cart has priority over the one tested
if ( $cart_rule -> priority <= $this -> priority ) {
return ( ! $display_error ) ? false : Tools :: displayError ( 'This voucher is not combinable with an other voucher already in your cart:' ) . ' ' . $cart_rule -> name ;
}
// But if the cart rule that is tested has priority over the one in the cart, we remove the one in the cart and keep this new one
else {
$context -> cart -> removeCartRule ( $cart_rule -> id );
}
}
}
}
}
if ( ! $nb_products ) {
return ( ! $display_error ) ? false : Tools :: displayError ( 'Cart is empty' );
}
if ( ! $display_error ) {
return true ;
}
}
protected function checkProductRestrictions ( Context $context , $return_products = false , $display_error = true , $already_in_cart = false )
{
$selected_products = array ();
// Check if the products chosen by the customer are usable with the cart rule
if ( $this -> product_restriction ) {
$product_rule_groups = $this -> getProductRuleGroups ();
foreach ( $product_rule_groups as $id_product_rule_group => $product_rule_group ) {
$eligible_products_list = array ();
if ( isset ( $context -> cart ) && is_object ( $context -> cart ) && is_array ( $products = $context -> cart -> getProducts ())) {
foreach ( $products as $product ) {
$eligible_products_list [] = ( int ) $product [ 'id_product' ] . '-' . ( int ) $product [ 'id_product_attribute' ];
}
}
if ( ! count ( $eligible_products_list )) {
return ( ! $display_error ) ? false : Tools :: displayError ( 'You cannot use this voucher in an empty cart' );
}
$product_rules = $this -> getProductRules ( $id_product_rule_group );
foreach ( $product_rules as $product_rule ) {
switch ( $product_rule [ 'type' ]) {
case 'attributes' :
$cart_attributes = Db :: getInstance () -> executeS ( '
2015-07-06 16:58:50 +02:00
SELECT cp . quantity , cp . `id_product` , pac . `id_attribute` , cp . `id_product_attribute`
FROM `'._DB_PREFIX_.'cart_product` cp
LEFT JOIN `'._DB_PREFIX_.'product_attribute_combination` pac ON cp . id_product_attribute = pac . id_product_attribute
WHERE cp . `id_cart` = '.(int)$context->cart->id.'
AND cp . `id_product` IN ( '.implode(' , ', array_map(' intval ', $eligible_products_list)).' )
AND cp . id_product_attribute > 0 ' );
2015-09-22 18:22:11 +02:00
$count_matching_products = 0 ;
$matching_products_list = array ();
foreach ( $cart_attributes as $cart_attribute ) {
if ( in_array ( $cart_attribute [ 'id_attribute' ], $product_rule [ 'values' ])) {
$count_matching_products += $cart_attribute [ 'quantity' ];
if ( $already_in_cart && $this -> gift_product == $cart_attribute [ 'id_product' ]
&& $this -> gift_product_attribute == $cart_attribute [ 'id_product_attribute' ]) {
-- $count_matching_products ;
}
$matching_products_list [] = $cart_attribute [ 'id_product' ] . '-' . $cart_attribute [ 'id_product_attribute' ];
}
}
if ( $count_matching_products < $product_rule_group [ 'quantity' ]) {
return ( ! $display_error ) ? false : Tools :: displayError ( 'You cannot use this voucher with these products' );
}
$eligible_products_list = CartRule :: array_uintersect ( $eligible_products_list , $matching_products_list );
break ;
case 'products' :
$cart_products = Db :: getInstance () -> executeS ( '
2015-07-06 16:58:50 +02:00
SELECT cp . quantity , cp . `id_product`
FROM `'._DB_PREFIX_.'cart_product` cp
WHERE cp . `id_cart` = '.(int)$context->cart->id.'
AND cp . `id_product` IN ( '.implode(' , ', array_map(' intval ', $eligible_products_list)).' ) ' );
2015-09-22 18:22:11 +02:00
$count_matching_products = 0 ;
$matching_products_list = array ();
foreach ( $cart_products as $cart_product ) {
if ( in_array ( $cart_product [ 'id_product' ], $product_rule [ 'values' ])) {
$count_matching_products += $cart_product [ 'quantity' ];
if ( $already_in_cart && $this -> gift_product == $cart_product [ 'id_product' ]) {
-- $count_matching_products ;
}
$matching_products_list [] = $cart_product [ 'id_product' ] . '-0' ;
}
}
if ( $count_matching_products < $product_rule_group [ 'quantity' ]) {
return ( ! $display_error ) ? false : Tools :: displayError ( 'You cannot use this voucher with these products' );
}
$eligible_products_list = CartRule :: array_uintersect ( $eligible_products_list , $matching_products_list );
break ;
case 'categories' :
$cart_categories = Db :: getInstance () -> executeS ( '
2015-07-06 16:58:50 +02:00
SELECT cp . quantity , cp . `id_product` , cp . `id_product_attribute` , catp . `id_category`
FROM `'._DB_PREFIX_.'cart_product` cp
LEFT JOIN `'._DB_PREFIX_.'category_product` catp ON cp . id_product = catp . id_product
WHERE cp . `id_cart` = '.(int)$context->cart->id.'
AND cp . `id_product` IN ( '.implode(' , ', array_map(' intval ', $eligible_products_list)).' )
AND cp . `id_product` <> ' . ( int ) $this -> gift_product );
2015-09-22 18:22:11 +02:00
$count_matching_products = 0 ;
$matching_products_list = array ();
foreach ( $cart_categories as $cart_category ) {
if ( in_array ( $cart_category [ 'id_category' ], $product_rule [ 'values' ])
/**
* We also check that the product is not already in the matching product list ,
* because there are doubles in the query results ( when the product is in multiple categories )
*/
&& ! in_array ( $cart_category [ 'id_product' ] . '-' . $cart_category [ 'id_product_attribute' ], $matching_products_list )) {
$count_matching_products += $cart_category [ 'quantity' ];
$matching_products_list [] = $cart_category [ 'id_product' ] . '-' . $cart_category [ 'id_product_attribute' ];
}
}
if ( $count_matching_products < $product_rule_group [ 'quantity' ]) {
return ( ! $display_error ) ? false : Tools :: displayError ( 'You cannot use this voucher with these products' );
}
// Attribute id is not important for this filter in the global list, so the ids are replaced by 0
foreach ( $matching_products_list as & $matching_product ) {
$matching_product = preg_replace ( '/^([0-9]+)-[0-9]+$/' , '$1-0' , $matching_product );
}
$eligible_products_list = CartRule :: array_uintersect ( $eligible_products_list , $matching_products_list );
break ;
case 'manufacturers' :
$cart_manufacturers = Db :: getInstance () -> executeS ( '
2015-07-06 16:58:50 +02:00
SELECT cp . quantity , cp . `id_product` , p . `id_manufacturer`
FROM `'._DB_PREFIX_.'cart_product` cp
LEFT JOIN `'._DB_PREFIX_.'product` p ON cp . id_product = p . id_product
WHERE cp . `id_cart` = '.(int)$context->cart->id.'
AND cp . `id_product` IN ( '.implode(' , ', array_map(' intval ', $eligible_products_list)).' ) ' );
2015-09-22 18:22:11 +02:00
$count_matching_products = 0 ;
$matching_products_list = array ();
foreach ( $cart_manufacturers as $cart_manufacturer ) {
if ( in_array ( $cart_manufacturer [ 'id_manufacturer' ], $product_rule [ 'values' ])) {
$count_matching_products += $cart_manufacturer [ 'quantity' ];
$matching_products_list [] = $cart_manufacturer [ 'id_product' ] . '-0' ;
}
}
if ( $count_matching_products < $product_rule_group [ 'quantity' ]) {
return ( ! $display_error ) ? false : Tools :: displayError ( 'You cannot use this voucher with these products' );
}
$eligible_products_list = CartRule :: array_uintersect ( $eligible_products_list , $matching_products_list );
break ;
case 'suppliers' :
$cart_suppliers = Db :: getInstance () -> executeS ( '
2015-07-06 16:58:50 +02:00
SELECT cp . quantity , cp . `id_product` , p . `id_supplier`
FROM `'._DB_PREFIX_.'cart_product` cp
LEFT JOIN `'._DB_PREFIX_.'product` p ON cp . id_product = p . id_product
WHERE cp . `id_cart` = '.(int)$context->cart->id.'
AND cp . `id_product` IN ( '.implode(' , ', array_map(' intval ', $eligible_products_list)).' ) ' );
2015-09-22 18:22:11 +02:00
$count_matching_products = 0 ;
$matching_products_list = array ();
foreach ( $cart_suppliers as $cart_supplier ) {
if ( in_array ( $cart_supplier [ 'id_supplier' ], $product_rule [ 'values' ])) {
$count_matching_products += $cart_supplier [ 'quantity' ];
$matching_products_list [] = $cart_supplier [ 'id_product' ] . '-0' ;
}
}
if ( $count_matching_products < $product_rule_group [ 'quantity' ]) {
return ( ! $display_error ) ? false : Tools :: displayError ( 'You cannot use this voucher with these products' );
}
$eligible_products_list = CartRule :: array_uintersect ( $eligible_products_list , $matching_products_list );
break ;
}
if ( ! count ( $eligible_products_list )) {
return ( ! $display_error ) ? false : Tools :: displayError ( 'You cannot use this voucher with these products' );
}
}
$selected_products = array_merge ( $selected_products , $eligible_products_list );
}
}
if ( $return_products ) {
return $selected_products ;
}
return ( ! $display_error ) ? true : false ;
}
protected static function array_uintersect ( $array1 , $array2 )
{
$intersection = array ();
foreach ( $array1 as $value1 ) {
foreach ( $array2 as $value2 ) {
if ( CartRule :: array_uintersect_compare ( $value1 , $value2 ) == 0 ) {
$intersection [] = $value1 ;
break 1 ;
}
}
}
return $intersection ;
}
protected static function array_uintersect_compare ( $a , $b )
{
if ( $a == $b ) {
return 0 ;
}
$asplit = explode ( '-' , $a );
$bsplit = explode ( '-' , $b );
if ( $asplit [ 0 ] == $bsplit [ 0 ] && ( ! ( int ) $asplit [ 1 ] || ! ( int ) $bsplit [ 1 ])) {
return 0 ;
}
return 1 ;
}
/**
* The reduction value is POSITIVE
*
* @ param bool $use_tax
* @ param Context $context
* @ param bool $use_cache Allow using cache to avoid multiple free gift using multishipping
* @ return float | int | string
*/
public function getContextualValue ( $use_tax , Context $context = null , $filter = null , $package = null , $use_cache = true )
{
if ( ! CartRule :: isFeatureActive ()) {
return 0 ;
}
if ( ! $context ) {
$context = Context :: getContext ();
}
if ( ! $filter ) {
$filter = CartRule :: FILTER_ACTION_ALL ;
}
$all_products = $context -> cart -> getProducts ();
$package_products = ( is_null ( $package ) ? $all_products : $package [ 'products' ]);
$all_cart_rules_ids = $context -> cart -> getOrderedCartRulesIds ();
$cart_amount_ti = $context -> cart -> getOrderTotal ( true , Cart :: ONLY_PRODUCTS );
$cart_amount_te = $context -> cart -> getOrderTotal ( false , Cart :: ONLY_PRODUCTS );
$reduction_value = 0 ;
$cache_id = 'getContextualValue_' . ( int ) $this -> id . '_' . ( int ) $use_tax . '_' . ( int ) $context -> cart -> id . '_' . ( int ) $filter ;
foreach ( $package_products as $product ) {
$cache_id .= '_' . ( int ) $product [ 'id_product' ] . '_' . ( int ) $product [ 'id_product_attribute' ] . ( isset ( $product [ 'in_stock' ]) ? '_' . ( int ) $product [ 'in_stock' ] : '' );
}
if ( Cache :: isStored ( $cache_id )) {
return Cache :: retrieve ( $cache_id );
}
// Free shipping on selected carriers
if ( $this -> free_shipping && in_array ( $filter , array ( CartRule :: FILTER_ACTION_ALL , CartRule :: FILTER_ACTION_ALL_NOCAP , CartRule :: FILTER_ACTION_SHIPPING ))) {
if ( ! $this -> carrier_restriction ) {
$reduction_value += $context -> cart -> getOrderTotal ( $use_tax , Cart :: ONLY_SHIPPING , is_null ( $package ) ? null : $package [ 'products' ], is_null ( $package ) ? null : $package [ 'id_carrier' ]);
} else {
$data = Db :: getInstance () -> executeS ( '
2015-07-06 16:58:50 +02:00
SELECT crc . id_cart_rule , c . id_carrier
FROM '._DB_PREFIX_.' cart_rule_carrier crc
INNER JOIN '._DB_PREFIX_.' carrier c ON ( c . id_reference = crc . id_carrier AND c . deleted = 0 )
WHERE crc . id_cart_rule = '.(int)$this->id.'
AND c . id_carrier = ' . ( int ) $context -> cart -> id_carrier );
2015-09-22 18:22:11 +02:00
if ( $data ) {
foreach ( $data as $cart_rule ) {
$reduction_value += $context -> cart -> getCarrierCost (( int ) $cart_rule [ 'id_carrier' ], $use_tax , $context -> country );
}
}
}
}
if ( in_array ( $filter , array ( CartRule :: FILTER_ACTION_ALL , CartRule :: FILTER_ACTION_ALL_NOCAP , CartRule :: FILTER_ACTION_REDUCTION ))) {
// Discount (%) on the whole order
if ( $this -> reduction_percent && $this -> reduction_product == 0 ) {
// Do not give a reduction on free products!
$order_total = $context -> cart -> getOrderTotal ( $use_tax , Cart :: ONLY_PRODUCTS , $package_products );
foreach ( $context -> cart -> getCartRules ( CartRule :: FILTER_ACTION_GIFT ) as $cart_rule ) {
$order_total -= Tools :: ps_round ( $cart_rule [ 'obj' ] -> getContextualValue ( $use_tax , $context , CartRule :: FILTER_ACTION_GIFT , $package ), _PS_PRICE_COMPUTE_PRECISION_ );
}
$reduction_value += $order_total * $this -> reduction_percent / 100 ;
}
// Discount (%) on a specific product
if ( $this -> reduction_percent && $this -> reduction_product > 0 ) {
foreach ( $package_products as $product ) {
if ( $product [ 'id_product' ] == $this -> reduction_product ) {
$reduction_value += ( $use_tax ? $product [ 'total_wt' ] : $product [ 'total' ]) * $this -> reduction_percent / 100 ;
}
}
}
// Discount (%) on the cheapest product
if ( $this -> reduction_percent && $this -> reduction_product == - 1 ) {
$minPrice = false ;
$cheapest_product = null ;
foreach ( $all_products as $product ) {
$price = $product [ 'price' ];
if ( $use_tax ) {
// since later on we won't be able to know the product the cart rule was applied to,
// use average cart VAT for price_wt
$price *= ( 1 + $context -> cart -> getAverageProductsTaxRate ());
}
if ( $price > 0 && ( $minPrice === false || $minPrice > $price )) {
$minPrice = $price ;
$cheapest_product = $product [ 'id_product' ] . '-' . $product [ 'id_product_attribute' ];
}
}
// Check if the cheapest product is in the package
$in_package = false ;
foreach ( $package_products as $product ) {
if ( $product [ 'id_product' ] . '-' . $product [ 'id_product_attribute' ] == $cheapest_product || $product [ 'id_product' ] . '-0' == $cheapest_product ) {
$in_package = true ;
}
}
if ( $in_package ) {
$reduction_value += $minPrice * $this -> reduction_percent / 100 ;
}
}
// Discount (%) on the selection of products
if ( $this -> reduction_percent && $this -> reduction_product == - 2 ) {
$selected_products_reduction = 0 ;
$selected_products = $this -> checkProductRestrictions ( $context , true );
if ( is_array ( $selected_products )) {
foreach ( $package_products as $product ) {
if ( in_array ( $product [ 'id_product' ] . '-' . $product [ 'id_product_attribute' ], $selected_products )
|| in_array ( $product [ 'id_product' ] . '-0' , $selected_products )) {
$price = $product [ 'price' ];
if ( $use_tax ) {
$price *= ( 1 + $context -> cart -> getAverageProductsTaxRate ());
}
$selected_products_reduction += $price * $product [ 'cart_quantity' ];
}
}
}
$reduction_value += $selected_products_reduction * $this -> reduction_percent / 100 ;
}
// Discount (¤)
if (( float ) $this -> reduction_amount > 0 ) {
$prorata = 1 ;
if ( ! is_null ( $package ) && count ( $all_products )) {
$total_products = $context -> cart -> getOrderTotal ( $use_tax , Cart :: ONLY_PRODUCTS );
if ( $total_products ) {
$prorata = $context -> cart -> getOrderTotal ( $use_tax , Cart :: ONLY_PRODUCTS , $package [ 'products' ]) / $total_products ;
}
}
$reduction_amount = $this -> reduction_amount ;
// If we need to convert the voucher value to the cart currency
if ( isset ( $context -> currency ) && $this -> reduction_currency != $context -> currency -> id ) {
$voucherCurrency = new Currency ( $this -> reduction_currency );
// First we convert the voucher value to the default currency
if ( $reduction_amount == 0 || $voucherCurrency -> conversion_rate == 0 ) {
$reduction_amount = 0 ;
} else {
$reduction_amount /= $voucherCurrency -> conversion_rate ;
}
// Then we convert the voucher value in the default currency into the cart currency
$reduction_amount *= $context -> currency -> conversion_rate ;
$reduction_amount = Tools :: ps_round ( $reduction_amount , _PS_PRICE_COMPUTE_PRECISION_ );
}
// If it has the same tax application that you need, then it's the right value, whatever the product!
if ( $this -> reduction_tax == $use_tax ) {
// The reduction cannot exceed the products total, except when we do not want it to be limited (for the partial use calculation)
if ( $filter != CartRule :: FILTER_ACTION_ALL_NOCAP ) {
$cart_amount = $context -> cart -> getOrderTotal ( $use_tax , Cart :: ONLY_PRODUCTS );
$reduction_amount = min ( $reduction_amount , $cart_amount );
}
$reduction_value += $prorata * $reduction_amount ;
} else {
if ( $this -> reduction_product > 0 ) {
foreach ( $context -> cart -> getProducts () as $product ) {
if ( $product [ 'id_product' ] == $this -> reduction_product ) {
$product_price_ti = $product [ 'price_wt' ];
$product_price_te = $product [ 'price' ];
$product_vat_amount = $product_price_ti - $product_price_te ;
if ( $product_vat_amount == 0 || $product_price_te == 0 ) {
$product_vat_rate = 0 ;
} else {
$product_vat_rate = $product_vat_amount / $product_price_te ;
}
if ( $this -> reduction_tax && ! $use_tax ) {
$reduction_value += $prorata * $reduction_amount / ( 1 + $product_vat_rate );
} elseif ( ! $this -> reduction_tax && $use_tax ) {
$reduction_value += $prorata * $reduction_amount * ( 1 + $product_vat_rate );
}
}
}
}
// Discount (¤) on the whole order
elseif ( $this -> reduction_product == 0 ) {
$cart_amount_te = null ;
$cart_amount_ti = null ;
$cart_average_vat_rate = $context -> cart -> getAverageProductsTaxRate ( $cart_amount_te , $cart_amount_ti );
// The reduction cannot exceed the products total, except when we do not want it to be limited (for the partial use calculation)
if ( $filter != CartRule :: FILTER_ACTION_ALL_NOCAP ) {
$reduction_amount = min ( $reduction_amount , $this -> reduction_tax ? $cart_amount_ti : $cart_amount_te );
}
if ( $this -> reduction_tax && ! $use_tax ) {
$reduction_value += $prorata * $reduction_amount / ( 1 + $cart_average_vat_rate );
} elseif ( ! $this -> reduction_tax && $use_tax ) {
$reduction_value += $prorata * $reduction_amount * ( 1 + $cart_average_vat_rate );
}
}
/*
* Reduction on the cheapest or on the selection is not really meaningful and has been disabled in the backend
* Please keep this code , so it won ' t be considered as a bug
* elseif ( $this -> reduction_product == - 1 )
* elseif ( $this -> reduction_product == - 2 )
*/
}
// Take care of the other cart rules values if the filter allow it
if ( $filter != CartRule :: FILTER_ACTION_ALL_NOCAP ) {
// Cart values
$cart = Context :: getContext () -> cart ;
if ( ! Validate :: isLoadedObject ( $cart )) {
$cart = new Cart ();
}
$cart_average_vat_rate = $cart -> getAverageProductsTaxRate ();
$current_cart_amount = $use_tax ? $cart_amount_ti : $cart_amount_te ;
foreach ( $all_cart_rules_ids as $current_cart_rule_id ) {
if (( int ) $current_cart_rule_id [ 'id_cart_rule' ] == ( int ) $this -> id ) {
break ;
}
$previous_cart_rule = new CartRule (( int ) $current_cart_rule_id [ 'id_cart_rule' ]);
$previous_reduction_amount = $previous_cart_rule -> reduction_amount ;
if ( $previous_cart_rule -> reduction_tax && ! $use_tax ) {
$previous_reduction_amount = $prorata * $previous_reduction_amount / ( 1 + $cart_average_vat_rate );
} elseif ( ! $previous_cart_rule -> reduction_tax && $use_tax ) {
$previous_reduction_amount = $prorata * $previous_reduction_amount * ( 1 + $cart_average_vat_rate );
}
$current_cart_amount = max ( $current_cart_amount - ( float ) $previous_reduction_amount , 0 );
}
$reduction_value = min ( $reduction_value , $current_cart_amount );
}
}
}
// Free gift
if (( int ) $this -> gift_product && in_array ( $filter , array ( CartRule :: FILTER_ACTION_ALL , CartRule :: FILTER_ACTION_ALL_NOCAP , CartRule :: FILTER_ACTION_GIFT ))) {
$id_address = ( is_null ( $package ) ? 0 : $package [ 'id_address' ]);
foreach ( $package_products as $product ) {
if ( $product [ 'id_product' ] == $this -> gift_product && ( $product [ 'id_product_attribute' ] == $this -> gift_product_attribute || ! ( int ) $this -> gift_product_attribute )) {
// The free gift coupon must be applied to one product only (needed for multi-shipping which manage multiple product lists)
if ( ! isset ( CartRule :: $only_one_gift [ $this -> id . '-' . $this -> gift_product ])
|| CartRule :: $only_one_gift [ $this -> id . '-' . $this -> gift_product ] == $id_address
|| CartRule :: $only_one_gift [ $this -> id . '-' . $this -> gift_product ] == 0
|| $id_address == 0
|| ! $use_cache ) {
$reduction_value += ( $use_tax ? $product [ 'price_wt' ] : $product [ 'price' ]);
if ( $use_cache && ( ! isset ( CartRule :: $only_one_gift [ $this -> id . '-' . $this -> gift_product ]) || CartRule :: $only_one_gift [ $this -> id . '-' . $this -> gift_product ] == 0 )) {
CartRule :: $only_one_gift [ $this -> id . '-' . $this -> gift_product ] = $id_address ;
}
break ;
}
}
}
}
Cache :: store ( $cache_id , $reduction_value );
return $reduction_value ;
}
/**
* Make sure caches are empty
* Must be called before calling multiple time getContextualValue ()
*/
public static function cleanCache ()
{
self :: $only_one_gift = array ();
}
/**
* @ param int $offset
* @ param int $limit
* @ param string $search
* @ return array
*/
protected function getCartRuleCombinations ( $offset = null , $limit = null , $search = '' )
{
$array = array ();
if ( $offset !== null && $limit !== null ) {
$sql_limit = ' LIMIT ' . ( int ) $offset . ', ' . ( int )( $limit + 1 );
} else {
$sql_limit = '' ;
}
$array [ 'selected' ] = Db :: getInstance () -> executeS ( '
2015-07-06 16:58:50 +02:00
SELECT cr .* , crl .* , 1 as selected
FROM '._DB_PREFIX_.' cart_rule cr
LEFT JOIN '._DB_PREFIX_.' cart_rule_lang crl ON ( cr . id_cart_rule = crl . id_cart_rule AND crl . id_lang = '.(int)Context::getContext()->language->id.' )
WHERE cr . id_cart_rule != '.(int)$this->id.($search ? ' AND crl . name LIKE " %'.pSQL( $search ).'% " ' : ' ').'
AND (
cr . cart_rule_restriction = 0
OR EXISTS (
SELECT 1
FROM '._DB_PREFIX_.' cart_rule_combination
WHERE cr . id_cart_rule = '._DB_PREFIX_.' cart_rule_combination . id_cart_rule_1 AND '.(int)$this->id.' = id_cart_rule_2
)
OR EXISTS (
SELECT 1
FROM '._DB_PREFIX_.' cart_rule_combination
WHERE cr . id_cart_rule = '._DB_PREFIX_.' cart_rule_combination . id_cart_rule_2 AND '.(int)$this->id.' = id_cart_rule_1
)
) ORDER BY cr . id_cart_rule ' . $sql_limit );
2015-09-22 18:22:11 +02:00
$array [ 'unselected' ] = Db :: getInstance () -> executeS ( '
2015-07-06 16:58:50 +02:00
SELECT cr .* , crl .* , 1 as selected
FROM '._DB_PREFIX_.' cart_rule cr
INNER JOIN '._DB_PREFIX_.' cart_rule_lang crl ON ( cr . id_cart_rule = crl . id_cart_rule AND crl . id_lang = '.(int)Context::getContext()->language->id.' )
LEFT JOIN '._DB_PREFIX_.' cart_rule_combination crc1 ON ( cr . id_cart_rule = crc1 . id_cart_rule_1 AND crc1 . id_cart_rule_2 = '.(int)$this->id.' )
LEFT JOIN '._DB_PREFIX_.' cart_rule_combination crc2 ON ( cr . id_cart_rule = crc2 . id_cart_rule_2 AND crc2 . id_cart_rule_1 = '.(int)$this->id.' )
WHERE cr . cart_rule_restriction = 1
AND cr . id_cart_rule != '.(int)$this->id.($search ? ' AND crl . name LIKE " %'.pSQL( $search ).'% " ' : ' ').'
AND crc1 . id_cart_rule_1 IS NULL
AND crc2 . id_cart_rule_1 IS NULL ORDER BY cr . id_cart_rule ' . $sql_limit );
2015-09-22 18:22:11 +02:00
return $array ;
}
/**
* @ param string $type
* @ param bool $active_only
* @ param bool $i18n
* @ param int $offset
* @ param int $limit
* @ param string $search_cart_rule_name
* @ return array | bool
* @ throws PrestaShopDatabaseException
*/
public function getAssociatedRestrictions ( $type , $active_only , $i18n , $offset = null , $limit = null , $search_cart_rule_name = '' )
{
$array = array ( 'selected' => array (), 'unselected' => array ());
if ( ! in_array ( $type , array ( 'country' , 'carrier' , 'group' , 'cart_rule' , 'shop' ))) {
return false ;
}
$shop_list = '' ;
if ( $type == 'shop' ) {
$shops = Context :: getContext () -> employee -> getAssociatedShops ();
if ( count ( $shops )) {
$shop_list = ' AND t.id_shop IN (' . implode ( array_map ( 'intval' , $shops ), ',' ) . ') ' ;
}
}
if ( $offset !== null && $limit !== null ) {
$sql_limit = ' LIMIT ' . ( int ) $offset . ', ' . ( int )( $limit + 1 );
} else {
$sql_limit = '' ;
}
if ( ! Validate :: isLoadedObject ( $this ) || $this -> { $type . '_restriction' } == 0 ) {
$array [ 'selected' ] = Db :: getInstance () -> executeS ( '
2015-07-06 16:58:50 +02:00
SELECT t .* '.($i18n ? ' , tl .* ' : ' ').' , 1 as selected
FROM `'._DB_PREFIX_.$type.'` t
'.($i18n ? ' LEFT JOIN `'._DB_PREFIX_.$type.'_lang` tl ON ( t . id_ '.$type.' = tl . id_ '.$type.' AND tl . id_lang = '.(int)Context::getContext()->language->id.' ) ' : ' ').'
WHERE 1
'.($active_only ? ' AND t . active = 1 ' : ' ').'
'.(in_array($type, array(' carrier ', ' shop ')) ? ' AND t . deleted = 0 ' : ' ').'
'.($type == ' cart_rule ' ? ' AND t . id_cart_rule != '.(int)$this->id : ' ' ) .
2015-09-22 18:22:11 +02:00
$shop_list .
( in_array ( $type , array ( 'carrier' , 'shop' )) ? ' ORDER BY t.name ASC ' : '' ) .
( in_array ( $type , array ( 'country' , 'group' , 'cart_rule' )) && $i18n ? ' ORDER BY tl.name ASC ' : '' ) .
$sql_limit );
} else {
if ( $type == 'cart_rule' ) {
$array = $this -> getCartRuleCombinations ( $offset , $limit , $search_cart_rule_name );
} else {
$resource = Db :: getInstance () -> query ( '
2015-07-06 16:58:50 +02:00
SELECT t .* '.($i18n ? ' , tl .* ' : ' ').' , IF ( crt . id_ '.$type.' IS NULL , 0 , 1 ) as selected
FROM `'._DB_PREFIX_.$type.'` t
'.($i18n ? ' LEFT JOIN `'._DB_PREFIX_.$type.'_lang` tl ON ( t . id_ '.$type.' = tl . id_ '.$type.' AND tl . id_lang = '.(int)Context::getContext()->language->id.' ) ' : ' ').'
LEFT JOIN ( SELECT id_ '.$type.' FROM `'._DB_PREFIX_.'cart_rule_'.$type.'` WHERE id_cart_rule = '.(int)$this->id.' ) crt ON t . id_ '.($type == ' carrier ' ? ' reference ' : $type).' = crt . id_ '.$type.'
WHERE 1 '.($active_only ? ' AND t . active = 1 ' : ' ' ) .
2015-09-22 18:22:11 +02:00
$shop_list
. ( in_array ( $type , array ( 'carrier' , 'shop' )) ? ' AND t.deleted = 0' : '' ) .
( in_array ( $type , array ( 'carrier' , 'shop' )) ? ' ORDER BY t.name ASC ' : '' ) .
( in_array ( $type , array ( 'country' , 'group' , 'cart_rule' )) && $i18n ? ' ORDER BY tl.name ASC ' : '' ) .
$sql_limit ,
false );
while ( $row = Db :: getInstance () -> nextRow ( $resource )) {
$array [( $row [ 'selected' ] || $this -> { $type . '_restriction' } == 0 ) ? 'selected' : 'unselected' ][] = $row ;
}
}
}
return $array ;
}
public static function autoRemoveFromCart ( $context = null )
{
if ( ! $context ) {
$context = Context :: getContext ();
}
if ( ! CartRule :: isFeatureActive () || ! Validate :: isLoadedObject ( $context -> cart )) {
return array ();
}
static $errors = array ();
foreach ( $context -> cart -> getCartRules () as $cart_rule ) {
if ( $error = $cart_rule [ 'obj' ] -> checkValidity ( $context , true )) {
$context -> cart -> removeCartRule ( $cart_rule [ 'obj' ] -> id );
$context -> cart -> update ();
$errors [] = $error ;
}
}
return $errors ;
}
/**
* @ param Context | null $context
* @ return mixed
*/
public static function autoAddToCart ( Context $context = null )
{
if ( $context === null ) {
$context = Context :: getContext ();
}
if ( ! CartRule :: isFeatureActive () || ! Validate :: isLoadedObject ( $context -> cart )) {
return ;
}
$sql = '
2015-07-06 16:58:50 +02:00
SELECT SQL_NO_CACHE cr .*
FROM '._DB_PREFIX_.' cart_rule cr
LEFT JOIN '._DB_PREFIX_.' cart_rule_shop crs ON cr . id_cart_rule = crs . id_cart_rule
'.(!$context->customer->id && Group::isFeatureActive() ? ' LEFT JOIN '._DB_PREFIX_.' cart_rule_group crg ON cr . id_cart_rule = crg . id_cart_rule ' : ' ').'
LEFT JOIN '._DB_PREFIX_.' cart_rule_carrier crca ON cr . id_cart_rule = crca . id_cart_rule
'.($context->cart->id_carrier ? ' LEFT JOIN '._DB_PREFIX_.' carrier c ON ( c . id_reference = crca . id_carrier AND c . deleted = 0 ) ' : ' ').'
LEFT JOIN '._DB_PREFIX_.' cart_rule_country crco ON cr . id_cart_rule = crco . id_cart_rule
WHERE cr . active = 1
AND cr . code = " "
AND cr . quantity > 0
AND cr . date_from < " '.date('Y-m-d H:i:s').' "
AND cr . date_to > " '.date('Y-m-d H:i:s').' "
AND (
cr . id_customer = 0
'.($context->customer->id ? ' OR cr . id_customer = '.(int)$context->cart->id_customer : ' ').'
)
AND (
cr . `carrier_restriction` = 0
'.($context->cart->id_carrier ? ' OR c . id_carrier = '.(int)$context->cart->id_carrier : ' ').'
)
AND (
cr . `shop_restriction` = 0
'.((Shop::isFeatureActive() && $context->shop->id) ? ' OR crs . id_shop = '.(int)$context->shop->id : ' ').'
)
AND (
cr . `group_restriction` = 0
'.($context->customer->id ? ' OR EXISTS (
SELECT 1
FROM `'._DB_PREFIX_.'customer_group` cg
INNER JOIN `'._DB_PREFIX_.'cart_rule_group` crg ON cg . id_group = crg . id_group
WHERE cr . `id_cart_rule` = crg . `id_cart_rule`
AND cg . `id_customer` = '.(int)$context->customer->id.'
LIMIT 1
) ' : (Group::isFeatureActive() ? ' OR crg . `id_group` = '.(int)Configuration::get(' PS_UNIDENTIFIED_GROUP ') : ' ')).'
)
AND (
cr . `reduction_product` <= 0
OR EXISTS (
SELECT 1
FROM `'._DB_PREFIX_.'cart_product`
WHERE `'._DB_PREFIX_.'cart_product` . `id_product` = cr . `reduction_product` AND `id_cart` = '.(int)$context->cart->id.'
)
)
AND NOT EXISTS ( SELECT 1 FROM '._DB_PREFIX_.' cart_cart_rule WHERE cr . id_cart_rule = '._DB_PREFIX_.' cart_cart_rule . id_cart_rule
AND id_cart = '.(int)$context->cart->id.' )
ORDER BY priority ' ;
2015-09-22 18:22:11 +02:00
$result = Db :: getInstance () -> executeS ( $sql , true , false );
if ( $result ) {
$cart_rules = ObjectModel :: hydrateCollection ( 'CartRule' , $result );
if ( $cart_rules ) {
foreach ( $cart_rules as $cart_rule ) {
/** @var CartRule $cart_rule */
if ( $cart_rule -> checkValidity ( $context , false , false )) {
$context -> cart -> addCartRule ( $cart_rule -> id );
}
}
}
}
}
/**
* @ return bool
*/
public static function isFeatureActive ()
{
static $is_feature_active = null ;
if ( $is_feature_active === null ) {
$is_feature_active = ( bool ) Configuration :: get ( 'PS_CART_RULE_FEATURE_ACTIVE' );
}
return $is_feature_active ;
}
/* When an entity associated to a product rule (product, category, attribute, supplier, manufacturer...) is deleted, the product rules must be updated */
public static function cleanProductRuleIntegrity ( $type , $list )
{
// Type must be available in the 'type' enum of the table cart_rule_product_rule
if ( ! in_array ( $type , array ( 'products' , 'categories' , 'attributes' , 'manufacturers' , 'suppliers' ))) {
return false ;
}
// This check must not be removed because this var is used a few lines below
$list = ( is_array ( $list ) ? implode ( ',' , array_map ( 'intval' , $list )) : ( int ) $list );
if ( ! preg_match ( '/^[0-9,]+$/' , $list )) {
return false ;
}
// Delete associated restrictions on cart rules
Db :: getInstance () -> execute ( '
2015-07-06 16:58:50 +02:00
DELETE crprv
FROM `'._DB_PREFIX_.'cart_rule_product_rule` crpr
LEFT JOIN `'._DB_PREFIX_.'cart_rule_product_rule_value` crprv ON crpr . `id_product_rule` = crprv . `id_product_rule`
WHERE crpr . `type` = " '.pSQL( $type ).' "
AND crprv . `id_item` IN ( '.$list.' ) ' ); // $list is checked a few lines above
2015-09-22 18:22:11 +02:00
// Delete the product rules that does not have any values
if ( Db :: getInstance () -> Affected_Rows () > 0 ) {
Db :: getInstance () -> delete ( 'cart_rule_product_rule' , 'NOT EXISTS (SELECT 1 FROM `' . _DB_PREFIX_ . ' cart_rule_product_rule_value `
2015-07-06 16:58:50 +02:00
WHERE `cart_rule_product_rule` . `id_product_rule` = `cart_rule_product_rule_value` . `id_product_rule` ) ' );
2015-09-22 18:22:11 +02:00
}
// If the product rules were the only conditions of a product rule group, delete the product rule group
if ( Db :: getInstance () -> Affected_Rows () > 0 ) {
Db :: getInstance () -> delete ( 'cart_rule_product_rule_group' , 'NOT EXISTS (SELECT 1 FROM `' . _DB_PREFIX_ . ' cart_rule_product_rule `
2015-07-06 16:58:50 +02:00
WHERE `cart_rule_product_rule` . `id_product_rule_group` = `cart_rule_product_rule_group` . `id_product_rule_group` ) ' );
2015-09-22 18:22:11 +02:00
}
2015-07-06 16:58:50 +02:00
2015-09-22 18:22:11 +02:00
// If the product rule group were the only restrictions of a cart rule, update de cart rule restriction cache
if ( Db :: getInstance () -> Affected_Rows () > 0 ) {
Db :: getInstance () -> execute ( '
2015-07-06 16:58:50 +02:00
UPDATE `'._DB_PREFIX_.'cart_rule` cr
LEFT JOIN `'._DB_PREFIX_.'cart_rule_product_rule_group` crprg ON cr . id_cart_rule = crprg . id_cart_rule
SET product_restriction = IF ( crprg . id_product_rule_group IS NULL , 0 , 1 ) ' );
2015-09-22 18:22:11 +02:00
}
return true ;
}
/**
* @ param $name
* @ param $id_lang
* @ return array
*/
public static function getCartsRuleByCode ( $name , $id_lang , $extended = false )
{
$sql_base = ' SELECT cr .* , crl .*
2015-07-06 16:58:50 +02:00
FROM '._DB_PREFIX_.' cart_rule cr
LEFT JOIN '._DB_PREFIX_.' cart_rule_lang crl ON ( cr . id_cart_rule = crl . id_cart_rule AND crl . id_lang = '.(int)$id_lang.' ) ' ;
2015-09-22 18:22:11 +02:00
if ( $extended ) {
return Db :: getInstance () -> executeS ( '(' . $sql_base . ' WHERE code LIKE \'%' . pSQL ( $name ) . '%\') UNION (' . $sql_base . ' WHERE name LIKE \'%' . pSQL ( $name ) . '%\')' );
} else {
return Db :: getInstance () -> executeS ( $sql_base . ' WHERE code LIKE \'%' . pSQL ( $name ) . '%\'' );
}
}
2015-07-06 16:58:50 +02:00
}