Заполните массив exclude() в get_posts()

Вопрос или проблема

Я использую этот код для заполнения выпадающего меню в мета-боксе.

        $parents = get_posts(
           array(
           'post_type'   => 'jhk_story', 
           'orderby'     => 'ID', 
           'order'       => 'ASC', 
           'numberposts' => -1,
           'exclude'     => array(121, 131, 138),
           )
        );

Этот post_type содержит родительские записи поста типа ‘jhk_frames’, которые являются единственными дочерними. Таким образом, дочерние записи содержат в поле post_parent идентификатор поста своего родителя. Родитель содержит в поле post_parent по-прежнему значение по умолчанию – ноль.

Мой вопрос: как мне выбрать только посты в post_type ‘jhk_story’, которые имеют дочерние записи?

Следующий шаг – поместить идентификаторы этих постов в массив ‘exclude’. Значения, которые вы видите сейчас, были добавлены мною только для примера (и для проверки, что это работает).

Буду признателен за любую помощь.

После трех дней борьбы и публикации вопроса здесь, мне удалось найти ответ. Да, я знаю… В свою защиту могу сказать, что это мой первый проект на WP. Я сделал это следующим образом:

    $exclude = get_excluded_parents();

    $parents = get_posts(
        array(
            'post_type'   => 'jhk_story', 
            'orderby'     => 'ID', 
            'order'       => 'ASC', 
            'numberposts' => -1,
            'exclude'     => $exclude,
        )
    );

    Остальная часть кода здесь ...

  }

} // story_frame_attributes_meta_box()


/* 
 * Фильтрует исключенные родителей из post_type: story_frame
 */
function  get_excluded_parents() {

  // Выбирает все посты с post_type = story_frame
  $childs = get_posts (
    array (
      'post_type'   => 'story_frame',
      'orderby'     => 'ID',
      'order'       => 'ASC',
      'numberposts' => -1
    )
  );

  $exclude = array();

  foreach ( $childs as $child ) {

    if ( 0 < $child->post_parent ) {

      array_push( $exclude, $child->post_parent );

    }

  } // foreach $child

  return $exclude;

} // get_excluded_parents()

Надеюсь, кто-то извлечет из этого пользу.

Ответ или решение

Вопрос: Как заполнить массив exclude в функции get_posts() для выбора только тех записей типа jhk_story, которые имеют дочерние записи?

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

Понимание исходных данных

В вашей кодовой базе есть два типа записей:

  1. jhk_story – родительские записи.
  2. jhk_frames (или story_frame в вашем коде) – дочерние записи, указывающие на своих родителей через поле post_parent.

Ваша цель – получить список идентификаторов всех родительских записей jhk_story, у которых есть дочерние записи, а затем использовать эти идентификаторы в качестве значений для массива exclude в функции get_posts().

Оптимизация решения

Вы уже правильно реализовали функцию get_excluded_parents(), где извлекаются все дочерние записи и отфильтровываются их родительские ID, но давайте рассмотрим процесс более подробно:

  1. Получение дочерних записей: Сначала вы получаете все дочерние записи типа story_frame. Это делается с помощью функции get_posts().

  2. Фильтрация родительских записей: Затем вы проходите по всем дочерним записям, проверяете, есть ли у них родитель (поле post_parent больше нуля), и добавляете идентификатор родителя в массив исключений.

Вот как может выглядеть ваш окончательный код:

$exclude = get_excluded_parents();

$parents = get_posts(
    array(
        'post_type'   => 'jhk_story', 
        'orderby'     => 'ID', 
        'order'       => 'ASC', 
        'numberposts' => -1,
        'exclude'     => $exclude,
    )
);

/* 
 * Функция для получения исключённых родителей из post_type: story_frame
 */
function get_excluded_parents() {
    // Извлечение всех дочерних записей
    $childs = get_posts (
        array (
            'post_type'   => 'story_frame',
            'orderby'     => 'ID',
            'order'       => 'ASC',
            'numberposts' => -1
        )
    );

    $exclude = array();

    // Фильтрация по наличию родителей
    foreach ($childs as $child) {
        if ($child->post_parent > 0) {
            $exclude[] = $child->post_parent; // Добавление идентификатора родителя в массив исключений
        }
    }

    return array_unique($exclude); // Убедитесь, что возвращается только уникальный набор ID
}

Пояснения к коду

  1. Функция get_posts(): Она возвращает массив записей согласно заданным критериям. В вашем случае это записи типа jhk_story, который сортируется по ID.

  2. Использование array_unique(): При добавлении идентификаторов родителей в массив исключений рекомендуется использовать array_unique(), чтобы удалить дублирующиеся значения. Это полезно, если один и тот же родитель может иметь несколько дочерних записей.

  3. Эффективность: Получая все дочерние записи за один запрос и фильтруя их, вы минимизируете количество запросов к базе данных, что улучшает производительность.

Заключение

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

Оцените материал
Добавить комментарий

Капча загружается...