Как исключить текущий пост и нежелательную таксономию из пользовательского запроса типа поста

Я нахожусь в single-product.php, где я создаю собственный тип сообщения, а также создаю таксономию под названием product-cat. одна из таксономий, которые я использовал в другом запросе, — «новые и бестселлеры».

На single-product.php В разделе я хочу запросить связанный продукт, кроме текущего продукта и таксономии «новый и бестселлер».

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

Это мой код до сих пор:

    <?php $productCats = get_the_terms($post->ID, 'product-cat');
//Pluck to get an array of ids
$productCats_ids = wp_list_pluck($productCats, 'term_id');
?>
<?php
$relatedProducts = new WP_Query(array(
  'post_type' => 'product',
  'tax_query' => array(
    // 'relation' => 'AND',
    array(
      'taxonomy' => 'product-cat',
      'field' => 'id',
      'terms' => $productCats_ids,
      'operator' => 'IN',
    ),
    // array(
    //   'taxonomy' => 'product-cat',
    //   'field' => 'id',
    //   'terms' => array('new-and-best-seller'),
    //   'operator' => 'NOT EXISTS'
    // )
  ),
  'category__not_in' => array(28)
));
if ($relatedProducts->have_posts()) { ?>
  <section id = "newest-products" class = "mb-section">
    <div class = "container">
      <h1 class = "main__title">
        <strong class = "main__title--bold">Related products</strong>
      </h1>
      <div class = "newest-products-wrapper owl-carousel owl-theme">
        <?php while ($relatedProducts->have_posts()) {
          $relatedProducts->the_post(); ?>
          <div class = "card product-card">
            <img class = "card-img-top product-card--img" src = "./assets/images/image 401.jpg" alt = "">
            <?php the_post_thumbnail('medium', array('class' => 'card-img-top product-card--img')); ?>
            <div class = "card-body">
              <h2 class = "card-title product-card--title"><?php esc_html(the_title()); ?></h2>
              <a href = "<?php esc_url(the_permalink()); ?>" class = "product-card--more">See available items</a>
            </div>
          </div>
        <?php }
        wp_reset_postdata(); ?>
      </div>
    </div>
  </section>
<?php } ?>

🤔 А знаете ли вы, что...
PHP предоставляет множество инструментов для отладки кода, таких как Xdebug.


106
1

Ответ:

Решено

Псевдокод ниже представлен для прояснения вопроса.

Псевдокод

$post1 = has( 'term' => array( 'new-and-best-seller' , 'A' ) );

$post2 = has( 'term' => array( 'new-and-best-seller', 'B' ) );

$post3 = has( 'term' => array( 'B', 'A', 'new-and-best-seller' ) );

$post4 = has( 'term' => array( 'new-and-best-seller' ) );

$post5 = has( 'term' => array( 'A' ) );

Пять сообщений выше относятся к вашему пользовательскому типу сообщений и указывают на термины таксономии product-cat, которые у них есть. $post1 — текущая запись.

Возникает вопрос: «Как мне отфильтровать свои пользовательские сообщения, чтобы включить в них $post3 и $post5 (сообщения, связанные с $post1 через термин A таксономии), исключая при этом $post2, $post4 и текущий пост ($post1)?

Запрос ниже должен найти нужные сообщения. (Приведенный ниже код не включает переменную WP_Query category__not_in. Было неясно, как она связана с вашим вопросом. Поэтому вам может потребоваться ее включить.)

Решение

function filter_for_product_custom_post() {
$unwanted_term_slug = 'new-and-best-seller';
$custom_taxonomy    = 'product-cat';

$current_post_id = \get_the_ID();

$unwanted_term_ids = \get_terms(array(
  'taxonomy' => $custom_taxonomy,
  'slug'     => $unwanted_term_slug,
  'fields'   => 'ids'
));

$wanted_term_ids = \wp_get_object_terms(
  $current_post_id,
  $custom_taxonomy,
  array(
    'exclude' => $unwanted_term_ids,
    'fields'  => 'ids'
  )
);
?>
<?php
$relatedProducts = new WP_Query(array(
  'post_type' => 'product',
  'tax_query' => array(
    array(
      'taxonomy' => $custom_taxonomy,
      'field' => 'term_id',
      'terms' => $wanted_term_ids,
      'operator' => 'IN',
    ),
  ),
  'post__not_in' => array($post->ID), //exclude current product
));

    ...

    while ( $relatedProducts->have_posts() ) {
        $relatedProducts->the_post();

        ...

    }

    ...

    \wp_reset_postdata();

}