Недавно просмотренные товары.

#
Re: Re: Недавно просмотренные товары.
piko писал(а):
Наберите в поиске просмотренные товары — где Ваша ссылка

прошу прощения, мне казалось что в поиске буквы "ё" и "е" должны быть эдентичными и при запросе "посещённые товары" у меня единственная ссылка.
Вопрос в том, помогло или нет??
#
Re: Недавно просмотренные товары.
Добрый день, у кого нибудь получилось сделать "недавно просмотренные товары", а то пару тем на форуме есть а рабочего решения нету. могли бы выложить на форум.
#
Re: Недавно просмотренные товары.
Miloserdov, ловите:

Отображение недавно просмотренных товаров в интернет-магазинах на HostCMS v.5

Установка и использование

Код показа последних просмотренных товаров интернет-магазина состоит из трех частей:

  1. коллектора просмотренных товаров;
  2. анализатора для подготовки отображения последних просмотренных товаров;
  3. и xsl-шаблона для самого отображения.


Установка коллектора просмотренных товаров

Коллектор сохраняет информацию о каждом просмотренном товара в массив, который сохраняется в кукисах у пользователя. Код коллектора размещается в _настройках_ ТДС Интернет-магазин, в том месте, где мы определили что мы выводим именно товар, и уже знаем идентификатор этого товара:
    // Если вывод информационного элемента
    if ($GLOBALS['shop_item_path']['item']) {
        // получаем данные о товаре
        $row_item = $shop->GetItem($GLOBALS['shop_item_path']['item']);
        
        // до этого места код ТДС идет без изменений

        /*
        * Последние просмотренные товары
        */
        // Start collecting
        
        // вычислим id родительского товара, если мы находимся на странице модификации
        if ($row_item['shop_items_catalog_modification_id']) {
            $cookie_last_item = $row_item['shop_items_catalog_modification_id'];
        } else {
            $cookie_last_item = $GLOBALS['shop_item_path']['item'];
        }

        // если кука с историей посещений товаров еще не существует
        if (!isset($_COOKIE['SHOP_LAST_ITEMS'])) {

            // то запишем id товара в массив
            $last_items(array($cookie_last_item));

        } else {

            // иначе получим массив с историй посещений товаров
            $last_items = @unserialize($_COOKIE['SHOP_LAST_ITEMS']);
            $last_items = to_array($last_items);

            // если в массиве уже есть id текущего товара
            if (in_array($cookie_last_item, $last_items)) {

                // то вычислим его индекс
                $key = array_search($cookie_last_item, $last_items);

                // и удалим этот элемент массива,
                
                if ($key) {
                    unset($last_items[$key]);
                }
            }
            
            // запишем iв текущего товара в конец массива
            array_push($last_items, $cookie_last_item);
        }

        // сериализуем массив
        $_COOKIE['SHOP_LAST_ITEMS'] = serialize($last_items);

        // сохраним куку
        $shop->SetCookie('SHOP_LAST_ITEMS', $_COOKIE['SHOP_LAST_ITEMS'], time() + 31536000, '/');
        // End collecting
        
        // далее код ТДС идет без изменений

        // имя элемента
        $item_name = $row_item['shop_items_catalog_name'];


В репозитории, в файле lib_config.php приведен полный код настроек ТДС Интернет-магазин, основанный на версии HostCMS 5.9.32 и включающий приведенный выше код коллектора.

Установка анализатора для подготовки отображения последних просмотренных товаров

Код анализатора может быть установлен в любое место макета или шаблона страницы, а также в код ТДС Интернет-магазин, после вызова метода ShowItem() класса shop. Сам код такой:
        /**
         * последние просмотренные товары
         **/
        // Показ последних просмотренных товаров - begin

        // макс. число выводимых последних элементов
        $count_last_visited_items = 6;

        // порядок вывода - true - случайный;  false - в порядке, обратном посещениям
        $is_random = false;

        // если есть кука с историей посещений товаров
        if (isset($_COOKIE['SHOP_LAST_ITEMS'])) {

            // то получим массив с историй посещений товаров
            $last_items = @unserialize($_COOKIE['SHOP_LAST_ITEMS']);
            $last_items = to_array($last_items);

            // если он не пустой
            if (sizeof($last_items)) {


                // Если вы используете этот код не в ТДС, а, например, в макете, или в шаблоне страницы,
                // то раскомментируйте следующий блок кода
                
                // определение текущего пользователя и создание объекта shop - начало
                /*
                // Если есть модуль "Пользователи сайта",
                if (class_exists('SiteUsers')) {
                    
                    $SiteUsers = &singleton('SiteUsers');
                    
                    // то получим текущего пользователя
                    $site_users_id = $SiteUsers->GetCurrentSiteUser();
                } else {
                    $site_users_id = 0;
                }

                // получим ссылку на экземпляр объекта shop
                $shop = &singleton('shop');
                */
                // определение текущего пользователя и создание объекта shop - конец
                

                // исключим из показа последних товаров те, что уже есть в корзине - начало
                // Если исключать их не нужно - закомментируйте этот блок.

                // получим содержимое корзины
                $a_row = $shop->GetItemsFromCart($site_user_id, $current_shop_id);

                // если в корзине что-то есть
                if ($a_row) {
                    // то запустим цикл по товарам лежащим в корзине
                    foreach ($a_row as $item_id => $cart_item_row) {

                        // получаем данные о товаре
                        $row_item = $shop->GetItem($item_id);

                        // вычислим id родительского товара, если в корзине лежит модификация
                        if ($row_item['shop_items_catalog_modification_id'])
                            $host_item_id = $row_item['shop_items_catalog_modification_id'];
                        else
                            $host_item_id = $item_id;

                        // определим в массиве с историей посещений товаров индекс товара, лежащего в корзине
                        $key = array_search($item_id, $last_items);

                        // если такой товар в массиве посещений есть
                        if ($key) {
                            // то исключим его из массива
                            unset($last_items[$key]);
                        }
                    }
                }
                // исключим из показа последних товаров те, что уже есть в корзине - конец

                // исключим текущий элемент
                // определим в массиве с историей посещений товаров индекс текущего товара
                $key = array_search($GLOBALS['shop_item_path']['item'], $last_items);
                // и если найдем, то исключим и его тоже
                if ($key) {
                    unset($last_items[$key]);
                }

                // и если после всего этого еще осталось что показывать :)
                if (sizeof($last_items)) {

                    $param = array();

                    // если задан режим случайного показа
                    if ($is_random) {

                        // то включим случайную сортировку
                        $param['items_order'] = 'rand';

                        // сформируем строку из id всех товаров из массива истории посещений
                        // для передачи ее в фильтр метода ShowShop()
                        // метод ShowShop() сам случайным образом выберет из них нужное количество товаров
                        $last_items_string = implode(',', $last_items);

                    }
                    // если задан показ в обратном хронологическом порядке
                    else {

                        // развернем массив историй посещения товаров задом наперед,
                        // и обрежем его, оставив только то количество элементов, которое необходимо показать
                        $last_items = array_slice(array_reverse($last_items), 0, $count_last_visited_items);

                        // сформируем строку из id оставшихся в массиве товаров
                        // для передачи ее в фильтр метода ShowShop()
                        $last_items_string = implode(',', $last_items);

                        // сформируем фрагмент XML, для описания порядка следования элементов в массиве истории посещения
                        $visit_order_xml = '<visit_order>' . "\n";
                        foreach ($last_items as $item_id) {
                            $visit_order_xml .= '<last_item>' . $item_id . '</last_item>' . "\n";
                        }
                        $visit_order_xml .= '</visit_order>' . "\n";

                        // и передадим его в метод ShowShop()
                        $param['external_xml'] = $visit_order_xml;

                    }

                    // создадим фильтр по основному свойству id товара.
                    // с помощью этого фильтра мы укажем методу ShowShop()?
                    // какие товары мы хотим вывести
                    // начало фильтра
                    $element = array();
                    $element['type'] = 0;
                    $element['prefix'] = ' and ';
                    $element['name'] = 'shop_items_catalog_table.shop_items_catalog_item_id';
                    $element['if'] = '';
                    $element['value'] = '';
                    $element['sufix'] = " IN ({$last_items_string})";
                    $param['select'][] = $element;
                    // конец фильтра


                    // мы можем ввести еще дополнительное ограничение -
                    // покажем только те, что есть в наличии.
                    //
                    // учтите, что в случае показа товаров в хронологическом порядке,
                    // если среди них будут такие, которых нет в наличии,
                    // то на экран выведется товаров меньше, чем задано в переменной $count_last_visited_items
                    // т.е. при показе товаров в хронологическом порядке фильтрация по наличию происходит уже после того,
                    // как мы отфильровали нужное кол-во товаров к показу!
                    //
                    // если над показывать все товары, закомментируйте этот блок
                    // начало фильтра
                    $element = array();
                    $element['type'] = '0';
                    $element['prefix'] = ' and (';
                    $element['name'] = 'shop_items_catalog_rest';
                    $element['if'] = '> 0 ';
                    $element['value'] = '';
                    $element['sufix'] = ')';
                    $param['select'][] = $element;
                    // конец фильтра

                    // вывод будет происходить из всех групп
                    $param['current_group_id'] = false;
                    // начиная с нулевого элемента
                    $param['items_begin'] = 0;
                    // будет выводить столько элементов, сколько нам нужно
                    $param['items_on_page'] = $count_last_visited_items;

                    // оптиимзируем работу метода ShowShop() отключив генерацию в XML лишней для нас информации
                    // если в XSL-шаблоне вам не хватает какой-то информации - закомментируйте соотв. строки
                    $param['xml_show_all_producers'] = false;
                    $param['xml_show_producers'] = false;
                    $param['xml_show_all_sellers'] = false;
                    $param['xml_show_tying_products'] = false;
                    $param['xml_show_modification'] = true;
                    $param['xml_show_group_property'] = false;
                    $param['xml_show_group_property_id'] = false;
                    $param['xml_show_item_property'] = false;
                    $param['xml_show_tags'] = false;
                    $param['xml_show_items_property_dir'] = false;
                    $param['xml_show_group_type'] = 'none';
                    $param['show_text'] = false;
                    $param['xml_show_items_property_dir'] = false;

                    $xsl_last_items = 'МагазинКаталогТоваровПоследниеПросмотренные';

                    // ну и выведем блок с последними просмотренными товарами
                    $shop->ShowShop($current_shop_id, $xsl_last_items, $param);
                }
            }
        }
        // Показ последних просмотренных товаров - End;


В репозитории, в файле lib.php приведен полный код ТДС Интернет-магазин, основанный на версии HostCMS 5.9.32 и включающий приведенный выше код анализатора.

Создание xsl-шаблона для отображения последних просмотренных товаров.

Xsl-шаблон для отображения последних просмотренных товаров основан на xsl-шаблоне "МагазинКаталогТоваровНаГлавнойСпецПред". Отличия заключаются в создании ключа по идентификаторам товара и переработке корневого темплейта. Изменения в коде приведены далее:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE xsl:stylesheet>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:output xmlns="http://www.w3.org/TR/xhtml1/strict" doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN" encoding="utf-8" indent="yes" method="html" omit-xml-declaration="no" version="1.0" media-type="text/xml"/>

        <!-- МагазинКаталогТоваровПоследниеПросмотренные, основан на шаблоне МагазинКаталогТоваровНаГлавнойСпецПред -->

        <!--Создадим ключ по идентификатору товара, чтобы оптимизировать выборку товаров при показе из в обратном хронологическом порядке-->
        <xsl:key name="items_id" match="/shop/item" use="@id"/>

        <!-- Шаблон для магазина -->
        <xsl:template match="/shop">

                <!-- Если есть товары -->
                <xsl:if test="item">

                        <h2>Последние просмотренные товары</h2>
                        

                        <xsl:choose>

                                <!--Если в XML существуют узлы, описывающие порядок показа товаров-->
                                <xsl:when test="visit_order/last_item/node()">

                                        <!--то запустим цикл по этим узлам-->
                                        <xsl:for-each select="visit_order/last_item">

                                                <!--и для каждого id товара будем вызывать темплейт item, передавая в него узел соответствующего товара, выбранный с помощью ключа-->
                                                <xsl:apply-templates select="key('items_id', .)"/>

                                        </xsl:for-each>

                                </xsl:when>

                                <!--а в случае рандомного показа просто вызовем темплейт item для всех товаров описанных в XML-->
                                <xsl:otherwise>
                                        <xsl:apply-templates select="item"/>
                                </xsl:otherwise>

                        </xsl:choose>

                </xsl:if>

        </xsl:template>

        <!-- Шаблон для товара -->
        <xsl:template match="item">

        <!-- Далее код идет без изменений -->

Полный код xsl-шаблона приведен в файле xsl-template.xsl, пример xml, генерируемого для обратно-хронологического пордяка показа приведен в файле sample.xml

Репозиторий для данного решения находится здесь https://bitbucket.org/JamesKotov/last-viewed-shop-items-for-hostcmsv5/ оттуда можно скачать все решение в виде архива, или посмотреть код каждого конкретного файла. Все обновления и изменения в коде будут выкладываться туда.

Желаю удачи
Заказов не беру. Консультирую редко.
#
Re: Недавно просмотренные товары.
уважаемый Kotoff, огромное спасибо за труды. обязательно воспользуюсь вашим решением. Пока думаю как это визуально отобразить на сайте))
#
Re: Недавно просмотренные товары.
xshock, всегда пожалуйста
Заказов не беру. Консультирую редко.
#
Re: Недавно просмотренные товары.
В коде коллектора исправлена опечатка - вместо
        // если кука с историей посещений товаров еще не существует
        if (!isset($_COOKIE['SHOP_LAST_ITEMS'])) {

            // то запишем id товара в массив
            $last_items(array($cookie_last_item));

        } else {
следует писать
        // если кука с историей посещений товаров еще не существует
        if (!isset($_COOKIE['SHOP_LAST_ITEMS'])) {

            // то запишем id товара в массив
            $last_items = array($cookie_last_item);

        } else {


Код в репозитории обновлен.
Заказов не беру. Консультирую редко.
#
Re: Недавно просмотренные товары.
И еще одна ошибка найдена и исправлена - в кодах коллектора и анализатора в строках проверки существования элемента в массиве по его значению вместо
if ($key) {
следует писать более строгое условие
if ($key !== false) {


Код в репозитории обновлен.
Заказов не беру. Консультирую редко.
#
Re: Недавно просмотренные товары.
Kotoff писал(а):
Код анализатора может быть установлен в любое место макета или шаблона страницы

в данном случае $current_shop_id - нужно заменить на код магазина
#
Re: Недавно просмотренные товары.
kvasiliy, ну это само собой.
Заказов не беру. Консультирую редко.
#
Re: Недавно просмотренные товары.
Еще я делал запись в БД для зарегистрированных пользователей. чтобы было возможно с других браузеров просматривать. или как оно обычно бывает дома смотрел, а на работе найти не можешь) а так всегда под рукой) и еще можно ограничивать количество товаров хранимое в куках так как их может быть оч-много. например делал по 10 а 11 заменял 1-й.....
Программист - это тот, чей код работает не только правильно, но и быстро!
Авторизация