Conditional hook based on the core function that is calling it

In a Multisite, I’m applying the filter get_blogs_of_user to sort the “My Sites” admin bar menu, where the sites are listed by blogname:

admin bar multisite my-sites

Read More

What happens is that I’d like another order elsewhere, where the sites are listed by domain.
For example, the sites that appear in the Users screen (/wp-admin/network/users.php):

user sites

The question is: for achieving that, I’m using debug_backtrace, but am not sure if this is working by accident or if the logic stands (?!).

I found that checking for debug_trace()->trace[4]['function'] I get to know where in the core the function get_blogs_of_user is being called.

Sample code

add_filter( 'get_blogs_of_user', 'bf_reorder_users_sites' );

function bf_reorder_users_sites( $blogs ) {
    $trace = debug_backtrace();
    // my_debug_dump();

    if( 'initialize' == $trace[4]['function'] )
        uasort( $blogs, 'bf_uasort_by_blogname' );
    else
        uasort( $blogs, 'bf_uasort_by_domain' );

    return $blogs;
}

function bf_uasort_by_domain( $a, $b ) {
    return strcasecmp( $a->domain, $b->domain );
}

function bf_uasort_by_blogname( $a, $b ) {
    return strcasecmp( $a->blogname, $b->blogname );
}

Debug

my_debug_dump() lists $trace[4]['file'] and $trace[4]['function'], and prints:

File:: /wp-path/wp-includes/admin-bar.php
Function:: initialize
--------
File:: /wp-path/wp-includes/class-wp-admin-bar.php
Function:: get_active_blog_for_user
--------
File:: /wp-path/wp-admin/admin-header.php
Function:: wp_user_settings
--------
File:: /wp-path/wp-includes/admin-bar.php
Function:: is_user_member_of_blog
--------
File:: /wp-path/wp-admin/includes/class-wp-list-table.php
Function:: display_rows
--------
File:: /wp-path/wp-admin/includes/class-wp-list-table.php
Function:: display_rows
--------
File:: /wp-path/wp-admin/includes/class-wp-list-table.php
Function:: display_rows

Related posts

Leave a Reply

1 comment

  1. Much probably, using debug_backtrace in this fashion is wild hackerism…

    Based on @toscho’s tip, the following achieves the same results:

    add_filter( 'get_blogs_of_user', 'reorder_users_sites' );
    
    function reorder_users_sites( $blogs ) 
    {
        if( !did_action( 'wp_before_admin_bar_render' ) )
            uasort( $blogs, 'bf_uasort_by_blogname' );
        else 
            uasort( $blogs, 'bf_uasort_by_domain' );
    
        return $blogs;
    }