Вопрос или проблема
Я использую этот код для заполнения выпадающего меню в мета-боксе.
$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
, которые имеют дочерние записи?
Ваша задача состоит в том, чтобы исключить из выборки родительские записи, у которых нет дочерних записей. Давайте разберем ваше решение и выявим, как именно оно работает, а также как оно может быть улучшено или оптимизировано.
Понимание исходных данных
В вашей кодовой базе есть два типа записей:
- jhk_story – родительские записи.
- jhk_frames (или
story_frame
в вашем коде) – дочерние записи, указывающие на своих родителей через полеpost_parent
.
Ваша цель – получить список идентификаторов всех родительских записей jhk_story
, у которых есть дочерние записи, а затем использовать эти идентификаторы в качестве значений для массива exclude
в функции get_posts()
.
Оптимизация решения
Вы уже правильно реализовали функцию get_excluded_parents()
, где извлекаются все дочерние записи и отфильтровываются их родительские ID, но давайте рассмотрим процесс более подробно:
-
Получение дочерних записей: Сначала вы получаете все дочерние записи типа
story_frame
. Это делается с помощью функцииget_posts()
. -
Фильтрация родительских записей: Затем вы проходите по всем дочерним записям, проверяете, есть ли у них родитель (поле
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
}
Пояснения к коду
-
Функция
get_posts()
: Она возвращает массив записей согласно заданным критериям. В вашем случае это записи типаjhk_story
, который сортируется по ID. -
Использование
array_unique()
: При добавлении идентификаторов родителей в массив исключений рекомендуется использоватьarray_unique()
, чтобы удалить дублирующиеся значения. Это полезно, если один и тот же родитель может иметь несколько дочерних записей. -
Эффективность: Получая все дочерние записи за один запрос и фильтруя их, вы минимизируете количество запросов к базе данных, что улучшает производительность.
Заключение
Ваше решение в целом верно и функционально. Тем не менее, предложенные улучшения помогут вам оптимизировать код и избежать возможных проблем с производительностью. Если у вас возникнут дополнительные вопросы или необходимость в дальнейшем улучшении кода, не стесняйтесь обратиться за помощью. Надеюсь, данная информация окажется для вас полезной и поможет улучшить ваш проект на WordPress.