В WordPress, как вы уже должны были знать, при использовании get_posts()
или query_posts()
или даже WP_Query
, вы не можете заказать возвращенные сообщения, указав список идентификаторов сообщений в том порядке, в котором мы хотим.Как избежать влияния на другие запросы при использовании posts_orderby?
Вместо этого мы должны просмотреть результаты и переупорядочить их на стороне PHP. Это хиты производительности и плохая практика. Вместо этого мы должны использовать встроенные функции MySQL для извлечения сообщений в нужном порядке.
К счастью, есть posts_orderby
, который может быть использован для определения пользовательского договора OrderBy, как это:
// My list of post IDs in my custom order
$my_post_ids = array(1,3,2);
// Apply filter to the ORDERBY SQL statement
add_filter('posts_orderby', 'my_custom_orderby');
function my_custom_orderby($orderby_statement) {
global $my_post_ids;
$orderby_statement = 'FIELD(ID, '.implode(',',$my_post_ids).')';
return $orderby_statement;
}
// My custom query
$my_custom_query = new WP_Query(array('post_type' => 'post', 'post__in' => $my_post_ids);
Однако есть проблема с вышеуказанным кодом, является то, что это будет влиять на порядок всех запросов на странице! Включая запросы, сделанные плагинами, шорткодами и т. Д.
Простая установка!
Простой способ исправить это, чтобы применить фильтр только один раз, и удалить его, как только он называется, поставив remove_filter()
внутри самого фильтра, поэтому он выполняется только один раз:
// My list of post IDs in my custom order
$my_post_ids = array(1,3,2);
// Apply filter to the ORDERBY SQL statement
add_filter('posts_orderby', 'my_custom_orderby');
function my_custom_orderby($orderby_statement) {
// Disable this filter for future queries!
remove_filter(current_filter(), __FUNCTION__);
global $my_post_ids;
$orderby_statement = 'FIELD(ID, '.implode(',',$my_post_ids).')';
return $orderby_statement;
}
// My custom query
$my_custom_query = new WP_Query(array('post_type' => 'post', 'post__in' => $my_post_ids);
Поскольку я устанавливаю этот фильтр непосредственно перед моим пользовательским запросом, после выполнения моего пользовательского запроса его следует фильтровать с помощью установленного выше фильтра posts_orderby
, который сразу же отключается, поэтому он не повлияет на будущие запросы.
Теоретически это здорово, и в большинстве случаев он отлично работает!
Проблема с WPML
Однако я столкнулся случай, когда с помощью WPML plugin, где этот фильтр влияет на другие запросы, чем у меня и вызывает ошибки. Я считаю, что плагин WPML создает собственный запрос, который выполняется непосредственно перед моим собственным пользовательским запросом, что делает мой фильтр применимым к запросу WPML вместо моего!
Есть ли способ добавить проверку в фильтр, чтобы убедиться, что он влияет на правильный запрос?
Большое спасибо
Edit:
Исправление WPML
Для получения дополнительной информации, а принятый ответ на этот вопрос правильно, это не решило проблему Я работал с WPML. Вот как я установил WPML конфликт:
// My list of post IDs in my custom order
$my_post_ids = array(1,3,2);
// Apply filter to the ORDERBY SQL statement
add_filter('posts_orderby', 'my_custom_orderby');
function my_custom_orderby($orderby_statement) {
// Disable this filter for future queries!
remove_filter(current_filter(), __FUNCTION__);
global $my_post_ids, $wpdb;
$orderby_statement = 'FIELD('.$wpdb->base_prefix.'posts.ID, '.implode(',',$my_post_ids).')';
return $orderby_statement;
}
// My custom query
$my_custom_query = new WP_Query(array('post_type' => 'post', 'post__in' => $my_post_ids);
Спасибо за ваш ответ.Я принял ваш ответ и предоставил вам репутацию +50 баунти, как только это позволит мне. Для информации ** это не решило мою проблему с WPML **, но по-прежнему является правильным ответом на мой вопрос. Я смог решить свою проблему, заменив 'ID' на' '. $ Wpdb-> base_prefix.'posts.ID' в инструкции. Поскольку WPML делает JOIN для каждого запроса (для получения перевода из другой таблицы, я думаю), имеющий сам идентификатор, вызвал ошибку MySQL, поскольку он не знал, к какой таблице относится поле идентификатора, поэтому добавление таблицы починил это! – Community
Приятно было знать, что мой вклад помог решить проблему;) Возможно, вы можете написать ответ своим решением и пометить его как правильный, или отредактировать его и отредактировать. – brasofilo