Make WordPress Core

Changeset 38859


Ignore:
Timestamp:
10/21/2016 11:11:42 AM (8 years ago)
Author:
swissspidy
Message:

General: Introduce a wp_list_sort() helper function.

In addition to wp_list_filter() for filtering a list of objects, and wp_list_pluck() for plucking a certain field out of each object in a list, this new function can be used for sorting a list of objects by specific fields. These functions are now all contained within the new WP_List_Util() class and wp_list_sort() is used in various parts of core for sorting lists.

Props flixos90, DrewAPicture, jorbin.
Fixes #37128.

Location:
trunk
Files:
2 added
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/category-template.php

    r38828 r38859  
    9898     */
    9999    return apply_filters( 'get_the_categories', $categories, $id );
    100 }
    101 
    102 /**
    103  * Sort categories by name.
    104  *
    105  * Used by usort() as a callback, should not be used directly. Can actually be
    106  * used to sort any term object.
    107  *
    108  * @since 2.3.0
    109  * @access private
    110  *
    111  * @param object $a
    112  * @param object $b
    113  * @return int
    114  */
    115 function _usort_terms_by_name( $a, $b ) {
    116     return strcmp( $a->name, $b->name );
    117 }
    118 
    119 /**
    120  * Sort categories by ID.
    121  *
    122  * Used by usort() as a callback, should not be used directly. Can actually be
    123  * used to sort any term object.
    124  *
    125  * @since 2.3.0
    126  * @access private
    127  *
    128  * @param object $a
    129  * @param object $b
    130  * @return int
    131  */
    132 function _usort_terms_by_ID( $a, $b ) {
    133     if ( $a->term_id > $b->term_id )
    134         return 1;
    135     elseif ( $a->term_id < $b->term_id )
    136         return -1;
    137     else
    138         return 0;
    139100}
    140101
  • trunk/src/wp-includes/class-wp-customize-manager.php

    r38829 r38859  
    25062506     *
    25072507     * @since 3.4.0
     2508     * @deprecated 4.7.0 Use wp_list_sort()
    25082509     *
    25092510     * @param WP_Customize_Panel|WP_Customize_Section|WP_Customize_Control $a Object A.
     
    25122513     */
    25132514    protected function _cmp_priority( $a, $b ) {
     2515        _deprecated_function( __METHOD__, '4.7.0', 'wp_list_sort' );
     2516
    25142517        if ( $a->priority === $b->priority ) {
    25152518            return $a->instance_number - $b->instance_number;
     
    25312534
    25322535        $controls = array();
    2533         uasort( $this->controls, array( $this, '_cmp_priority' ) );
     2536        $this->controls = wp_list_sort( $this->controls, array(
     2537            'priority'        => 'ASC',
     2538            'instance_number' => 'ASC',
     2539        ) );
    25342540
    25352541        foreach ( $this->controls as $id => $control ) {
     
    25442550
    25452551        // Prepare sections.
    2546         uasort( $this->sections, array( $this, '_cmp_priority' ) );
     2552        $this->sections = wp_list_sort( $this->sections, array(
     2553            'priority'        => 'ASC',
     2554            'instance_number' => 'ASC',
     2555        ) );
    25472556        $sections = array();
    25482557
     
    25522561            }
    25532562
    2554             usort( $section->controls, array( $this, '_cmp_priority' ) );
     2563
     2564            $section->controls = wp_list_sort( $section->controls, array(
     2565                'priority'        => 'ASC',
     2566                'instance_number' => 'ASC',
     2567            ) );
    25552568
    25562569            if ( ! $section->panel ) {
     
    25672580
    25682581        // Prepare panels.
    2569         uasort( $this->panels, array( $this, '_cmp_priority' ) );
     2582        $this->panels = wp_list_sort( $this->panels, array(
     2583            'priority'        => 'ASC',
     2584            'instance_number' => 'ASC',
     2585        ) );
    25702586        $panels = array();
    25712587
     
    25752591            }
    25762592
    2577             uasort( $panel->sections, array( $this, '_cmp_priority' ) );
     2593            $panel->sections = wp_list_sort( $panel->sections, array(
     2594                'priority'        => 'ASC',
     2595                'instance_number' => 'ASC',
     2596            ) );
    25782597            $panels[ $panel->id ] = $panel;
    25792598        }
     
    25822601        // Sort panels and top-level sections together.
    25832602        $this->containers = array_merge( $this->panels, $this->sections );
    2584         uasort( $this->containers, array( $this, '_cmp_priority' ) );
     2603        $this->containers = wp_list_sort( $this->containers, array(
     2604            'priority'        => 'ASC',
     2605            'instance_number' => 'ASC',
     2606        ) );
    25852607    }
    25862608
  • trunk/src/wp-includes/customize/class-wp-customize-nav-menu-item-setting.php

    r38618 r38859  
    533533
    534534        if ( ARRAY_A === $args['output'] ) {
    535             $GLOBALS['_menu_item_sort_prop'] = $args['output_key'];
    536             usort( $items, '_sort_nav_menu_items' );
     535            $items = wp_list_sort( $items, array(
     536                $args['output_key'] => 'ASC',
     537            ) );
    537538            $i = 1;
    538539
  • trunk/src/wp-includes/customize/class-wp-customize-nav-menu-setting.php

    r37539 r38859  
    288288        // Make sure the menu objects get re-sorted after an update/insert.
    289289        if ( ! $is_delete && ! empty( $args['orderby'] ) ) {
    290             $this->_current_menus_sort_orderby = $args['orderby'];
    291             usort( $menus, array( $this, '_sort_menus_by_orderby' ) );
     290            $menus = wp_list_sort( $menus, array(
     291                $args['orderby'] => 'ASC',
     292            ) );
    292293        }
    293294        // @todo add support for $args['hide_empty'] === true
     
    314315     *
    315316     * @since 4.3.0
     317     * @deprecated 4.7.0 Use wp_list_sort()
    316318     * @access protected
     319     *
    317320     * @param object $menu1
    318321     * @param object $menu2
     
    322325     */
    323326    protected function _sort_menus_by_orderby( $menu1, $menu2 ) {
     327        _deprecated_function( __METHOD__, '4.7.0', 'wp_list_sort' );
     328
    324329        $key = $this->_current_menus_sort_orderby;
    325330        return strcmp( $menu1->$key, $menu2->$key );
  • trunk/src/wp-includes/deprecated.php

    r38785 r38859  
    37993799    return preg_replace( '%&\s*\{[^}]*(\}\s*;?|$)%', '', $string );
    38003800}
     3801
     3802/**
     3803 * Sort categories by ID.
     3804 *
     3805 * Used by usort() as a callback, should not be used directly. Can actually be
     3806 * used to sort any term object.
     3807 *
     3808 * @since 2.3.0
     3809 * @deprecated 4.7.0 Use wp_list_sort()
     3810 * @access private
     3811 *
     3812 * @param object $a
     3813 * @param object $b
     3814 * @return int
     3815 */
     3816function _usort_terms_by_ID( $a, $b ) {
     3817    _deprecated_function( __FUNCTION__, '4.7.0', 'wp_list_sort' );
     3818
     3819    if ( $a->term_id > $b->term_id )
     3820        return 1;
     3821    elseif ( $a->term_id < $b->term_id )
     3822        return -1;
     3823    else
     3824        return 0;
     3825}
     3826
     3827/**
     3828 * Sort categories by name.
     3829 *
     3830 * Used by usort() as a callback, should not be used directly. Can actually be
     3831 * used to sort any term object.
     3832 *
     3833 * @since 2.3.0
     3834 * @deprecated 4.7.0 Use wp_list_sort()
     3835 * @access private
     3836 *
     3837 * @param object $a
     3838 * @param object $b
     3839 * @return int
     3840 */
     3841function _usort_terms_by_name( $a, $b ) {
     3842    _deprecated_function( __FUNCTION__, '4.7.0', 'wp_list_sort' );
     3843
     3844    return strcmp( $a->name, $b->name );
     3845}
     3846
     3847/**
     3848 * Sort menu items by the desired key.
     3849 *
     3850 * @since 3.0.0
     3851 * @deprecated 4.7.0 Use wp_list_sort()
     3852 * @access private
     3853 *
     3854 * @global string $_menu_item_sort_prop
     3855 *
     3856 * @param object $a The first object to compare
     3857 * @param object $b The second object to compare
     3858 * @return int -1, 0, or 1 if $a is considered to be respectively less than, equal to, or greater than $b.
     3859 */
     3860function _sort_nav_menu_items( $a, $b ) {
     3861    global $_menu_item_sort_prop;
     3862
     3863    _deprecated_function( __FUNCTION__, '4.7.0', 'wp_list_sort' );
     3864
     3865    if ( empty( $_menu_item_sort_prop ) )
     3866        return 0;
     3867
     3868    if ( ! isset( $a->$_menu_item_sort_prop ) || ! isset( $b->$_menu_item_sort_prop ) )
     3869        return 0;
     3870
     3871    $_a = (int) $a->$_menu_item_sort_prop;
     3872    $_b = (int) $b->$_menu_item_sort_prop;
     3873
     3874    if ( $a->$_menu_item_sort_prop == $b->$_menu_item_sort_prop )
     3875        return 0;
     3876    elseif ( $_a == $a->$_menu_item_sort_prop && $_b == $b->$_menu_item_sort_prop )
     3877        return $_a < $_b ? -1 : 1;
     3878    else
     3879        return strcmp( $a->$_menu_item_sort_prop, $b->$_menu_item_sort_prop );
     3880}
  • trunk/src/wp-includes/functions.php

    r38849 r38859  
    34903490 *
    34913491 * @since 3.0.0
     3492 * @since 4.7.0 Uses WP_List_Util class.
    34923493 *
    34933494 * @param array       $list     An array of objects to filter
     
    35033504 */
    35043505function wp_filter_object_list( $list, $args = array(), $operator = 'and', $field = false ) {
    3505     if ( ! is_array( $list ) )
     3506    if ( ! is_array( $list ) ) {
    35063507        return array();
    3507 
    3508     $list = wp_list_filter( $list, $args, $operator );
    3509 
    3510     if ( $field )
    3511         $list = wp_list_pluck( $list, $field );
    3512 
    3513     return $list;
     3508    }
     3509
     3510    $util = new WP_List_Util( $list );
     3511
     3512    $util->filter( $args, $operator );
     3513
     3514    if ( $field ) {
     3515        $util->pluck( $field );
     3516    }
     3517
     3518    return $util->get_output();
    35143519}
    35153520
     
    35183523 *
    35193524 * @since 3.1.0
     3525 * @since 4.7.0 Uses WP_List_Util class.
    35203526 *
    35213527 * @param array  $list     An array of objects to filter.
     
    35293535 */
    35303536function wp_list_filter( $list, $args = array(), $operator = 'AND' ) {
    3531     if ( ! is_array( $list ) )
     3537    if ( ! is_array( $list ) ) {
    35323538        return array();
    3533 
    3534     if ( empty( $args ) )
    3535         return $list;
    3536 
    3537     $operator = strtoupper( $operator );
    3538     $count = count( $args );
    3539     $filtered = array();
    3540 
    3541     foreach ( $list as $key => $obj ) {
    3542         $to_match = (array) $obj;
    3543 
    3544         $matched = 0;
    3545         foreach ( $args as $m_key => $m_value ) {
    3546             if ( array_key_exists( $m_key, $to_match ) && $m_value == $to_match[ $m_key ] )
    3547                 $matched++;
    3548         }
    3549 
    3550         if ( ( 'AND' == $operator && $matched == $count )
    3551           || ( 'OR' == $operator && $matched > 0 )
    3552           || ( 'NOT' == $operator && 0 == $matched ) ) {
    3553             $filtered[$key] = $obj;
    3554         }
    3555     }
    3556 
    3557     return $filtered;
     3539    }
     3540
     3541    $util = new WP_List_Util( $list );
     3542    return $util->filter( $args, $operator );
    35583543}
    35593544
     
    35663551 * @since 3.1.0
    35673552 * @since 4.0.0 $index_key parameter added.
     3553 * @since 4.7.0 Uses WP_List_Util class.
    35683554 *
    35693555 * @param array      $list      List of objects or arrays
     
    35763562 */
    35773563function wp_list_pluck( $list, $field, $index_key = null ) {
    3578     if ( ! $index_key ) {
    3579         /*
    3580          * This is simple. Could at some point wrap array_column()
    3581          * if we knew we had an array of arrays.
    3582          */
    3583         foreach ( $list as $key => $value ) {
    3584             if ( is_object( $value ) ) {
    3585                 $list[ $key ] = $value->$field;
    3586             } else {
    3587                 $list[ $key ] = $value[ $field ];
    3588             }
    3589         }
    3590         return $list;
    3591     }
    3592 
    3593     /*
    3594      * When index_key is not set for a particular item, push the value
    3595      * to the end of the stack. This is how array_column() behaves.
    3596      */
    3597     $newlist = array();
    3598     foreach ( $list as $value ) {
    3599         if ( is_object( $value ) ) {
    3600             if ( isset( $value->$index_key ) ) {
    3601                 $newlist[ $value->$index_key ] = $value->$field;
    3602             } else {
    3603                 $newlist[] = $value->$field;
    3604             }
    3605         } else {
    3606             if ( isset( $value[ $index_key ] ) ) {
    3607                 $newlist[ $value[ $index_key ] ] = $value[ $field ];
    3608             } else {
    3609                 $newlist[] = $value[ $field ];
    3610             }
    3611         }
    3612     }
    3613 
    3614     return $newlist;
     3564    $util = new WP_List_Util( $list );
     3565    return $util->pluck( $field, $index_key );
     3566}
     3567
     3568/**
     3569 * Sorts a list of objects, based on one or more orderby arguments.
     3570 *
     3571 * @since 4.7.0
     3572 *
     3573 * @param array        $list    An array of objects to filter.
     3574 * @param string|array $orderby Optional. Either the field name to order by or an array
     3575 *                              of multiple orderby fields as $orderby => $order.
     3576 * @param string       $order   Optional. Either 'ASC' or 'DESC'. Only used if $orderby
     3577 *                              is a string.
     3578 * @return array The sorted array.
     3579 */
     3580function wp_list_sort( $list, $orderby = array(), $order = 'ASC' ) {
     3581    if ( ! is_array( $list ) ) {
     3582        return array();
     3583    }
     3584
     3585    $util = new WP_List_Util( $list );
     3586    return $util->sort( $orderby, $order );
    36153587}
    36163588
  • trunk/src/wp-includes/link-template.php

    r38814 r38859  
    170170            $cats = get_the_category($post->ID);
    171171            if ( $cats ) {
    172                 usort($cats, '_usort_terms_by_ID'); // order by ID
     172                $cats = wp_list_sort( $cats, array(
     173                    'term_id' => 'ASC',
     174                ) );
    173175
    174176                /**
  • trunk/src/wp-includes/nav-menu.php

    r38744 r38859  
    559559
    560560/**
    561  * Sort menu items by the desired key.
    562  *
    563  * @since 3.0.0
    564  * @access private
    565  *
    566  * @global string $_menu_item_sort_prop
    567  *
    568  * @param object $a The first object to compare
    569  * @param object $b The second object to compare
    570  * @return int -1, 0, or 1 if $a is considered to be respectively less than, equal to, or greater than $b.
    571  */
    572 function _sort_nav_menu_items( $a, $b ) {
    573     global $_menu_item_sort_prop;
    574 
    575     if ( empty( $_menu_item_sort_prop ) )
    576         return 0;
    577 
    578     if ( ! isset( $a->$_menu_item_sort_prop ) || ! isset( $b->$_menu_item_sort_prop ) )
    579         return 0;
    580 
    581     $_a = (int) $a->$_menu_item_sort_prop;
    582     $_b = (int) $b->$_menu_item_sort_prop;
    583 
    584     if ( $a->$_menu_item_sort_prop == $b->$_menu_item_sort_prop )
    585         return 0;
    586     elseif ( $_a == $a->$_menu_item_sort_prop && $_b == $b->$_menu_item_sort_prop )
    587         return $_a < $_b ? -1 : 1;
    588     else
    589         return strcmp( $a->$_menu_item_sort_prop, $b->$_menu_item_sort_prop );
    590 }
    591 
    592 /**
    593561 * Return if a menu item is valid.
    594562 *
     
    683651
    684652    if ( ARRAY_A == $args['output'] ) {
    685         $GLOBALS['_menu_item_sort_prop'] = $args['output_key'];
    686         usort($items, '_sort_nav_menu_items');
     653        $items = wp_list_sort( $items, array(
     654            $args['output_key'] => 'ASC',
     655        ) );
    687656        $i = 1;
    688657        foreach ( $items as $k => $item ) {
     
    777746                $menu_item->type_label = __( 'Post Type Archive' );
    778747                $post_content = wp_trim_words( $menu_item->post_content, 200 );
    779                 $post_type_description = '' == $post_content ? $post_type_description : $post_content; 
     748                $post_type_description = '' == $post_content ? $post_type_description : $post_content;
    780749                $menu_item->url = get_post_type_archive_link( $menu_item->object );
    781750            } elseif ( 'taxonomy' == $menu_item->type ) {
  • trunk/src/wp-settings.php

    r38832 r38859  
    9292// Load early WordPress files.
    9393require( ABSPATH . WPINC . '/compat.php' );
     94require( ABSPATH . WPINC . '/class-wp-list-util.php' );
    9495require( ABSPATH . WPINC . '/functions.php' );
    9596require( ABSPATH . WPINC . '/class-wp-matchesmapregex.php' );
Note: See TracChangeset for help on using the changeset viewer.