Conditional Tag for has post [closed]

I am not familiar with the plugin, but it seems unlikely that the $conditions array you’re adding to should contain any variety of WordPress query arguments. Further, referencing the $conditions array within a property that you’re setting on that very array won’t contain the new data you’ve added, but rather the array as it existed before your additions (i.e. get_posts( $conditions ) will not pass all of those query arguments you’ve added to get_posts()). Just leave the keys as the example demonstrated and pass your query arguments to the query instead of trying to push them through the $conditions variable:

function my_new_menu_conditions( $conditions ) {
  $conditions[] = array(
    'name'    =>  'If User has Listing', // name of the condition
    'condition' =>  function( ) {        // callback - must return TRUE or FALSE
      $args = array(
        'offset'       => 0,
        'author'       => '$current_user',
        'post_type'    => 'job_listing',
        'post_status'  => 'publish'
      );

      return get_posts( $args );
    }
  );

  return $conditions;
}

The next problem is that the example code states the condition must return TRUE or FALSE – if you check out the documentation for the get_posts() function, it details

Return Value


(array)

List of WP_Post objects.

So the plugin expects a boolean (true/false) value, and by returning the return value of get_posts() it instead receives an array (either populated with posts or empty). The plugin may interpret that array as either true or false depending on how it tests the “truthiness” of the condition‘s return value. Without digging through plugin code yourself, it’s better to be safe and explicitly return a boolean value as the plugin requests.

Here, you wish to return true if your query finds any (more than 0) posts, so:

function my_new_menu_conditions( $conditions ) {      
  $conditions[] = array(
    'name'    =>  'If User has Listing', // name of the condition
    'condition' =>  function( ) {        // callback - must return TRUE or FALSE
      $args = array(
        'offset'       => 0,
        'author'       => '$current_user',
        'post_type'    => 'job_listing',
        'post_status'  => 'publish'
      );

      $posts = get_posts( $args );

      return 0 < count( $posts );
    }
  );

  return $conditions;
}

There are a number of other problems here, though

  • PHP will evaluate strings in double-quotes "" for variable replacement, but treats single-quotes '' as “string-literals” – this means that your query is literally asking WordPress for posts authored by the user '$current_user' rather than the value of the variable $current_user. You can fix this by placing the variable name in double quotes, or simply no quotes at all.
  • The variable $current_user is never declared anywhere in your filter. The code may still work if you’ve defined it in a higher scope, such as the top of the file in which your function resides. In this instance however, you want to use the WordPress global variable $current_user – so to make sure that $current_user is referencing the right data, you should specify as much at the top of your function by adding global $current_user;. This is, however, something of a hack – the preferred method for acquiring the current user is the wp_get_current_user() function.
  • In fixing the previous issues your query will now throw an error. As noted in the Codex entry on author query parameters, 'author' should be an integer user ID, while global $current_user and the return value of wp_get_current_user() function return a WP_User object. You can get the ID from a WP_User object by reading the ID property, i.e. $id = $current_user->ID;, or you can take a shortcut and simply call the get_current_user_id() function.

As a final couple reflections, an 'offset' of 0 is implied, so that argument can be omitted. And really, you only care if at least one post exists that fits your criteria, so we can limit the query to one post by setting 'posts_per_page' to 1. If there is no current user (i.e. a guest visitor), there’s really no reason to run the query at all – we can do this by checking for a user ID of 0.

Putting it all together:

add_filter( 'if_menu_conditions', 'wpse_223598_add_menu_conditions' );

function wpse_223598_add_menu_conditions( $conditions ) {      
  $conditions[] = array(
    'name'    =>  'If Current User has Authored Listing',
    'condition' =>  function( ) {
      $current_user_id = get_current_user_id();

      // If the user's not logged in, they can't have authored a listing
      if( 0 === $current_user_id )
        return false;

      $args = array(
        'posts_per_page' => 1,
        'author'         => $current_user_id,
        'post_type'      => 'job_listing',
        'post_status'    => 'publish'
      );

      $listings = get_posts( $args );

      // Return "there are more than 0 listings"
      return 0 < count( $listings );
    }
  );

  return $conditions;
}