• Hello! I have been working on a plugin to add custom columns to users table and then make them sortable by meta_value and meta_key. So far I got everything working except the last bit, to make them sort based on the meta_value of a chosen meta_key. I don’t know what I’m doing wrong. The code section I think that is at fault is immediately below, and my entire code is at the bottom.

    The name of my meta_key in the database is ‘last_name’ and the name of the column header is ‘LastName’ and I want it to sort alphabetically in ascending and descending order as you click it. It keeps sorting and always has sorted alphabetically based on the username in Column 1, no matter which sort column I click. That is the problem. I am apparently not able to change the query variables array. I’m sure my error is pretty simple. I have tried different variations of the code below.

    Thanks a ton!!!

    // SORT BLOCK
    // add columns to sortable columns array
    function sort_mishas_user_columns ($columns){
      $columns["FirstName"] = "FirstName";
      $columns["LastName"] = "LastName";
    	return $columns;
    }
    add_filter('manage_users_sortable_columns', 'sort_mishas_user_columns'); // the hook
    
    // modify/merge sort criteria array with new criteria --- I think there's an error here, something not working. It sorts by the username still
    function sort_az_users($vars) { 
      if(array_key_exists('orderby', $vars)) {  // Assuming this is correct and auto-created by the WP hook below
        if('LastName' == $vars['orderby']) {    // 'LastName' is the column header name that is clickable. Assuming it gets set to that on "click"
          $vars['orderby'] = 'meta_value';
          $vars['meta_key'] = 'last_name';      // 'last_name' is the name in the database under 'meta_key' 
        } 
      } 
      return $vars; 
    } 
    add_filter('request', 'sort_az_users'); // the hook
    // END SORT BLOCK

    My entire code

    <?php
    /**
     * Plugin Name: j-w-m
     * Plugin URI: http://www.journeywithmisha.com/j-w-m
     * Description: The very first plugin that I have ever created.
     * Version: 1.0
     * Author: Gerald Ryan
     * Author URI: http://www.webbuildermn.com
     */
    
    function add_custom_misha_columns($columns){
    	$columns["Nova"] = "Nova";
    	$columns["Brilliant.org"] = "Brilliant.org";
     	$columns["FirstName"] = "FirstName";
    	$columns["LastName"] = "LastName";
    	return $columns;
    }
    add_filter('manage_users_columns', 'add_custom_misha_columns'); // the hook
    
    // SORT BLOCK
    
    // add columns to sortable columns array
    function sort_mishas_user_columns ($columns){
      $columns["FirstName"] = "FirstName";
      $columns["LastName"] = "LastName";
    	return $columns;
    }
    add_filter('manage_users_sortable_columns', 'sort_mishas_user_columns'); // the hook
    
    // modify/merge sort criteria array with new criteria --- I think there's an error here, something not working. It sorts by the username still
    function sort_az_users($vars) { 
      if(array_key_exists('orderby', $vars)) {  // Assuming this is correct and auto-created by the WP hook below
        if('LastName' == $vars['orderby']) {    // 'LastName' is the column header name that is clickable. Assuming it gets set to that on "click"
          $vars['orderby'] = 'meta_value';
          $vars['meta_key'] = 'last_name';      // 'last_name' is the name in the database under 'meta_key' 
        } 
      } 
      return $vars; 
    } 
    add_filter('request', 'sort_az_users'); // the hook
    
    // END SORT BLOCK
    
    // // Populate the column
    function add_content_to_mishas_column($value, $column_name, $user_id){
      global $wpdb;
      $fname = $wpdb->get_var("SELECT meta_value FROM $wpdb->usermeta WHERE user_ID = $user_id AND meta_key = 'first_name' "  );
      $lname = $wpdb->get_var("SELECT meta_value FROM $wpdb->usermeta WHERE user_ID = $user_id AND meta_key = 'last_name' "  );
    	if ($column_name == "FirstName"){
        return $fname;
        // return "Romeo";
    	}
    	if ($column_name == "LastName"){
        return $lname;
        // return "Montague";
      }
    
      if ($column_name == "Brilliant.org"){
        return $user_id;
      }
      if ($column_name == "Nova"){
        return $value;
      }
      
    }
    add_action('manage_users_custom_column', 'add_content_to_mishas_column', 10, 3);
    
Viewing 7 replies - 1 through 7 (of 7 total)
  • This plugin does it all: https://wordpress.org/plugins/codepress-admin-columns/
    You can use it or just look at the code to see how.
    But it seems that you are trying to do in PHP what is coded to happen in JS. You should be using the functions for WP_List_Table to filter which columns exist and their contents and which are sortable. You don’t have to sort them yourself, or modify the query to sort them. You fill the column with data and the sort is for the already retrieved data (not all of the database table).

    Thread Starter webbuildermn

    (@webbuildermn)

    Thanks joy. Yeah I had that add-in for the site, but to get sort, we have to pay $49. It’s not just me being cheap. It’s a site I built for free for a friend/professor and also it’s good training for my upcoming bootcamp and we only need it for this one use. I was looking into the source code of that add-in and it’s intense (compared to what I’m used to), whereas if I got mine to work, it would be lean.

    Anyway, that’s a good reference you linked me but I don’t see any method that looks like it sorts the data. Is it something with views? How do I take the next step?

    I’ve been following this article btw, but there’s also one other article that talks about sorting columns that I’ve found, though that one doesn’t’ cover admin tables.

    OK, I think I misspoke before about the sort.
    The WP_List_Table is just like a theme, in that it doesn’t control what is shown. It just shows it. So your code needs to manipulate the query args that form the request, so that the correct entries are shown. Each sort is a page request, as is each filtering dropdown at the top (like Categories).
    You can see some of this in the WP_Posts_List_Table class.

    Thread Starter webbuildermn

    (@webbuildermn)

    Thanks again Joy. The way I was trying to manipulate the query was by altering the query array before sending it off, which is what I read about and makes sense. In my code below, the query array is called $vars. I am trusting that through WP hooks and the guidance I’ve read, it is passing what I need and I am modifying and passing back what it needs.

    I was following the article referenced above because that’s the only one that mentions manipulating admin tables specifically. He uses $array[x] = “string” notation as opposed to “=>” notation other articles use, but again he’s the only one that describes how to sort or alter admin tables. Does his way still work?

    I like using formal reference documentation when possible but I can’t make sense of it in this case. I already added the chosen columns to the manage_sortable_columns array, although that doesn’t look like a WP_Posts_list_Table method. Remember it is not a post or a custom post or page but a user’s admin table.

    Anyway I added the two columns in. I don’t know if they need to be in order of priority as with adding columns to display. Anyway they are in there, now we just have to change the query and make them sort based on it.

    I’m not sure where my mistake is but I had an idea or thought. In my SQL query, I only return a single cell of the database table per WP iteration as it implements its hook, as opposed to an entire filtered column of last names from the database table. What I did works perfectly for displaying last names correctly where I want them, but maybe that’s why it doesn’t sort, as you can’t sort an array of 1×1. It’s a timing thing but I’m not sure if this is the reason, it’s just an idea. When I asked SQL to pull my entire filtered column, then for each person’s last name it said “array”, so I’d need to learn how to index by user_name, and so I’d have to probably pull a 2 column multi row array to link the two. Maybe it’s this??

    Also I’m used to other languages so I have no idea how to debug PHP or if you can look inside the value of variables in process as the code is running. I’m not sure as it’s not a compiled language… But I’m starting my course soon.

    Any tips and help you can provide is appreciated. I view everything as a learning experience.

    
    // SORT BLOCK
    // add columns to sortable columns array
    function sort_mishas_user_columns ($columns){
      $columns["FirstName"] = "FirstName";
      $columns["LastName"] = "LastName";
    	return $columns;
    }
    add_filter('manage_users_sortable_columns', 'sort_mishas_user_columns'); // the hook
    // modify/merge sort criteria array with new criteria --- I think there's an error here, something not working. It sorts by the username still
    function sort_az_users($vars) { 
      if(array_key_exists('orderby', $vars)) {  // Assuming this is correct and auto-created by the WP hook below
        if('LastName' == $vars['orderby']) {    // 'LastName' is the column header name that is clickable. Assuming it gets set to that on "click"
          $vars['orderby'] = 'meta_value';
          $vars['meta_key'] = 'last_name';      // 'last_name' is the name in the database under 'meta_key' 
        } 
      } 
      return $vars; 
    } 
    add_filter('request', 'sort_az_users'); // the hook
    // END SORT BLOCK

    It looks like you need to filter users_list_table_query_args. See https://developer.wordpress.org/reference/classes/wp_users_list_table/prepare_items/

    https://developer.wordpress.org/reference/classes/wp_users_list_table/ is the whole class. Sorry I posted the Posts one before.

    Thread Starter webbuildermn

    (@webbuildermn)

    Hi thanks for your continued help. Not there yet. I tried a couple things. I tried (learning) debugging with some results. I noticed in the URL when I clicked on LastName, it entered in parameters, so I did see that orderby had a value and order did too. Reassuring. I think comes from the ‘manage_users_sortable_columns’. It was confirmatory:

    http://journey.local/wp-admin/users.php?orderby=LastName&order=asc

    I tried using methods you suggested as well as pre_get_posts and pre_get_user. I got a weird error there with

    Can’t use method return value in write context

    and squiggly lines even on VS Code when I try the pre_get_posts that others have suggested by code like this:
    $query->set( 'orderby', 'meta_value' );

    Last I tried the “users_list_table_query_args” you pointed to. Same results- page loads, but doesn’t sort. I got an interesting error when I forgot to change the name of the variable from pasted code. It showed up in the debug mode and said Notice: Undefined variable: vars in /app/public/wp-content/plugins/j-w-m/j-w-m.php on line 108 Warning:

      array_key_exists() expects parameter 2 to be array, null given in

    /app/public/wp-content/plugins/j-w-m/j-w-m.php on line 108

    because here

    add_filter( 'users_list_table_query_args', 'filter_users_list_table_query_args', 10, 1 );
    function filter_users_list_table_query_args( $args ) { 
      // make filter magic happen here... 
      if(array_key_exists('orderby', $vars)) {  


    of course I forgot to change $args to $vars. When I did, that error went away, page loaded like normal but that does tell us
    1. the function is being run
    2. When run, $vars is an array, as one would expect

    Just why doesn’t it modify and work as expected.

    Because it’s a meta value that you want to sort by, it’s not as straight forward as a normal column that exists in the user table.
    I would
    1) try to get a normal column sortable, just to prove to yourself that you can
    2) read up on how to specify meta queries in general, so you can apply that to this query. I think it involves an array to indicate the key and the other stuff (since it’s a different table), so you might have to do it in another filter.

Viewing 7 replies - 1 through 7 (of 7 total)

The topic ‘Sorting admin columns with meta_value’ is closed to new replies.