Skip Navigation

[Resolved] Get an array of WooCommerce products that have a related post

This thread is resolved. Here is a description of the problem and solution.

Problem:

Query related posts on Toolset post type relationship in custom PHP codes.

Solution:

You can try the Relationship API function toolset_get_related_post(), see our document:

Relevant Documentation:

https://toolset.com/documentation/customizing-sites-using-php/post-relationships-api/#toolset_get_related_post

This support ticket is created 3 years, 3 months ago. There's a good chance that you are reading advice that it now obsolete.

This is the technical support forum for Toolset - a suite of plugins for developing WordPress sites without writing PHP.

Everyone can read this forum, but only Toolset clients can post in it. Toolset support works 6 days per week, 19 hours per day.

Sun Mon Tue Wed Thu Fri Sat
- 9:00 – 13:00 9:00 – 13:00 9:00 – 13:00 9:00 – 13:00 9:00 – 13:00 -
- 14:00 – 18:00 14:00 – 18:00 14:00 – 18:00 14:00 – 18:00 14:00 – 18:00 -

Supporter timezone: Asia/Hong_Kong (GMT+08:00)

This topic contains 4 replies, has 2 voices.

Last updated by diegoQ-2 3 years, 2 months ago.

Assisted by: Luo Yang.

Author
Posts
#2207367

Tell us what you are trying to do?
In my website, some WooCommerce products have another post related (one to one relationship). I need an array that includes all post ID for the WooCommerce products that have such related post.
E.g.
1. Product ID 916 is related to custom-post-type ID 567
2. Product ID 2568 is related to custom-post-type ID 9856
3. Product ID 52645 doesn't have a related custom-post-type
The resulting array must be: array(916,2568);

Context: I want to remove any WooCommerce product that has previously explained relationship from Search Results. I'm using following snipped to manually remove the post IDs of the products I KNOW that have a relation, but I want to automate that:

add_filter( 'pre_get_posts', function( $query ) {
  if ( $query->is_search && !is_admin() ) {
    $query->set( 'post__not_in',array(916,2568) );
  }
  return $query;
});

Is there any documentation that you are following?
I tried https://toolset.com/documentation/customizing-sites-using-php/post-relationships-api/#toolset_get_related_posts
But couldn't figure out how to make it work.

Is there a similar example that we can see?
I couldn't find any.

What is the link to your site?
hidden link

#2207673

Hello,

For the question:
I want to remove any WooCommerce product that has previously explained relationship from Search Results

There isn't such kind of built-in feature within Toolset plugins, you might consider other workaround, for example:
setup a nested views:
1) Parent post view:
- Query Product posts
- In views loop, display below child post view

2) Child post view:
- Query custom-post-type posts
- Filter by post type relationship between Product and custom-post-type posts
- in section "Loop Editor", if there isn't any result found, you can display the product information within shortcode [wpv-no-items-found] ... [/wpv-no-items-found]

More help:
https://toolset.com/documentation/programmer-reference/views/views-shortcodes/#wpv-no-items-found

#2209389

Hello Luo, thanks for the response. Unfortunately, I believe I didn't explain myself properly.
I already have a working code to remove, manually any post from the search results, this is the code:

add_filter( 'pre_get_posts', function( $query ) {
  if ( $query->is_search && !is_admin() ) {
    $query->set( 'post__not_in',array(916,2568) );
  }
  return $query;
});

Currently, I can go to my admin panel, search for the post ID manually and then fill that snippet with the woo products I want to hide. In fact, I already did that.

What I'm asking for is your help to find a way to consult the list (array) of all post ID of the post type "product" that have a relationship with any other post type (currently can be "producto-woocommerce-p" or "producto-woocommerce" (those are one to one relationship field slugs).

I tried the following code but didn't seems to work (please note the relationship is set as a custom field in the other post types, and not in the 'product' type).

//filter search results
add_filter( 'pre_get_posts', function( $query ) {
  //only if not admin
  if ( $query->is_search && !is_admin() ) {
    //array with IDs to exclude, add manually here those you want
    $exclude_array_ids = array(232266,231900,311); //these ID are pages I want to manually remove

    //get all product ID
    $args_a = array(
      'post_type'    => 'curso-presencial',
      'meta_key'     => 'wpcf-producto-woocommerce-p',
      'meta_value'   => '',
      'meta_compare' => '!='
    );
    $postslist_a = get_posts( $args_a );

    foreach ($postslist_a as $post_a) {
      array_push($exclude_array_ids,$post_a['wpcf-producto-woocommerce-p']);
    }

    //get all product ID
    $args_b = array(
      'post_type'    => 'sfwd-courses',
      'meta_key'     => 'wpcf-producto-woocommerce',
      'meta_value'   => '',
      'meta_compare' => '!='
    );
    $postslist_b = get_posts( $args_b );

    foreach ($postslist_b as $post_b) {
      $exclude_array_ids[] = $post_b['wpcf-producto-woocommerce-p'];
    }

    $query->set( 'post__not_in',$exclude_array_ids );
  }
  return $query;
});
#2209631

In your case, you can try the Relationship API function toolset_get_related_post(), see our document:
https://toolset.com/documentation/customizing-sites-using-php/post-relationships-api/#toolset_get_related_post
Retrieve an ID of a single related post.

#2211335

I was able to make this work as following:

add_filter( 'pre_get_posts', function( $query ) {
  //only if not admin
  if ( $query->is_main_query() && $query->is_search && !is_admin() ) {
    //array with IDs to exclude, add manually here those you want
    $exclude_array_ids = array(231900,311);

    //Exclude Woo Products that have a related post for Online (wpcf-producto-woocommerce)
    // and In-person (wpcf-producto-woocommerce-p) Course
    $args = array(
      'post_type'   => 'product',
      'numberposts' => -1,
      'post_status' => 'publish',
      'fields'      => 'ids',
    );
    $woo_products = get_posts( $args );
    error_log('WOO IDs: ' . print_r($woo_products, true));

    foreach ($woo_products as $product_id) {
      $cp_rel = toolset_get_related_post( $product_id,'producto-woocommerce-p','child');
      error_log('InPerson ID for ('.$product_id.'): ' . print_r($cp_rel, true));
      $co_rel = toolset_get_related_post( $product_id,'producto-woocommerce','child');
      error_log('Online ID for ('.$product_id.'): ' . print_r($co_rel, true));
      if ($cp_rel !== 0 OR $co_rel !== 0) {
        $exclude_array_ids[] = $product_id;
      }
    }
    error_log('EXCLUD IDS: ' . print_r($exclude_array_ids, true));

    $query->set( 'post__not_in',$exclude_array_ids );
    //$query->set( 'post__not_in',array(916,231045,232266,231900,311) );
  }
  return $query;
});

Bests!