Skip Navigation

[Resolved] Filtering Posts for relationship connection in a submission form

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

Problem: I would like to filter the parent post options in a Form that creates child posts. I would like to add custom code that filters the options based on their other post relationships.

Solution: Use the pre_get_posts filter to filter the parent post options in the parent post field. See the following example code:

/**
 * Filter the Children parent field in the connect-toy-to-childmale Relationship Form 
 * to only show Children connected to Gender Male.
 * https://toolset.com/forums/topic/filtering-posts-for-relationship-connection-in-a-submission-form/
 */
function filter_parent_posts( $query ){
  $parent_post_type = "child";  // slug of parent post type
  $child_post_type = "toy";     // slug of child post type
  $rel_slug = "gender-child";   // slug of gender-child post relationship
  $male_post_id = 9;            // ID of Gender Male post
  $rel_form_id = 26;            // ID of the relationship form
 
  // relationship form is on Toy single posts, queries parent_post_type posts
  if ( ( defined('DOING_AJAX') && DOING_AJAX )
    && isset($query->query['post_type'][0])
    && $query->query['post_type'][0] == $parent_post_type
    && isset($_REQUEST['action'])
    && $_REQUEST['action'] == 'cred_association_form_ajax_role_find'
    && isset($_REQUEST['form_id'])
    && $_REQUEST['form_id'] == $rel_form_id
  ) {
    // querying by gender post, which is parent in gender-child
    $males = toolset_get_related_posts( $male_post_id, $rel_slug, array(
      'query_by_role' => 'parent',
      'limit' => 1000,
      'offset' => 0,
      'args' => array(),
      'return' => 'post_id',
      'role_to_return' => 'child'
    ));
 
    $query->set( 'post__in', $males );
  }
}
add_action( 'pre_get_posts', 'filter_parent_posts', 101, 1 );

Relevant Documentation:
https://toolset.com/forums/topic/how-to-show-in-cred-parent-selector-only-posts-of-logged-in-user/page/2/#post-605405

https://toolset.com/forums/topic/filter-post-relationship-dropdown-by-taxonomy/#post-1220408

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

This support ticket is created 3 years, 6 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
8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 - -
13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 - -

Supporter timezone: America/New_York (GMT-04:00)

This topic contains 11 replies, has 2 voices.

Last updated by igorL-3 3 years, 6 months ago.

Assisted by: Christian Cox.

Author
Posts
#2035771

Tell us what you are trying to do? I have a number of custom post types(POST_A and POST_B) that are in one-to-many relationship. I have made a form to enter new POST_As and connect them with POST_Bs s in a relationship. In a form I get a dropdown menu of all the POST_Bs and I can pick one to connect with the new POST_A. However, POST_Bs have an additional relationships with custom post type POST_C which contain 3 posts (X, Y, Z). custom post type POST_C is connected to only one of the posts of type POST_C. For example: POST_B1<—>X, POST_B2<—>X, POST_B3<—>X, POST_B10<—>Y, POST_B20<—>Y, POST_B100<—>Z, POST_B200<—>Z. What I want to do in my form to connect new POST_A type to POST_B type is to have a dropdown menu that lists only POST_Bs that are connected to X or Y or Z but not XY, XYZ etc…

How can I filter on the (X, Y, Z) in the dropdown menu in the form.

Thank you in advance

Is there any documentation that you are following?

Is there a similar example that we can see?

What is the link to your site?

#2035981

Hello, I'm a bit confused by your examples, but it sounds like you have a Form that creates posts in post type A. This post type A is a child in a one-to-many post relationship with post type B. Post type B is the parent post type in this relationship. In the Form that creates post type A, you have a field that allows Users to select the parent post type B, but you want to filter the list of possible type B posts based on some criteria involving a post relationship between post type B and post type C.

There's nothing exactly like that built into the system, but there are some custom code examples available in other tickets showing how to use the WordPress API pre_get_posts to filter the options in a parent select field:
https://toolset.com/forums/topic/how-to-show-in-cred-parent-selector-only-posts-of-logged-in-user/page/2/#post-605405
https://toolset.com/forums/topic/filter-post-relationship-dropdown-by-taxonomy/#post-1220408

The post relationships APIs toolset_get_related_post and toolset_get_related_posts can be used to query related posts from any post relationship:
https://toolset.com/documentation/customizing-sites-using-php/post-relationships-api/#toolset_get_related_post
https://toolset.com/documentation/customizing-sites-using-php/post-relationships-api/#toolset_get_related_posts

If you run into problems implementing this type of filter code, I can take a closer look if you provide more details about what you want to accomplish and the problem you are experiencing.

#2036581

Thank you Christian but I’m a bit confused with that code. I wonder if you could work the example I’ve created on the hidden link site. This is the same site you used last time to show me how to disconnect posts so you still have admin rights there.

I have added more children and a custom type GENDER (with two posts MALE and FEMALE). The CHILD custom post is in a relationship wit GENDER. I have assigned each child a gender. I then created, on the Homepage, a form that asks you to enter a new toy, say a truck. Then it goes to the next page where it allows you to connect the new toy to one of the children and I want the dropdown menu to only show say males.

Can that be done?

Thank you in advance

#2036731

Unfortunately there is no way to add custom PHP code to discover-wp.com sandbox sites. It is not possible to install a child theme, create custom code snippets in Toolset > Settings, or add any custom code snippet plugins. We would need to work in a different sandbox site where one of these features is available. Do you have a server set up somewhere we could use?

#2036773

Right, I made a copy of the test site and made you admin. If you don't get an email about your account send me a secure request and I'll send you the account details

#2037111

Okay thanks, I am able to log in and access the admin area. I am working on some examples now and I will give you another update shortly.

#2037221

Okay I've added a new snippet "filter-children-parent-male" in Toolset > Settings > Custom code with the following custom code:

/**
 * Filter the Children parent field in the connect-toy-to-childmale Relationship Form 
 * to only show Children connected to Gender Male.
 * https://toolset.com/forums/topic/filtering-posts-for-relationship-connection-in-a-submission-form/
 */
function filter_parent_posts( $query ){
  $parent_post_type = "child";  // slug of parent post type
  $child_post_type = "toy";     // slug of child post type
  $rel_slug = "gender-child";   // slug of gender-child post relationship
  $male_post_id = 9;            // ID of Gender Male post
  $rel_form_id = 26;            // ID of the relationship form

  // relationship form is on Toy single posts, queries parent_post_type posts
  if ( ( defined('DOING_AJAX') && DOING_AJAX )
    && isset($query->query['post_type'][0])
    && $query->query['post_type'][0] == $parent_post_type
    && isset($_REQUEST['action'])
    && $_REQUEST['action'] == 'cred_association_form_ajax_role_find'
    && isset($_REQUEST['form_id'])
    && $_REQUEST['form_id'] == $rel_form_id
  ) {
    // querying by gender post, which is parent in gender-child
    $males = toolset_get_related_posts( $male_post_id, $rel_slug, array(
      'query_by_role' => 'parent',
      'limit' => 1000,
      'offset' => 0,
      'args' => array(),
      'return' => 'post_id',
      'role_to_return' => 'child'
    ));

    $query->set( 'post__in', $males );
  }
}
add_action( 'pre_get_posts', 'filter_parent_posts', 101, 1 );

You can see I'm using the post relationships API toolset_get_related_posts to get all the Child posts associated with the Male post (ID 9). That API returns an array of post IDs, which I am in turn passing into the filter options post query as the post__in parameter: https://developer.wordpress.org/reference/classes/wp_query/#post-page-parameters

Now when you visit a Toy post, the filter options only include Children associated with the Male post from the Gender post type, and only those Children that are not already associated to this Toy post:
hidden link

I ran a quick test and was able to associate one of the male children using the Form. I reverted that change from wp-admin for now. Care to take a look?

#2037487

Thank you very much this has helped to get the idea. I have two questions for clarification:

1. When you generate an array of id's "$males = toolset_get_related_posts(...." you placed a limit of 1000. Does that mean this method will only work for a relatively small number of entries. If say instead of 1000 posts there are 10 times or more and the database can also grow with use. Will it generate a hudge array and possibly run into problems or will it do so dynamically as needed?

2. What if instead of 2 types to filter by (as in this case MALE and FEMALE) there are more types. Is it possible to filter by a negation (ie. an array of all NOT FEMALES as would be in this case)?

#2037493

PS. in the example for toolset_get_related_posts() it gives the following:

// pagination
'limit' => $posts_per_page,
'offset' => ( $current_page - 1 ) * $post_per_page,

is that the answer to my first question, where you have set $posts_per_page=1000?

#2038797

I set 'limit' => -1 and got rid of the 'offset'. Also obtained a second array using a different post id to search and then joined the two array before setting in $query. Seems to work, not sure if there is a better way to do this

#2039755

1. When you generate an array of id's "$males = toolset_get_related_posts(...." you placed a limit of 1000. Does that mean this method will only work for a relatively small number of entries. If say instead of 1000 posts there are 10 times or more and the database can also grow with use. Will it generate a hudge array and possibly run into problems or will it do so dynamically as needed?
I placed an arbitrary limit of 1000 because a limit number is required for the API arguments and the default value is 100. If the maximum number you need is higher, the API can handle a higher limit. There is no hard-set maximum number for limit, so adjust it as needed for your site.

2. What if instead of 2 types to filter by (as in this case MALE and FEMALE) there are more types. Is it possible to filter by a negation (ie. an array of all NOT FEMALES as would be in this case)?
The API does not support this type of query, it is designed to find posts that are related to specific posts, not posts that are not related to specific posts. You can submit multiple post IDs in an indexed array, and the API will return all posts related to those posts. So for example, if you have MALE, NEUTER, and OTHER gender posts, you would submit those post IDs in an array indexed by role name, and the API would find all the posts related to all those Gender posts. See the API documentation section "Arrays of arrays of posts indexed by role names" for an example in code.
https://toolset.com/documentation/customizing-sites-using-php/post-relationships-api/#toolset_get_related_posts

...Also obtained a second array using a different post id to search and then joined the two array before setting in $query. Seems to work, not sure if there is a better way to do this
Sure, and see in the documentation "Arrays of arrays of posts indexed by role names" for more information about querying by multiple post IDs. That might be simpler.
https://toolset.com/documentation/customizing-sites-using-php/post-relationships-api/#toolset_get_related_posts

#2039783

My issue is resolved now. Thank you!