Skip Navigation

[Resolved] Validate that the parent has specific term/field value

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

Problem: I have a Form that creates child posts. I would like to use the cred_form_validate API to ensure that the parent post chosen in the Form has specific terms and custom field values.

Solution: Use custom code to query the parent post and compare its terms and custom field values.

add_filter('cred_form_validate','validate_parent_consultant',10,2);
 
function validate_parent_consultant($field_data, $form_data)
{
    list($fields,$errors)=$field_data;
    //error_log(print_r($fields, true));
    $forms = array( 6 );
 
    // validate if correct CRED form ID
    if ( in_array( $form_data['id'], $forms ) ) {
 
      // edit these 6 lines as needed
      $parent_field_post_name = '@consultant-event_parent';
      $parent_field_name = '@consultant-event.parent';
      $checkbox_slug = 'parent-checkbox-field';
      $taxonomy_slug = 'consultant-taxonomy';
      $taxonomy_terms = array('a', 'b');
      $test_cbs = array( 'a', 'b', 'c' );
 
      // get the parent ID from the form field
      $parent_id = $_POST[$parent_field_post_name];
 
      // check if parent has all matching checkboxes
      $vals = types_render_field($checkbox_slug, array( "separator"=>",", "id"=>$parent_id));
      $any = strlen($vals) > 0 ? explode(',', $vals) : array();
      $cbs_match = sizeof($any) > 0 && sizeof(array_intersect( $any, $test_cbs)) == sizeof($test_cbs);
 
      // Test if the parent has all the right term(s)
      $matching_terms = [];
      foreach($taxonomy_terms as $tax_term) {
        if( is_object_in_term( $parent_id, $taxonomy_slug, $tax_term ) ){
          $matching_terms[]= $tax_term;
        }
      }
      $terms_match = sizeof($matching_terms) == sizeof($taxonomy_terms);
 
      // combine parent validations
      if( !$cbs_match || !$terms_match ) {
        $errors[$parent_field_name] = __('Select a different parent post.', 'your-theme-domain');
      }
    }
 
    //return result
    return array($fields,$errors);
}

Relevant Documentation:
https://toolset.com/documentation/customizing-sites-using-php/functions/
https://toolset.com/documentation/programmer-reference/cred-api/#cred_form_validate
https://codex.wordpress.org/Function_Reference/is_object_in_term

This support ticket is created 6 years, 5 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 8 replies, has 3 voices.

Last updated by ioannisM-2 6 years, 5 months ago.

Assisted by: Christian Cox.

Author
Posts
#924691

How could use cred validate hook to allow the creation of a child post only if the parent post has specific term value and/or specific custom field value?

#924988

You would craft a Custom Code, that get's the parent post ID of the post you create, and then it's field value.
In the Custom Code you then compare that value to what you want it to be.

After, you either allow the form to submit, or abort.

This particular aspect (allowing/denying the for to submit) is done by adding above Custom Code with the Toolset Forms cred_form_vaidate() hook to the Form:
https://toolset.com/documentation/programmer-reference/cred-api/#cred_form_validate

This means:

add_filter('cred_form_validate','my_validation',10,2);//We add our Custom Code to the Form

function my_validation($error_fields, $form_data) //This is our Custom Code
{
    //Everything here is written so to get and compare values (Custom Code)
    //return result
    return array($fields,$errors);//We return what Toolset Forms expects from such a code
}

As you see a lot of this is Custom Code that needs to be crafted with WordPress API and PHP.

But, since you need to get Toolset Related posts, there are things to know and you can use.
For example we have an API to get those Parent Posts or Post, and then you can use WordPress API to get that Posts Field.
The Toolset API to get related posts is documented here:
https://toolset.com/documentation/customizing-sites-using-php/post-relationships-api/

Now, since there are several ways to connect posts, and if you do not know how to proceed with the Toolset API to get posts, please let me know these details:
- your setup (Many to many, one to many, etc etc)
- what kind of field you want to validate
- does the happen on a post form for new child posts where you link from a parent, or how do you set the new posts parent?

I can then help crafting a sample code.

#929914

Hello Beda,

1)I have created the post type consultant that has the taxonomy, "consultant-taxonomy" and the field "wpcf-parent-checkbox-field" that is a checkbox multifield.
2) I have created the post type event that is a child of consultants
3) I have created with the new relationship system the relationship consultants-events that is a many to many relationship. Multiple events can be assigned to multiple consultants.
4) I have created the post type job that is child of consultant
5)I have created the relationship consultant-job that is one to many relationship. Multiple jobs can be assigned to only one consultant
6) The creation of the childs is done through a cred child link in the parent's post content template
7) If the child post exists I assign the parent through an edit form and the default value for the parent comes from url parameter

This is what I am trying to do:

a) a job or an event can be created as child of a consultant
b) a job or an event that exists can be assigned to the consultant as a child

only If a consultant post has:

a) the consultant-taxonomy term a, consultant taxonomy term b or
b) wpcf-parent-checkbox-field with the values a,b or c

#947948

Here's the general format:

add_filter('cred_form_validate','validate_parent_consultant',10,2);

function validate_parent_consultant($field_data, $form_data)
{
    list($fields,$errors)=$field_data;
    //error_log(print_r($fields, true));
    $forms = array( 12345 );

    // validate if correct CRED form ID
    if ( in_array( $form_data['id'], $forms ) ) {

      // edit these 6 lines as needed
      $parent_field_post_name = '@consultant-event_parent';
      $parent_field_name = '@consultant-event.parent';
      $checkbox_slug = 'parent-checkbox-field';
      $taxonomy_slug = 'consultant-taxonomy';
      $taxonomy_terms = array('a', 'b');
      $test_cbs = array( 'a', 'b', 'c' );

      // get the parent ID from the form field
      $parent_id = $_POST[$parent_field_post_name];

      // check for matching checkboxes
      $vals = types_render_field($checkbox_slug, array( "separator"=>",", "id"=>$parent_id));
      $any = strlen($vals) > 0 ? explode(',', $vals) : array();
      $cbs_match = sizeof($any) > 0 && !empty( array_intersect( $any, $test_cbs ));

      // Test if the parent has the right term(s)
      $terms_match = is_object_in_term( $parent_id, $taxonomy_slug, $taxonomy_terms );

      // combine parent validations
      if( !$cbs_match && !$terms_match ) {
        $errors[$parent_field_name] = __('Select a different parent post.', 'your-theme-domain');
      }
    }

    //return result
    return array($fields,$errors);
}

Change 12345 to match the form ID. Edit the slugs and values as needed in the 6 lines that are noted if necessary.

#952280

Thank you so much Cristian, you helped me a lot! I would like also to ask you:

1) If I need to use the validation for more than one forms, how could I insert multiple form ids?

2) The validation works if one of the conditions exist. Is there a way to make it also work if all the conditions exist?

#953135

1) If I need to use the validation for more than one forms, how could I insert multiple form ids?
Add the form IDs as a comma-separated list in line 7 of the code above, like this:

$forms = array( 12345, 67890, 54321 );

2) The validation works if one of the conditions exist. Is there a way to make it also work if all the conditions exist?
The validation works if any checkboxes match, or if any terms match. If checkboxes and terms match, the validation still passes. Not sure I understand - should at least one matching term AND one matching checkbox be required?

#953206

Hello Cristian,

I mean to validate that ALL terms AND ALL checkboxes exist. How could I do that?

#953230

Something like this would work:

add_filter('cred_form_validate','validate_parent_consultant',10,2);

function validate_parent_consultant($field_data, $form_data)
{
    list($fields,$errors)=$field_data;
    //error_log(print_r($fields, true));
    $forms = array( 6 );

    // validate if correct CRED form ID
    if ( in_array( $form_data['id'], $forms ) ) {

      // edit these 6 lines as needed
      $parent_field_post_name = '@consultant-event_parent';
      $parent_field_name = '@consultant-event.parent';
      $checkbox_slug = 'parent-checkbox-field';
      $taxonomy_slug = 'consultant-taxonomy';
      $taxonomy_terms = array('a', 'b');
      $test_cbs = array( 'a', 'b', 'c' );

      // get the parent ID from the form field
      $parent_id = $_POST[$parent_field_post_name];

      // check if parent has all matching checkboxes
      $vals = types_render_field($checkbox_slug, array( "separator"=>",", "id"=>$parent_id));
      $any = strlen($vals) > 0 ? explode(',', $vals) : array();
      $cbs_match = sizeof($any) > 0 && sizeof(array_intersect( $any, $test_cbs)) == sizeof($test_cbs);

      // Test if the parent has all the right term(s)
      $matching_terms = [];
      foreach($taxonomy_terms as $tax_term) {
        if( is_object_in_term( $parent_id, $taxonomy_slug, $tax_term ) ){
          $matching_terms[]= $tax_term;
        }
      }
      $terms_match = sizeof($matching_terms) == sizeof($taxonomy_terms);

      // combine parent validations
      if( !$cbs_match || !$terms_match ) {
        $errors[$parent_field_name] = __('Select a different parent post.', 'your-theme-domain');
      }
    }

    //return result
    return array($fields,$errors);
}
#953945

Yes, it is working! Thank you Christian!!!!