Динамическое обновление основной корзины
У MS2 есть хорошая вещь как возможность расширения класса msCartHandler. Все обновленные данные берутся $miniShop2->cart->status() и отсюда следует что нужно в этот массив данных дописать нужные нам данные, а именно список товаров которые попадут в [[+goods]]
И так начнем «колдовать»!Для начала создаем в папке core/components/minishop2/custom/cart файл msсartзroductрandler.class.php с следующим содержимым:
В файле assets/components/minishop2/js/web/default.js после строки
Осталось только обернуть вызов сниппета [[!msCart]] в блок с классом «ms2_total_products».
И так начнем «колдовать»!Для начала создаем в папке core/components/minishop2/custom/cart файл msсartзroductрandler.class.php с следующим содержимым:
<?php
class msCartProductHandler extends msCartHandler {
// сюда будут добавляться модифицированные функции
}
Далее я залез в файл mscarthandler.class.php чтобы скопировать код функции status и модифицировать его как мне нужно, получилось следующее:<?php
class msCartProductHandler extends msCartHandler {
public function status($data = array()) {
$status = array(
'total_count' => 0
,'total_cost' => 0
,'total_weight' => 0
,'cart' => $this->getProducts() // добавил елемент в массив "status" куда будет генерироваться "большая" корзина.
);
foreach ($this->cart as $item) {
if (empty($item['ctx']) || $item['ctx'] == $this->modx->context->key){
$status['total_count'] += $item['count'];
$status['total_cost'] += $item['price'] * $item['count'];
$status['total_weight'] += $item['weight'] * $item['count'];
}
}
return array_merge($data, $status);
}
}
Как можно заметить я добавил вывод функции getProducts, добавляем ее в наш модификатор и в итоге получаем такое его содержимое:<?php
class msCartProductHandler extends msCartHandler {
public function status($data = array()) {
$status = array(
'total_count' => 0
,'total_cost' => 0
,'total_weight' => 0
,'cart' => $this->getProducts()
);
foreach ($this->cart as $item) {
if (empty($item['ctx']) || $item['ctx'] == $this->modx->context->key){
$status['total_count'] += $item['count'];
$status['total_cost'] += $item['price'] * $item['count'];
$status['total_weight'] += $item['weight'] * $item['count'];
}
}
return array_merge($data, $status);
}
public function getProducts($cart) {
$products = '';
$cart = $this->get();
if (!$this->modx->loadClass('pdofetch', MODX_CORE_PATH . 'components/pdotools/model/pdotools/', false, true)) {return false;}
$pdoFetch = new pdoFetch($this->modx, $scriptProperties);
$tplOuter = 'msCartOuter';
$tplRow = 'msCartRow';
$products = array('goods' => '', 'total_count' => 0, 'total_weight' => 0, 'total_cost' => 0);
foreach ($cart as $k => $v) {
$product = $this->modx->getObject('msProduct', $v['id']);
$row['id'] = $product->get(id);
$row['key'] = $k;
$row['count'] = $v['count'];
$row['pagetitle'] = $product->get('pagetitle');
$row['old_price'] = $this->ms2->formatPrice(
$row['price'] != $v['price']
? $row['price']
: $row['old_price']
);
$row['price'] = $this->ms2->formatPrice($v['price']);
$row['weight'] = $this->ms2->formatWeight($v['weight']);
$row['cost'] = $this->ms2->formatPrice($v['count'] * $v['price']);
if (!empty($v['options']) && is_array($v['options'])) {
foreach ($v['options'] as $key => $value) {
$row['option.'.$key] = $value;
}
}
unset($v['options']);
$row['idx'] = $pdoFetch->idx++;
$products['goods'] .= empty($tplRow)
? $pdoFetch->getChunk('', $row)
: $pdoFetch->getChunk($tplRow, $row, $pdoFetch->config['fastMode']);
$products['total_count'] += $v['count'];
$products['total_cost'] += $v['count'] * $v['price'];
$products['total_weight'] += $v['count'] * $v['weight'];
}
$products['total_cost'] = $this->ms2->formatPrice($products['total_cost']);
$products['total_weight'] = $this->ms2->formatWeight($products['total_weight']);
return empty($tplOuter)
? $pdoFetch->getChunk('', $products)
: $pdoFetch->getChunk($tplOuter, $products, $pdoFetch->config['fastMode']);
}
}
Сохраняем файл. Переходим в систему управления, в настройки системы/minishop2/корзина и меняем класс обработчик корзины на msCartProductHandler.В файле assets/components/minishop2/js/web/default.js после строки
miniShop2.Cart.totalCost = '.ms2_total_cost';
дописываем miniShop2.Cart.totalProducts = '.ms2_total_products';
и после $(miniShop2.Cart.totalCost).text(miniShop2.Utils.formatPrice(status['total_cost']));
пишем $(miniShop2.Cart.totalProducts).html(status['cart']);
Осталось только обернуть вызов сниппета [[!msCart]] в блок с классом «ms2_total_products».
Комментарии: 29
Интересно, а какую проблему решал автор?
аналогичную описанную тут modx.pro/help/3898/
Было бы неплохо дописать в начало заметки.
Ну и редактировать default.js плохо — он перезапишется при обновлении.
Ну и редактировать default.js плохо — он перезапишется при обновлении.
я вообще убрал предложение про проблему, а про default.js полностью согласен, на проекте где я использую данное решение, скрипт вообще не участвует т.к. создана его копия с глобальными доработками. Ну и в настройке системы путь до нового файла указан.
В начало заметки добавьте какой функционал реализует это решение. А то так сразу и не поймешь. :) Спасибо.
Кстати на счет перезаписи при обновлении. Столкнулся с проектом в котором пришлось в стандартном классе msProduct поменять поле $allowChildResource с false на true, чтобы в дереве ресурсов у него можно было создавать дочерние ресурсы. При обновлении этот момент может слететь. Василий не подскажете, как этого избежать?
Понимаю, что по большему счету можно просто написать JS скриптик, который в дереве на node будет классы вешать, которые выпадающий список вернут. Но как это правильно делается на ExtJS понятия не имею, а криво писать нет желания абсолютно никакого.
По-моему отличное решение. Попробовал.
Для потомков оставлю, если хотите выводить ещё и картинку от товара, то в классе корзины нужно добавить:
Для потомков оставлю, если хотите выводить ещё и картинку от товара, то в классе корзины нужно добавить:
...
foreach ($cart as $k => $v) {
...
$row['thumb'] = $product->get('thumb'); // вот эту строку
...
}
...
Сделал всё по инструкции.
Не могу понять, почему выводит массив с данными, а не заменяет строки?
Вот код, который выводится:
Не могу понять, почему выводит массив с данными, а не заменяет строки?
Вот код, который выводится:
Array ( [goods] => Array ( [id] => 9 [key] => fde9a248d43d903de47f1878b2004da4 [count] => 1 [pagetitle] => Ручка перьевая "Оптимист" [old_price] => 0 [price] => 340 [weight] => 0 [cost] => 340 [thumb] => /assets/images/products/9/120x90/01.jpg [idx] => 1 ) [total_count] => 1 [total_weight] => 0 [total_cost] => 340 )
Как превратить этот массив в обычные строки?
А вы чанки указали? $tplOuter = '...'; и $tplRow = '...';
Да, столкнулся с такой же проблемой, выводит чисто массив, чанки указаны, делал так же все по инструкции. В логах такая ситуация
[2014-12-14 03:39:05] (ERROR @ /home/d/dilladesign/store/public_html/core/components/minishop2/custom/cart/msсartproductрandler.class.php : 22) PHP warning: Missing argument 1 for msCartProductHandler::getProducts(), called in /home/d/dilladesign/store/public_html/core/components/minishop2/custom/cart/msсartproductрandler.class.php on line 9 and defined
[2014-12-14 03:39:05] (ERROR @ /home/d/dilladesign/store/public_html/core/components/pdotools/model/pdotools/pdofetch.class.php : 18) Recoverable error: Argument 1 passed to pdoFetch::setConfig() must be an array, null given, called in /home/d/dilladesign/store/public_html/core/components/pdotools/model/pdotools/pdotools.class.php on line 39 and defined
[2014-12-14 03:39:05] (ERROR @ /home/d/dilladesign/store/public_html/core/components/pdotools/model/pdotools/pdofetch.class.php : 46) PHP warning: array_merge() [<a href='function.array-merge'>function.array-merge</a>]: Argument #2 is not an array
[2014-12-14 03:39:05] (ERROR @ /home/d/dilladesign/store/public_html/core/components/pdotools/model/pdotools/pdotools.class.php : 67) Recoverable error: Argument 1 passed to pdoTools::setConfig() must be an array, null given, called in /home/d/dilladesign/store/public_html/core/components/pdotools/model/pdotools/pdofetch.class.php on line 47 and defined
[2014-12-14 03:39:05] (ERROR @ /home/d/dilladesign/store/public_html/core/components/pdotools/model/pdotools/pdotools.class.php : 81) PHP warning: array_merge() [<a href='function.array-merge'>function.array-merge</a>]: Argument #2 is not an array
[2014-12-14 03:39:05] (ERROR @ /home/d/dilladesign/store/public_html/core/components/minishop2/custom/cart/msсartproductрandler.class.php : 22) PHP warning: Missing argument 1 for msCartProductHandler::getProducts(), called in /home/d/dilladesign/store/public_html/core/components/minishop2/custom/cart/msсartproductрandler.class.php on line 9 and defined
[2014-12-14 03:39:05] (ERROR @ /home/d/dilladesign/store/public_html/core/components/pdotools/model/pdotools/pdofetch.class.php : 18) Recoverable error: Argument 1 passed to pdoFetch::setConfig() must be an array, null given, called in /home/d/dilladesign/store/public_html/core/components/pdotools/model/pdotools/pdotools.class.php on line 39 and defined
[2014-12-14 03:39:05] (ERROR @ /home/d/dilladesign/store/public_html/core/components/pdotools/model/pdotools/pdofetch.class.php : 46) PHP warning: array_merge() [<a href='function.array-merge'>function.array-merge</a>]: Argument #2 is not an array
[2014-12-14 03:39:05] (ERROR @ /home/d/dilladesign/store/public_html/core/components/pdotools/model/pdotools/pdotools.class.php : 67) Recoverable error: Argument 1 passed to pdoTools::setConfig() must be an array, null given, called in /home/d/dilladesign/store/public_html/core/components/pdotools/model/pdotools/pdofetch.class.php on line 47 and defined
[2014-12-14 03:39:05] (ERROR @ /home/d/dilladesign/store/public_html/core/components/pdotools/model/pdotools/pdotools.class.php : 81) PHP warning: array_merge() [<a href='function.array-merge'>function.array-merge</a>]: Argument #2 is not an array
Я разобрался в чем дело. Проглядел про чанки и то что надо указывать те, которые есть в самом классе msCartProductHandler.
$tplOuter = 'msCartOuter';
$tplRow = 'msCartRow';
Но в логах все равно записывается ошибка.
Здравствуйте, Вам удалось решить проблему?
Сделал все по инструкции, а в ответ белый экран. Уже всю голову сломал
А что в логах пишется?
в логах все чисто
попробовал на тестовом сайте, такая же ситуация
все сделал, но old_price=0 и после того как вставил строчку про картинку она не появилась, а в исходном коде пишется код как в чанке
Поделитесь пожалуйста информацией как белый экран побороли. Та же история, видимо что то упускаю
логи чисты…
логи чисты…
Все работает, только в лог сыпятся ошибки:
[2015-06-10 08:11:24] (ERROR @ /home/s2040/www/system_heart/components/minishop2/custom/cart/mscustomcarthandler.class.php : 30) PHP warning: Missing argument 1 for myCustomCart::getProducts(), called in /home/s2040/www/system_heart/components/minishop2/custom/cart/mscustomcarthandler.class.php on line 13 and defined
[2015-06-10 08:11:24] (ERROR @ /home/s2040/www/system_heart/components/pdotools/model/pdotools/pdofetch.class.php : 18) Recoverable error: Argument 1 passed to pdoFetch::setConfig() must be of the type array, null given, called in /home/s2040/www/system_heart/components/pdotools/model/pdotools/pdotools.class.php on line 41 and defined
[2015-06-10 08:11:24] (ERROR @ /home/s2040/www/system_heart/components/pdotools/model/pdotools/pdofetch.class.php : 45) PHP warning: array_merge(): Argument #2 is not an array
[2015-06-10 08:11:24] (ERROR @ /home/s2040/www/system_heart/components/pdotools/model/pdotools/pdotools.class.php : 51) Recoverable error: Argument 1 passed to pdoTools::setConfig() must be of the type array, null given, called in /home/s2040/www/system_heart/components/pdotools/model/pdotools/pdofetch.class.php on line 46 and defined
[2015-06-10 08:11:24] (ERROR @ /home/s2040/www/system_heart/components/pdotools/model/pdotools/pdotools.class.php : 66) PHP warning: array_merge(): Argument #2 is not an array
Сделал все как написано, в ответ белый экран, а в логах вот это:
[2015-10-12 16:39:38] (ERROR @ /index.php) Unexpected tag 'id' in 98d45d5752e8b6d3778629a5b27f35d0 line 52, near '{id:' <- there
[2015-10-12 16:39:38] (ERROR @ /index.php) Unexpected tag 'id' in 98d45d5752e8b6d3778629a5b27f35d0 line 52, near '{id:' <- there
[2015-10-12 16:39:38] (ERROR @ /index.php) Unexpected tag 'id' in 98d45d5752e8b6d3778629a5b27f35d0 line 52, near '{id:' <- there
[2015-10-12 16:39:38] (ERROR @ /index.php) Unexpected tag 'id' in 98d45d5752e8b6d3778629a5b27f35d0 line 52, near '{id:' <- there
[2015-10-12 16:39:38] (ERROR @ /index.php) Unexpected tag 'id' in 98d45d5752e8b6d3778629a5b27f35d0 line 52, near '{id:' <- there
[2015-10-12 16:39:38] (ERROR @ /index.php) Unexpected tag 'id' in 98d45d5752e8b6d3778629a5b27f35d0 line 52, near '{id:' <- there
[2015-10-12 16:39:38] (ERROR @ /index.php) Unexpected tag 'id' in 98d45d5752e8b6d3778629a5b27f35d0 line 52, near '{id:' <- there
[2015-10-12 16:39:38] (ERROR @ /index.php) Unexpected tag 'id' in c154339fa7a364f0d071e960b902d8c5 line 52, near '{id:' <- there
Для miniShop2 версии 2.3 alpha не подходит. Есть какое-то решение?
Спасибо, всё работает. Только для тех, кто еще будет делать была проблема, что не работает пересчет корзины когда меняем количество товара в input. Нужно вручную добавить событие сабмита формы в onchange этого инпута:
<input type="number" name="count" value="[[+count]]" max-legth="4" onchange="$(this).closest(miniShop2.form).submit();" class="input-sm form-control" />
Здравствуйте. Подскажите пожалуйста, как решить проблему перезагрузки страницы, когда корзина становится пустой?
Здравствуйте. Но не могу понять что имел ввиду автор сообщения за 2014
Неужели надо самому создать чанк msCartOuter, в настройках снипета заменить tpl.msCart.Outer на tpl.msCartOuter?
Я разобрался в чем дело. Проглядел про чанки и то что надо указывать те, которые есть в самом классе msCartProductHandler.В настройках сниппета msCart вижу что указан чанк tpl.msCart.Outer'
$tplOuter = 'msCartOuter';
$tplRow = 'msCartRow';
Неужели надо самому создать чанк msCartOuter, в настройках снипета заменить tpl.msCart.Outer на tpl.msCartOuter?
Костыль, но всё же
<button onClick="setTimeout(function(){history.go(0);},0300);"></button>
Если страница грузится достаточно быстро, то можно избежать волокиты с дефолтными js.
Может это поможет?
modx.pro/help/3898#comment-113583
modx.pro/help/3898#comment-113583
на текущий момент не актуально. сделал все, как описано, выводится стандартный сниппет со стандартными чанками
Грохните мой комментарий ерунду написал =(
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.