Support

Account

Home Forums ACF PRO Continuous loop in Relationship field with custom title + custom search

Solving

Continuous loop in Relationship field with custom title + custom search

  • I have a Relationship field that I am using a custom title and a custom search (that includes a custom field) and I am seeing three problems:

    1- When I scrool down and it loads with AJAX, it’s loading the same results again and again 8 times, until it excludes only the first entry on the results list and, again, it loops 8 times.

    2- When I search for my custom field, it only filters correctly when I am searching for the begining of that custom field. E.g. if I have a custom field with “ABC ZXW” and I try to search for “ab”, it shows the result correctly, but not if I search for “zx”.

    3- When I search for the title of any post, it only shows me the first result, although I know that it was supposed to appear more than one results, only one appears on the list.

    And this is the code:

    // Custom Field on Relationship Field Results - ACF Field -> estate_entity_associated_properties
    	function relationship_entity_property_result( $title, $post, $field, $post_id ) {
    	
    		// load a custom field from this $object and show it in the $result
    		$propRef = get_field('estate_property_id', $post->ID);
    		$title = '['.$propRef.'] '.$title;
    		return $title;
    	}
    	
    	// filter for a specific field based on it's name
    	add_filter('acf/fields/relationship/result/name=estate_entity_associated_properties', 'relationship_entity_property_result', 10, 4);
    	
    	
    	// Property Search Inside Entity - ACF Field -> estate_entity_associated_properties
    	function search_custom_meta_acf_add_join($joins) {
    	    global $wpdb;
    	    remove_filter('posts_join','search_custom_meta_acf_add_join');
    	    return $joins . " INNER JOIN {$wpdb->postmeta} as METACF ON ({$wpdb->posts}.ID = METACF.post_id)";
    	}
    	
    	function search_custom_meta_acf_alter_search($search,$qry) {
    	    global $wpdb;
    	    remove_filter('posts_search','search_custom_meta_acf_alter_search',1,2);
    	    $add = $wpdb->prepare("(METACF.meta_key = 'estate_property_id' AND CAST(METACF.meta_value AS CHAR) LIKE '%%%s%%')",$qry->get('s'));
    	    $pat = '|\(\((.+)\)\)|';
    	    $search = preg_replace($pat,'(($1 OR '.$add.'))',$search);
    	    return $search;
    	}
    	function modify_acf_relationship_search_query ($args, $field, $post ) {
    	    add_filter('posts_join','search_custom_meta_acf_add_join');
    	    add_filter('posts_search','search_custom_meta_acf_alter_search',1,2);
    	    return $args;
    	}
    	add_filter('acf/fields/relationship/query/name=estate_entity_associated_properties', 'modify_acf_relationship_search_query', 10, 3);

    Does anyone have any idea on how this can be done flawlessly? Is this a ACF bug?

    Thanks.

    WP v4.5.2
    ACF v5.3.8.1

  • The hook you’re using is for filtering the Label of each choice, so for each label you doing a query. The hook you want to be using for altering the results is https://www.advancedcustomfields.com/resources/acf-fields-relationship-query/

  • I thank you for your answer, but that’s exactly the same hook that I am using.

    Please notice that I am using two different hooks, one for the result, that only adds a custom field to the title and that’s working perfectly, and the other for the query which is done with the same hook you said.

  • Sorry, I didn’t see the second hook, I was thinking it was something simple. Honestly, I can tell what the functions search_custom_meta_acf_add_join and search_custom_meta_acf_alter_search are doing and if it’s doing it correctly or incorrectly, obviously there’s something wrong there.

    What does the actual query that being run look like? That would probably give you some clue about what’s actually happening, as well what the actual results being returned are.

    Since this is happening during AJAX you’ll need to be creative to see what’s actually going on.

    
    // add this to wp-config.php
    // to log errors
    define('WP_DEBUG', true );
    define('WP_DEBUG_DISPLAY', false);
    define('WP_DEBUG_LOG', true);
    
    
    // add this action to
    // log complete query to error log
    add_action('posts_selection', 'log_the_query');
    function log_the_query($query) {
      error_log($query);
    }
    

    Then you can look at the query that’s being done an see if there’s anything in it that could cause the problem.

  • I had actually tried that before but I cannot get any kind of output in any log. Maybe I am doing it wrong, but I actually don’t know where should I put that error_log.

    Should I put it inside some ACF file? I have no idea whatsoever…

  • The error log should should be located at wp-content/debug.log

    you can put the action in your functions.php file.

    Unless there’s something else going on with the site it should work. Make sure that you aren’t defining the constants more than once in wp-config.php, it’s possible that they are defined already.

  • Yup, there it was:

    [12-Jun-2016 19:57:05 UTC]  AND wp_posts.post_type = 'property' AND ((wp_posts.post_status <> 'trash' AND wp_posts.post_status <> 'auto-draft')) AND ( ( t.language_code = 'pt-pt' AND wp_posts.post_type  IN ('post','page','acf-field-group','acf-field','property','testimonial' )  ) OR wp_posts.post_type  NOT  IN ('post','page','acf-field-group','acf-field','property','testimonial' )  )wp_posts.post_date DESCLIMIT 40, 20 JOIN wp_icl_translations t
    							ON wp_posts.ID = t.element_id
    								AND t.element_type = CONCAT('post_', wp_posts.post_type)  INNER JOIN wp_postmeta as METACF ON (wp_posts.ID = METACF.post_id)
    [12-Jun-2016 19:57:05 UTC]  AND wp_posts.post_type = 'property' AND ((wp_posts.post_status <> 'trash' AND wp_posts.post_status <> 'auto-draft')) AND ( ( t.language_code = 'pt-pt' AND wp_posts.post_type  IN ('post','page','acf-field-group','acf-field','property','testimonial' )  ) OR wp_posts.post_type  NOT  IN ('post','page','acf-field-group','acf-field','property','testimonial' )  )wp_posts.post_date DESC JOIN wp_icl_translations t
    							ON wp_posts.ID = t.element_id
    								AND t.element_type = CONCAT('post_', wp_posts.post_type)  

    And this is doing a query with the word “test”, which should return at least 4 results and it returns only the first one:

    [12-Jun-2016 20:06:27 UTC]  AND (((wp_posts.post_title LIKE '%test%') OR (wp_posts.post_excerpt LIKE '%test%') OR (wp_posts.post_content LIKE '%test%') OR (METACF.meta_key = 'estate_property_id' AND CAST(METACF.meta_value AS CHAR) LIKE '%test%')))  AND wp_posts.post_type = 'property' AND ((wp_posts.post_status <> 'trash' AND wp_posts.post_status <> 'auto-draft')) AND ( ( t.language_code = 'pt-pt' AND wp_posts.post_type  IN ('post','page','acf-field-group','acf-field','property','testimonial' )  ) OR wp_posts.post_type  NOT  IN ('post','page','acf-field-group','acf-field','property','testimonial' )  )wp_posts.post_date DESCLIMIT 0, 20 JOIN wp_icl_translations t
    							ON wp_posts.ID = t.element_id
    								AND t.element_type = CONCAT('post_', wp_posts.post_type)  INNER JOIN wp_postmeta as METACF ON (wp_posts.ID = METACF.post_id)
  • Any solution for this problem? I’m still stuck with this… πŸ™

  • To be honest, I don’t understand the query that’s being done. For some reason it appears to me that the WHERE does not look correct, but that could be my lack of understanding of a very complex query.

    This part seems particularly out of place

    
    wp_posts.post_date DESCLIMIT 40, 20 JOIN 
    wp_icl_translations t ON wp_posts.ID = t.element_id
    

    Looking at the entire query, that line does not seem, at least to me, to be part of either the clause before it or the one after it. Here is one of them broken down a bit with some white space to make it easier to look at.

    
    AND wp_posts.post_type = 'property'
     
    AND ((wp_posts.post_status <> 'trash' AND wp_posts.post_status <> 'auto-draft')) 
    
    AND ((t.language_code = 'pt-pt' 
          AND wp_posts.post_type IN ('post', 'page', 'acf-field-group', 'acf-field','property', 'testimonial')) 
          OR wp_posts.post_type  NOT  IN ('post', 'page', 'acf-field-group', 'acf-field', 'property', 'testimonial'))
           
    wp_posts.post_date DESCLIMIT 40, 20 JOIN wp_icl_translations t ON wp_posts.ID = t.element_id
    
    AND t.element_type = CONCAT('post_', wp_posts.post_type) 
      INNER JOIN wp_postmeta as METACF ON (wp_posts.ID = METACF.post_id)
    

    You may need to find another way to do this. Is there some reason that you’re not using the filter provided by ACF for altering the relationship query? https://www.advancedcustomfields.com/resources/acf-fields-relationship-query/

  • Hello,

    I’m having the same issue. I’m using Woocommerce, so I need the relationship field to be able to filter by product’s sku. I used the hookes mentioned above by @pedrolima, the original hooks are from StackExchange: http://wordpress.stackexchange.com/questions/178574/acf-relationship-field-search-filtering/207853

    Those hooks are working great (they can search in meta data as well as post title) but, as @pedrolima said, it causes to loop the first result again and again instead of showing the relevant results.

    Before I used those hooks from Stackoverflow, I tried to use the filter @hube2 mentioned “acf-fields-relationship-query”, I added the meta query that I need to $args array but unfortunately it didn’t work as excepted… It showed no results for any search I typed.

    Any help will be appreciated!

  • The ACF relationship query has a know issue when adding a meta query, but I thought it was corrected in the newest version of ACF. What version did you try it on?

  • I’m using ACF version 4.4.11 , but my wordpress version is quite old – 4.4.5.

  • ACF 4 does not have the correction. When I said newest version I meant for ACF5. You can’t do this with the filter I mentioned in ACF4.

  • Ok, so I need to buy ACF5 just for adding a simple query ?

  • Well, you can do that, or wait for ACF5 to be published as a free version, or you can modify the ACF4 files, and I don’t know how to do that. Elliot is working on getting a free version of ACF5 ready to publish and is not really making improvements to v4 any more. I know this is not a great answer.

    To be honest, I just looked at the code for the relationship field in ACF4 and I don’t see why there should be any problem with adding a meta query using acf/fields/relationship/query, it could be that the problem only existed in 5 to begin with.

    If you post the code for your filter maybe there’s something in it that might help and maybe we can get it working.

  • This is how I tried to hook the query filter:

    function modify_acf_relationship_search_query ($args, $field, $post ) {
        $args['meta_query'] = array(
            'key'=> '_sku',
            'value'=> '$args['s'],
            'compare' => 'LIKE'
        );
        return $args;
    }
    
    add_filter('acf/fields/relationship/query/name=related_products', 'modify_acf_relationship_search_query', 10, 3);

    Again, this hook doesn’t work, The query always showing no results.

  • The meta query you add needs to be formatted the same as for WP_Query, so it needs to be a nested array. That could be the cause.

    
    function modify_acf_relationship_search_query ($args, $field, $post ) {
        $args['meta_query'] = array(
          array(
            'key'=> '_sku',
            'value'=> '$args['s'],
            'compare' => 'LIKE'
          )
        );
        return $args;
    }
    
    add_filter('acf/fields/relationship/query/name=related_products', 'modify_acf_relationship_search_query', 10, 3);
    

    Let me know if that helps at all.

  • Well actually I tried it also and still the same result…

  • So, this is just a theory, but when you do a search, ACF uses the standard WP_Query to get posts and it sets the ‘s’ parameter in the query. This searches the title and content of the post for the keywords. When you add a meta query I’m pretty sure that what you end up with is something like this

    (title LIKE keyword OR content LIKE keyword) AND meta value LIKE keyword

    Which means that you’ll never find anything unless the sku is also in either the post title or the post content. Again, this is just a theory.

    What you can try is to unset the ‘s’ argument, so that you only search the sku field.

    Either that or you can look at the ‘s’ arg and try to determine if it looks like a sku, if it does then add you meta query and unset the ‘s’ arg. This would let you search by title or sku, but I don’t know if this is possible.

    Like I said, at this point it’s just a theory that the ‘s’ arg is causing the issue.

Viewing 19 posts - 1 through 19 (of 19 total)

You must be logged in to reply to this topic.