WordPress.org

Make WordPress Core

Ticket #37128: 37128.5.diff

File 37128.5.diff, 40.1 KB (added by flixos90, 4 years ago)
  • src/wp-includes/category-template.php

     
    100100}
    101101
    102102/**
    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;
    139 }
    140 
    141 /**
    142103 * Retrieve category name based on category ID.
    143104 *
    144105 * @since 0.71
  • src/wp-includes/class-wp-customize-manager.php

     
    25052505         * Helper function to compare two objects by priority, ensuring sort stability via instance_number.
    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.
    25102511         * @param WP_Customize_Panel|WP_Customize_Section|WP_Customize_Control $b Object B.
    25112512         * @return int
    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;
    25162519                } else {
     
    25302533        public function prepare_controls() {
    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                ), 'ASC', true );
    25342540
    25352541                foreach ( $this->controls as $id => $control ) {
    25362542                        if ( ! isset( $this->sections[ $control->section ] ) || ! $control->check_capabilities() ) {
     
    25432549                $this->controls = $controls;
    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                ), 'ASC', true );
    25472556                $sections = array();
    25482557
    25492558                foreach ( $this->sections as $section ) {
     
    25512560                                continue;
    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 ) {
    25572570                                // Top-level section.
     
    25662579                $this->sections = $sections;
    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                ), 'ASC', true );
    25702586                $panels = array();
    25712587
    25722588                foreach ( $this->panels as $panel ) {
     
    25742590                                continue;
    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                        ), 'ASC', true );
    25782597                        $panels[ $panel->id ] = $panel;
    25792598                }
    25802599                $this->panels = $panels;
    25812600
    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                ), 'ASC', true );
    25852607        }
    25862608
    25872609        /**
  • src/wp-includes/class-wp-list-util.php

     
     1<?php
     2/**
     3 * WordPress List utility class
     4 *
     5 * @package WordPress
     6 * @since 4.7.0
     7 */
     8
     9/**
     10 * List utility.
     11 *
     12 * Utility class to handle operations on an array of objects.
     13 *
     14 * @since 4.7.0
     15 */
     16class WP_List_Util {
     17        /**
     18         * The input array.
     19         *
     20         * @since 4.7.0
     21         * @access private
     22         * @var array
     23         */
     24        private $input = array();
     25
     26        /**
     27         * The output array.
     28         *
     29         * @since 4.7.0
     30         * @access private
     31         * @var array
     32         */
     33        private $output = array();
     34
     35        /**
     36         * Temporary arguments for sorting.
     37         *
     38         * @since 4.7.0
     39         * @access private
     40         * @var array
     41         */
     42        private $orderby = array();
     43
     44        /**
     45         * Constructor.
     46         *
     47         * Sets the input array.
     48         *
     49         * @since 4.7.0
     50         *
     51         * @param array $input Array to perform operations on.
     52         */
     53        public function __construct( $input ) {
     54                $this->output = $this->input = $input;
     55        }
     56
     57        /**
     58         * Returns the original input array.
     59         *
     60         * @since 4.7.0
     61         * @access public
     62         *
     63         * @return array The input array.
     64         */
     65        public function get_input() {
     66                return $this->input;
     67        }
     68
     69        /**
     70         * Returns the output array.
     71         *
     72         * @since 4.7.0
     73         * @access public
     74         *
     75         * @return array The output array.
     76         */
     77        public function get_output() {
     78                return $this->output;
     79        }
     80
     81        /**
     82         * Filters the list, based on a set of key => value arguments.
     83         *
     84         * @since 4.7.0
     85         *
     86         * @param array  $args     Optional. An array of key => value arguments to match
     87         *                         against each object. Default empty array.
     88         * @param string $operator Optional. The logical operation to perform. 'AND' means
     89         *                         all elements from the array must match. 'OR' means only
     90         *                         one element needs to match. 'NOT' means no elements may
     91         *                         match. Default 'AND'.
     92         * @return array Array of found values.
     93         */
     94        public function filter( $args = array(), $operator = 'AND' ) {
     95                if ( empty( $args ) ) {
     96                        return $this->output;
     97                }
     98
     99                $operator = strtoupper( $operator );
     100
     101                if ( ! in_array( $operator, array( 'AND', 'OR', 'NOT' ), true ) ) {
     102                        return array();
     103                }
     104
     105                $count = count( $args );
     106                $filtered = array();
     107
     108                foreach ( $this->output as $key => $obj ) {
     109                        $to_match = (array) $obj;
     110
     111                        $matched = 0;
     112                        foreach ( $args as $m_key => $m_value ) {
     113                                if ( array_key_exists( $m_key, $to_match ) && $m_value == $to_match[ $m_key ] ) {
     114                                        $matched++;
     115                                }
     116                        }
     117
     118                        if ( ( 'AND' == $operator && $matched == $count )
     119                          || ( 'OR' == $operator && $matched > 0 )
     120                          || ( 'NOT' == $operator && 0 == $matched ) ) {
     121                                $filtered[$key] = $obj;
     122                        }
     123                }
     124
     125                $this->output = $filtered;
     126
     127                return $this->output;
     128        }
     129
     130        /**
     131         * Plucks a certain field out of each object in the list.
     132         *
     133         * This has the same functionality and prototype of
     134         * array_column() (PHP 5.5) but also supports objects.
     135         *
     136         * @since 4.7.0
     137         *
     138         * @param int|string $field     Field from the object to place instead of the entire object
     139         * @param int|string $index_key Optional. Field from the object to use as keys for the new array.
     140         *                              Default null.
     141         * @return array Array of found values. If `$index_key` is set, an array of found values with keys
     142         *               corresponding to `$index_key`. If `$index_key` is null, array keys from the original
     143         *               `$list` will be preserved in the results.
     144         */
     145        public function pluck( $field, $index_key = null ) {
     146                if ( ! $index_key ) {
     147                        /*
     148                         * This is simple. Could at some point wrap array_column()
     149                         * if we knew we had an array of arrays.
     150                         */
     151                        foreach ( $this->output as $key => $value ) {
     152                                if ( is_object( $value ) ) {
     153                                        $this->output[ $key ] = $value->$field;
     154                                } else {
     155                                        $this->output[ $key ] = $value[ $field ];
     156                                }
     157                        }
     158                        return $this->output;
     159                }
     160
     161                /*
     162                 * When index_key is not set for a particular item, push the value
     163                 * to the end of the stack. This is how array_column() behaves.
     164                 */
     165                $newlist = array();
     166                foreach ( $this->output as $value ) {
     167                        if ( is_object( $value ) ) {
     168                                if ( isset( $value->$index_key ) ) {
     169                                        $newlist[ $value->$index_key ] = $value->$field;
     170                                } else {
     171                                        $newlist[] = $value->$field;
     172                                }
     173                        } else {
     174                                if ( isset( $value[ $index_key ] ) ) {
     175                                        $newlist[ $value[ $index_key ] ] = $value[ $field ];
     176                                } else {
     177                                        $newlist[] = $value[ $field ];
     178                                }
     179                        }
     180                }
     181
     182                $this->output = $newlist;
     183
     184                return $this->output;
     185        }
     186
     187        /**
     188         * Sorts the list, based on one or more orderby arguments.
     189         *
     190         * @since 4.7.0
     191         *
     192         * @param string|array $orderby       Optional. Either the field name to order by or an array
     193         *                                    of multiple orderby fields as $orderby => $order.
     194         * @param string       $order         Optional. Either 'ASC' or 'DESC'. Only used if $orderby
     195         *                                    is a string.
     196         * @param bool         $preserve_keys Optional. Whether to preserve keys. Default false.
     197         * @return array The sorted array.
     198         */
     199        public function sort( $orderby = array(), $order = 'ASC', $preserve_keys = false ) {
     200                if ( empty( $orderby ) ) {
     201                        return $this->output;
     202                }
     203
     204                if ( is_string( $orderby ) ) {
     205                        $orderby = array( $orderby => $order );
     206                }
     207
     208                foreach ( $orderby as $field => $direction ) {
     209                        $orderby[ $field ] = 'DESC' === strtoupper( $direction ) ? 'DESC' : 'ASC';
     210                }
     211
     212                $this->orderby = $orderby;
     213
     214                if ( $preserve_keys ) {
     215                        uasort( $this->output, array( $this, 'sort_callback' ) );
     216                } else {
     217                        usort( $this->output, array( $this, 'sort_callback' ) );
     218                }
     219
     220                $this->orderby = array();
     221
     222                return $this->output;
     223        }
     224
     225        /**
     226         * Callback to sort the list by specific fields.
     227         *
     228         * @since 4.7.0
     229         * @access private
     230         *
     231         * @see WP_List_Util::sort()
     232         *
     233         * @param object|array $a One object to compare.
     234         * @param object|array $b The other object to compare.
     235         * @return int 0 if both objects equal. -1 if second object should come first, 1 otherwise.
     236         */
     237        private function sort_callback( $a, $b ) {
     238                if ( empty( $this->orderby ) ) {
     239                        return 0;
     240                }
     241
     242                $a = (array) $a;
     243                $b = (array) $b;
     244
     245                foreach ( $this->orderby as $field => $direction ) {
     246                        if ( ! isset( $a[ $field ] ) || ! isset( $b[ $field ] ) ) {
     247                                continue;
     248                        }
     249
     250                        if ( $a[ $field ] == $b[ $field ] ) {
     251                                continue;
     252                        }
     253
     254                        $results = 'DESC' === $direction ? array( 1, -1 ) : array( -1, 1 );
     255
     256                        if ( is_numeric( $a[ $field ] ) && is_numeric( $b[ $field ] ) ) {
     257                                return ( $a[ $field ] < $b[ $field ] ) ? $results[0] : $results[1];
     258                        }
     259
     260                        return 0 > strcmp( $a[ $field ], $b[ $field ] ) ? $results[0] : $results[1];
     261                }
     262
     263                return 0;
     264        }
     265}
  • src/wp-includes/customize/class-wp-customize-nav-menu-item-setting.php

    Property changes on: src/wp-includes/class-wp-list-util.php
    ___________________________________________________________________
    Added: svn:executable
    ## -0,0 +1 ##
    +*
    \ No newline at end of property
     
    532532                }
    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
    539540                        foreach ( $items as $k => $item ) {
  • src/wp-includes/customize/class-wp-customize-nav-menu-setting.php

     
    287287
    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
    294295
     
    313314         * This is a workaround for a lack of closures.
    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
    319322         * @return int
     
    321324         * @see WP_Customize_Nav_Menu_Setting::filter_wp_get_nav_menus()
    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 );
    326331        }
  • src/wp-includes/deprecated.php

     
    37983798
    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}
  • src/wp-includes/functions.php

     
    34893489 * Filters a list of objects, based on a set of key => value arguments.
    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
    34943495 * @param array       $args     Optional. An array of key => value arguments to match
     
    35023503 * @return array A list of objects or object fields.
    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();
     3508        }
     3509
     3510        $util = new WP_List_Util( $list );
    35073511
    3508         $list = wp_list_filter( $list, $args, $operator );
     3512        $util->filter( $args, $operator );
    35093513
    3510         if ( $field )
    3511                 $list = wp_list_pluck( $list, $field );
     3514        if ( $field ) {
     3515                $util->pluck( $field );
     3516        }
    35123517
    3513         return $list;
     3518        return $util->get_output();
    35143519}
    35153520
    35163521/**
    35173522 * Filters a list of objects, based on a set of key => value arguments.
    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.
    35223528 * @param array  $args     Optional. An array of key => value arguments to match
     
    35283534 * @return array Array of found values.
    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                 }
    35553539        }
    35563540
    3557         return $filtered;
     3541        $util = new WP_List_Util( $list );
     3542        return $util->filter( $args, $operator );
    35583543}
    35593544
    35603545/**
     
    35653550 *
    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
    35703556 * @param int|string $field     Field from the object to place instead of the entire object
     
    35753561 *               `$list` will be preserved in the results.
    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         }
     3564        $util = new WP_List_Util( $list );
     3565        return $util->pluck( $field, $index_key );
     3566}
    35923567
    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                 }
     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 * @param bool         $preserve_keys Optional. Whether to preserve keys. Default false.
     3579 * @return array The sorted array.
     3580 */
     3581function wp_list_sort( $list, $orderby = array(), $order = 'ASC', $preserve_keys = false ) {
     3582        if ( ! is_array( $list ) ) {
     3583                return array();
    36123584        }
    36133585
    3614         return $newlist;
     3586        $util = new WP_List_Util( $list );
     3587        return $util->sort( $orderby, $order, $preserve_keys );
    36153588}
    36163589
    36173590/**
     
    55725545        }
    55735546
    55745547        return $last_changed;
    5575 }
    5576  No newline at end of file
     5548}
  • src/wp-includes/link-template.php

     
    169169                if ( strpos($permalink, '%category%') !== false ) {
    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                                /**
    175177                                 * Filters the category that gets used in the %category% permalink token.
  • src/wp-includes/nav-menu.php

     
    558558}
    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 *
    595563 * @link https://core.trac.wordpress.org/ticket/13958
     
    682650        }
    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 ) {
    689658                        $items[$k]->{$args['output_key']} = $i++;
     
    776745
    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 ) {
    782751                                $object = get_taxonomy( $menu_item->object );
  • src/wp-settings.php

     
    9191
    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' );
    9697require( ABSPATH . WPINC . '/class-wp.php' );
  • tests/phpunit/tests/functions/wpListUtil.php

     
     1<?php
     2
     3/**
     4 * @group functions.php
     5 */
     6class Tests_WP_List_Util extends WP_UnitTestCase {
     7        public function data_test_wp_list_pluck() {
     8                return array(
     9                        'arrays'                         => array(
     10                                array(
     11                                        array( 'foo' => 'bar', 'bar' => 'baz', 'abc' => 'xyz' ),
     12                                        array( 'foo' => 'foo', '123' => '456', 'lorem' => 'ipsum' ),
     13                                        array( 'foo' => 'baz' ),
     14                                ),
     15                                'foo',
     16                                null,
     17                                array( 'bar', 'foo', 'baz' ),
     18                        ),
     19                        'arrays with index key'          => array(
     20                                array(
     21                                        array( 'foo' => 'bar', 'bar' => 'baz', 'abc' => 'xyz', 'key' => 'foo' ),
     22                                        array( 'foo' => 'foo', '123' => '456', 'lorem' => 'ipsum', 'key' => 'bar' ),
     23                                        array( 'foo' => 'baz', 'key' => 'value' ),
     24                                ),
     25                                'foo',
     26                                'key',
     27                                array( 'foo' => 'bar', 'bar' => 'foo', 'value' => 'baz' ),
     28                        ),
     29                        'arrays with index key missing'  => array(
     30                                array(
     31                                        array( 'foo' => 'bar', 'bar' => 'baz', 'abc' => 'xyz' ),
     32                                        array( 'foo' => 'foo', '123' => '456', 'lorem' => 'ipsum', 'key' => 'bar' ),
     33                                        array( 'foo' => 'baz', 'key' => 'value' ),
     34                                ),
     35                                'foo',
     36                                'key',
     37                                array( 'bar' => 'foo', 'value' => 'baz', 'bar' ),
     38                        ),
     39                        'objects'                        => array(
     40                                array(
     41                                        (object) array( 'foo' => 'bar', 'bar' => 'baz', 'abc' => 'xyz' ),
     42                                        (object) array( 'foo' => 'foo', '123' => '456', 'lorem' => 'ipsum' ),
     43                                        (object) array( 'foo' => 'baz' ),
     44                                ),
     45                                'foo',
     46                                null,
     47                                array( 'bar', 'foo', 'baz' ),
     48                        ),
     49                        'objects with index key'         => array(
     50                                array(
     51                                        (object) array( 'foo' => 'bar', 'bar' => 'baz', 'abc' => 'xyz', 'key' => 'foo' ),
     52                                        (object) array( 'foo' => 'foo', '123' => '456', 'lorem' => 'ipsum', 'key' => 'bar' ),
     53                                        (object) array( 'foo' => 'baz', 'key' => 'value' ),
     54                                ),
     55                                'foo',
     56                                'key',
     57                                array( 'foo' => 'bar', 'bar' => 'foo', 'value' => 'baz' ),
     58                        ),
     59                        'objects with index key missing' => array(
     60                                array(
     61                                        (object) array( 'foo' => 'bar', 'bar' => 'baz', 'abc' => 'xyz' ),
     62                                        (object) array( 'foo' => 'foo', '123' => '456', 'lorem' => 'ipsum', 'key' => 'bar' ),
     63                                        (object) array( 'foo' => 'baz', 'key' => 'value' ),
     64                                ),
     65                                'foo',
     66                                'key',
     67                                array( 'bar' => 'foo', 'value' => 'baz', 'bar' ),
     68                        ),
     69                );
     70        }
     71
     72        /**
     73         * @dataProvider data_test_wp_list_pluck
     74         *
     75         * @param array      $list      List of objects or arrays.
     76         * @param int|string $field     Field from the object to place instead of the entire object
     77         * @param int|string $index_key Field from the object to use as keys for the new array.
     78         * @param array      $expected  Expected result.
     79         */
     80        public function test_wp_list_pluck( $list, $field, $index_key, $expected ) {
     81                $this->assertEqualSetsWithIndex( $expected, wp_list_pluck( $list, $field, $index_key ) );
     82        }
     83
     84        public function data_test_wp_list_filter() {
     85                return array(
     86                        'string instead of array'  => array(
     87                                'foo',
     88                                array(),
     89                                'AND',
     90                                array(),
     91                        ),
     92                        'object instead of array'  => array(
     93                                (object) array( 'foo' ),
     94                                array(),
     95                                'AND',
     96                                array(),
     97                        ),
     98                        'empty args'               => array(
     99                                array( 'foo', 'bar' ),
     100                                array(),
     101                                'AND',
     102                                array( 'foo', 'bar' ),
     103                        ),
     104                        'invalid operator'         => array(
     105                                array(
     106                                        (object) array( 'foo' => 'bar' ),
     107                                        (object) array( 'foo' => 'baz' ),
     108                                ),
     109                                array( 'foo' => 'bar' ),
     110                                'XOR',
     111                                array(),
     112                        ),
     113                        'single argument to match' => array(
     114                                array(
     115                                        (object) array( 'foo' => 'bar', 'bar' => 'baz', 'abc' => 'xyz', 'key' => 'foo' ),
     116                                        (object) array( 'foo' => 'foo', '123' => '456', 'lorem' => 'ipsum', 'key' => 'bar' ),
     117                                        (object) array( 'foo' => 'baz', 'key' => 'value' ),
     118                                        (object) array( 'foo' => 'bar', 'key' => 'value' ),
     119                                ),
     120                                array( 'foo' => 'bar' ),
     121                                'AND',
     122                                array(
     123                                        0 => (object) array( 'foo' => 'bar', 'bar' => 'baz', 'abc' => 'xyz', 'key' => 'foo' ),
     124                                        3 => (object) array( 'foo' => 'bar', 'key' => 'value' ),
     125                                ),
     126                        ),
     127                        'all must match'           => array(
     128                                array(
     129                                        (object) array( 'foo' => 'bar', 'bar' => 'baz', 'abc' => 'xyz', 'key' => 'foo' ),
     130                                        (object) array( 'foo' => 'foo', '123' => '456', 'lorem' => 'ipsum', 'key' => 'bar' ),
     131                                        (object) array( 'foo' => 'baz', 'key' => 'value', 'bar' => 'baz' ),
     132                                        (object) array( 'foo' => 'bar', 'key' => 'value' ),
     133                                ),
     134                                array( 'foo' => 'bar', 'bar' => 'baz' ),
     135                                'AND',
     136                                array(
     137                                        0 => (object) array( 'foo' => 'bar', 'bar' => 'baz', 'abc' => 'xyz', 'key' => 'foo' ),
     138                                ),
     139                        ),
     140                        'any must match'           => array(
     141                                array(
     142                                        (object) array( 'foo' => 'bar', 'bar' => 'baz', 'abc' => 'xyz', 'key' => 'foo' ),
     143                                        (object) array( 'foo' => 'foo', '123' => '456', 'lorem' => 'ipsum', 'key' => 'bar' ),
     144                                        (object) array( 'foo' => 'baz', 'key' => 'value', 'bar' => 'baz' ),
     145                                        (object) array( 'foo' => 'bar', 'key' => 'value' ),
     146                                ),
     147                                array( 'key' => 'value', 'bar' => 'baz' ),
     148                                'OR',
     149                                array(
     150                                        0 => (object) array( 'foo' => 'bar', 'bar' => 'baz', 'abc' => 'xyz', 'key' => 'foo' ),
     151                                        2 => (object) array( 'foo' => 'baz', 'key' => 'value', 'bar' => 'baz' ),
     152                                        3 => (object) array( 'foo' => 'bar', 'key' => 'value' ),
     153                                ),
     154                        ),
     155                        'none must match'          => array(
     156                                array(
     157                                        (object) array( 'foo' => 'bar', 'bar' => 'baz', 'abc' => 'xyz', 'key' => 'foo' ),
     158                                        (object) array( 'foo' => 'foo', '123' => '456', 'lorem' => 'ipsum', 'key' => 'bar' ),
     159                                        (object) array( 'foo' => 'baz', 'key' => 'value' ),
     160                                        (object) array( 'foo' => 'bar', 'key' => 'value' ),
     161                                ),
     162                                array( 'key' => 'value', 'bar' => 'baz' ),
     163                                'NOT',
     164                                array(
     165                                        1 => (object) array( 'foo' => 'foo', '123' => '456', 'lorem' => 'ipsum', 'key' => 'bar' ),
     166                                ),
     167                        ),
     168                );
     169        }
     170
     171        /**
     172         * @dataProvider data_test_wp_list_filter
     173         *
     174         * @param array  $list     An array of objects to filter.
     175         * @param array  $args     An array of key => value arguments to match
     176         *                         against each object.
     177         * @param string $operator The logical operation to perform.
     178         * @param array  $expected Expected result.
     179         */
     180        public function test_wp_list_filter( $list, $args, $operator, $expected ) {
     181                $this->assertEqualSetsWithIndex( $expected, wp_list_filter( $list, $args, $operator ) );
     182        }
     183
     184        public function data_test_wp_list_sort() {
     185                return array(
     186                        'single orderby ascending'        => array(
     187                                array(
     188                                        array( 'foo' => 'bar', 'bar' => 'baz', 'key' => 'foo' ),
     189                                        array( 'foo' => 'foo', 'lorem' => 'ipsum', 'key' => 'bar' ),
     190                                        array( 'foo' => 'baz', 'key' => 'value' ),
     191                                ),
     192                                'foo',
     193                                'ASC',
     194                                array(
     195                                        array( 'foo' => 'bar', 'bar' => 'baz', 'key' => 'foo' ),
     196                                        array( 'foo' => 'baz', 'key' => 'value' ),
     197                                        array( 'foo' => 'foo', 'lorem' => 'ipsum', 'key' => 'bar' ),
     198                                ),
     199                        ),
     200                        'single orderby descending'       => array(
     201                                array(
     202                                        array( 'foo' => 'bar', 'bar' => 'baz', 'key' => 'foo' ),
     203                                        array( 'foo' => 'foo', 'lorem' => 'ipsum', 'key' => 'bar' ),
     204                                        array( 'foo' => 'baz', 'key' => 'value' ),
     205                                ),
     206                                'foo',
     207                                'DESC',
     208                                array(
     209                                        array( 'foo' => 'foo', 'lorem' => 'ipsum', 'key' => 'bar' ),
     210                                        array( 'foo' => 'baz', 'key' => 'value' ),
     211                                        array( 'foo' => 'bar', 'bar' => 'baz', 'key' => 'foo' ),
     212                                ),
     213                        ),
     214                        'single orderby array ascending'  => array(
     215                                array(
     216                                        array( 'foo' => 'bar', 'bar' => 'baz', 'key' => 'foo' ),
     217                                        array( 'foo' => 'foo', 'lorem' => 'ipsum', 'key' => 'bar' ),
     218                                        array( 'foo' => 'baz', 'key' => 'value' ),
     219                                ),
     220                                array( 'foo' => 'ASC' ),
     221                                'IGNORED',
     222                                array(
     223                                        array( 'foo' => 'bar', 'bar' => 'baz', 'key' => 'foo' ),
     224                                        array( 'foo' => 'baz', 'key' => 'value' ),
     225                                        array( 'foo' => 'foo', 'lorem' => 'ipsum', 'key' => 'bar' ),
     226                                ),
     227                        ),
     228                        'single orderby array descending' => array(
     229                                array(
     230                                        array( 'foo' => 'bar', 'bar' => 'baz', 'key' => 'foo' ),
     231                                        array( 'foo' => 'foo', 'lorem' => 'ipsum', 'key' => 'bar' ),
     232                                        array( 'foo' => 'baz', 'key' => 'value' ),
     233                                ),
     234                                array( 'foo' => 'DESC' ),
     235                                'IGNORED',
     236                                array(
     237                                        array( 'foo' => 'foo', 'lorem' => 'ipsum', 'key' => 'bar' ),
     238                                        array( 'foo' => 'baz', 'key' => 'value' ),
     239                                        array( 'foo' => 'bar', 'bar' => 'baz', 'key' => 'foo' ),
     240                                ),
     241                        ),
     242                        'multiple orderby ascending'      => array(
     243                                array(
     244                                        array( 'foo' => 'bar', 'bar' => 'baz', 'key' => 'foo' ),
     245                                        array( 'foo' => 'foo', 'lorem' => 'ipsum', 'key' => 'bar' ),
     246                                        array( 'foo' => 'foo', 'key' => 'key' ),
     247                                        array( 'foo' => 'baz', 'key' => 'key' ),
     248                                        array( 'foo' => 'bar', 'key' => 'value' ),
     249                                ),
     250                                array( 'key' => 'ASC', 'foo' => 'ASC' ),
     251                                'IGNORED',
     252                                array(
     253                                        array( 'foo' => 'foo', 'lorem' => 'ipsum', 'key' => 'bar' ),
     254                                        array( 'foo' => 'bar', 'bar' => 'baz', 'key' => 'foo' ),
     255                                        array( 'foo' => 'baz', 'key' => 'key' ),
     256                                        array( 'foo' => 'foo', 'key' => 'key' ),
     257                                        array( 'foo' => 'bar', 'key' => 'value' ),
     258                                ),
     259                        ),
     260                        'multiple orderby descending'     => array(
     261                                array(
     262                                        array( 'foo' => 'bar', 'bar' => 'baz', 'key' => 'foo' ),
     263                                        array( 'foo' => 'foo', 'lorem' => 'ipsum', 'key' => 'bar' ),
     264                                        array( 'foo' => 'foo', 'key' => 'key' ),
     265                                        array( 'foo' => 'baz', 'key' => 'key' ),
     266                                        array( 'foo' => 'bar', 'key' => 'value' ),
     267                                ),
     268                                array( 'key' => 'DESC', 'foo' => 'DESC' ),
     269                                'IGNORED',
     270                                array(
     271                                        array( 'foo' => 'bar', 'key' => 'value' ),
     272                                        array( 'foo' => 'foo', 'key' => 'key' ),
     273                                        array( 'foo' => 'baz', 'key' => 'key' ),
     274                                        array( 'foo' => 'bar', 'bar' => 'baz', 'key' => 'foo' ),
     275                                        array( 'foo' => 'foo', 'lorem' => 'ipsum', 'key' => 'bar' ),
     276                                ),
     277                        ),
     278                        'multiple orderby mixed'          => array(
     279                                array(
     280                                        array( 'foo' => 'bar', 'bar' => 'baz', 'key' => 'foo' ),
     281                                        array( 'foo' => 'foo', 'lorem' => 'ipsum', 'key' => 'bar' ),
     282                                        array( 'foo' => 'foo', 'key' => 'key' ),
     283                                        array( 'foo' => 'baz', 'key' => 'key' ),
     284                                        array( 'foo' => 'bar', 'key' => 'value' ),
     285                                ),
     286                                array( 'key' => 'DESC', 'foo' => 'ASC' ),
     287                                'IGNORED',
     288                                array(
     289                                        array( 'foo' => 'bar', 'key' => 'value' ),
     290                                        array( 'foo' => 'baz', 'key' => 'key' ),
     291                                        array( 'foo' => 'foo', 'key' => 'key' ),
     292                                        array( 'foo' => 'bar', 'bar' => 'baz', 'key' => 'foo' ),
     293                                        array( 'foo' => 'foo', 'lorem' => 'ipsum', 'key' => 'bar' ),
     294                                ),
     295                        ),
     296                );
     297        }
     298
     299        /**
     300         * @dataProvider data_test_wp_list_sort
     301         *
     302         * @param string|array $orderby Either the field name to order by or an array
     303         *                              of multiple orderby fields as $orderby => $order.
     304         * @param string       $order   Either 'ASC' or 'DESC'.
     305         */
     306        public function test_wp_list_sort( $list, $orderby, $order, $expected ) {
     307                $this->assertEquals( $expected, wp_list_sort( $list, $orderby, $order ) );
     308        }
     309
     310        public function data_test_wp_list_sort_preserve_keys() {
     311                return array(
     312                        'single orderby ascending'        => array(
     313                                array(
     314                                        'foobar' => array( 'foo' => 'bar', 'bar' => 'baz', 'key' => 'foo' ),
     315                                        'foofoo' => array( 'foo' => 'foo', 'lorem' => 'ipsum', 'key' => 'bar' ),
     316                                        'foobaz' => array( 'foo' => 'baz', 'key' => 'value' ),
     317                                ),
     318                                'foo',
     319                                'ASC',
     320                                array(
     321                                        'foobar' => array( 'foo' => 'bar', 'bar' => 'baz', 'key' => 'foo' ),
     322                                        'foobaz' => array( 'foo' => 'baz', 'key' => 'value' ),
     323                                        'foofoo' => array( 'foo' => 'foo', 'lorem' => 'ipsum', 'key' => 'bar' ),
     324                                ),
     325                        ),
     326                        'single orderby descending'       => array(
     327                                array(
     328                                        'foobar' => array( 'foo' => 'bar', 'bar' => 'baz', 'key' => 'foo' ),
     329                                        'foofoo' => array( 'foo' => 'foo', 'lorem' => 'ipsum', 'key' => 'bar' ),
     330                                        'foobaz' => array( 'foo' => 'baz', 'key' => 'value' ),
     331                                ),
     332                                'foo',
     333                                'DESC',
     334                                array(
     335                                        'foofoo' => array( 'foo' => 'foo', 'lorem' => 'ipsum', 'key' => 'bar' ),
     336                                        'foobaz' => array( 'foo' => 'baz', 'key' => 'value' ),
     337                                        'foobar' => array( 'foo' => 'bar', 'bar' => 'baz', 'key' => 'foo' ),
     338                                ),
     339                        ),
     340                        'single orderby array ascending'  => array(
     341                                array(
     342                                        'foobar' => array( 'foo' => 'bar', 'bar' => 'baz', 'key' => 'foo' ),
     343                                        'foofoo' => array( 'foo' => 'foo', 'lorem' => 'ipsum', 'key' => 'bar' ),
     344                                        'foobaz' => array( 'foo' => 'baz', 'key' => 'value' ),
     345                                ),
     346                                array( 'foo' => 'ASC' ),
     347                                'IGNORED',
     348                                array(
     349                                        'foobar' => array( 'foo' => 'bar', 'bar' => 'baz', 'key' => 'foo' ),
     350                                        'foobaz' => array( 'foo' => 'baz', 'key' => 'value' ),
     351                                        'foofoo' => array( 'foo' => 'foo', 'lorem' => 'ipsum', 'key' => 'bar' ),
     352                                ),
     353                        ),
     354                        'single orderby array descending' => array(
     355                                array(
     356                                        'foobar' => array( 'foo' => 'bar', 'bar' => 'baz', 'key' => 'foo' ),
     357                                        'foofoo' => array( 'foo' => 'foo', 'lorem' => 'ipsum', 'key' => 'bar' ),
     358                                        'foobaz' => array( 'foo' => 'baz', 'key' => 'value' ),
     359                                ),
     360                                array( 'foo' => 'DESC' ),
     361                                'IGNORED',
     362                                array(
     363                                        'foofoo' => array( 'foo' => 'foo', 'lorem' => 'ipsum', 'key' => 'bar' ),
     364                                        'foobaz' => array( 'foo' => 'baz', 'key' => 'value' ),
     365                                        'foobar' => array( 'foo' => 'bar', 'bar' => 'baz', 'key' => 'foo' ),
     366                                ),
     367                        ),
     368                        'multiple orderby ascending'      => array(
     369                                array(
     370                                        'foobarfoo'   => array( 'foo' => 'bar', 'bar' => 'baz', 'key' => 'foo' ),
     371                                        'foofoobar'   => array( 'foo' => 'foo', 'lorem' => 'ipsum', 'key' => 'bar' ),
     372                                        'foofookey'   => array( 'foo' => 'foo', 'key' => 'key' ),
     373                                        'foobazkey'   => array( 'foo' => 'baz', 'key' => 'key' ),
     374                                        'foobarvalue' => array( 'foo' => 'bar', 'key' => 'value' ),
     375                                ),
     376                                array( 'key' => 'ASC', 'foo' => 'ASC' ),
     377                                'IGNORED',
     378                                array(
     379                                        'foofoobar'   => array( 'foo' => 'foo', 'lorem' => 'ipsum', 'key' => 'bar' ),
     380                                        'foobarfoo'   => array( 'foo' => 'bar', 'bar' => 'baz', 'key' => 'foo' ),
     381                                        'foobazkey'   => array( 'foo' => 'baz', 'key' => 'key' ),
     382                                        'foofookey'   => array( 'foo' => 'foo', 'key' => 'key' ),
     383                                        'foobarvalue' => array( 'foo' => 'bar', 'key' => 'value' ),
     384                                ),
     385                        ),
     386                        'multiple orderby descending'     => array(
     387                                array(
     388                                        'foobarfoo'   => array( 'foo' => 'bar', 'bar' => 'baz', 'key' => 'foo' ),
     389                                        'foofoobar'   => array( 'foo' => 'foo', 'lorem' => 'ipsum', 'key' => 'bar' ),
     390                                        'foofookey'   => array( 'foo' => 'foo', 'key' => 'key' ),
     391                                        'foobazkey'   => array( 'foo' => 'baz', 'key' => 'key' ),
     392                                        'foobarvalue' => array( 'foo' => 'bar', 'key' => 'value' ),
     393                                ),
     394                                array( 'key' => 'DESC', 'foo' => 'DESC' ),
     395                                'IGNORED',
     396                                array(
     397                                        'foobarvalue' => array( 'foo' => 'bar', 'key' => 'value' ),
     398                                        'foofookey'   => array( 'foo' => 'foo', 'key' => 'key' ),
     399                                        'foobazkey'   => array( 'foo' => 'baz', 'key' => 'key' ),
     400                                        'foobarfoo'   => array( 'foo' => 'bar', 'bar' => 'baz', 'key' => 'foo' ),
     401                                        'foofoobar'   => array( 'foo' => 'foo', 'lorem' => 'ipsum', 'key' => 'bar' ),
     402                                ),
     403                        ),
     404                        'multiple orderby mixed'          => array(
     405                                array(
     406                                        'foobarfoo'   => array( 'foo' => 'bar', 'bar' => 'baz', 'key' => 'foo' ),
     407                                        'foofoobar'   => array( 'foo' => 'foo', 'lorem' => 'ipsum', 'key' => 'bar' ),
     408                                        'foofookey'   => array( 'foo' => 'foo', 'key' => 'key' ),
     409                                        'foobazkey'   => array( 'foo' => 'baz', 'key' => 'key' ),
     410                                        'foobarvalue' => array( 'foo' => 'bar', 'key' => 'value' ),
     411                                ),
     412                                array( 'key' => 'DESC', 'foo' => 'ASC' ),
     413                                'IGNORED',
     414                                array(
     415                                        'foobarvalue' => array( 'foo' => 'bar', 'key' => 'value' ),
     416                                        'foobazkey'   => array( 'foo' => 'baz', 'key' => 'key' ),
     417                                        'foofookey'   => array( 'foo' => 'foo', 'key' => 'key' ),
     418                                        'foobarfoo'   => array( 'foo' => 'bar', 'bar' => 'baz', 'key' => 'foo' ),
     419                                        'foofoobar'   => array( 'foo' => 'foo', 'lorem' => 'ipsum', 'key' => 'bar' ),
     420                                ),
     421                        ),
     422                );
     423        }
     424
     425        /**
     426         * @dataProvider data_test_wp_list_sort_preserve_keys
     427         *
     428         * @param string|array $orderby Either the field name to order by or an array
     429         *                              of multiple orderby fields as $orderby => $order.
     430         * @param string       $order   Either 'ASC' or 'DESC'.
     431         */
     432        public function test_wp_list_sort_preserve_keys( $list, $orderby, $order, $expected ) {
     433                $this->assertEquals( $expected, wp_list_sort( $list, $orderby, $order, true ) );
     434        }
     435
     436        public function test_wp_list_util_get_input() {
     437                $input = array( 'foo', 'bar' );
     438                $util  = new WP_List_Util( $input );
     439
     440                $this->assertEqualSets( $input, $util->get_input() );
     441        }
     442
     443        public function test_wp_list_util_get_output_immediately() {
     444                $input = array( 'foo', 'bar' );
     445                $util  = new WP_List_Util( $input );
     446
     447                $this->assertEqualSets( $input, $util->get_output() );
     448        }
     449
     450        public function test_wp_list_util_get_output() {
     451                $expected = array( (object) array( 'foo' => 'bar', 'bar' => 'baz' ) );
     452
     453                $util   = new WP_List_Util( array( (object) array( 'foo' => 'bar', 'bar' => 'baz' ), (object) array( 'bar' => 'baz' ) ) );
     454                $actual = $util->filter( array( 'foo' => 'bar' ) );
     455
     456                $this->assertEqualSets( $expected, $actual );
     457                $this->assertEqualSets( $expected, $util->get_output() );
     458        }
     459}