Поддержка Проблемы и решения Проблемы с query_posts()

  • Добрый день!
    Появилось задание на сайте вордпресс создать фильтр по товарам. Есть несколько категорий товаров и в каждом товаре параметры. Например категория ‘Двери’, у нее параметры
    ‘Тип дверей’
    -Арочные
    -Двойные
    -Не стандартные
    -Раздвижные
    ‘Стиль’
    -Кантри
    -Классический
    -Современный
    Надо внутри категории фильтровать товары по этим параметрам

    Начал знакомиться с вордпрессом, гуглил, читал и пришел к выводу что нужно добавить произвольные поля к товарам и по ним фильтровать. Написал блок формы, обработчик и столкнулся с проблемой — Если выбирать больше 3 параметров система виснет, дошло до того что хостер на время заблокировал сайт.

    Вот код:
    ФОРМА

    <form name="search" role="search" action="/dveri/" method="post">
    <div>ФИЛЬТРАЦИЯ</div>
    <div>Тип дверей</div>
    <ul>
    <?php
    $optionArray = array();
    if (isset($_POST['filtr_door'])) {
    	$optionArray = $_POST['filtr_door'];
    }
    $filters = $wpdb->get_results("SELECT meta_value FROM $wpdb->postmeta WHERE meta_key = 'filtr_door_1' GROUP BY meta_value ");
    if ($filters) {
    	foreach ($filters as $filter) {
    		foreach ($filter as $item) {
    			if (in_array($item, $optionArray)) {
    				echo '<li><input type="checkbox" name="filtr_door[]" checked value="'.$item.'">'.$item.'</li>';
    			} else {
    				echo '<li><input type="checkbox" name="filtr_door[]" value="'.$item.'">'.$item.'</li>';
    			}
    		}
    	}
    }
    ?>
    </ul>
    <div>Стиль</div>
    <ul>
    <?php
    $filters = $wpdb->get_results("SELECT meta_value FROM $wpdb->postmeta WHERE meta_key = 'filtr_door_2' GROUP BY meta_value ");
    if ($filters) {
    	foreach ($filters as $filter) {
    		foreach ($filter as $item) {
    			echo '<li><input type="checkbox" name="filtr_door[]" value="'.$item.'">'.$item.'</li>';
    		}
    	}
    }
    
    ?>
    </ul>
    <input type="submit" value="Применить">
    </form>

    ОБРАБОТЧИК

    if (isset($_POST['filtr_door'])) {
        $optionArray = $_POST['filtr_door'];
        $args = array('relation' => 'OR');
        foreach ($optionArray as $optionItem) {
            $args[] = array('value' => $optionItem);
        }
    }
    query_posts(array('paged' => $paged, 'cat' => $cat, 'meta_query' => $args));
    while (have_posts()) : the_post();

    Вот запрос который генерится

    SELECT SQL_CALC_FOUND_ROWS smiela_posts.ID
    FROM smiela_posts
    INNER JOIN smiela_term_relationships
    ON (smiela_posts.ID = smiela_term_relationships.object_id)
    INNER JOIN smiela_postmeta
    ON (smiela_posts.ID = smiela_postmeta.post_id)
    INNER JOIN smiela_postmeta AS mt1
    ON (smiela_posts.ID = mt1.post_id)
    INNER JOIN smiela_postmeta AS mt2
    ON (smiela_posts.ID = mt2.post_id)
    WHERE 1=1
    AND ( smiela_term_relationships.term_taxonomy_id IN (6,15,16) )
    AND smiela_posts.post_type = 'post'
    AND (smiela_posts.post_status = 'publish'
    OR smiela_posts.post_status = 'private')
    AND ( (smiela_postmeta.meta_key = 'filtr_door_1'
    AND CAST(smiela_postmeta.meta_value AS CHAR) = 'Арочные')
    OR (mt1.meta_key = 'filtr_door_1'
    AND CAST(mt1.meta_value AS CHAR) = 'Двойные')
    OR (mt2.meta_key = 'filtr_door_1'
    AND CAST(mt2.meta_value AS CHAR) = 'Раздвижные') )
    GROUP BY smiela_posts.ID
    ORDER BY smiela_posts.post_date DESC
    LIMIT 0, 12

    Думаю что проблема в том что query_posts создает дополнительный INNER JOIN для каждого выбранного параметра.

    Подскажите, пожалуйса, как можно в WP_Query вставить рукописный sql (не смог этого нагуглить) или может укажите на другую мою ошибку.
    Спасибо большоу!

Просмотр 3 ответов — с 1 по 3 (всего 3)
  • Никто не может помочь?
    Подскаэите, как обычно решается задача: Фильтр записей по произвольным полям (поля могут добавляться админом сайта, т.е. не по фиксированным)

    Спасибо за совет!

    Но при помощи get_post_meta() я вижу только вариант ручной переборки всей выборки товаров. Хотя наверно это и неплохой способ.

    Решил проблему другим способом.

    Я пошел неверным путем когда использовал в построении запроса ‘relation’ => ‘OR’. Надо было просто проверять вхождение значения поля в массив ‘compare’ => ‘IN’

    Правильный код фильтрованной выборки:

    $args = array();
    if (isset($_POST['filtr_door_1'])) {
        $optionArray1 = $_POST['filtr_door_1'];
        $args[] = array('key' => 'filtr_door_1', 'value' => $optionArray1, 'compare' => 'IN');
    }
    if (isset($_POST['filtr_door_2'])) {
        $optionArray2 = $_POST['filtr_door_2'];
        $args[] = array('key' => 'filtr_door_2', 'value' => $optionArray2, 'compare' => 'IN');
    }
    if (sizeof($args)) {
        query_posts(array('paged' => $paged, 'cat' => $cat, 'meta_query' => $args));
    } else {
        query_posts(array('paged' => $paged, 'cat' => $cat));
    }
Просмотр 3 ответов — с 1 по 3 (всего 3)
  • Тема «Проблемы с query_posts()» закрыта для новых ответов.