Как отсортировать функцию query_posts по настраиваемому полю, а ограничивать сообщения другим настраиваемым полем

Я запрашиваю серию сообщений в WP со следующей функцией:

<?php $thirtydays = date('Y/m/d', strtotime('+30 days')); $paged = (get_query_var('paged')) ? get_query_var('paged') : 1; query_posts( array( 'post_type' => array('post', 'real-estate'), 'meta_key' => 'Time Available', 'meta_compare' => '<=', 'meta_value' => $thirtydays, 'paged' => $paged )); ?> 

Эта часть работает нормально. Это, в основном, тянет все мои сообщения о недвижимости, но только возвращает результаты, имеющие «доступное время» 30 дней или меньше.

Мне нужно это, чтобы также заказывать сообщения в порядке возрастания от низкого до высокого, используя данные из другого настраиваемого поля «Цена».

Всякий раз, когда я добавляю стандартный 'orderby' => 'meta_value', 'meta_key' => 'Price' он больше не показывает результаты в течение 30 дней.

Есть ли способ объединить эти два? И можно ли добавить кнопку, которая повторно запускает запрос и сортирует по цене, спальне и т. Д.? Или это слишком специфично для WP?

Я считаю, что это обеспечит вам то, что вам нужно. Это класс под названием PostsOrderedByMetaQuery который расширяет WP_Query и принимает новые аргументы 'orderby_meta_key' и « orderby_order' :

 class PostsOrderedByMetaQuery extends WP_Query { var $posts_ordered_by_meta = true; var $orderby_order = 'ASC'; var $orderby_meta_key; function __construct($args=array()) { add_filter('posts_join',array(&$this,'posts_join'),10,2); add_filter('posts_orderby',array(&$this,'posts_orderby'),10,2); $this->posts_ordered_by_meta = true; $this->orderby_meta_key = $args['orderby_meta_key']; unset($args['orderby_meta_key']); if (!empty($args['orderby_order'])) { $this->orderby_order = $args['orderby_order']; unset($args['orderby_order']); } parent::query($args); } function posts_join($join,$query) { if (isset($query->posts_ordered_by_meta)) { global $wpdb; $join .=<<<SQL INNER JOIN {$wpdb->postmeta} postmeta_price ON postmeta_price.post_id={$wpdb->posts}.ID AND postmeta_price.meta_key='{$this->orderby_meta_key}' SQL; } return $join; } function posts_orderby($orderby,$query) { if (isset($query->posts_ordered_by_meta)) { global $wpdb; $orderby = "postmeta_price.meta_value {$this->orderby_order}"; } return $orderby; } } не class PostsOrderedByMetaQuery extends WP_Query { var $posts_ordered_by_meta = true; var $orderby_order = 'ASC'; var $orderby_meta_key; function __construct($args=array()) { add_filter('posts_join',array(&$this,'posts_join'),10,2); add_filter('posts_orderby',array(&$this,'posts_orderby'),10,2); $this->posts_ordered_by_meta = true; $this->orderby_meta_key = $args['orderby_meta_key']; unset($args['orderby_meta_key']); if (!empty($args['orderby_order'])) { $this->orderby_order = $args['orderby_order']; unset($args['orderby_order']); } parent::query($args); } function posts_join($join,$query) { if (isset($query->posts_ordered_by_meta)) { global $wpdb; $join .=<<<SQL INNER JOIN {$wpdb->postmeta} postmeta_price ON postmeta_price.post_id={$wpdb->posts}.ID AND postmeta_price.meta_key='{$this->orderby_meta_key}' SQL; } return $join; } function posts_orderby($orderby,$query) { if (isset($query->posts_ordered_by_meta)) { global $wpdb; $orderby = "postmeta_price.meta_value {$this->orderby_order}"; } return $orderby; } } не class PostsOrderedByMetaQuery extends WP_Query { var $posts_ordered_by_meta = true; var $orderby_order = 'ASC'; var $orderby_meta_key; function __construct($args=array()) { add_filter('posts_join',array(&$this,'posts_join'),10,2); add_filter('posts_orderby',array(&$this,'posts_orderby'),10,2); $this->posts_ordered_by_meta = true; $this->orderby_meta_key = $args['orderby_meta_key']; unset($args['orderby_meta_key']); if (!empty($args['orderby_order'])) { $this->orderby_order = $args['orderby_order']; unset($args['orderby_order']); } parent::query($args); } function posts_join($join,$query) { if (isset($query->posts_ordered_by_meta)) { global $wpdb; $join .=<<<SQL INNER JOIN {$wpdb->postmeta} postmeta_price ON postmeta_price.post_id={$wpdb->posts}.ID AND postmeta_price.meta_key='{$this->orderby_meta_key}' SQL; } return $join; } function posts_orderby($orderby,$query) { if (isset($query->posts_ordered_by_meta)) { global $wpdb; $orderby = "postmeta_price.meta_value {$this->orderby_order}"; } return $orderby; } } 

Вы бы назвали это так:

 $thirtydays = date('Y/m/d', strtotime('+30 days')); $paged = (get_query_var('paged')) ? get_query_var('paged') : 1; $query = new PostsOrderedByMetaQuery(array( 'post_type' => array('post', 'real-estate'), 'meta_key' => 'Time Available', 'meta_compare' => '<=', 'meta_value' => $thirtydays, 'paged' => $paged, 'orderby_meta_key' => 'Price', 'orderby_order' => 'DESC', )); foreach($query->posts as $post) { echo " {$post->post_title}\n"; } 

Вы можете скопировать класс PostsOrderedByMetaQuery в файл functions.php вашей темы, или вы можете использовать его в файле .php плагина, который вы можете писать.

Если вы хотите быстро его протестировать, я разместил автономную версию кода для Gist, которую вы можете загрузить и скопировать в корень вашего веб-сервера в качестве test.php , изменить для своего варианта использования, а затем запросить у своего браузера, используя URL, например http://example.com/test.php .

Надеюсь это поможет.

-Майк

PS Этот ответ очень похож на ответ, который я только что передал в WordPress Answers , который является сестринским сайтом StackOverflow, где многие энтузиасты WordPress, подобные мне, ежедневно отвечают на вопросы. Возможно, вы захотите увидеть этот ответ, потому что он имеет более подробное объяснение и потому, что вы можете захотеть увидеть ответы WordPress . Надеюсь, вы посчитаете, что размещаете свои вопросы WordPress там тоже в будущем?

Поскольку для 'orderby' => 'meta_value' требуется meta_key , и ваша meta_key уже используется для сравнения, я не думаю, что вы можете это сделать. meta_key принимает только одно значение, а не массив параметров. Это определенно ограничение, и я призываю вас открыть запрос, если вы не найдете решение.

Что касается кнопки для повторного запуска запроса, вы можете просто перезагрузить страницу и передать переменную запроса, чтобы изменить сортировку. К сожалению, вам еще предстоит решить первую часть вашего вопроса.

ОБНОВИТЬ

Вы всегда можете отсортировать возвращаемый массив с помощью PHP.

Кроме того, не уверен, что вы проверяете с доступным временем, но вы можете зарегистрировать фильтр, который может помочь вам настроить запрос немного дальше add_filter('posts_where', ...); http://codex.wordpress.org/Function_Reference/query_posts