Skip to content

Instantly share code, notes, and snippets.

@gvozdb
Last active July 12, 2021 11:53
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save gvozdb/9d14f40710a23fa74084ad9c5bd77d64 to your computer and use it in GitHub Desktop.
Save gvozdb/9d14f40710a23fa74084ad9c5bd77d64 to your computer and use it in GitHub Desktop.
[MODX Revo] Разные скидки для miniShop2 в зависимости от общей суммы корзины
<?php
$chunk = 'tpl.msdfcMsg';
$discounts = array(
'100000' => '10%',
'150000' => '15%',
'200000' => '20%',
);
krsort($discounts);
reset($discounts);
$actionKey = 'msdfc_action';
/* Содержимое чанка $chunk:
[[+current.discount:ne=`0`:then=`<p>Текущая скидка <b>[[+current.discount]]</b> и <b>[[+discount_amount]] [[%ms2_frontend_currency]]</b></p>`]]
[[+next.discount:ne=`0`:then=`<p>Если наберете на <b>[[+next.total_cost]] [[%ms2_frontend_currency]]</b>, то получите скидку <b>[[+next.discount]]</b>.</p>`]]
*/
switch ($modx->event->name) {
case 'msOnAddToCart':
case 'msOnChangeInCart':
case 'msOnRemoveFromCart':
$tmpPrices =
$tmpOldPrices = array();
$cartArray = $cart->get();
// Восстанавливаем оригинальные цены в корзине
foreach ($cartArray as &$cartProduct) {
if (isset($cartProduct['original_price'])) {
$tmpPrices[$cartProduct['id']] =
$cartProduct['price'] = $cartProduct['original_price'];
$tmpOldPrices[$cartProduct['id']] = $cartProduct['original_old_price'];
} elseif ($product = $modx->getObject('msProduct', $cartProduct['id'])) {
$tmpPrices[$cartProduct['id']] =
$cartProduct['price'] = $product->get('price');
$tmpOldPrices[$cartProduct['id']] = $product->get('old_price');
}
unset($cartProduct['old_price']);
unset($cartProduct['original_price']);
unset($cartProduct['original_old_price']);
}
$cart->set($cartArray);
$cartStatus = $cart->status();
// Получаем процент скидки
$discount = array(
'current' => array(
'total_cost' => '0',
'value' => '0%',
),
'next' => array(
'total_cost' => '0',
'value' => '0%',
),
);
$keys = array_keys($discounts);
for ($i = 0; $i < count($keys); $i++)
{
if ($cartStatus['total_cost'] >= $keys[$i]) {
$discount['current']['total_cost'] = $keys[$i];
$discount['current']['value'] = $discounts[$keys[$i]];
if ($i > 0) {
$discount['next']['total_cost'] = $keys[$i - 1];
$discount['next']['value'] = $discounts[$keys[$i - 1]];
}
break;
}
}
// Если не нашли подходящей скидки, запишем в следующую скидку - первую по очереди
if ($discount['current']['value'] == '0%') {
$discount['next']['total_cost'] = end($keys);
$discount['next']['value'] = $discounts[end($keys)];
}
// $modx->log(1,'$discounts '.print_r($discounts,1));
// $modx->log(1,'$discount '.print_r($discount,1));
// Ставим новые цены со скидкой
foreach ($cartArray as &$cartProduct) {
if (!isset($tmpPrices[$cartProduct['id']]) && !isset($tmpOldPrices[$cartProduct['id']])) {
if ($product = $modx->getObject('msProduct', $cartProduct['id'])) {
$tmpPrices[$cartProduct['id']] = $product->get('price');
if (!isset($tmpOldPrices[$cartProduct['id']]) || empty($tmpOldPrices[$cartProduct['id']])) {
$tmpOldPrices[$cartProduct['id']] = $product->get('old_price');
}
}
}
if (isset($tmpPrices[$cartProduct['id']])) {
$cartProduct['original_price'] = $tmpPrices[$cartProduct['id']];
$cartProduct['original_old_price'] = isset($tmpOldPrices[$cartProduct['id']])
? $tmpOldPrices[$cartProduct['id']]
: 0;
$cartProduct['price'] = $tmpPrices[$cartProduct['id']] - ($tmpPrices[$cartProduct['id']] * $discount['current']['value'] / 100); // Вычисляем скидку и записываем новую цену
$cartProduct['old_price'] = (isset($tmpOldPrices[$cartProduct['id']]) && !empty($tmpOldPrices[$cartProduct['id']]) && ($tmpOldPrices[$cartProduct['id']] > $tmpPrices[$cartProduct['id']] || $tmpPrices[$cartProduct['id']] <= $cartProduct['price']))
? $tmpOldPrices[$cartProduct['id']]
: $tmpPrices[$cartProduct['id']];
if (empty($cartProduct['old_price']) && $tmpPrices[$cartProduct['id']] != $cartProduct['price']) {
$cartProduct['old_price'] = $tmpPrices[$cartProduct['id']];
}
if ($cartProduct['old_price'] == $cartProduct['price']) {
unset($cartProduct['old_price']);
}
}
}
$cart->set($cartArray);
$cartStatusNew = $cart->status();
// Пишем в сессию
$_SESSION['msdfc'] = array(
'discount' => $discount,
'discount_amount' => $cartStatus['total_cost'] - $cartStatusNew['total_cost'],
);
break;
case 'OnHandleRequest':
case 'OnLoadWebDocument':
$isAjax = !empty($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest';
if (!(empty($_REQUEST[$actionKey]) || ($isAjax && $modx->event->name != 'OnHandleRequest') || (!$isAjax && $modx->event->name != 'OnLoadWebDocument'))) {
$action = trim($_REQUEST[$actionKey]);
$ctx = !empty($_REQUEST['ctx']) ? (string)$_REQUEST['ctx'] : 'web';
if ($ctx != 'web') {
$modx->switchContext($ctx);
}
/* @var miniShop2 $miniShop2 */
$miniShop2 = $modx->getService('minishop2');
$miniShop2->initialize($ctx, array('json_response' => $isAjax));
if (!($miniShop2 instanceof miniShop2)) {
@session_write_close();
exit('Could not initialize miniShop2');
}
switch ($action) {
case 'cart/get':
$discounts = $_SESSION['msdfc'];
$response['cart'] = $miniShop2->cart->get();
$response['status'] = $miniShop2->cart->status();
$response['msdfc'] = $discounts;
$pls['discount_amount'] = $miniShop2->formatPrice(isset($discounts['discount_amount'])
? $discounts['discount_amount']
: 0);
foreach (array('current', 'next') as $val) {
$pls[$val.'.discount'] = isset($discounts['discount'][$val]['value'])
? ($discounts['discount'][$val]['value'] != '0%'
? $discounts['discount'][$val]['value']
: 0)
: 0;
$pls[$val.'.total_cost'] = $miniShop2->formatPrice(isset($discounts['discount'][$val]['total_cost'])
? $discounts['discount'][$val]['total_cost']
: 0);
}
$response['msdfc']['msg'] = $modx->getChunk($chunk, $pls);
$response = $modx->toJSON($response);
break;
default:
$message = ($_REQUEST[$actionKey] != $action)
? 'ms2_err_register_globals'
: 'ms2_err_unknown';
$response = $miniShop2->error($message);
}
if ($isAjax) {
@session_write_close();
exit($response);
}
}
$data_js = preg_replace(array('/\t{6}/', '/[ ]{24}/'), '', "
(function(window, document, $, undefined) {
if (typeof msdfc == 'undefined') {
msdfc = {}
}
msdfc.setup = function() {
if (typeof msdfc.param == 'undefined') {
msdfc.param = {};
}
if (typeof msdfc.param.msg == 'undefined') {
msdfc.param.msg = '.msdfc_msg';
}
if (typeof msdfc.param.price == 'undefined') {
msdfc.param.price = 'span.price';
}
if (typeof msdfc.param.old_price == 'undefined') {
msdfc.param.old_price = 'span.old_price';
}
if (typeof msdfc.param.refresh_old_price == 'undefined') {
msdfc.param.refresh_old_price = true;
}
}
msdfc.initialize = function() {
msdfc.setup();
msdfc.Send.freshenCart('cart/get');
}
msdfc.Cart = {
freshen: function(resp) {
// console.log('freshen', resp)
if (typeof(resp) != 'undefined') {
// Ставим цены для товаров в корзине
if ('cart' in resp) {
msdfc.Cart.setPrices(resp.cart);
}
// Подставляем новое сообщение о скидке
if ('msdfc' in resp) {
msdfc.Cart.setMsg(resp.msdfc);
}
}
else {
msdfc.Send.freshenCart('cart/get');
}
},
setPrices: function(cart) {
if (typeof cart != 'undefined') {
for (var key in cart) {
// манипуляции с old_price
if (msdfc.param.refresh_old_price) {
if (typeof cart[key].old_price != 'undefined' && cart[key].old_price != 0) {
// подставляем новый old_price в товар в корзине
$('#' + key)
.find(msdfc.param.old_price)
.show()
.find('span')
.html(miniShop2.Utils.formatPrice(cart[key].old_price));
} else {
// скрываем old_price для товара в корзине
$('#' + key)
.find(msdfc.param.old_price)
.hide();
}
}
// манипуляции с price
$('#' + key)
.find(msdfc.param.price + ' span')
.html(miniShop2.Utils.formatPrice(cart[key].price));
}
}
},
setMsg: function(resp) {
if (typeof resp != 'undefined' && 'msg' in resp) {
$(msdfc.param.msg)
.html(resp.msg);
}
},
}
msdfc.Send = {
freshenCart: function(action) {
var data = {};
data['{$actionKey}'] = action;
$.post(
document.location.href, data,
function(resp) {
// console.log('freshenCart', resp)
if (resp != {} || ('length' in resp && resp.length > 0)) {
msdfc.Cart.freshen(resp);
}
},
'json'
);
},
}
msdfc.utils = {
cloneObj: function(obj) {
if (obj == null || typeof(obj) != 'object') { return obj; }
var tmp = new obj.constructor();
for (var key in obj)
{
tmp[key] = msdfc.utils.cloneObj(obj[key]);
}
return tmp;
},
}
msdfc.initialize();
})
(this, document, jQuery);
setTimeout(function() {
msdfc.ms2CallbacksClone = msdfc.utils.cloneObj(miniShop2.Callbacks);
msdfc.ms2Callbacks = {
Cart: {
change: { response: {
success: function (response) {
if (typeof(msdfc.ms2CallbacksClone.Cart.change.response.success) == 'function') {
msdfc.ms2CallbacksClone.Cart.change.response.success(response);
}
msdfc.Cart.freshen();
},
error: function (response) {
if (typeof(msdfc.ms2CallbacksClone.Cart.change.response.error) == 'function') {
msdfc.ms2CallbacksClone.Cart.change.response.error(response);
}
msdfc.Cart.freshen();
},
}},
remove: { response: {
success: function (response) {
if (typeof(msdfc.ms2CallbacksClone.Cart.remove.response.success) == 'function') {
msdfc.ms2CallbacksClone.Cart.remove.response.success(response);
}
msdfc.Cart.freshen();
},
error: function (response) {
if (typeof(msdfc.ms2CallbacksClone.Cart.remove.response.error) == 'function') {
msdfc.ms2CallbacksClone.Cart.remove.response.error(response);
}
msdfc.Cart.freshen();
},
}},
},
};
miniShop2.Callbacks.Cart.change.response = msdfc.ms2Callbacks.Cart.change.response;
miniShop2.Callbacks.Cart.remove.response = msdfc.ms2Callbacks.Cart.remove.response;
}, 200);
");
$modx->regClientScript("<script type=\"text/javascript\">\n".$data_js."\n</script>", true);
break;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment