UMIhelp

Разработка дополнительного функционала => Custom макросы => Тема начата: bosya от 05 Марта 2012, 19:19:49

Название: фильтр товаров с условием OR и поиск по нескольким (не всем) разделам каталога
Отправлено: bosya от 05 Марта 2012, 19:19:49
Делаем интернет магазин. Есть расширенный поиск. Нужно иметь возможность
фильтровать объекты каталога следующим образом.

Допустим, поискать объекты из нескольких конкретных разделов. Сейчас можно
найти объекты одного раздела или всех (mode=all). Нужно иметь возможность
найти, скажем, объекты из раздела с id 2 и 3. Это возможно?

Далее. Если используется фильтрация по полям через
fields_filter[название_поля], можно ли искать, используя OR условие? То есть
чтобы запрос ?fields_filter[above_sea]=1&fields_filter[greenhouse]=1 находил
все объекты, для которых флажок above_sea установлен в 1 или флажок greenhouse
установлен в 1?

Кто-нибудь реализовывал подобный функционал? Не могли бы поделиться кастомными методами, если есть? Или навести на путь истинный.
Название: Re:фильтр товаров с условием OR и поиск по нескольким (не всем) разделам каталога
Отправлено: admin от 06 Марта 2012, 08:02:09
насчет первого вопроса, делается выпадающий список(удобнее его делать usel выводом всех подразделов каталога) в шаблоне формы фильтра, вида

<select onchange="changeFormAction(this.value)">
<option />
<option value="/razdel1/">Раздел 1</option>
<option value="/razdel2/">Раздел 2</option>
<option value="/razdel3/">Раздел 3</option>
</select>

и пишем js функцию которая меняет action у формы на адресс инетересующего вас раздела, соответсвенно фильтр будет перекидывать пользователя на этот подраздел и там применять все фильтры

насчет второго вопроса, надо смотреть код, но предположительно придется писать свой кастом, который будет работать через свой вариант def_module::autoDetectFilters, который и подхватывает параметры из адресной строки, в макросе %catalog getObjectsList()%, и добавляет их в выборку

Название: Re:фильтр товаров с условием OR и поиск по нескольким (не всем) разделам каталога
Отправлено: web-industry от 18 Мая 2012, 09:12:19
На вики появилась статья - http://wiki.umisoft.ru/%D0%94%D0%BE%D0%B1%D0%B0%D0%B2%D0%B8%D1%82%D1%8C_%D0%B2_%D1%84%D0%B8%D0%BB%D1%8C%D1%82%D1%80%D0%B0%D1%86%D0%B8%D1%8E_%D1%82%D0%BE%D0%B2%D0%B0%D1%80%D0%BE%D0%B2_%D0%98%D0%9B%D0%98_%D0%B4%D0%BB%D1%8F_%D0%BD%D0%B5%D0%BA%D0%BE%D1%82%D0%BE%D1%80%D1%8B%D1%85_%D0%BF%D0%BE%D0%BB%D0%B5%D0%B9
Название: Re:фильтр товаров с условием OR и поиск по нескольким (не всем) разделам каталога
Отправлено: web-industry от 18 Мая 2012, 11:08:37
Только там ошибки, и вообще работает не совсем верно. Модифицировал на скорую руку, т.к. заказчик уже рвет и мечет. Если кто подчистит - буду безумно рад. Сам смогу заняться оптимизацией не знаю когда.
public function getObjectsListCustom($template = "default", $path = false, $limit = false, $ignore_paging = false, $i_need_deep = 0, $field_id = false, $asc = true) {
if($this->breakMe()) return;
if(!$template) $template = "default";
if (!$i_need_deep) $i_need_deep = intval(getRequest('param4'));
if (!$i_need_deep) $i_need_deep = 0;
$i_need_deep = intval($i_need_deep);
if ($i_need_deep === -1) $i_need_deep = 100;
$hierarchy = umiHierarchy::getInstance();
list($template_block, $template_block_empty, $template_block_search_empty, $template_line) = def_module::loadTemplates("catalog/".$template, "objects_block", "objects_block_empty", "objects_block_search_empty", "objects_block_line");
$hierarchy_type_id = umiHierarchyTypesCollection::getInstance()->getTypeByName("catalog", "object")->getId();
$category_id = $this->analyzeRequiredPath($path);
if($category_id === false && $path != KEYWORD_GRAB_ALL) {
throw new publicException(getLabel('error-page-does-not-exist', null, $path));
}
$category_element = $hierarchy->getElement($category_id);
$per_page = ($limit) ? $limit : $this->per_page;
$curr_page = getRequest('p');
if($ignore_paging) $curr_page = 0;
$sel = new umiSelection;
$sel->setElementTypeFilter();
$sel->addElementType($hierarchy_type_id);
if($path != KEYWORD_GRAB_ALL) {
$sel->setHierarchyFilter();
$sel->addHierarchyFilter($category_id, $i_need_deep);
}
$sel->setPermissionsFilter();
$sel->addPermissions();
$hierarchy_type = umiHierarchyTypesCollection::getInstance()->getType($hierarchy_type_id);
$type_id = umiObjectTypesCollection::getInstance()->getBaseType($hierarchy_type->getName(), $hierarchy_type->getExt());
if($path === KEYWORD_GRAB_ALL) {
$curr_category_id = cmsController::getInstance()->getCurrentElementId();
} else {
$curr_category_id = $category_id;
}
if($path != KEYWORD_GRAB_ALL) {
$type_id = $hierarchy->getDominantTypeId($curr_category_id, $i_need_deep, $hierarchy_type_id);
}
if(!$type_id) {
$type_id = umiObjectTypesCollection::getInstance()->getBaseType($hierarchy_type->getName(), $hierarchy_type->getExt());
}
if($type_id) {
$this->autoDetectOrders($sel, $type_id);
$this->autoDetectFilters($sel, $type_id);
if($this->isSelectionFiltered) {
$template_block_empty = $template_block_search_empty;
$this->isSelectionFiltered = false;
}
} else {
$sel->setOrderFilter();
$sel->setOrderByName();
}
if($curr_page !== "all") {
$curr_page = (int) $curr_page;
//$sel->setLimitFilter();
//$sel->addLimit($per_page, $curr_page);
}
if($field_id) {
if (is_numeric($field_id)) {
$sel->setOrderByProperty($field_id, $asc);
} else {
if ($type_id) {
$field_id = umiObjectTypesCollection::getInstance()->getType($type_id)->getFieldId($field_id);
if ($field_id) {
$sel->setOrderByProperty($field_id, $asc);
} else {
$sel ->setOrderByOrd($asc);
}
} else {
$sel ->setOrderByOrd($asc);
}
}
}
else {
$sel ->setOrderByOrd($asc);
}
$result = umiSelectionsParser::runSelection($sel);
$total = umiSelectionsParser::runSelectionCounts($sel);

$colors = Array(
"krasnyj_cvet" => "krasnyj_cvet",
"rozovyj_cvet" => "rozovyj_cvet",
"chernyj_cvet" => "chernyj_cvet",
"seryj_cvet" => "seryj_cvet",
"belyj_cvet" => "belyj_cvet",
"bezhevyj_cvet" => "bezhevyj_cvet",
"korichnevyj_cvet" => "korichnevyj_cvet",
"zelenyj_cvet" => "zelenyj_cvet",
"goluboj_cvet" => "goluboj_cvet",
"fioletovyj_cvet" => "fioletovyj_cvet",
"multicolor_cvet" => "multicolor_cvet"

);
$result_result = Array();

if ((getRequest('krasnyj_cvet') == '1')||(getRequest('rozovyj_cvet') == '1')||(getRequest('chernyj_cvet') == '1')||(getRequest('seryj_cvet') == '1')||(getRequest('belyj_cvet') == '1')||(getRequest('bezhevyj_cvet') == '1')||(getRequest('korichnevyj_cvet') == '1')||(getRequest('zelenyj_cvet') == '1')||(getRequest('goluboj_cvet') == '1')||(getRequest('fioletovyj_cvet') == '1')||(getRequest('multicolor_cvet') == '1')) {
foreach ($colors as $i => $value) {
unset($colors[$i]); //это что б фильтр срабатывал при каком-нибудь условии
}
}

if(getRequest('krasnyj_cvet') == '1'){
$colors['krasnyj_cvet'] = 'krasnyj_cvet';
}
if(getRequest('rozovyj_cvet') == '1'){
$colors['rozovyj_cvet'] = 'rozovyj_cvet';
}
if(getRequest('chernyj_cvet') == '1'){
$colors['chernyj_cvet'] = 'chernyj_cvet';
}
if(getRequest('seryj_cvet') == '1'){
$colors['seryj_cvet'] = 'seryj_cvet';
}
if(getRequest('belyj_cvet') == '1'){
$colors['belyj_cvet'] = 'belyj_cvet';
}
if(getRequest('bezhevyj_cvet') == '1'){
$colors['bezhevyj_cvet'] = 'bezhevyj_cvet';
}
if(getRequest('korichnevyj_cvet') == '1'){
$colors['korichnevyj_cvet'] = 'korichnevyj_cvet';
}
if(getRequest('zelenyj_cvet') == '1'){
$colors['zelenyj_cvet'] = 'zelenyj_cvet';
}
if(getRequest('goluboj_cvet') == '1'){
$colors['goluboj_cvet'] = 'goluboj_cvet';
}
if(getRequest('fioletovyj_cvet') == '1'){
$colors['fioletovyj_cvet'] = 'fioletovyj_cvet';
}
if(getRequest('multicolor_cvet') == '1'){
$colors['multicolor_cvet'] = 'multicolor_cvet';
}

$count = 0;
$start = $curr_page * $per_page;
$last_count_element = 0;


for($i = 0; $i < $total; $i++){ //это цикл для подсчета общего количества элемнтов по фильтру (что б пэйджинг нормально работал)
$hierarchy = umiHierarchy::getInstance();
$page = $hierarchy->getElement($result[$i]);
$okay = 0;
foreach($colors as $color){
if($page -> getValue($color) == 1){
$okay++;
}
}
if($okay > 0){
$count++;
}
}
$total_page_filtr = $count;
$count = 0;









if ($start == 0) { //это тоже для пэйджинга
for($i = $start; $i < $total; $i++){
if($count < $per_page){
$hierarchy = umiHierarchy::getInstance();
$page = $hierarchy->getElement($result[$i]);
$okay = 0;
foreach($colors as $color){
if($page -> getValue($color) == 1){
$okay++;
}
}
if($okay > 0){
$result_result[$count] = $result[$i];
$count++;
}
}
}
}
else {
for($i = 0; $i < $total; $i++){
if($count < $start){
$hierarchy = umiHierarchy::getInstance();
$page = $hierarchy->getElement($result[$i]);
$okay = 0;
foreach($colors as $color){
if($page -> getValue($color) == 1){
$okay++;
}
}
if($okay > 0){
$count++;
$last_count_element = $i;
}
}
}



$count = 0;
for($i = $last_count_element+1; $i < $total; $i++){
if($count < $per_page){
$hierarchy = umiHierarchy::getInstance();
$page = $hierarchy->getElement($result[$i]);
$okay = 0;
foreach($colors as $color){
if($page -> getValue($color) == 1){
$okay++;
}
}
if($okay > 0){
$result_result[$count] = $result[$i];
$count++;
$last_count_element = $i;
}
}
}
}



$result = $result_result;

if(($sz = sizeof($result)) > 0) {
$block_arr = Array();
$lines = Array();
for($i = 0; $i < $sz; $i++) {
$element_id = $result[$i];
$element = umiHierarchy::getInstance()->getElement($element_id);
if(!$element) continue;
$line_arr = Array();
$line_arr['attribute:id'] = $element_id;
$line_arr['attribute:alt_name'] = $element->getAltName();
$line_arr['attribute:link'] = umiHierarchy::getInstance()->getPathById($element_id);
$line_arr['xlink:href'] = "upage://" . $element_id;
$line_arr['node:text'] = $element->getName();
$lines[] = self::parseTemplate($template_line, $line_arr, $element_id);
templater::pushEditable("catalog", "object", $element_id);
umiHierarchy::getInstance()->unloadElement($element_id);
}
$block_arr['subnodes:lines'] = $lines;
$block_arr['numpages'] = umiPagenum::generateNumPage($total, $per_page);
$block_arr['total'] = $total_page_filtr;
$block_arr['per_page'] = $per_page;
$block_arr['category_id'] = $category_id;
if($type_id) {
$block_arr['type_id'] = $type_id;
}
return self::parseTemplate($template_block, $block_arr, $category_id);
} else {
$block_arr['numpages'] = umiPagenum::generateNumPage(0, 0);
$block_arr['lines'] = "";
$block_arr['total'] = 0;
$block_arr['per_page'] = 0;
$block_arr['category_id'] = $category_id;
return self::parseTemplate($template_block_empty, $block_arr, $category_id);;
}

}