Intereting Posts
Проблема с памятью при параметре post per page Как получить URL-адрес в панели управления для пользовательского типа сообщений? добавьте комментарии GD Star Rating's к комментариям приятеля Повторно обрабатывать изображения Перенаправление на другую страницу посредством регистрации, в зависимости от страницы как проверить прикрепленное изображение PHP Sniffer – стандарты кодирования WordPress VIP Сохранение пользовательских сообщений через jquery или javascript Проблема с верхним / нижним краем панели навигации Недопустимый стол столбцов таблицы WP WP Как использовать правило перезаписи или переписать конечную точку для переключения языков? Шорткод для опции «Тема администратора»? Когда загружается таблица метаданных пользователя? Как отредактировать опечатку в отрывке? Вставить / липкую специальную запись в Loop в определенном месте

Сортировка списка сообщений, отображаемых в списке связанных терминов (которые должны быть отсортированы без начальных статей)

У меня есть ряд вопросов сортировки на странице, которую я пытаюсь выяснить, но до сих пор безрезультатно.

Сортировка списка сообщений CPT, которые перечислены в соответствующих пользовательских таксономических условиях

Я нашел эту часть кода в ответе на этот вопрос , который отлично подходит для возврата списка всех пользовательских таксономических терминов со списком связанных пользовательских типов сообщений под каждым.

$custom_terms = get_terms('custom_taxonomy'); foreach($custom_terms as $custom_term) { wp_reset_query(); $args = array('post_type' => 'custom_post_type', 'tax_query' => array( array( 'taxonomy' => 'custom_taxonomy', 'field' => 'slug', 'terms' => $custom_term->slug, ), ), ); $loop = new WP_Query($args); if($loop->have_posts()) { echo '<h2>'.$custom_term->name.'</h2>'; while($loop->have_posts()) : $loop->the_post(); echo '<a href="'.get_permalink().'">'.get_the_title().'</a>'; endwhile; } } 

Однако список пользовательских типов сообщений, отображаемых под каждым таксономическим термином, не сортируется (или может быть отсортирован по дате публикации), и я хотел бы сортировать его в алфавитном порядке (или даже лучше – посредством пользовательской сортировки, отображаемой в этом потоке и вопрос ниже этого).

Обычно я просто добавлял 'orderby' => 'title' где 'orderby' => 'title' то в миксе, но, похоже, здесь это не работает, или я не могу понять, куда его следует добавить.

Кто-нибудь знает, как их отсортировать?

ОБНОВИТЬ

Попробовал добавить 'orderby' => 'title' после 'post_type' => 'custom_post_type' в $args который не имел никакого эффекта.

Игнорирование исходной статьи «The» из возвращаемых терминов пользовательской таксономии

С помощью некоторого кода из этой записи в блоге и этих исправлений и предложений по улучшению мне удалось получить список всех сообщений в настраиваемом типе сообщений и отобразить их в алфавитном порядке, игнорируя «The» в заголовках сообщений.

Теперь я также хотел бы, чтобы мой список пользовательских таксономических терминов возвращался аналогичным образом, если это вообще возможно.

Это код, используемый для сортировки сообщений по алфавиту при игнорировании начального «The»:

 function wpcf_create_temp_column($fields) { global $wpdb; $matches = 'The'; $has_the = " CASE WHEN $wpdb->posts.post_title regexp( '^($matches)[[:space:]]' ) THEN trim(substr($wpdb->posts.post_title from 4)) ELSE $wpdb->posts.post_title END AS title2"; if ($has_the) { $fields .= ( preg_match( '/^(\s+)?,/', $has_the ) ) ? $has_the : ", $has_the"; } return $fields; } function wpcf_sort_by_temp_column ($orderby) { $custom_orderby = " UPPER(title2) ASC"; if ($custom_orderby) { $orderby = $custom_orderby; } return $orderby; } 

Это позволяет мне использовать этот фильтр, используя параметр _custom :

 add_filter( 'posts_orderby', function( $orderby, \WP_Query $q ) { // Do nothing if( '_custom' !== $q->get( 'orderby' ) ) return $orderby; global $wpdb; $matches = 'The'; // REGEXP is not case sensitive here // Custom ordering (SQL) return sprintf( " CASE WHEN {$wpdb->posts}.post_title REGEXP( '^($matches)[[:space:]]+' ) THEN TRIM( SUBSTR( {$wpdb->posts}.post_title FROM %d )) ELSE {$wpdb->posts}.post_title END %s ", strlen( $matches ) + 1, 'ASC' === strtoupper( $q->get( 'order' ) ) ? 'ASC' : 'DESC' ); }, 10, 2 ); 

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

Можно ли переписать код для применения к таксономии в списке вместо сообщений?

Ограничение списка возвращенных терминов таксономии + связанных должностей с теми, которые начинаются с определенного письма

На данный момент список терминов таксономии + связанных должностей возвращается очень долго. Чтобы сделать его немного более управляемым при просмотре списка, я хотел бы нарезать его на 5 или 6 страниц, отображающих условия в алфавитном порядке от AE, FJ и т. Д.

Если это не выполнимо, я был бы в порядке, разделив его полностью на A, B, C, D и т. Д.

Я пробовал просматривать предыдущие вопросы по этому поводу, но я не нашел ничего, что отдаленно работало для меня.

ОБНОВИТЬ

Я нашел этот пост, который, кажется, делает то, что я хочу, но я не могу заставить его работать на моем сайте. Это код, который я добавил с изменениями, основанными на связанном сообщении. Все, что он делает, это возврат полностью пустого списка.

 $game_titles = get_terms('game'); $count = count($game_titles); $letters = 'A'; if($count > 0){ foreach($game_titles as $game_title) { wp_reset_query(); $args = array('post_type' => 'release', 'tax_query' => array( array( 'taxonomy' => 'game', 'field' => 'slug', 'terms' => $game_title->slug, ), ), ); unset($game_titles); if (preg_match("/^$letters/i", $term->name)){ $loop = new WP_Query($args); if($loop->have_posts()) { echo '<h2>' . $game_title->name . '</h2>'; echo '<ul>'; unset($game_title); unset($args); while($loop->have_posts()) : $loop->the_post(); /* code */ endwhile; echo '</ul>'; } } } } этот $game_titles = get_terms('game'); $count = count($game_titles); $letters = 'A'; if($count > 0){ foreach($game_titles as $game_title) { wp_reset_query(); $args = array('post_type' => 'release', 'tax_query' => array( array( 'taxonomy' => 'game', 'field' => 'slug', 'terms' => $game_title->slug, ), ), ); unset($game_titles); if (preg_match("/^$letters/i", $term->name)){ $loop = new WP_Query($args); if($loop->have_posts()) { echo '<h2>' . $game_title->name . '</h2>'; echo '<ul>'; unset($game_title); unset($args); while($loop->have_posts()) : $loop->the_post(); /* code */ endwhile; echo '</ul>'; } } } } не $game_titles = get_terms('game'); $count = count($game_titles); $letters = 'A'; if($count > 0){ foreach($game_titles as $game_title) { wp_reset_query(); $args = array('post_type' => 'release', 'tax_query' => array( array( 'taxonomy' => 'game', 'field' => 'slug', 'terms' => $game_title->slug, ), ), ); unset($game_titles); if (preg_match("/^$letters/i", $term->name)){ $loop = new WP_Query($args); if($loop->have_posts()) { echo '<h2>' . $game_title->name . '</h2>'; echo '<ul>'; unset($game_title); unset($args); while($loop->have_posts()) : $loop->the_post(); /* code */ endwhile; echo '</ul>'; } } } } с $game_titles = get_terms('game'); $count = count($game_titles); $letters = 'A'; if($count > 0){ foreach($game_titles as $game_title) { wp_reset_query(); $args = array('post_type' => 'release', 'tax_query' => array( array( 'taxonomy' => 'game', 'field' => 'slug', 'terms' => $game_title->slug, ), ), ); unset($game_titles); if (preg_match("/^$letters/i", $term->name)){ $loop = new WP_Query($args); if($loop->have_posts()) { echo '<h2>' . $game_title->name . '</h2>'; echo '<ul>'; unset($game_title); unset($args); while($loop->have_posts()) : $loop->the_post(); /* code */ endwhile; echo '</ul>'; } } } } эта $game_titles = get_terms('game'); $count = count($game_titles); $letters = 'A'; if($count > 0){ foreach($game_titles as $game_title) { wp_reset_query(); $args = array('post_type' => 'release', 'tax_query' => array( array( 'taxonomy' => 'game', 'field' => 'slug', 'terms' => $game_title->slug, ), ), ); unset($game_titles); if (preg_match("/^$letters/i", $term->name)){ $loop = new WP_Query($args); if($loop->have_posts()) { echo '<h2>' . $game_title->name . '</h2>'; echo '<ul>'; unset($game_title); unset($args); while($loop->have_posts()) : $loop->the_post(); /* code */ endwhile; echo '</ul>'; } } } } не $game_titles = get_terms('game'); $count = count($game_titles); $letters = 'A'; if($count > 0){ foreach($game_titles as $game_title) { wp_reset_query(); $args = array('post_type' => 'release', 'tax_query' => array( array( 'taxonomy' => 'game', 'field' => 'slug', 'terms' => $game_title->slug, ), ), ); unset($game_titles); if (preg_match("/^$letters/i", $term->name)){ $loop = new WP_Query($args); if($loop->have_posts()) { echo '<h2>' . $game_title->name . '</h2>'; echo '<ul>'; unset($game_title); unset($args); while($loop->have_posts()) : $loop->the_post(); /* code */ endwhile; echo '</ul>'; } } } } 

UPDATE – добавлен код @ PieterGoosen

Я добавил код из ответа @ PieterGoosen ниже на мои functions.php (код идентичен таковому в ответе) и файл шаблона страницы ( здесь можно увидеть код с добавленным контентом ).

То, что я получаю, отчасти верное, но все же некоторые вещи не так. С новым кодом я получаю список всех сообщений release CPT, отсортированных по 1 связанному game термину. Выбранный термин – это термин, начинающийся с самого раннего происходящего письма в алфавите – так как в астероидах будут выбраны более Pac-Man, но Pac-Man будет выбран по сравнению с Space Invaders.

Он должен отображать список всех условий game и под каждым термином список всех связанных release . Кроме того, кажется, что каждый пост публикации отображается только один раз, хотя оптимально я хотел бы, чтобы они снова появлялись под каждым game термином, если у них более одного связанного с ними.

Однако функция сортировки работает отлично. Этот новый код игнорирует «все» во всех заголовках сообщений, и кажется, что он игнорируется в именах терминов, а также на основе текущей сортировки (было бы более ясно, если бы отображались имена терминов).

ОБНОВЛЕНИЕ 2 – Тестирование нового кода PieterGoosen

Я обновил свой код с обновленным кодом, и он работает как шарм. Все, что мне нужно сделать, это применить некоторые стили и контуры содержимого.

Для справки это решение VASTLY улучшило количество запросов к базе данных на моей странице по сравнению с моим старым кодом (как видно в начале этого вопроса. Использование get_num_queries() для проверки – мой старый код имел 3166 запросов к базе данных. С новым кодом I 'm at 33 вместо (+ теперь я фактически получаю все данные, которые я хочу отображать +, страница загружается быстрее).

Это действительно интересный вопрос, который может привести к очень дорогостоящему, ресурсоемкому процессу, который может существенно замедлить вашу страницу вниз

PRELUDE

Весь мой код в этом вопросе основан на следующем типе почтового отправления и таксономии, поэтому перед запуском какого-либо кода не забудьте настроить тип сообщения и таксономию в соответствии с вашими требованиями

  • Пользовательский тип сообщения -> release

  • Пользовательская таксономия -> game

ВАЖНОЕ ОБНОВЛЕНИЕ

Поскольку вам нужно включить все термины и почту, принадлежащую этим терминам, а не просто сортировать и включать первый термин, назначенный на сообщение, нам нужно полностью посмотреть на другое решение, но при этом сохранить производительность.

Новое решение идеально подойдет решению @birgire к вашему предыдущему вопросу, так как теперь мы отсортируем сам запрос, а не возвращенные сообщения.

Мое первоначальное решение по тому же вопросу, о котором вы просили , для этого не требуется больше, чтобы решить эту проблему, поэтому зависит от вас, хотите ли вы все же создать и отсортировать цикл со скрытым настраиваемым полем. Мое решение, использующее настраиваемое поле, все еще полностью действует. Поскольку мой первоначальный ответ на этот вопрос включал мое настраиваемое полевое решение, я продолжу использовать его, хотя я попытаюсь показать изменения, которые вы можете сделать, если решите использовать решение @ birgire, а не мое настраиваемое полевое решение

ЧАСТЬ ПЕРВАЯ ТОЧКА

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

Вы можете проверить это, выполнив echo get_num_queries() после вашего кода. Это покажет, сколько запросов db вы действительно делаете на этой конкретной загрузке страницы. Я бы посоветовал вам сесть, прежде чем делать это 😉

( ПРИМЕЧАНИЕ: сначала получите контрольный результат. Удалите весь свой код, затем запустите echo get_num_queries() , сделайте заметку, замените свой код и снова запустите echo get_num_queries() и echo get_num_queries() для получения точного подсчета)

Прежде чем мы начнем что-либо, давайте сначала рассмотрим вспомогательную функцию, которая будет обрабатывать удаление наших запрещенных слов из терминов и имен сообщений. Эта функция важна и будет использоваться повсеместно, чтобы наш код DRY и организованный

 /** * Function get_name_banned_removed() * * A helper function to handle removing banned words * * @param string $tring String to remove banned words from * @param array $banned Array of banned words to remove * @return string $string */ function get_name_banned_removed( $string = '', $banned = [] ) { // Make sure we have a $string to handle if ( !$string ) return $string; // Sanitize the string $string = filter_var( $string, FILTER_SANITIZE_STRING ); // Make sure we have an array of banned words if ( !$banned || !is_array( $banned ) ) return $string; // Make sure that all banned words is lowercase $banned = array_map( 'strtolower', $banned ); // Trim the string and explode into an array, remove banned words and implode $text = trim( $string ); $text = strtolower( $text ); $text_exploded = explode( ' ', $text ); if ( in_array( $text_exploded[0], $banned ) ) unset( $text_exploded[0] ); $text_as_string = implode( ' ', $text_exploded ); return $string = $text_as_string; } 

Этот код должен входить в functions.php или внутри настраиваемого плагина ( желательно )

Теперь, когда мы покрыли это, давайте посмотрим на следующую часть

ЧАСТЬ ВТОРАЯ ТОЧКА ДВА

ПРИМЕЧАНИЕ. Если вы собираетесь использовать метод @ birgire для удаления запрещенных слов и сортировки с помощью этих измененных заголовков сообщений, вы можете полностью пропустить эту часть, поскольку мы будем настраивать скрытое настраиваемое поле, которое мы будем сортировать)

Еще раз, вкратце, вот мое решение по ссылке выше, этот код ( который должен войти в плагин или functions.php ) и должен быть запущен только один раз, чтобы установить скрытое настраиваемое поле под названием _custom_sort_post_title для каждого сообщения. Это сохраняет заголовок сообщения с удаленным удаленным словом

( БОЛЬШОЕ ПРИМЕЧАНИЕ: У меня есть сильно отредактированная версия исходного кода из моего ответа в ссылке)

 add_action( 'wp', function () { add_filter( 'posts_fields', function ( $fields, \WP_Query $q ) { global $wpdb; remove_filter( current_filter(), __FUNCTION__ ); // Only target a query where the new custom_query parameter is set with a value of custom_meta_1 if ( 'custom_meta_1' === $q->get( 'custom_query' ) ) { // Only get the ID and post title fields to reduce server load $fields = "$wpdb->posts.ID, $wpdb->posts.post_title"; } return $fields; }, 10, 2); $args = [ 'post_type' => 'release', // Set according to needs 'posts_per_page' => -1, // Set to execute smaller chucks per page load if necessary 'suppress_filters' => false, // Allow the posts_fields filter 'custom_query' => 'custom_meta_1', // New parameter to allow that our filter only target this query 'meta_query' => [ [ 'key' => '_custom_sort_post_title', // Make it a hidden custom field 'compare' => 'NOT EXISTS' ] ] ]; $q = get_posts( $args ); // Make sure we have posts before we continue, if not, bail if ( !$q ) return; foreach ( $q as $p ) { $new_post_title = strtolower( $p->post_title ); if ( function_exists( 'get_name_banned_removed' ) ) $new_post_title = get_name_banned_removed( $new_post_title, ['the'] ); // Set our custom field value add_post_meta( $p->ID, // Post ID '_custom_sort_post_title', // Custom field name $new_post_title // Custom field value ); } //endforeach $q }); 

После удаления этого кода в файле functions.php или плагине вам будет нужен только следующий код: ( ПРИМЕЧАНИЕ. Мы добавим еще несколько работ для этого действия в ЧАСТИ ВТОРОЙ )

 add_action( 'transition_post_status', function ( $new_status, $old_status, $post ) { // Make sure we only run this for the release post type if ( 'release' !== $post->post_type ) return; $text = strtolower( $post->post_title ); if ( function_exists( 'get_name_banned_removed' ) ) $text = get_name_banned_removed( $text, ['the'] ); // Set our custom field value update_post_meta( $post->ID, // Post ID '_custom_sort_post_title', // Custom field name $text // Custom field value ); }, 10, 3 ); 

Этот код будет следить за тем, чтобы каждое новое опубликованное сообщение или каждое отредактированное _custom_sort_post_title настраивали _custom_sort_post_title пользовательское поле _custom_sort_post_title .

ЧАСТЬ ВТОРАЯ

Это та часть, которая действительно может стать дорогой. Простое получение всех терминов и прокрутка через них и запрос сообщений соответственно НЕ являются опцией здесь, поскольку это действительно дорогостоящая операция db.

Нам нужно будет только выполнить один запрос, чтобы получить все наши идентификаторы сообщений, обновить терминологический кеш, использовать get_object_term_cache() для получения условий сообщения, сортировать массив идентификаторов в соответствии с их терминами и затем безопасны наши результаты в переходный период. Мы будем безопасны только после того, как вы закончите переход, поскольку мы не хотим забивать огромное количество почтовых данных в беспорядочный сериализованный массив

Мы будем много полагаться на get_name_banned_removed() чтобы создавать имена терминов и заголовки сообщений с удаленными словами.

ПОСЛЕДНИЕ ПРИМЕЧАНИЯ

  • Я сделал код этого раздела немного более динамичным. Вместо жесткого кодирования типа сообщения и таксономии, я сделал им аргументы, которые вы можете передать функции. Вы должны прочитать блоки кода, которые поставляются с кодом

КОД

 /** * Function get_sorted_post_ids_terms_and_fields() * * Return a sorted array of post ids. These ID's are sorted according to * - Post title with the banned words removed before sorting * - Post terms with the banned words removed before sorting * * @param string $post_type Post type to get posts from Default 'release' * @param string $taxonomy Taxonomy to get posts from Default 'game' * @return array $ids */ function get_sorted_post_ids_terms_and_fields( $post_type = 'release', $taxonomy = 'game' ) { $array_combine = []; // Sanitize our post type and taxonomy names if ( 'release' !== $post_type ) $post_type = filter_var( $post_type, FILTER_SANITIZE_STRING ); if ( 'game' !== $taxonomy ) $taxonomy = filter_var( $taxonomy, FILTER_SANITIZE_STRING ); // Make sure that the taxonomy exist to avoid bugs later on if ( !taxonomy_exists( $taxonomy ) ) return $array_combine; // Our taxonomy exist, let's continue // Create a unique transient name $transient_name = 'spbtaf_' . md5( $taxonomy.$post_type ); if ( false === ( $array_combine = get_transient ( $transient_name ) ) ) { // Set our query arguments. Note, we will not do any sorting here $args = [ 'fields' => 'ids', // Only get post ID's 'post_type' => $post_type, 'posts_per_page' => -1, 'meta_key' => '_custom_sort_post_title', // Remove if you use @birgire's solution 'orderby' => 'meta_value', // Change to '_custom' if you use @birgire's solution 'order' => 'ASC', 'tax_query' => [ [ 'taxonomy' => $taxonomy, 'operator' => 'EXISTS' ] ], ]; $ids = get_posts( $args ); // Make sure we have posts if ( $ids ) { // Update the object term cache, saves plenty db time and calls update_object_term_cache( $ids, $post_type ); $term_post_ids_array = []; $term_names = []; // Loop through the posts and save in an array foreach ( $ids as $id ) { // Get the post terms from our post term cache $terms = get_object_term_cache( $id, $taxonomy ); // Loop through the terms. We definitely have terms foreach ( $terms as $term ) { // Remove the banned words from the term name $term_name = strtolower( $term->name ); if ( function_exists( 'get_name_banned_removed' ) ) $term_name = get_name_banned_removed( $term_name, ['the'] ); // Save the term name and post ids in an array $term_post_ids_array[$term_name][] = $id; // Save the real term names in an array $term_names[$term_name] = $term->name; } //endforeach $terms unset( $term ); } //endforeach $ids unset( $id ); // Sort the array according to our modified term ids ksort( $term_post_ids_array ); ksort( $term_names ); // Lets replace the modified term names with their proper names $array_combine = array_combine( $term_names, $term_post_ids_array ); } // endif $ids // Set the transient set_transient( $transient_name, $array_combine, 30*DAY_IN_SECONDS ); } // endif get_transient return $array_combine; } 

Это должно функционировать, должно возвращать отсортированный массив идентификаторов сообщений, который сортируется в соответствии с

  • термин, к которому они принадлежат, с ведущими запрещенными словами ( например, ) удален

  • Заголовок сообщения с удаленным удаленным словом

Массив также сортируется в соответствии с термином

Переходный период установлен на 30 дней, вы можете отрегулировать его по мере необходимости.

Нам нужно удалить и перезагрузить переходный процесс, когда опубликовано новое сообщение, или когда сообщение обновляется, удаляется или восстанавливается. Для этого мы будем использовать hook_post_status. ( Чтобы сохранить все аккуратно и вместе, давайте объединим действие с PART ONE POINT TWO вместе с этим действием. Я выделил раздел, который вы можете удалить, если сортируете с помощью настраиваемого фильтра @ birgire )

 add_action( 'transition_post_status', function ( $new_status, $old_status, $post ) { /* ----------START DELETE IF YOU USE @birgire's SORTING FILTER------------*/ // Make sure we only run this for the release post type if ( 'release' !== $post->post_type ) return; $text = strtolower( $post->post_title ); if ( function_exists( 'get_name_banned_removed' ) ) $text = get_name_banned_removed( $text, ['the'] ); // Set our custom field value update_post_meta( $post->ID, // Post ID '_custom_sort_post_title', // Custom field name $text // Custom field value ); /* -------------END DELETE IF YOU USE @birgire's SORTING FILTER------------*/ global $wpdb; // Delete the transients $wpdb->query( "DELETE FROM $wpdb->options WHERE `option_name` LIKE ('_transient%_spbtaf_%')" ); $wpdb->query( "DELETE FROM $wpdb->options WHERE `option_name` LIKE ('_transient_timeout%_spbtaf_%')" ); // Reset the transient if ( function_exists( 'get_sorted_post_ids_terms_and_fields' ) ) get_sorted_post_ids_terms_and_fields(); //REMEMBER TO SET POST TYPE AND TAXONOMY }, 10, 3 ); 

Как вы можете видеть, мы перезапускаем переходный процесс в действии transition_post_status , это также отнимает много нагрузки от переднего конца

ЧАСТЬ ТРЕТЬЯ

Цикл немного сложный. У нас есть многомерный массив имен терминов и идентификаторов сообщений, поступающих из функции get_sorted_post_ids_terms_and_fields() . Мы должны быть умными здесь, чтобы поддерживать наши звонки в сети и т. Д. Как можно ниже. Трудная часть состоит в том, чтобы получить полные объекты сообщения из их соответствующих идентификаторов. Кроме того, поскольку сообщения относятся к нескольким терминам, мы также имеем дубликаты идентификаторов.

ПЛАН

Мы будем использовать пользовательский запрос для получения всех сообщений. У нас здесь небольшая проблема: WP_Query не возвращает повторяющиеся сообщения. В этом заключается трюк, WP_Query добавляет сообщения, которые он возвращает в кеш. Как только сообщение находится в кеше, мы можем запросить его с помощью get_post() снова и снова без вызова db. Это умная часть всего кода.

Во-первых, нам также нужен способ сгладить многомерный массив, чтобы захватить все post_ids, прежде чем передать его WP_Query

 /** * Function flatten_array() * * Function to flatten an array and get all array values * Special thanks to zdenko * @link https://gist.github.com/kohnmd/11197713 * * @param array $array The multidimensional array to flatten * @return array $array The flattened array */ function flatten_array( $array ) { // Make sure $array is an array, if not return $array as an array if ( !is_array( $array ) ) return [$array]; return array_reduce( $array, function ( $a, $b ) { return array_merge( $a, flatten_array( $b ) ); }, [] ); } 

Теперь мы будем запрашивать наши сообщения из массива сглаживания идентификаторов, чтобы хранить их в кэше сообщений. Для этого мы будем использовать специальный SQL-запрос по следующим причинам

  • Это сверхбыстрый

  • Нам не нужны никакие фильтры или действия для изменения этого запроса

  • Вся тяжелая работа уже была выполнена в get_sorted_post_ids_terms_and_fields() . Все, что нам нужно сделать, это взять идентификаторы из этой функции и получить полные объекты post.

После того, как у нас есть полные сообщения, мы можем использовать update_post_cache чтобы добавлять наши сообщения в кеш сообщений

 /** * Function set_posts_to_cache() * * Function to query all the full post objects who's ID's is in the * get_sorted_post_ids_terms_and_fields() function and then to add these * post objects into the post cache so we can query them over and over again * with get_post() * * @param string $post_type Post type to get posts from Default 'release' * @param string $taxonomy Taxonomy to get posts from Default 'game' */ function set_posts_to_cache( $post_type = 'release', $taxonomy = 'game' ) { global $wpdb; // Check if the taxonomy exists if ( !taxonomy_exists( $taxonomy ) ) return false; // Sanitize the taxonomy name $taxonomy = filter_var( $taxonomy, FILTER_SANITIZE_STRING ); // Sanitize the post type if ( 'release' !== $post_type ) $post_type = filter_var( $post_type, FILTER_SANITIZE_STRING ); // Get our post ID's if ( function_exists( 'get_sorted_post_ids_terms_and_fields' ) ) { $combined_array = get_sorted_post_ids_terms_and_fields( $post_type, $taxonomy ); if ( $combined_array ) { if ( function_exists( 'flatten_array' ) ) { // Flatten our array in order to pass it to WP_Query $flatten_array = flatten_array( $combined_array ); $unique_ids = array_unique( $flatten_array ); $string_ids = implode( ', ', array_map( 'absint', $unique_ids ) ); /** * Run our custom SQL query and add our posts in cache * * We only need to get the posts by ID and post type. Remember, the function * get_sorted_post_ids_terms_and_fields() has already taken care of all the hard * work. All this query needs to do is to retrieve the posts which ID's are returned * by get_sorted_post_ids_terms_and_fields() to add the posts in cache */ $posts_to_cache = $wpdb->get_results( $wpdb->prepare( "SELECT $wpdb->posts.* FROM $wpdb->posts WHERE 1=1 AND $wpdb->posts.ID IN ($string_ids) AND $wpdb->posts.post_type = %s ORDER BY $wpdb->posts.post_date DESC LIMIT 0, %d", $post_type, count( $unique_ids ) ) ); // Update the post cache update_post_caches( $posts_to_cache ); } // endif function_exists( 'flatten_array' ) } // endif if ( $combined_array ) } // endif ( function_exists( 'get_sorted_post_ids_terms_and_fields' ) ) } 

Давайте посмотрим на цикл сейчас

 if ( function_exists( 'get_sorted_post_ids_terms_and_fields' ) ) { $combined_array = get_sorted_post_ids_terms_and_fields(); // Make sure we have a valid array if ( $combined_array ) { if ( function_exists( 'set_posts_to_cache' ) ) { // Set all our posts into the post cache. remember to pass the correct post type and taxonomy set_posts_to_cache( 'release', 'game'); // Set a variable to hold the first letter of the term name $first_letter = ''; foreach ( $combined_array as $term_name=>$post_ids ) { // Display the first letter from the terms $term_name_modified = strtolower( $term_name ); if ( function_exists( 'get_name_banned_removed' ) ) $term_name_modified = get_name_banned_removed( $term_name_modified, ['the'] ); $starting_letter = strtoupper( mb_substr( $term_name_modified, 0, 1 ) ); if ( $first_letter !== $starting_letter ) echo '<p>' . $starting_letter . '</p>'; // Update the $first_letter variable $first_letter = $starting_letter; // Display the term name above the posts echo $term_name . '</br>'; // Apply the get_post() function to all post ids to get full posts objects $posts_array = array_map( 'get_post', $post_ids ); // Now that we have full posts, lets display them in our loop foreach ( $posts_array as $post ) { setup_postdata( $post ); // APPLY YOUR LOOP AS PER NORMAL AS PER YOUR LINK. echo '<li>' . get_the_title() . '</li>'; } // endforeach $posts_array wp_reset_postdata(); // VERY VERY IMPORTANT } // endforeach $combined_array } // endif function_exists flatten_array } // endif $combined_array } // endif function_exists get_sorted_post_ids_terms_and_fields 

Теперь ваши сообщения должны отображаться следующим образом:

  • Все сообщения сортируются по алфавиту в соответствии с термином, который они принадлежат, в соответствии с именем сообщения с запрещенным словом, удаленным в процессе начальной сортировки

  • Все термины сортируются в алфавитном порядке с запрещенными словами, удаленными от начальной сортировки. Все термины имеют свои записи, отсортированные под ними

  • Все термины сортируются по букве, имя которой начинается с запрещенных слов, удаленных при начальной сортировке

Вам просто нужно применить свой собственный стиль и отметить до цикла

РЕЗУЛЬТАТЫ ИСПЫТАНИЙ – ДОКАЗАТЕЛЬСТВО В ЧУДОВЕ, НЯММЕ !!!

После этого огромного марафона, давайте хруст цифры. На 24 сообщениях, при всей огромной работе по разметке и сортировке названий сообщений и названий терминов, я закончил с

  • 6 дБ звонков примерно через 0.16 секунды

  • 5 дБ звонков примерно через 0.14 секунды

и мы не злоупотребляли нашим преходящим. Довольно впечатляет для такой огромной работы, LOL.

Просто ради интереса, я скопировал цикл из вашего первого блока кода и получил следующий результат:

  • 73 запросов за 0,5 секунды

Огромное различие, доказательство моей точки 😉

ЧАСТЬ ПОД СТРОИТЕЛЬСТВОМ

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

Независимо от того, какое решение я придумал, это не повлияет на части 1 и 2 моего ответа. Часть третья определенно будет затронута и потребуется какая-то переписывание