Задача: иметь возможность фильтровать товар в каталоге по 2м измерениям, оба измерения - часть наименования (мл, г)
Реализация:
>catalog/model/catalog/product.php
код до замены и после, вставки отмечены красным:
public function getProductsByCategoryId($category_id, $sort = 'p.sort_order', $order = 'ASC', $start = 0, $limit = 20, $filter = '') {
//filter in the end of next string
$sql = "SELECT *, pd.name AS name, p.image, m.name AS manufacturer, ss.name AS stock, (SELECT AVG(r.rating) FROM " . DB_PREFIX . "review r WHERE p.product_id = r.product_id GROUP BY r.product_id) AS rating FROM " . DB_PREFIX . "product p LEFT JOIN " . DB_PREFIX . "product_description pd ON (p.product_id = pd.product_id) LEFT JOIN " . DB_PREFIX . "product_to_store p2s ON (p.product_id = p2s.product_id) LEFT JOIN " . DB_PREFIX . "manufacturer m ON (p.manufacturer_id = m.manufacturer_id) LEFT JOIN " . DB_PREFIX . "stock_status ss ON (p.stock_status_id = ss.stock_status_id) LEFT JOIN " . DB_PREFIX . "product_to_category p2c ON (p.product_id = p2c.product_id) WHERE p.status = '1' AND p.date_available <= NOW() AND pd.language_id = '" . (int)$this->config->get('config_language_id') . "' AND p2s.store_id = '" . (int)$this->config->get('config_store_id') . "' AND ss.language_id = '" . (int)$this->config->get('config_language_id') . "' AND p2c.category_id = '" . (int)$category_id . "'".$filter;
>catalog/controller/product/category.php
код до замены и после, вставки отмечены красным:
$this->data['products'] = array();
//FILTER
$filter ='';
//
$this->data['filter1'] = ( isset($this->request->get['filter1']) ? $this->request->get['filter1'] : '');
$this->data['filter2'] = ( isset($this->request->get['filter2']) ? $this->request->get['filter2'] : '');
$this->data['filter3'] = ( isset($this->request->get['filter3']) ? $this->request->get['filter3'] : '');
if ($this->data['filter1']){ $filter .= " AND pd.name LIKE '%".$this->data['filter1']."%'"; }
if ($this->data['filter2']){ $filter .= " AND pd.name LIKE '%".$this->data['filter2']."%'"; }
if ($this->data['filter3']){ $filter .= " AND pd.name LIKE '%".$this->data['filter3']."%'"; }
//
$product_total = sizeof($this->model_catalog_product->getProductsByCategoryId($category_id, $sort, $order, 0, 99999, $filter));
//END OF FILTER
$results = $this->model_catalog_product->getProductsByCategoryId($category_id, $sort, $order, ($page - 1) * $this->config->get('config_catalog_limit'), $this->config->get('config_catalog_limit'),$filter);
и чуть ниже
//FILTER URL OPTIONS --------
$url .= '&filter1='.$this->data['filter1'].'&filter2='.$this->data['filter2'].'&filter3='.$this->data['filter3'];
//---------------------------
$pagination = new Pagination();
$pagination->total = $product_total;
$pagination->page = $page;
$pagination->limit = $this->config->get('config_catalog_limit');
$pagination->text = $this->language->get('text_pagination');
$pagination->url = $this->model_tool_seo_url->rewrite(HTTP_SERVER . 'index.php?route=product/category&path=' . $this->request->get['path'] . $url . '&page={page}');
//FILTER URL OPTIONS --------------------
$this->data['filter_url'] = $this->model_tool_seo_url->rewrite(HTTP_SERVER . 'index.php?route=product/category&path=' . $this->request->get['path'] . $url);
$this->data['category_id'] = $category_id;
//---------------------------------------
$this->data['pagination'] = $pagination->render();
ну и наконец шаблон
>catalog/view/theme/имя.темы/template/product/catalog.tpl
вставляется в тело <div class="sort"> ... </div> перед списком сортировки
<?php
$filters = array();
// перечисление каталогов, для кого применяется фильтр и собственно структура фильтров
// обратите внимание, что одинаковые каталоги не должны входить в разные наборы фильтров,
// т.е. $filters[',1,2,'] вместе с $filters[',1,3,'] - для категории 1 выведет 2хКол-во определенных
// фильтров, т.е. задублируются, что приведет к ошибке
$filters[',1,39,40,41,42,43,'] = array (
'filter1' => array ('Name' => 'Параметр 1 ', 'Options' => array ('', 'Значение 1','Значение 2') ),
'filter2' => array ('Name' => 'Параметр 2 ', 'Options' => array ('', 'Значение 1','Значение 2','Значение 3','Значение 4') ),
'filter3' => array ('Name' => '', 'Options' => array () ) );
foreach ($filters as $key => $value){
if (!(strpos($key,','.$category_id.',') === false) ) { ?>
<?php if( $value['filter1']['Name'] ){ ?>
<div class="filter_option">
<span><?php echo $value['filter1']['Name']; ?></span>
<select name="filter1" onchange="location = this.value">
<?php foreach ( $value['filter1']['Options'] as $filter) { ?>
<?php $option = preg_replace('/filter1=[^&]*&/','filter1='.$filter.'&',$filter_url); ?>
<?php if ($filter1 == $filter) { ?>
<option value="<?php echo $option; ?>" selected="selected"><?php echo $filter; ?></option>
<?php } else { ?>
<option value="<?php echo $option; ?>"><?php echo $filter; ?></option>
<?php } ?>
<?php } ?>
</select>
</div>
<?php } ?>
<?php if( $value['filter2']['Name'] ){ ?>
<div class="filter_option">
<span><?php echo 'Содержание никотина '; ?></span>
<select name="filter2" onchange="location = this.value">
<?php foreach ( $value['filter2']['Options'] as $filter) { ?>
<?php $option = preg_replace('/filter2=[^&]*&/','filter2='.$filter.'&',$filter_url); ?>
<?php if ($filter2 == $filter) { ?>
<option value="<?php echo $option; ?>" selected="selected"><?php echo $filter; ?></option>
<?php } else { ?>
<option value="<?php echo $option; ?>"><?php echo $filter; ?></option>
<?php } ?>
<?php } ?>
</select>
</div>
<?php } ?>
<?php if( $value['filter3']['Name'] ){ ?>
<div class="filter_option">
<span><?php echo 'Содержание никотина '; ?></span>
<select name="filter3" onchange="location = this.value">
<?php foreach ( $value['filter3']['Options'] as $filter) { ?>
<?php $option = preg_replace('/filter3=[^&]*&/','filter3='.$filter.'&',$filter_url); ?>
<?php if ($filter3 == $filter) { ?>
<option value="<?php echo $option; ?>" selected="selected"><?php echo $filter; ?></option>
<?php } else { ?>
<option value="<?php echo $option; ?>"><?php echo $filter; ?></option>
<?php } ?>
<?php } ?>
</select>
</div>
<?php } ?>
<?php break; } ?>
<?php } ?>
</div>
и немного CSS:
.filter_option { float: left; margin-top: 7px; margin-left: 20px; }
Сильно не бейте, в php я почти ноль - мог что и пропустить.
Все три фильтра используются для фильтрации по наименованию.
В контроллере можно отредактировать на практически любые поля - просто немного изучить sql запрос под кодом фильтра
В шаблоне можно создать структуру фильтров для любых категорий.
Надеюсь кому нибудь пригодится :)) Кстати работает на 1.4.9 - на ней собственно и сижу.
*Updated! Исправлен баг: при изменении параметра номер страницы оставался.
*Updated! Исправлены ошибки данного поста.