WordPress.org

Ready to get started?Download WordPress

Forums

[resolved] Orderby custom field (meta_key) (12 posts)

  1. Jonathan Lake
    Member
    Posted 1 year ago #

    On the about page of my website (http://it4.wickedsmartdesign.net/about/), I have the employees listed alphabetically on the left-hand side. I've achieved this by using a user query (WP_User_Query). However, instead of having them listed alphabetically, I want them to be ordered by a custom field ('about_order'). Below you can see my attempt, yet I can't get it to work. Any ideas?

    /* Employee Query for About page */
    function it4_get_users_with_job_title() {
    	$args = array(
    		'orderby'  => 'meta_value',
    		'meta_query' => array(
    			array(
    				'key'     => 'about_order',
    			),
    			array(
    				'key'     => 'job_title',
    				'value'   => null,
    				'compare' => '!=' // Make sure the user's job title field has a value (i.e. job_title != null)
    			)
    
    		), // End of meta_query
    		'fields'  => 'ID',
    		'exclude' => array(
    			1
    		),
    
    	);
    	$user_query = new WP_User_Query( $args );
    	return $user_query->get_results();
    }
  2. vtxyzzy
    Member
    Posted 1 year ago #

    Try moving the 'about_order' meta_key outside the meta_query, like this:

    $args = array(
    	'orderby'  => 'meta_value',
    	'meta_key' => 'about_order',
    	'meta_query' => array(
    		array(
    			'key'     => 'job_title',
    			'value'   => null,
    			'compare' => '!=' // Make sure the user's job title field has a value (i.e. job_title != null)
    		)
    
    	), // End of meta_query
    	'fields'  => 'ID',
    	'exclude' => array(
    		1
    	),
    
    );
  3. Jonathan Lake
    Member
    Posted 1 year ago #

    Thanks, but it's still not working.

  4. Shaun Scovil
    Member
    Posted 1 year ago #

    The 'orderby' parameter does not accept 'meta_value' as a value. See this section of the Codex for valid options.

    In order to do what you want, you'll need to re-order the WP_User_Query results in PHP.

    Try this:

    /* Employee Query for About page */
    function it4_get_users_with_job_title() {
        $args = array(
            'meta_query' => array(
                array(
                    'key'     => 'job_title',
                    'value'   => null,
                    'compare' => '!=' // Make sure the user's job title field has a value (i.e. job_title != null)
                )
            ), // End of meta_query
    
            'fields'  => 'ID',
            'exclude' => array( 1 ),
        );
        $user_query = new WP_User_Query( $args );
        $user_ids   = $user_query->get_results();
        $meta_key   = 'about_order';
    
        return it4_sort_users_by_meta_key( $user_ids, $meta_key );
    }
    
    /**
     * Sort Users By Meta Key
     *
     * @param array $user_ids
     * @param string $meta_key
     *
     * @return array|boolean
     */
    function it4_sort_users_by_meta_key( array $user_ids, $meta_key ) {
        $user_order = array();
        foreach( $user_ids as $user_id ) {
            $user_order[$user_id] = intval( get_user_meta( $user_id, $meta_key, true ) );
        }
        asort( $user_order );
    
        return array_keys( $user_order );
    }

    What this new function does is accept two parameters -- your array of user ids, which you got from your WP_User_Query, and the meta key you want to sort your users by. It then loops through the array of user ids, assigning each user id as a key in a key=>value pair to a new array called $user_order. The values in that array are the integer values of the meta key (i.e. 'about_order' ).

    Finally, it runs the PHP function asort() on the new array, which sorts the $user_id=>$meta_key pairs by $meta_key, from lowest to highest, and returns a new array of $user_ids in that order.

    Hope this helps! If you have any questions, feel free to get in touch...

  5. vtxyzzy
    Member
    Posted 1 year ago #

    I think that section of the Codex must be out of date. This code:

    $args = array(
       		'orderby'  => 'meta_value',
       		'meta_key' => 'about_order',
       		'meta_query' => array(
       			array(
       				'key'     => 'job_title',
       				'value'   => null,
       				'compare' => '!=' // Make sure the user's job title field has a value (i.e. job_title != null)
       			)
    
       		), // End of meta_query
       		'fields'  => 'ID',
       		'exclude' => array(
       			1
       		),
    
       	);
    $q = new WP_Query($args);
    
    print_r('<pre>REQUEST:');print_r($q->request);print_r('</pre>');

    shows this result:

    REQUEST:SELECT SQL_CALC_FOUND_ROWS  bmc_posts.ID FROM bmc_posts  INNER JOIN bmc_postmeta ON (bmc_posts.ID = bmc_postmeta.post_id)
    INNER JOIN bmc_postmeta AS mt1 ON (bmc_posts.ID = mt1.post_id) WHERE 1=1  AND bmc_posts.post_type = 'post' AND (bmc_posts.post_status = 'publish') AND (bmc_postmeta.meta_key = 'about_order'
    AND mt1.meta_key = 'job_title' ) GROUP BY bmc_posts.ID ORDER BY bmc_postmeta.meta_value DESC LIMIT 0, 12

    The 'ORDER BY' is set correctly.

  6. Shaun Scovil
    Member
    Posted 1 year ago #

    @vtxyzzy In that request, the 'ORDER BY' is set to the column 'meta_value', which doesn't exist. The expectation of Jonathan (above) is that 'meta_value' would be replaced by 'about_order', which is a custom user meta field.

    To confirm, take a look at wp-includes/user.php, lines 415-437 (in WP v3.5.2). You can see how WP_User_Query handles the orderby parameter...it does not handle 'meta_value' as a parameter.

  7. vtxyzzy
    Member
    Posted 1 year ago #

    But meta_value does exist. It is brought in by this JOIN:

    INNER JOIN bmc_postmeta ON (bmc_posts.ID = bmc_postmeta.post_id)

    and limited to the meta_key 'about_order' by this part of the WHERE clause:

    AND (bmc_postmeta.meta_key = 'about_order'
    REQUEST:SELECT SQL_CALC_FOUND_ROWS  bmc_posts.ID
    FROM bmc_posts
    INNER JOIN bmc_postmeta
       ON (bmc_posts.ID = bmc_postmeta.post_id)
    INNER JOIN bmc_postmeta AS mt1
       ON (bmc_posts.ID = mt1.post_id)
    WHERE 1=1
       AND bmc_posts.post_type = 'post'
       AND (bmc_posts.post_status = 'publish')
       AND (bmc_postmeta.meta_key = 'about_order'
       AND mt1.meta_key = 'job_title' )
    GROUP BY bmc_posts.ID
    ORDER BY bmc_postmeta.meta_value DESC
    LIMIT 0, 12
  8. Jonathan Lake
    Member
    Posted 1 year ago #

    Awesome! Works great, thanks.

  9. vtxyzzy
    Member
    Posted 1 year ago #

    Sorry, I was using WP_Query, not WP_User_Query. It should work with that.

    $q = new WP_Query($args);
  10. Athen
    Member
    Posted 6 months ago #

    The is indeed a interesting thread.

    I was wondering if this could be used to sort a alphabetic list of CPTs by a certain meta key?

    I have at listings site with persons as CTPs and I need to list them alphabetic by surname. On each I have a CF with value=surname. But I cannot find the missing link between a array and the CF.. Any thoughts would be much appreciated.

  11. vtxyzzy
    Member
    Posted 6 months ago #

    @Athen, you have replied to a Resolved thread started by someone else. You normally would not get any answers to this. You should start your own thread.

    And please, try to explain the problem in more detail.

  12. Athen
    Member
    Posted 5 months ago #

    Sure thing vtxyzzy. Sorry about that :)

Topic Closed

This topic has been closed to new replies.

About this Topic

Tags