Делюсь решением, может кому-нибудь пригодится. Делал для магазина we-pool.ru.
Решение основано на модификации старой версии шаблона Electronics, для новой надо менять пути и имена файлов модулей.
Могу сделать и вам, не бесплатно конечно. Обращайтесь в скайп cravciucandy.
Задача: В правой колонке есть сквозной блок "Специальные предложения" с jQuery ротацией товаров. Туда нужно вывести 25 акционных товаров и 25 хитов продаж, перемешав случайным образом этот объединенный список.
Проблема: В стандартной Impera CMS списки акционных товаров и хитов продаж доступны только на главной и страницах категорий. Следовательно в хелпер шаблона - файл шаблон/html/emulator.php - надо добавить свои функции чтения акционных и хитов - actionProducts и hitProducts, а также зарегистрировать их в хелпере шаблона.
Я сделал двойной копипаст готовой функции из стандартного хелпера, назвав дубли нужными именами и сменив один параметр в каждом копипасте. Вот что получилось:
<?php
class TemplateEmulator {
...
...
// ===================================================================
/**
* Подключение наших функций и модификаторов в шаблонизатор Smarty
*
* -------------------------------------------------------------------
*
* @access protected
* @param object $cms объект движка
* @return void
*/
// ===================================================================
protected function setSmartyPlugins ( & $cms ) {
...
...
// регистрируем свои функции
$cms->smarty->registerPlugin('function', 'actionProducts', array($this, 'actionProducts'));
$cms->smarty->registerPlugin('function', 'hitProducts', array($this, 'hitProducts'));
}
// ===================================================================
/**
* Обработчик шаблонизационной функции actionProducts
*
* -------------------------------------------------------------------
*
* @access public
* @param array $params массив параметров, указанных в вызове:
* ['var'] = в какую переменную возвратить результат
* ['count'] = число записей на странице (по умолчанию 12)
* ['page'] = номер текущей страницы (по умолчанию 1)
* @param object $smarty объект шаблонизатора Smarty
* @return string всегда пустая строка
*/
// ===================================================================
public function actionProducts ( $params = null, & $smarty = null ) {
// проверяем наличие обязательного параметра
$field = 'var';
if (isset($params[$field]) && is_string($params[$field]) && $params[$field] != '') {
// опциональные праметры
$count = 'count';
$count = isset($params[$count]) ? max(1, @ intval($params[$count])) : 12;
$page = 'page';
$page = isset($params[$page]) ? max(1, @ intval($params[$page])) : 1;
// текущий пользователь, если есть
$user = null;
if (isset($this->cms->user)) $user = & $this->cms->user;
// настраиваем фильтр записей
$filter = new stdClass;
// только акционные
$filter->type = TYPE_PRODUCTS_ACTIONAL;
// только разрешенные к показу
$filter->enabled = 1;
// если это обычный посетитель, тогда только не скрытые от неавторизованных
if (!isset($user->user_id)) $filter->hidden = 0;
// упорядочить список по убыванию веса "как расставлены"
$filter->sort_direction = SORT_DIRECTION_DESCENDING;
// процент скидки пользователя и его ценовая группа
$filter->discount = isset($user->discount) ? $user->discount : 0;
$filter->price_id = isset($user->price_id) ? $user->price_id : 0;
// интересует список начиная с такой позиции и столько записей
$filter->start = ($page - 1) * $count;
$filter->maxcount = $count;
// читаем список товаров
$items = array();
$this->cms->db->products->get($items, $filter);
$this->cms->db->products->unpack_records($items, $filter);
// передаем в указанную переменную
if (!is_object($smarty)) return $items;
$smarty->assignByRef($params[$field], $items);
}
return '';
}
// ===================================================================
/**
* Обработчик шаблонизационной функции hitProducts
*
* -------------------------------------------------------------------
*
* @access public
* @param array $params массив параметров, указанных в вызове:
* ['var'] = в какую переменную возвратить результат
* ['count'] = число записей на странице (по умолчанию 12)
* ['page'] = номер текущей страницы (по умолчанию 1)
* @param object $smarty объект шаблонизатора Smarty
* @return string всегда пустая строка
*/
// ===================================================================
public function hitProducts ( $params = null, & $smarty = null ) {
// проверяем наличие обязательного параметра
$field = 'var';
if (isset($params[$field]) && is_string($params[$field]) && $params[$field] != '') {
// опциональные праметры
$count = 'count';
$count = isset($params[$count]) ? max(1, @ intval($params[$count])) : 12;
$page = 'page';
$page = isset($params[$page]) ? max(1, @ intval($params[$page])) : 1;
// текущий пользователь, если есть
$user = null;
if (isset($this->cms->user)) $user = & $this->cms->user;
// настраиваем фильтр записей
$filter = new stdClass;
// только хиты продаж
$filter->type = TYPE_PRODUCTS_HIT;
// только разрешенные к показу
$filter->enabled = 1;
// если это обычный посетитель, тогда только не скрытые от неавторизованных
if (!isset($user->user_id)) $filter->hidden = 0;
// упорядочить список по убыванию веса "как расставлены"
$filter->sort_direction = SORT_DIRECTION_DESCENDING;
// процент скидки пользователя и его ценовая группа
$filter->discount = isset($user->discount) ? $user->discount : 0;
$filter->price_id = isset($user->price_id) ? $user->price_id : 0;
// интересует список начиная с такой позиции и столько записей
$filter->start = ($page - 1) * $count;
$filter->maxcount = $count;
// читаем список товаров
$items = array();
$this->cms->db->products->get($items, $filter);
$this->cms->db->products->unpack_records($items, $filter);
// передаем в указанную переменную
if (!is_object($smarty)) return $items;
$smarty->assignByRef($params[$field], $items);
}
return '';
}
...
...
}
?>
От разработчика: Идеальным решением было бы создать один копипаст, назвав эту функцию например featuredProducts, а параметр type задавать из шаблона при вызове функции, что позволило бы использовать всего лишь одну функцию для чтения новинок, хитов, акционных, обсуждаемых, ожидаемых товаров и так далее. Для задания типа читаемых записей в этом случае можно было бы использовать следующие константы:
TYPE_PRODUCTS_ORDERED - недавно покупавшиеся товары
TYPE_PRODUCTS_COMMENTED - недавно обсуждавшиеся товары
TYPE_PRODUCTS_HIT - хиты продаж (у которых включен такой флажок)
TYPE_PRODUCTS_NEWEST - новинки (у которых включен такой флажок)
TYPE_PRODUCTS_NEWEST_MIXED - новинки вперемешку с недавно добавленными
TYPE_PRODUCTS_ACTIONAL - акционные (у которых включен такой флажок или такая цена)
TYPE_PRODUCTS_DISCOUNTED - товары со скидками (без учета флажка "акционный")
TYPE_PRODUCTS_AWAITED - товары, скоро ожидаемые в продаже (у которых такой флажок)
TYPE_PRODUCTS_NONUSABLE - товары не для продажи (экспонаты)
TYPE_PRODUCTS_DOMAINED - товары, размещенные на своем субдомене
TYPE_PRODUCTS_TEMPLATED - товары, изображаемые своим шаблоном (landing page)
TYPE_PRODUCTS_CANONIZED - с канонизацией главного (разновидности главного товара)
тогда в шаблоне эта единая функция вызывалась бы следующим образом, допустим в переменную $result хотим прочесть 15 хитов продаж со 2 страницы этого воображаемого списка
{featuredProducts var=result count=15 type=$smarty.const.TYPE_PRODUCTS_HIT page=2}
Теперь надо дополнить модуль вывода "Специальные предложения" чтением акционных и хитов и смешиванием их в одном списке. В старой версии Electronics модуль находится в файле шаблон/html/right/featured.htm. Я дополнил модуль так:
{* <!-- правая колонка: товары (акционные) --> *}{strip} {* <!-- читаем 25 акционных товаров в переменную $actions --> *} {actionProducts var=actions count=25} {* <!-- сносим акционные в переменную $items --> *} {$items = []} {$maxcount = 50} {$i = 0} {if !empty($actions)} {foreach $actions as $tovar} {$items[$i] = $tovar} {$i = $i + 1} {if $i >= $maxcount} {break} {/if} {/foreach} {/if} {* <!-- читаем 25 хитов продаж в переменную $actions --> *} {if $i < $maxcount} {hitProducts var=actions count=25} {* <!-- подмешиваем хиты продаж в объединенный список --> *} {if !empty($actions)} {foreach $actions as $tovar} {$items[$i] = $tovar} {$i = $i + 1} {if $i >= $maxcount} {break} {/if} {/foreach} {/if} {/if} {* <!-- перемешиваем объединенный список товаров случайным образом --> *} {(shuffle($items)) ? '' : ''} {* <!-- выводим --> *} {include file = 'center/featured.htm' items = $items maxcount = $maxcount title_link = '' title = 'Специальное предложение' with_scroller = true} {/strip}
Вот и все.