Как отфильтровать категории по значению кастомного поля в постах?

Вывожу посты кастомной таксономии списком.
Нужно вывести категории, которые содержат посты с определенным значением кастомного поля (сделанного через ACF).
Например, в постах есть кастомное поле "publish_in". Один из вариантов его значения — "true".

В общем архиве кастомных постов нужно отобразить только те рубрики, где есть посты с кастомным полем "publish_in" со значением "true".
Если же таких постов нет, то не выводить данную категорию в общем списке вовсе.
Возможно ли прописать данную проверку?

Вывод постов на странице архива:
<?php
/*
 * Loop through Categories and Display Posts within
 */
$post_type = 'my-tax';
 
// Get all the taxonomies for this post type
$taxonomies = get_object_taxonomies( array( 'post_type' => $post_type ) );
 
foreach( $taxonomies as $taxonomy ) :
 
    // Gets every "category" (term) in this taxonomy to get the respective posts
    $terms = get_terms( $taxonomy );
 
    foreach( $terms as $term ) : ?>

        <?php
        $args = array(
                'post_type' => $post_type,
                'posts_per_page' => -1,  //show all posts
                'tax_query' => array(
                    array(
                        'taxonomy' => $taxonomy,
                        'field' => 'slug',
                        'terms' => $term->slug,
                    )
                )
 
            );
        $posts = new WP_Query($args);
        if( $posts->have_posts() ): ?> 

			<!-- Описание категории и т.д. -->
			
			<?php while( $posts->have_posts() ) : $posts->the_post(); ?>
				<!--Вывод превью поста-->
        				<?php endwhile;?>
					</div>
				</div>
    			<?php endif;?>
    <?php endforeach; ?>
<?php endforeach; ?>
  • Вопрос задан
  • 118 просмотров
Пригласить эксперта
Ответы на вопрос 1
artzolin
@artzolin Куратор тега WordPress
php, WordPress разработка сайтов artzolin.ru
Если рассматривать ваш пример, то можно пытаться получить хотя бы один пост со значением publish_in = true в каждой таксономии

$taxonomies = get_object_taxonomies( array( 'post_type' => $post_type ) );

foreach( $taxonomies as $taxonomy )  {
	
	$terms = get_terms( $taxonomy );

	foreach( $terms as $term ) {

		$posts = get_posts(  array(
			'post_type' => $post_type,
			'posts_per_page' => 1,
			'fields' => 'ids',
			'tax_query' => array(
				array(
					'taxonomy' => $taxonomy,
					'field' => 'slug',
					'terms' => $term->slug,
				)
			),
			'meta_query' => array(
				array(
					'key' => 'publish_in',
					'value' => true,
				),
			),
		) );

		if ( is_array( $posts ) && count( $posts ) > 0 ) {
			print_r( $term );
		}

	}
}


Но это плодит очень много запросов

Можно на любом хуке до контента проверять наличие постов со значением publish_in = true, если находимся в категории и писать это в мету

add_action( 'wp_head', 'category_publish_in_update' );
function category_publish_in_update() {
	
	// выходим, если не категория
	if ( !is_category() ) {
		return;
	}

	// проверяем, что поле publish_in не обновлено
	if ( !get_term_meta( get_queried_object()->term_id, 'publish_in', true ) ) {

		// если находимся в категории, пытаемся получить хоть один пост с publish_in = true
		$posts = get_posts( array(
			'posts_per_page' => 1,
			'cat' => get_queried_object()->term_id,
			'fields' => 'ids',
			'meta_query' => array(
				array(
					'key' => 'publish_in',
					'value' => true,
				),
			),
		) );

		// если такой пост есть, записываем в мету категории publish_in = true
		if ( is_array( $posts ) && count( $posts ) > 0 ) {
			update_term_meta( get_queried_object()->term_id, 'publish_in', true );
		}

		// обновляем поле publish_in_update, чтобы не запускать функцию каждый раз
		update_term_meta( get_queried_object()->term_id, 'publish_in_update', true );

	}
		
}


На хук обновления поста вешаем обновление обновление меты таксономии

// обновляем поле publish_in_update при публикации записи
add_action( 'save_post', 'custom_save_post', 25 );
function custom_save_post( $post_id ) {

	// проверяем, что это post и у него есть хотя бы одна категория
	if ( get_post_type( $post_id ) === 'post' && has_term( '', 'category', $post_id ) ) {

		foreach( get_the_terms( $post_id, 'category' ) as $category ) {
			update_term_meta( $category->term_id, 'publish_in_update', false );
		}

	}

}


Теперь в запросе можно получить таксономии только с ключом publish_in true

$taxonomies = get_object_taxonomies( array( 'post_type' => $post_type ) );

$args = [
	'taxonomy' => [ $taxonomies ],
	'meta_query' => array(
		array(
			'key' => 'publish_in',
			'value' => true,
		),
	),
];

if ( $terms = get_terms( $args ) ) {
	foreach( $terms as $term ){
		print_r( $term );
	}
}


PS. Писалось без тестов, что-то может не работать, а проверки вида is_category() нужно заменить на проверки вашей таксономии
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы