Support

Account

Home Forums ACF PRO Getting number of times selected from relationship field

Solved

Getting number of times selected from relationship field

  • Hi,

    I’m trying to find the number of times a page has been selected in other posts through the relationship field.

    My situation is this:
    I have many businesses across the US, each one of them is a single post with its state location selected from a relationship field.

    Each post from the relationship field is a custom post type called ‘locations’ I’ve created.

    I have followed this guide:
    https://www.advancedcustomfields.com/resources/querying-relationship-fields/

    Everything works great for me, the only thing I want is to get a current number which should update automatically as more businesses are being added to the site so I can keep track of how many businesses I have in each state.

    This should be at the back-end and it is not in order to put on the site itself but for statistics purposes.

    I have ACF PRO 5.3.9.2.

    Is this possible?

    Thanks!

  • After a few hours messing around with the code I got it working, the only thing I can’t seem to figure out is how to get it sortable, here’s what I got so far:

    function change_columns( $cols ) {
      $cols = array(
        'cb'       => '<input type="checkbox" />',
    	'title'      => __( 'Title',      'trans' ),
        'number'      => __( 'Number',      'trans' ),
    	'author'      => __( 'Author',      'trans' ),
    	'Date'      => __( 'Date',      'trans' ),	
      );
      return $cols;
    }
    add_filter( "manage_edit-usa-locations_columns", "change_columns" );
    
    function columns_content_only_locations($column_name, $post_ID) {
        if ($column_name == 'number') {
    
    	$locations = get_posts(array(
    		'post_type' => 'post',
    		'category'  => '3',
    		'numberposts'=>-1,
    		'orderby' => 'title',
    		'posts_per_page'   => -1,
    		'meta_query' => array(
    			array(
    				'key' => 'headquarters', // name of custom field
    				'value' => '"' . get_the_ID() . '"', // matches exaclty "123", not just 123. This prevents a match for "1234"
    				'compare' => 'LIKE'
    			)
    		)
    	));
    	
    	$totalCount = count( $locations );
    	echo $totalCount;
    	
        }
    }
    
    add_action('manage_usa-locations_posts_custom_column', 'columns_content_only_locations', 10, 2);
    
    // Make these columns sortable
    function sortable_columns() {
      return array(
        'number'      => 'number',
    	'title'      => 'title',
      );
    }
    
    add_filter( "manage_edit-usa-locations_sortable_columns", "sortable_columns" );
    
    function number_column_order( $vars ) {
        if ( isset( $vars['order'] ) && 'number' == $vars['order'] ) {
            $vars = array_merge( $vars, array(
                'order' => 'ASC'
            ) );
        }
     
        return $vars;
    }
    add_filter( 'request', 'number_column_order' );
  • Glad you figured out the query. As far as making an admin column sortable, you’re going to need to find the information on that somewhere else. There are several tutorials and code examples available https://www.google.com/search?q=wordpress+make+admin+column+sortable&ie=utf-8&oe=utf-8

  • If it was any other column I would have had no problem,
    The thing is this column is using a total count of information that is no present on the locations posts.

    This is why I can’t use a custom field from the post and use meta_value_num to order it by.

    The only idea I have is making a custom field that the function will insert the information to and then to sort by it but I’m having troubles in implementing such a thing.

    WordPress tutorials I’ve checked weren’t very helpful because none of them refer to my situation using information from a custom field which is not on the post itself but with relationship fields from other posts.

  • I didn’t think about that until you said it. What you really need is to have this count stored somewhere else. The idea you have is right. You need to create another custom field, and it does not even need to be part of ACF since you’ll only reference it in code.

    You will need to update this other field whenever the relationship field is updated and you’ll not only need to know what posts are selected you’re also going to need to know if a relationship is removed.

    You can use the acf/update_value filter for this. I’m not going to go into all the code but I will give you an example. The ACF 2 way relationship plugin I created does something similar. When it relationship field is updated it compares that old values with the new values and updates other posts as needed. https://github.com/Hube2/acf-post2post/blob/master/acf-post2post.php

    What you need to to is get the old values, compare them and then update a post meta field in each of the related posts with the correct count.

  • I’m not sure what you’re saying is a good way to go by, seems to be too complicated for such a thing, is it really necessary? I tried something else which seems to work when I echo the meta_value from the WordPress default custom field.

    Here’s my code for this now, just added the last update_post_data line.

    function columns_content_only_locations($column_name, $post_ID) {
        if ($column_name == 'number') {
    
    	$locations = get_posts(array(
    		'post_type' => 'post',
    		'category'  => '3',
    		'numberposts'=>-1,
    		'orderby' => 'title',
    		'posts_per_page'   => -1,
    		'meta_query' => array(
    			array(
    				'key' => 'headquarters', // name of custom field
    				'value' => '"' . get_the_ID() . '"', // matches exaclty "123", not just 123. This prevents a match for "1234"
    				'compare' => 'LIKE'
    			)
    		)
    	));
    	
    	$totalCount = count( $locations );
    	echo $totalCount;
    	
    	update_post_meta($post_ID, 'count', $totalCount);
    	
    	
        }
    }

    And my sorting function is there but it sorts in a weird order I can’t figure what it is, when I sort it goes always to to the same order: 2, 6, 15, 4, 8 and so on… not ordered at all.

    Here is it:

    function number_column_order( $vars ) {
        if ( isset( $vars['orderby'] ) && 'count' == $vars['orderby'] ) {
    
    		$vars["meta_key"] = "count";
    		$vars["order"] = "ASC";
    		$vars["orderby"] = "meta_value meta_value_num";
    	
        }
     
        return $vars;
    }
    add_filter( 'request', 'number_column_order' );
  • Try $vars["orderby"] = "meta_value_num"; having both may be confusing WP.

    Yes, what you’re doing will work, it just means that the value will be updated during the loading of the admin page and will not be updated at any other time. Only the posts you are currently viewing will be updated, so, only the first 20 posts. Once you have more than 20 posts you need to page through all of the lists until you’ve seen them all to get them all updated so that you filter will work. In addition to this you’re doing a WP_Query with a “LIKE” meta_query for every post listed. This could slow down your page loads considerably.

    Using the acf/update_value hook will only do the updates when it needs to be done and all the values will be correct before you view the list on the admin page so that the filter will work correctly. You also remove the need to do the query for every post so the page will load faster.

  • I tried using $vars["orderby"] = "meta_value_num"; But I get the same result, still weird order =/

    This is a custom post type for USA states and it will always stay 50 I won’t have more pages there as there is no more states 🙂

    I have set the number of items on page to 999 so it won’t be paginated.

    Using “LIKE” with this function will slow down my site or this specific page in the admin panel you mean? because everything seems to be quick and works great..

  • The the only thing is why is it not ordering correctly, and I don’t have the answer for that. I found an example that’s similar to your code here http://scribu.net/wordpress/custom-sortable-columns.html and what you’re doing looks correct with the exception of the orderby value that I mentioned above.

    The only other thing that I notice is that in your original code in the first post has the name of the column as number and in the second code you’re using a column name of count If these aren’t the same then that would cause it.

  • I didn’t quite understand you, where do you see this difference?

    Here’s the entire code I have till now:

    function change_columns( $cols ) {
      $cols = array(
        'cb'       => '<input type="checkbox" />',
    	'title'      => __( 'Title',      'trans' ),
        'number'      => __( 'Number',      'trans' ),
    	'author'      => __( 'Author',      'trans' ),
    	'Date'      => __( 'Date',      'trans' ),	
      );
      return $cols;
    }
    add_filter( "manage_edit-usa-locations_columns", "change_columns" );
    
    function columns_content_only_locations($column_name, $post_ID) {
        if ($column_name == 'number') {
    
    	$locations = get_posts(array(
    		'post_type' => 'post',
    		'category'  => '3',
    		'numberposts'=>-1,
    		'orderby' => 'title',
    		'posts_per_page'   => -1,
    		'meta_query' => array(
    			array(
    				'key' => 'headquarters', // name of custom field
    				'value' => '"' . get_the_ID() . '"', // matches exaclty "123", not just 123. This prevents a match for "1234"
    				'compare' => 'LIKE'
    			)
    		)
    	));
    	
    	$totalCount = count( $locations );
    	echo $totalCount;
    	
    	update_post_meta($post_ID, 'count', $totalCount);
    	
    	
        }
    }
    
    add_action('manage_usa-locations_posts_custom_column', 'columns_content_only_locations', 10, 2);
    
    // Make these columns sortable
    function sortable_columns() {
      return array(
        'number'      => 'number',
    	'title'      => 'title',
      );
    }
    
    add_filter( "manage_edit-usa-locations_sortable_columns", "sortable_columns" );
    
    function number_column_order( $vars ) {
        if ( isset( $vars['orderby'] ) && 'count' == $vars['orderby'] ) {
    
    		$vars["meta_key"] = "count";
    		$vars["order"] = "ASC";
    		$vars["orderby"] = "meta_value_num";
    	
        }
     
        return $vars;
    }
    add_filter( 'request', 'number_column_order' );
  • Column name

    
    'number'      => __( 'Number',      'trans' ),
    

    I think that this if statement need to use that column name

    
    if ( isset( $vars['orderby'] ) && 'count' == $vars['orderby'] ) {
    

    like this

    
    if ( isset( $vars['orderby'] ) && 'number' == $vars['orderby'] ) {
    
  • You are a life saver.

    It’s so much fun to see something works after a few hours of struggling with.

    Thanks a lot this works perfectly!

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

The topic ‘Getting number of times selected from relationship field’ is closed to new replies.