Skip Navigation

[Resolved] get_posts Returning Empty Array within cred_form_validate

This support ticket is created 3 years, 1 month 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: Africa/Casablanca (GMT+01:00)

This topic contains 7 replies, has 2 voices.

Last updated by Jamal 3 years, 1 month ago.

Assisted by: Jamal.

Author
Posts
#2212719
Screenshot 2021-11-04 11.35.01 - Display 2.png
Screenshot 2021-11-04 11.35.00 - Display 1.png

Tell us what you are trying to do?
Use get_posts to check if a post already exists with the same title that a form is attempting to create. The title is formed from a pair of select fields, so cannot be unpredictable.

Is there any documentation that you are following?
https://toolset.com/forums/topic/cred-before-save-data-allow-only-one-submition-of-the-form/
https://toolset.com/documentation/programmer-reference/cred-api/#cred_form_validate
https://codex.wordpress.org/Template_Tags/get_posts

Is there a similar example that we can see?
https://toolset.com/forums/topic/cred-before-save-data-allow-only-one-submition-of-the-form/

What is the link to your site?
Links and access can be provided in PM's.

All I have been trying to do is create a custom validation that assembles what will be saved as the post title (as stated above, it is formed from two select fields and as such is entirely predictable) and ensure that a post has not already been created with that title. This should have been a simple case of using get_posts to search for an existing post_title within the post_type being used. But no matter what arguments I pass to get_posts, it will always return an empty array! This happens if I try using the CPT, or just pages, or any other simple or complex set of arguments. Nothing is ever returned. I have even tried including the global posts argument, but that made no difference either.

Here is the relevant part of the snippet:

add_filter('cred_form_validate','my_validation',10,2);
function my_validation($error_fields, $form_data)
{
  //Load list of field data comprised of field values and errors
  list( $fields, $errors ) = $error_fields;
  //uncomment this if you want to print the field values
  //print_r($fields);

  //** Validation for New Term form **//
  if ( $form_data['id'] == 446 )
  {

    /***  Other working validation is here  ***/

    /* Check if a Term with the same name has already been created */

    if ( isset( $fields['wpcf-school-term']['value'] ) )
    {
      global $posts;

      //Assemble the name from the select fields
      $current_term = $fields['wpcf-school-term']['value'] . " " . $fields['wpcf-term-year']['value'];

      //Array of arguments to check existing academic-term posts
      $args = array(
        'orderby'         =>  'post_date',
        'order'           =>  'ASC',
        'posts_per_page'  => 1,
        'post_type'       =>  'pages',
       'post_title'      =>  $current_term
      );

      $terms = get_posts( $args );

      if ( $terms['post_title'] == $current_term )
      {
        //set error message for post title
        $errors['school-term'] = $fields['wpcf-school-term']['value'] . " " . $fields['wpcf-term-year']['value'] . ' already exists, so you cannot create another one.';
      }
    }
  }

  //Return array of results
  return array($fields,$errors);
}

I also tried

if ( sizeof( $terms ) > 0 )

like the other post suggested, but it returns a size of 1, so always triggers the validation.

No matter what, the $terms array (and oddly the $args array if I try dumping it) always output an empty array.

The form is being loaded in a modal (I attached a screenshot for reference) and submitted via ajax, not that this should make any difference as all of the other validations work fine, so the hook is definitely firing properly. Also, before it is asked, 'academic-term' is definitely the correct post type, see second attached screenshot for proof. But as mentioned before, get_posts is refusing to return anything at all and I am stuck as to how I can debug it any further.

Thanks in advance.

#2212845

Hello and thank you for contacting the Toolset support.

I am a bit confused, do you want to have unique titles for the posts, or do you want the posts to have unique values for the custom field "school-term"?

Because you are testing the value of the school-term, and then adding the error on it, I am keen to think that you want unique values for the custom field instead of unique titles.
If you want unique titles, the arguments for get_posts are not correct:
- The post_type should be set to school-term instead of 'pages' at line 29: " 'post_type' => 'pages', "

If you want to check against the custom field "school-term", the argument should include a meta_key rule.

Would you like to allow me temporary access to check this further? Your next reply will be private to let you share credentials safely.
Please elaborate more on what you want to achieve and I'll do my best to help.

#2212983

Thank you for the details and the credentials. In this case, you need to use these arguments, the post_type should not be "pages":

      $args = array(
        'orderby'         =>  'post_date',
        'order'           =>  'ASC',
        'posts_per_page'  => 1,
        'post_type'       =>  'academic-term',
       'post_title'      =>  $current_term
      );

The post_type should "academic-term" because that's the post type that you want to check against, right!

If that does not help, let me know where the form is used on the frontend so I can test it.

#2212997

Ok, this is partly my bad as the code I posted contained this mistake due to my desperate testing to try and get ANY results back. As such, and as I stated in my opening post, I changed the post_type to page and pages and various other things to see if it would return anything at all, which it didn't. I had put the rest of the arguments back in but missed that one before I took a copy.for the post. So that is my mistake.

However, I do state in my opening post that in no uncertain terms I know it should be "academic-term" in the post_typs, as this is what I had been trying for the last hour or two prior to posting.

So I'm afraid, unless there's something else I've missed, this isn't the answer as I've tested it very thoroughly with this parameter, even just this parameter and no others, before opening a support thread.

You can find it on the front end under Terms, click on a term name on the left, then New Exclusion. Although this code us currently commented as I stopped working on it whilst waiting for the support thread to be answered. It's currently in a bit of a commented, disjointed mess at the bottom of the Toolset Snippet custom_form_validations if I remember rightly (I'm not at my computer right now I'm afraid, but it's definitely the only snippet that refers to form validation).

#2213725

Apologies, my previous post had some errors in it as I wasn't at my desk and couldn't fact check so please disregard anything this post contradicts as THIS post is 100% accurate.

Just so there's no further confusion, here is the actual validation code as it was when I put back to normal (I just removed a bunch of commented tests and gave up testing) and I've fully commented it to try and help:

/* Check if a Term with the same name has already been created */

    //Once the term has been selected, validation can run (probably unnecessary, here as a test)
    if ( isset( $fields['wpcf-school-term']['value'] ) )
    {

      //Assemble name from form fields
      $current_term = $fields['wpcf-school-term']['value'] . " " . $fields['wpcf-term-year']['value'];

      //Setup arguments to check if any other term has the same name
      $args = array(
        'orderby'         =>  'post_date',
        'order'           =>  'ASC',
        'posts_per_page'  => 1,
        'post_type'       =>  'academic-term',
        'post_title'      =>  $current_term
      );

      //Check for existing terms with the same name
      $terms = get_posts( $args );
      
      //If a term is found and it's post title is the same as the one being set by the form, fail to validate      
      //if ( sizeof( $terms ) > 0 )  //Originally used but returning 1 from empty array so not being used at present
      if ( $terms['post_title'] == $current_term )
      {

        //School Term error message (doesn't matter if this is attributed to term or year as they both form the title, term is used as it's first)
        $errors['school-term'] = $fields['wpcf-school-term']['value'] . " " . $fields['wpcf-term-year']['value'] . ' already exists, so you cannot create another one.';
      }
    }

I didn't bother to include the function, form check and return bits, but obviously they're there and work fine.

I've just retested this as well and it still returns an empty array. I dumped $args, $terms and $terms['post_title'] just to check and got nothing:

Args = Array
Terms = Array
Post Title =

The snippet is called custom_form_validations, it's running on form ID 446, which is accessed from the New Term button academic-term archive, which is archive ID 448.

Hopefully that clarifies everything and you can see where everything is and the problem still persists.

#2215147

My apologies for missing this on the first place, but the WP_Query class does not accept an "post_title" argument. So, you must search by custom fields or use some custom code, eventually SQL code. Check these examples:
- https://stackoverflow.com/questions/31904585/search-only-in-post-titles-in-the-wordpress-to-get-title-and-id
- https://stackoverflow.com/questions/25103949/wordpress-get-posts-by-title-like
- https://stackoverflow.com/questions/27833926/search-query-for-post-title
- hidden link

However, there are two WordPress functions that perform search by titles:
- https://developer.wordpress.org/reference/functions/post_exists/
- https://developer.wordpress.org/reference/functions/get_page_by_title/

Using post_exists, you can do something like:

$post_exists = post_exists( $current_term, null, null, 'academic-term', null);
if ( $post_exists > 0 )
{
    $errors['school-term'] = $fields['wpcf-school-term']['value'] . " " . $fields['wpcf-term-year']['value'] . ' already exists, so you cannot create another one.';
}

I hope this helps. Let me know if you have any questions.

#2215913

Ah, I see! I was getting confused between what it accepted and what it returned! Many thanks for that, I got a bit too obsessed with why that wasn't working and didn't think to explore other functions!

That is indeed working. But I have to wonder why it wouldn't return anything when I didn't use the post_title as a parameter. Even just asking it to return all posts of academic_term or pages resulted in a blank array. Weird.

Any thought's on that so I can figure out why and learn from the experience before I close the ticket off bud?

#2215937

Well, I am keen to think, that it was a small mistake on using the WP_Query class arguments. Usually, it is something obvious that we don't spot quickly at first. Programming experience 🙂
https://developer.wordpress.org/reference/classes/wp_query/

If you need me to debug something, please prepare an example and let me check it.