Хиты продаж для UMI.CMS

xity-prodazh-dlya-umi-cms
К большому сожалению, у UMI.CMS отсутствует огромное количество функционала, как на популярный бесплатных CMS, но ничего, будет это исправлять.

В этой статье я коснусь достаточно интересной функции, а именно — хиты продаж.

Данный функционал будет вам полезен в качестве привлечение пользователя к продаваемым товарам. У них всегда на глазах будет те товары, которые являются наиболее покупаемыми у вас в интернет магазине.

Обновления товаров будет происходит каждый раз, когда пользователи совершают покупку в вашем интернет-магазине, или в интернет-магазине вашего заказчика.

Приступим к реализации. Она будет разбита на 3 части:

1. Добавление поля в шаблон данных;
2. Добавление события, для обработки свешенного заказа и обновление кол-ва покупок.
3. Добавление функции, которая обрабатывает купленные товары
4. Показ товаров на сайте.

1. Добавление шаблона данных.

Для этого нужно зайти в модуль «Шаблон данных» и выбывать из списка «объект каталога». Далее добавить в него новое поле:

Количество продаж, видимое, qty_of_sell, число

xity-prodazh-dlya-umi-cms-2014-02-22_2327

2. Добавление события, для обработки свешенного заказа и обновление кол-ва покупок

В папке с вашим шаблоном создаете следующую иерархию из папок — classes\modules\emarket\. Далее нужно добавить три файла - class.php, events.php, permissions.php.

В файла events.php следует добавить:

<?php
new umiEventListener('order-status-changed', 'emarket', 'setQtyOfSell');
?>

В файла permissions.php следует добавить:

<?php
$permissions = array(
    'purchasing' => array(
        'setQtyOfSell'
    )
);
?>

В файла class.php следует добавить:

<?php
class emarket_custom extends def_module {
    /*
        Устанавливаем количество покупок одной единицы товара
    */
    public function setQtyOfSell(iUmiEventPoint $event){
        //получаем режим работы обработчика
        $mode = $event->getMode();
        //если режим 'после'
        if ($mode == 'after'){
            //получаем ссылку на значение из контекста вызова события (в нашем случае это объект "Заказ")
            $order = $event->getRef('order');

            $order_items = $order->getItems();
            foreach($order_items as $order_item) {
                $el = $order_item->getItemElement();

                if ($order_item->getAmount()) $ia = $order_item->getAmount();
                else $ia = 0;

                if ($el->getValue('qty_of_sell')) $sc = $el->getValue('qty_of_sell');
                else $sc = 0;

                $el->setValue('qty_of_sell', $sc+$ia);
                $el->commit();
            }
        }
    }
}
?>

Теперь, каждый раз, когда пользователь совершает заказ в вашем интернет-магазине, системы ловит событие и в поле qty_of_sell обновляет информацию о том, какое кол-во раз был куплен товар.

3. Показ товаров на сайте.

Для того, чтобы продемонстрировать вашему пользователю самый хитовый товар нужно добавить функцию, которая делает выборку из БД, а далее вывести этот товар используя XSLT-шаблонизатор.

Данный пример рассматривает только XSLT-шаблонизатор. С TPL-шаблонизатором я более не работаю и вам не советую.
Также мною используется стандартный шаблон demodizzy для реализации примеров.

Для того, чтобы сделать выборку хитов продаж в вашем интернет магазине UMI.CMS, в папке вашего шаблона создаете следующую иерархию — classes\modules\catalog\. Далее нужно добавить два файла файла - class.php, permissions.php.
В файла permissions.php следует добавить:

<?php
    $permissions = Array(      
        'view' => 
                 Array(
                     'getBestSellers'
                 )
    );    
?>

В файла class.php добавить:

<?php
class catalog_custom extends catalog {
    /*
     * getBestSellers - функция для получения хитов продаж
     *
     * @limit - количество объектов для показа
     * @field - поле по которому следует сортировать объекты title | price | qty_of_sell
     * @order - порядок сортировки desc | asc | rand
     * @template - не участвует, так как используется xslt шаблоназатор
     */
    public function getBestSellers($limit = 100, $field = false, $order = false, $template = 'default') {
        /* Формирована для TPL-шаблоназитора*/
        if(!$template) $template = "default"; // Имя шаблона по умолчанию
        $template_line = 'objects_list'; // Имя секции для шаблона TPL
        list($theme) = def_module::loadTemplates('catalog/' . $template, 'elements'); // Загрузка в шаблон

        $pages = new selector('pages');

        $pages->types('hierarchy-type')->name('catalog', 'object');

        $pages->option('exclude-nested', true);

        /* Устанавливаются значения поиска */
        $pages->where('qty_of_sell')->more('1');

        if ($field) {
            if($order == 'desc')
                $pages->order($field)->desc();
            elseif ($order == 'asc')
                $pages->order($field)->asc();
            elseif ($order == 'rand')
                $pages->order($field)->rand();
        }

        if(!$field && $order) {
            if($order == 'desc')
                $pages->order('id')->desc();
            elseif ($order == 'asc')
                $pages->order('id')->asc();
            elseif ($order == 'rand')
                $pages->order('id')->rand();
        }

        $lines = Array();
        $total = 0; foreach($pages as $page) {$total ++;}

        $lim = 0;
        foreach($pages as $page) {
            if ($limit == $lim) break;

            $element = umiHierarchy::getInstance()->getElement($page->id);

            $line_arr = Array();
            $line_arr['attribute:id'] = $page->id;
            $line_arr['attribute:link'] = $page->link;
            $line_arr['xlink:href'] = "upage://" . $page->id;

            $line_arr['h1'] = $element->getValue('h1');
            $line_arr['qty_of_sell'] = $element->getValue('qty_of_sell');
            $line_arr['name'] = $page->name;

            $price = $element->getValue('price');
            $line_arr['price'] = number_format($price, 0, '.', ' ');

            $line_arr['photo'] = $element->getValue('photo');

            $lines[] = self::parseTemplate($template_line, $line_arr, $page->id);
            $lim ++;

            umiHierarchy::getInstance()->unloadElement($page->id);
        }

        $block_arr = array();

        if ($total != 0) {
            $block_arr['subnodes:items'] = $lines;
            $block_arr['total'] = $total;
        } else {
            $block_arr['subnodes:items'] = "Нет объектов, которые бы совпадали с указанными параметрами";
            $block_arr['total'] = $total;
        }
        // Возвращаем значение
        return def_module::parseTemplate($theme, $block_arr);
    }
}
?>

Функция getBestSellers принимает параметры:

  • @limit — количество объектов для показа
  • @field — поле по которому следует сортировать объекты title | price | qty_of_sell
  • @order — порядок сортировки desc | asc | rand
  • @template — не участвует, так как используется xslt шаблоназатор

Теперь вам нужно определиться с блоком на сайте, в котором следует выводить ваши бестселлеры. Определились? Отлично. Я буду выводить в правой колонке своего интернет магазина и будет это выглядеть примерно следующим образом:
xity-prodazh-dlya-umi-cms-2014-02-23_1008_001

Добавляем вывод.
В том месте, где должны выводиться хиты добавляете:

<xsl:apply-templates select="document('udata://catalog/getBestSellers/3//rand')/udata" mode="getBestSellers" />

Далее в любое место шаблона, перед /xsl:stylesheet добавляете

<xsl:template match="udata[@method = 'getBestSellers']" mode="getBestSellers">
    <!-- Если у есть хиты, то они будет на сайте. Если нет, блок не будет виден -->
    <xsl:choose>
        <xsl:when test="count(items/item) > 0">
            <div class="infoblock">
                <div class="title">
                    <h2>Хиты продаж!</h2>
                </div>
                <div class="body">
                    <div class="in">
                        <xsl:apply-templates select="items/item" mode="getBestSellers_item" />
                    </div>
                </div>
            </div>
        </xsl:when>
    </xsl:choose>
</xsl:template>

Далее, ниже добавляете сам шаблон формирования отображения:

<xsl:template match="item" mode="getBestSellers_item">
    <div umi:element-id="37" umi:region="list" umi:sortable="none" umi:module="news" umi:method="lastlist" umi:button-position="top right">
        <div class="news_item" umi:element-id="{@id}" umi:region="row">
            <a href="{@link}" title="{h1}" class="title" umi:field-name="name" umi:delete="delete" umi:empty="Название страницы">
                <xsl:value-of select="h1" />
            </a>
            <div class="descr">
                <xsl:call-template name="catalog-thumbnail">
                    <xsl:with-param name="element-id" select="@id" />
                    <xsl:with-param name="field-name">photo</xsl:with-param>
                    <xsl:with-param name="width">100</xsl:with-param>
                    <xsl:with-param name="height">auto</xsl:with-param>
                    <xsl:with-param name="empty">&empty-photo;</xsl:with-param>
                </xsl:call-template>
            </div>
        </div>
    </div>
</xsl:template>

Хиты продаж для UMI.CMS готовы. Теперь ваши пользователи будет видеть товары, которые являются самыми продаваемыми.
Как вы могли заметить у вас есть возможность самостоятельно управлять вашими бестселлерами, для этого в объекте каталога просто отредактируйте поле «Количество продаж».

P.S. Если вы знакомились со статьей Оптимизация изображений в UMI.CMS, то вы можете вывести оптимизированные изображения. Для этого, просто замените вот этот участок кода:

<xsl:call-template name="catalog-thumbnail">
    <xsl:with-param name="element-id" select="@id" />
    <xsl:with-param name="field-name">photo</xsl:with-param>
    <xsl:with-param name="width">100</xsl:with-param>
    <xsl:with-param name="height">auto</xsl:with-param>
    <xsl:with-param name="empty">&empty-photo;</xsl:with-param>
</xsl:call-template>

на данный участок кода:

<xsl:call-template name="makeSubDomainImage">
    <xsl:with-param name="subdomain">img</xsl:with-param>
    <xsl:with-param name="element_id" select="@id" />
    <xsl:with-param name="field_name">photo</xsl:with-param>
    <xsl:with-param name="width">100</xsl:with-param>
    <xsl:with-param name="height">auto</xsl:with-param>
    <xsl:with-param name="alt" select="name" />
    <xsl:with-param name="class">image</xsl:with-param>
    <xsl:with-param name="link" select="@link" />
    <!--<xsl:with-param name="empty">&empty-photo;</xsl:with-param>-->
</xsl:call-template>

Надеюсь, что данный материал поможет вам.
Ну и последнее, если вам лень читать, то вы можете скачать готовый вариант