Облако брендов для SimplaCMS 2.1+

Облако брендов для SimplaCMS 2.1+

Дата публикации:
Поделиться:

Открывает файл api/Brands.php и перед методом get_brand (~37 строка) добавляем наш

public function get_brands_weight($filter = array())
{
    $brands = array();
    $category_id_filter = '';
    if(!empty($filter['category_id']))
      $category_id_filter = $this->db->placehold('LEFT JOIN s_products_categories pc ON p.id = pc.product_id WHERE pc.category_id in(?@)', (array)$filter['category_id']);

    // Выбираем все бренды
    $query = $this->db->placehold("SELECT DISTINCT b.id, b.name, b.url, COUNT(p.id) AS `count`
                     FROM s_brands b LEFT JOIN s_products p ON p.brand_id=b.id $category_id_filter 
                     WHERE p.visible = 1
                     GROUP BY b.id ORDER BY b.name");
    $this->db->query($query);

    return $this->db->results();
}

По сути мы создали копию выборки группы брендов, но уже с учетом весов. Менять базовые методы в данном случае не рекомендую, т.к. не всегда знаешь (я-то знаю :) ) где они вызываются и как работают.

Следующим шагом сделаем копию виджета для вывода "развесованного" списка брендов. Для этого открываем файл view/View.php и добавляем сначала вызов метода - находим вызов

$this->design->smarty->registerPlugin("function", "get_brands", array($this, 'get_brands_plugin'));

И сразу после него добавляем наш расширенный вызов

$this->design->smarty->registerPlugin("function", "get_brands_cloud", array($this, 'get_brands_cloud_plugin'));

Теперь создадим сам метод. В этом же файле перед методом get_browsed_products вставим наш метод

public function get_brands_cloud_plugin($params, &$smarty)
{
    if(!isset($params['visible']))
        $params['visible'] = 1;
    if(!empty($params['var'])) {

        $min = 0; $max = 0;
        $steps = 5; //делаем 5 градаций веса
        
        if(!isset($params['steps']))
            $steps = max($steps, $params['steps']);        
        
        $brands = $this->brands->get_brands_weight($params);
        //вычисляем наибольшее и наименьшее значение
        foreach($brands AS $v) {
            if(!$max || $max < $v->count) $max = $v->count;
            if(!$min || $min > $v->count) $min = $v->count;
        } 
        $range = log($max + 1) - log($min + 1);
        if(!$range) $range = 1;
        //расставляем веса к каждому бренду
        foreach($brands AS $v)
            $v->weigth = round((log($v->count + 1) - log($min + 1)) * $steps / $range);

        $smarty->assign($params['var'], $brands);
    }
}

После обсуждений на форуме и экспериментов - алгоритм поменял на логарифмический. Теперь вес товара колеблется строго между 0 и значением $steps.

Теперь осталось вывести данные в шаблон. Открываем на файл шаблона design/[ваш_шаблон]/html/index.tpl и вместо стандартной конструкции

{get_brands var=all_brands}

вызываем модифицированную нами

{get_brands_cloud var=all_brands}
{if $all_brands}
<div id="all_brands">
    <h2>Все бренды:</h2>
    {foreach $all_brands as $b}	
        <a href="brands/{$b->url}" style="font-size: {math equation="round(12 + 3 * x)" x=$b->weigth}px">{$b->name}</a>
    {/foreach}
</div>
{/if}

А также если надо, то в Вашей переменной $b содержится количество товара по этому бренду, т.е. Вы можете использовать его в виде {$b->count} для вывода на сайте.

В переменной {$b->weigth} будет значение из интервала от 0 до 1 - коэффициент. Следовательно в выводе round(12 + 3 * x) мы получим значение от 12 до 25 при значении шага равным 5.

Вот что у меня получилось

Все файлы можно скачать по ссылке. Следующим шагом будем прикручивать флешевый вариант - веса-то у нас уже есть.

Удачной работы!

P.S. Изменил алгоритм расчета, спасибо помощи сообщества Yii.

Отзывы

Ваш отзыв будет первым
Оставьте отзыв
На него будут приходить уведомление при ответе. На сайте не публикуется