Переделывание поиска в VirtueMart. Добавление фильтрации по цене и производителю.
25.08.2012
Нужно было для магазина, поднятого на VirtueMart 1.1.6, сделать фильтр по цене, производителю и паре дополнительных полей.
Код модуля приводить не буду, это просто форма с несколькими чекбоксами и полями для цен.
Сосредоточимся на том , как обработать переданные параметры и сформировать запрос.
Формирование запроса происходит в файле:
/administrator/components/com_virtuemart/html/shop_browse_queries.php
Просмотрев файл, решил, что удобнее будет не дополнять уже готовые условия, а написать отдельную ветку, которая будет отрабатываться только для нового модуля.
Собственно код:
1 |
mm_showMyFileName( __FILE__ ); // Descending or Ascending Order? possible values: [ASC|DESC] $DescOrderBy = strtoupper($vm_mainframe->getUserStateFromRequest( "browse{$keyword}{$category_id}{$manufacturer_id}DescOrderBy", 'DescOrderBy', "DESC" )); $DescOrderBy = $DescOrderBy == 'ASC' ? 'ASC' : 'DESC'; //Проверяем, пришли ли данные из модуля $shop_filter = JRequest::getVar('shop_filter', 0); if ($shop_filter) { $VM_BROWSE_ORDERBY_FIELDS = array(); // Отключение списка "Сортировать по" $fieldnames = "`real_{vm}_product`.`product_id`, `product_name`, `product_full_image`, `product_thumb_image`, `product_s_desc`, `product_parent_id`, `product_publish`, `product_in_stock`, `product_sku`, `product_url`, `product_weight`, `product_weight_uom`, `product_length`, `product_width`, `product_height`, `product_lwh_uom`, `product_available_date`, `product_availability`, `availability`, `real_{vm}_product`.`mdate`, `real_{vm}_product`.`cdate`"; $count_name = "COUNT(DISTINCT `real_{vm}_product`.`product_sku`) as num_rows"; $table_names = '`real_{vm}_product`'; $join_array = array(); $where_clause = array(); $where_clause[] = 'product_publish = "Y"'; $orderbyField = '`real_{vm}_product`.`product_sku`'; $sf_price1 = JRequest::getVar('sf_price1', 0); $sf_price2 = JRequest::getVar('sf_price2', 0); if ($sf_price2) { $join_array[] = 'LEFT JOIN `real_{vm}_product_price` ON `real_{vm}_product`.`product_id` = `real_{vm}_product_price`.`product_id`'; $where_clause[] = '`real_{vm}_product_price`.`product_price` BETWEEN '.$sf_price1.' AND '.$sf_price2.''; } // Производитель $aProduce = JRequest::getVar('sf_produce', array()); if(count($aProduce)) { $table_names .= ',`real_{vm}_product_mf_xref`'; $where_clause[] = "`real_{vm}_product`.`product_id`=`real_{vm}_product_mf_xref`.`product_id` "; $aTmp = ''; foreach($aProduce as $sf_produce) { switch ($sf_produce) { case '1': // HF $aTmp[] = '`real_{vm}_product_mf_xref`.manufacturer_id=4'; break; case '2': // AEL $aTmp[] = '`real_{vm}_product_mf_xref`.manufacturer_id=3'; break; case '3': // Ecotronic $aTmp[] = '`real_{vm}_product_mf_xref`.manufacturer_id=5'; break; } } $where_clause[] = ' (' . implode(' OR ', $aTmp) . ')'; } // Тип: $aParam = JRequest::getVar('sf_type', array()); if(count($aParam)) { $bWith_lower_load = False; $aTmp = array(); foreach($aParam as $sParam) { if ( $sParam == 3) { $bWith_lower_load = True; } else { $aTmp[] = 'type='.$sParam; } } if (count($aTmp)) { $where_clause[] = ' (' . implode(' OR ', $aTmp) . ')'; } if ($bWith_lower_load) { $where_clause[] = 'with_lower_load=1'; } } // Охлаждение: $aParam = JRequest::getVar('sf_coolingtype', array()); if(count($aParam)) { $aTmp = ''; foreach($aParam as $sParam) { $aTmp[] = 'coolingtype='.$sParam; } $where_clause[] = ' (' . implode(' OR ', $aTmp) . ')'; } $list = "SELECT DISTINCT $fieldnames FROM ($table_names) "; $count = "SELECT $count_name FROM ($table_names) "; if ($_SERVER['REMOTE_ADDR'] == '83.166.96.95') { echo implode("\n AND ", $where_clause); } $q = implode("\n", $join_array ).' WHERE '. implode("\n AND ", $where_clause ); $count .= $q; // $q .= "\n GROUP BY `real_{vm}_product`.`product_sku` "; $q .= "\n ORDER BY $orderbyField $DescOrderBy"; // Joomla! 1.5 supports listing "All" items, which means $limit == 0 if( vmIsJoomla(1.5) && $limit == 0 ) { $list .= $q; } else { $list .= $q . " LIMIT $limitstart, " . $limit; } if ($_SERVER['REMOTE_ADDR'] == '83.166.96.95') { echo '<br/><br/>'.nl2br(str_replace('real_{vm}', 'jos_vm', $list)); } // Store current GET parameters for usage on the product details page navigation $_SESSION['last_browse_parameters'] = array( 'category_id' => $category_id, 'manufacturer_id' => $manufacturer_id, 'keyword' => $keyword, 'keyword1' => $keyword1, 'keyword2' => $keyword2, 'featured' => $featured, 'discounted' => $discounted ); if( !empty($product_type_id) ) { $_SESSION['last_browse_parameters']['product_type_id'] = $product_type_id; } } else { //Далее идет оригинальный код |
Пара дополнений к задаче:
- Нужно было убрать «сортировать по:»
В приведенном примере уже есть решение этой задачи:
$VM_BROWSE_ORDERBY_FIELDS = array();
- Также убрать постраничное деление
В файле: /administrator/components/com_virtuemart/html/shop.browse.php
Заменяем код
1
2
3
4
5// Prepare Page Navigation require_once( CLASSPATH . 'pageNavigation.class.php' ); $pagenav = new vmPageNav( $num_rows, $limitstart, $limit ); $tpl->set( 'pagenav', $pagenav );
На
1
2
3
4
5
6
7
8
9
10
11
12
13// Prepare Page Navigation // Oddler $shop_filter = JRequest::getVar('shop_filter', 0); if (!$shop_filter) { require_once( CLASSPATH . 'pageNavigation.class.php' ); $pagenav = new vmPageNav( $num_rows, $limitstart, $limit ); $tpl->set( 'pagenav', $pagenav ); } else { $tpl->set( 'pagenav', '' ); }