Делюсь решением, может кому-нибудь пригодится. Делал для магазина 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}
Вот и все.