Сохранение корзины для пользователей
        На одном из проектов появилась задача сохранять содержимое корзины для зарегистрированных пользователей, чтобы при последующей авторизации с любого компьютера они имели возможность продолжить покупки, а не добавлять все заново. 
В качестве решения получился очень простой плагин, который выполняет 2 действия:
1) Сохраняет содержимое корзины в extended поля пользователя после каждого изменения корзины
2) Восстанавливает содержимое корзины перед каждой обработкой запрошенной страницы.
Возможно, появится вопрос, почему реальная корзина переписывается при каждой обработке страницы и почему нельзя это сделать только при авторизации?
В качестве ответа ситуация:
1) На одном компьютере пользователь добавил капкейк и торт
2) На втором компьютере удалил торт и добавил макаруны
3) При возвращении на первый ПК в корзине окажутся капкейк и макаруны
По коду плагина понятно, какие события нужно активировать в его свойствах.
Еще можно добавить сравнение текущего состояния корзины с имеющейся в профиле на случай авторизации при заполненной корзине, но это уже индивидуально.
Оформлять пакет из такого плагина бессмысленно, но если в комментариях идея будет поддержана и развита, возможно появление более функционального варианта в виде компонента.
    
    
                                                                                
            В качестве решения получился очень простой плагин, который выполняет 2 действия:
1) Сохраняет содержимое корзины в extended поля пользователя после каждого изменения корзины
2) Восстанавливает содержимое корзины перед каждой обработкой запрошенной страницы.
Возможно, появится вопрос, почему реальная корзина переписывается при каждой обработке страницы и почему нельзя это сделать только при авторизации?
В качестве ответа ситуация:
1) На одном компьютере пользователь добавил капкейк и торт
2) На втором компьютере удалил торт и добавил макаруны
3) При возвращении на первый ПК в корзине окажутся капкейк и макаруны
По коду плагина понятно, какие события нужно активировать в его свойствах.
<?php
switch($modx->event->name) {
    case 'msOnAddToCart':
    case 'msOnChangeInCart':
    case 'msOnEmptyCart':
    case 'msOnRemoveFromCart':
        if ($user = $modx->getAuthenticatedUser('web') and $ms2 = $modx->getService('minishop2')) {
            $ms2->initialize($modx->context->key);
            $profile = $user->getOne('Profile');
            $extended = $profile->get('extended');
            $extended['ms2cart'] = $ms2->cart->get();
            $profile->set('extended', $extended);
            $profile->save();
        }
        break;
        
    case 'OnWebPageInit':
    case 'OnWebLogin':
        if ( $user = $modx->getAuthenticatedUser('web') and  $ms2 = $modx->getService('minishop2')) {
            $ms2->initialize($modx->context->key);
            $profile = $user->getOne('Profile');
            $extended = $profile->get('extended');
            if ( isset($extended['ms2cart']) && !empty($extended['ms2cart']) ) {
                $ms2->cart->set($extended['ms2cart']);
            }
        }
        break;
}Еще можно добавить сравнение текущего состояния корзины с имеющейся в профиле на случай авторизации при заполненной корзине, но это уже индивидуально.
Оформлять пакет из такого плагина бессмысленно, но если в комментариях идея будет поддержана и развита, возможно появление более функционального варианта в виде компонента.
Комментарии: 13
                По-моему, очень нужная вещь. У меня жена только так делает заказы — на мобильном телефоне добавляет всё, что нужно в корзину, потом лишнее убирает, а уже оформляет заказ через компьютер — так удобнее вводить адрес и данные.            
                    
                Илья, предлагай расширение функционала :)            
                    
                Нужно сохранять эти корзины в базе данных, с возможностью их просмотра из админки. Но вообще, есть дополнение ordersUnformed. Лучше было бы как-то связаться с автором и предложить внедрить в дополнение функционал восстановления корзин для пользователей. Или делать дублирующее дополнение, но с расширенным функционалом.            
                    
                Написал предложение Александру.            
                    
                Очень полезный плагин.
В качестве расширения функционала:
— отправлять посетителю на почту письмо с содержимым корзины в автоматическом или ручном режиме.
                    В качестве расширения функционала:
— отправлять посетителю на почту письмо с содержимым корзины в автоматическом или ручном режиме.
                есть небольшая проблема в логике! 
Если мы формируем заказ будучи не авторизованными, а потом авторизовываемся на странице оформления заказа, то корзина заменяется и мы теряем товары, которые только что сложили.
Для исправления необходимо чуть поправить событие OnWebLogin
                    Если мы формируем заказ будучи не авторизованными, а потом авторизовываемся на странице оформления заказа, то корзина заменяется и мы теряем товары, которые только что сложили.
Для исправления необходимо чуть поправить событие OnWebLogin
case 'OnWebLogin':
        if ( $user = $modx->getAuthenticatedUser('web') and  $ms2 = $modx->getService('minishop2')) {
            $ms2->initialize($modx->context->key);
            $profile = $user->getOne('Profile');
            $extended = $profile->get('extended');
            if ( isset($extended['ms2cart']) && !empty($extended['ms2cart']) ) {
                $currentcart = $ms2->cart->get();
                $cart = array_merge($currentcart, $extended['ms2cart']);
                $ms2->cart->set($cart);
            }
        }
        break;            
                Тоже нельзя сказать, что это идеальное решение. Все зависит от конкретного случая. Потому пусть будут оба варианта, а разработчики сами для себя выберут подходящий.            
                    
                так и есть, только индивидуально… в моем случае есть возможность авторизоваться непосредственно на странице оформления для того, чтобы заполнить все поля за пользователя, а тут получается заподлянка какая-то(сложил одно, а в заказ упало другое)
Хорошим решением будет отличать устройства, если же устройства одни и те же — то корзину не восстанавливать! Иначе восстановить.
                    Хорошим решением будет отличать устройства, если же устройства одни и те же — то корзину не восстанавливать! Иначе восстановить.
                Тут столкнулся с проблемой, msPromoCode не работает с данным решением, вообще хрень полная происходит, концов не найти) походу по событию msOnChangeInCart перезаписывает данные, которые уже обновлены.            
                    
                Данное решение является лишь направлением для мысли и, естественно, легко может конфликтовать с любыми похожими алгоритмами. В качестве решения попробуйте изменит приоритеты плагинов. Если не поможет, придется самостоятельно вникать в суть конфликта.            
                    
                Подскажите, как сделать условие для msOptionsPrice2? А то фасовки сбиваются…            
                    
                Смотреть, что хранит в сессии msOptionsPrice, сохранять и восстанавливать эти данные вместе с корзиной.            
                    
                У меня для авторизации используется Login. Создал плагин, отметил события, но что-то ничего не сохраняется.            
                    
                            Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.